OSDN Git Service

3e9467e100423aff666697fbe2954e550cca2fe8
[handbrake-jp/handbrake-jp-git.git] / scripts / manicure.rb
1 #! /usr/bin/ruby
2 # manincure.rb version 0.66
3
4 # This file is part of the HandBrake source code.
5 # Homepage: <http://handbrake.m0k.org/>.
6 # It may be used under the terms of the GNU General Public License.
7
8 # This script parses HandBrake's Mac presets into hashes, which can
9 # be displayed in various formats for use by the CLI and its wrappers.
10
11 # For handling command line arguments to the script
12 require 'optparse'
13 require 'ostruct'
14 require 'rubygems'
15 require 'plist'
16
17 # CLI options: (code based on http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/index.html )
18 def readOptions
19   
20   # --[no-]cli-raw, -r gives raw CLI for wiki
21   # --cli-parse, -p gives CLI strings for wrappers
22   # --api, -a gives preset code for test.c
23   # --api-list, -A gives CLI strings for --preset-list display
24   # --[no-]header, -h turns off banner display
25   options = OpenStruct.new
26   options.cliraw = false
27   options.cliparse = false
28   options.api = false
29   options.apilist = false
30   options.header = false
31   
32   opts = OptionParser.new do |opts|
33     opts.banner = "Usage: manicure.rb [options]"
34     
35     opts.separator ""
36     opts.separator "Options:"
37     
38     opts.on("-r", "--cli-raw", "Gives example strings for the HB wiki") do |raw|
39       options.cliraw = raw
40       option_set = true
41     end
42     
43     opts.on("-p", "--cli-parse", "Gives presets as wrapper-parseable CLI", " option strings") do |par|
44       options.cliparse = par
45     end
46     
47     opts.on("-a", "--api", "Gives preset code for test.c") do |api|
48       options.api = api
49     end
50     
51     opts.on("-A", "--api-list", "Gives code for test.c's --preset-list", " options") do |alist|
52       options.apilist = alist
53     end
54     
55     opts.on("-H", "--Header", "Display a banner before each preset") do |head|
56       options.header = head
57     end
58     
59     opts.on_tail("-h", "--help", "Show this message") do
60         puts opts
61         exit
62     end
63   end.parse!
64   
65   return options
66   
67 end
68
69 # These arrays contain all the other presets and hashes that are going to be used.
70 # Yeah, they're global variables. In an object-oriented scripting language.
71 # Real smooth, huh?
72
73 # This class parses the user's presets .plist into an array of hashes
74 class Presets
75   
76   attr_reader :hashMasterList
77   
78   # Running initialization runs everything.
79   # Calling it will also call the parser
80   # and display output.
81   def initialize
82     
83    # Grab the user's home path
84    homeLocation = `echo $HOME`.chomp
85    
86    # Use that to build a path to the presets .plist
87    inputFile = homeLocation+'/Library/Application Support/HandBrake/UserPresets.plist'
88    
89     # Parse the presets into hashes
90     @hashMasterList = Plist::parse_xml( inputFile )
91     
92   end
93
94 end
95
96 # This class displays the presets to stdout in various formats.
97 class Display
98   
99   def initialize(hashMasterList, options)
100   
101     @hashMasterList = hashMasterList
102     @options = options
103
104     # A width of 40 gives nice, compact output.
105     @columnWidth=40
106     
107     # Print to screen.
108     displayCommandStrings
109     
110   end
111   
112   def displayCommandStrings # prints everything to screen
113     
114     # Iterate through the hashes.    
115     @hashMasterList.each do |hash|
116     
117       # Check to see whether we've got a preset or afolder
118       if !hash["Folder"]
119         # It's a top-level preset
120        displayIndividualPreset(hash, 0) 
121       else
122         # It's a folder, yay
123         displayFolder( hash, 0 )
124         hash["ChildrenArray"].each do |subhash|
125           # Drill down to see its contents
126           if !subhash["Folder"]
127             # It's a preset
128             displayIndividualPreset(subhash, 1)
129           else
130             # It's a folder
131             displayFolder( subhash, 1 )
132             subhash["ChildrenArray"].each do |subsubhash|
133               # At this point we're far enough down we won't try to drill further
134               if !subsubhash["Folder"]
135                 displayIndividualPreset(subsubhash, 2)
136               end
137             end
138             displayFolderCloser( 1 )
139           end
140         end
141         displayFolderCloser( 0 )
142       end
143     end
144   end
145   
146   def displayIndividualPreset(hash, depth)
147     if @options.header == true
148       # First throw up a header to make each preset distinct
149       displayHeader(hash)
150     end
151     
152     if @options.cliraw == true
153       # Show the preset's full CLI string equivalent
154       generateCLIString(hash, depth)
155     end
156     
157     if @options.cliparse == true
158       generateCLIParse(hash, depth)
159     end
160     
161     if @options.api == true
162       # Show the preset as code for test/test.c, HandBrakeCLI
163       generateAPIcalls(hash)
164     end
165     
166     if @options.apilist == true
167       # Show the preset as print statements, for CLI wrappers to parse.
168       generateAPIList(hash, depth) 
169     end
170   end
171   
172   def displayHeader(hash) # A distinct banner to separate each preset
173     
174     # Print a line of asterisks
175     puts "*" * @columnWidth
176     
177     # Print the name, centered
178     puts '* '+hash["PresetName"].to_s.center(@columnWidth-4)+' *'
179     
180     # Print a line of dashes
181     puts '~' * @columnWidth
182     
183     # Print the description, centered and word-wrapped
184     puts hash["PresetDescription"].to_s.center(@columnWidth).gsub(/\n/," ").scan(/\S.{0,#{@columnWidth-2}}\S(?=\s|$)|\S+/)
185     
186     # Print another line of dashes
187     puts '~' * @columnWidth
188     
189     # Print the formats the preset uses
190     puts "#{hash["FileCodecs"]}".center(@columnWidth)
191     
192     # Note if the preset isn't built-in
193     if hash["Type"] == 1
194       puts "Custom Preset".center(@columnWidth)
195     end
196
197     # Note if the preset is marked as default.
198     if hash["Default"] == 1
199       puts "This is your default preset.".center(@columnWidth)
200     end
201     
202     # End with a line of tildes.  
203     puts "~" * @columnWidth
204     
205   end
206   
207   def displayFolder( hash, depth )
208
209     if @options.cliraw == true
210       # Show the folder's full in a format that matches the CLI equivalents
211       generateCLIFolderString(hash, depth)
212     end
213     
214     if @options.cliparse == true
215       # Show the folder in a format that matches the CLI wrapper equivalents
216       generateCLIFolderParse(hash, depth)
217     end
218     
219     if @options.apilist == true
220       # Show the folder as print statements, for CLI wrappers to parse.
221       generateAPIFolderList(hash, depth) 
222     end
223     
224   end
225   
226   def displayFolderCloser( depth )
227     if @options.cliraw == true
228       # Show the folder's full in a format that matches the CLI equivalents
229       generateCLIFolderCloserString( depth )
230     end
231     
232     if @options.cliparse == true
233       # Show the folder in a format that matches the CLI wrapper equivalents
234       generateCLIFolderCloserParse( depth )
235     end
236     
237     if @options.apilist == true
238       # Show the folder as print statements, for CLI wrappers to parse.
239       generateAPIFolderCloserList( depth ) 
240     end
241   end
242   
243   def generateCLIFolderString( hash, depth ) # Shows the folder for the CLI equivalents
244     commandString = ""
245     depth.times do
246       commandString << "   "
247     end
248     (depth+1).times do
249       commandString << "<"
250     end
251     commandString << " " << hash["PresetName"] << "\n\n"
252     puts commandString
253   end
254   
255   def generateCLIFolderCloserString( depth )
256     commandString = ""
257     depth.times do
258       commandString << "   "
259     end
260     (depth+1).times do
261       commandString << ">"
262     end
263     commandString << "\n\n"
264     puts commandString
265   end
266   
267   def generateCLIString(hash, depth) # Makes a full CLI equivalent of a preset
268     commandString = ""
269     depth.times do
270       commandString << "   "
271     end
272     commandString << './HandBrakeCLI -i DVD -o ~/Movies/movie.'
273     
274     #Filename suffix
275     case hash["FileFormat"]
276     when /MP4/
277       commandString << "mp4 "
278     when /AVI/
279       commandString << "avi "
280     when /OGM/
281       commandString << "ogm "
282     when /MKV/
283       commandString << "mkv "
284     end
285     
286     #Video encoder
287     if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
288       commandString << " -e "
289       case hash["VideoEncoder"]
290       when /x264/
291         commandString << "x264"
292       when /XviD/
293         commandString << "xvid"
294       end
295     end
296
297     #VideoRateControl
298     case hash["VideoQualityType"]
299     when 0
300       commandString << " -S " << hash["VideoTargetSize"]
301     when 1
302       commandString << " -b " << hash["VideoAvgBitrate"]
303     when 2
304       commandString << " -q " << hash["VideoQualitySlider"].to_s
305     end
306
307     #FPS
308     if hash["VideoFramerate"] != "Same as source"
309       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
310         commandString << " -r " << "23.976"
311       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
312         commandString << " -r " << "29.97"
313       else
314         commandString << " -r " << hash["VideoFramerate"]
315       end
316     end
317     
318     #Audio tracks
319     commandString << " -a "
320     commandString << hash["Audio1Track"].to_s
321     if hash["Audio2Track"]
322       commandString << "," << hash["Audio2Track"].to_s
323     end
324     if hash["Audio3Track"]
325       commandString << "," << hash["Audio3Track"].to_s
326     end
327     if hash["Audio4Track"]
328       commandString << "," << hash["Audio4Track"].to_s
329     end
330     
331     #Audio encoders
332     commandString << " -E "
333     case hash["Audio1Encoder"]
334     when /AC3 /
335       commandString << "ac3"
336     when /AAC/
337       commandString << "faac"
338     when /Vorbis/
339       commandString << "vorbis"
340     when /MP3/
341       commandString << "lame"
342     end
343     case hash["Audio2Encoder"]
344     when /AC3 /
345       commandString << ",ac3"
346     when /AAC/
347       commandString << ",faac"
348     when /Vorbis/
349       commandString << ",vorbis"
350     when /MP3/
351       commandString << ",lame"
352     end
353     case hash["Audio3Encoder"]
354     when /AC3 /
355       commandString << ",ac3"
356     when /AAC/
357       commandString << ",faac"
358     when /Vorbis/
359       commandString << ",vorbis"
360     when /MP3/
361       commandString << ",lame"
362     end
363     case hash["Audio4Encoder"]
364     when /AC3 /
365       commandString << ",ac3"
366     when /AAC/
367       commandString << ",faac"
368     when /Vorbis/
369       commandString << ",vorbis"
370     when /MP3/
371       commandString << ",lame"
372     end
373     
374     #Audio bit rate
375     commandString << " -B "
376     commandString << hash["Audio1Bitrate"]
377     if hash["Audio2Bitrate"]
378       if hash["Audio2Encoder"] != "AC3 Passthru"
379         commandString << "," << hash["Audio2Bitrate"]
380       else
381         commandString << "," << "auto"
382       end
383     end
384     if hash["Audio3Bitrate"]
385       if hash["Audio3Encoder"] != "AC3 Passthru"
386         commandString << "," << hash["Audio3Bitrate"]
387       else
388         commandString << "," << "auto"
389       end
390     end
391     if hash["Audio4Bitrate"]
392       if hash["Audio4Encoder"] != "AC3 Passthru"
393         commandString << "," << hash["Audio4Bitrate"]
394       else
395         commandString << "," << "auto"
396       end
397     end
398
399     #Audio sample rate
400     commandString << " -R "
401     commandString << hash["Audio1Samplerate"]
402     if hash["Audio2Samplerate"]
403       commandString << "," << hash["Audio2Samplerate"]
404     end
405     if hash["Audio3Samplerate"]
406       commandString << "," << hash["Audio3Samplerate"]
407     end
408     if hash["Audio4Samplerate"]
409       commandString << "," << hash["Audio4Samplerate"]
410     end
411     
412     #Audio Mixdown
413     commandString << " -6 "
414     case hash["Audio1Mixdown"]
415     when /Mono/
416       commandString << "mono"
417     when /Stereo/
418       commandString << "stereo"
419     when /Dolby Surround/
420       commandString << "dpl1"
421     when /Dolby Pro Logic II/
422       commandString << "dpl2"
423     when /discrete/
424       commandString << "6ch"
425     when /Passthru/
426       commandString << "auto"
427     end
428     
429     if hash["Audio2Mixdown"]
430       case hash["Audio2Mixdown"]
431       when /Mono/
432         commandString << ",mono"
433       when /Stereo/
434         commandString << ",stereo"
435       when /Dolby Surround/
436         commandString << ",dpl1"
437       when /Dolby Pro Logic II/
438         commandString << ",dpl2"
439       when /discrete/
440         commandString << ",6ch"
441       when /Passthru/
442         commandString << ",auto"
443       end
444     end
445     
446     if hash["Audio3Mixdown"]
447       case hash["Audio3Mixdown"]
448       when /Mono/
449         commandString << ",mono"
450       when /Stereo/
451         commandString << ",stereo"
452       when /Dolby Surround/
453         commandString << ",dpl1"
454       when /Dolby Pro Logic II/
455         commandString << ",dpl2"
456       when /discrete/
457         commandString << ",6ch"
458       when /Passthru/
459         commandString << ",auto"
460       end
461     end
462     
463     if hash["Audio4Mixdown"]
464       case hash["Audio4Mixdown"]
465       when /Mono/
466         commandString << ",mono"
467       when /Stereo/
468         commandString << ",stereo"
469       when /Dolby Surround/
470         commandString << ",dpl1"
471       when /Dolby Pro Logic II/
472         commandString << ",dpl2"
473       when /discrete/
474         commandString << ",6ch"
475       when /Passthru/
476         commandString << ",auto"
477       end
478     end
479     
480     #Container
481     commandString << " -f "
482     case hash["FileFormat"]
483     when /MP4/
484       commandString << "mp4"
485     when /AVI/
486       commandString << "avi"
487     when /OGM/
488       commandString << "ogm"
489     when /MKV/
490       commandString << "mkv"
491     end
492     
493     #iPod MP4 atom
494     if hash["Mp4iPodCompatible"].to_i == 1
495       commandString << " -I"
496     end
497     
498     # 64-bit files
499     if hash["Mp4LargeFile"] == 1
500       commandString << " -4"
501     end
502     
503     #Cropping
504     if hash["PictureAutoCrop"] == 0
505       commandString << " --crop "
506       commandString << hash["PictureTopCrop"].to_s
507       commandString << ":"
508       commandString << hash["PictureBottomCrop"].to_s
509       commandString << ":"
510       commandString << hash["PictureLeftCrop"].to_s
511       commandString << ":"
512       commandString << hash["PictureRightCrop"].to_s
513     end
514     
515     #Dimensions
516     if hash["PictureWidth"] != 0
517       commandString << " -X "
518       commandString << hash["PictureWidth"].to_s
519     end
520     if hash["PictureHeight"] != 0
521       commandString << " -Y "
522       commandString << hash["PictureHeight"].to_s
523     end
524     
525     #Subtitles
526     if hash["Subtitles"] != "None"
527       commandString << " -s "
528       commandString << hash["Subtitles"]
529     end
530
531     #Video Filters
532     if hash["UsesPictureFilters"] == 1
533       
534       case hash["PictureDeinterlace"]
535       when 1
536         commandString << " --deinterlace=\"fast\""
537       when 2
538         commandString << " --deinterlace=\slow\""
539       when 3
540         commandString << " --deinterlace=\"slower\""
541       when 4
542         commandString << " --deinterlace=\"slowest\""
543       end
544       
545       case hash["PictureDenoise"]
546       when 1
547         commandString << " --denoise=\"weak\""
548       when 2
549         commandString << " --denoise=\"medium\""
550       when 3
551         commandString << " --denoise=\"strong\""
552       end
553       
554       if hash["PictureDetelecine"] == 1 then commandString << " --detelecine" end
555       if hash["PictureDeblock"] == 1 then commandString << " --deblock" end
556       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
557       if hash["PictureDecomb"] == 1 then commandString << " --decomb" end
558       
559     end
560     
561     #Anamorphic
562     if hash["PicturePAR"] == 1
563       commandString << " -p"
564     elsif hash["PicturePAR"] == 2
565       commandString << " -P"
566     end
567
568     #Booleans
569     if hash["ChapterMarkers"] == 1 then commandString << " -m" end
570     if hash["VideoGrayScale"] == 1 then commandString << " -g" end
571     if hash["VideoTwoPass"] == 1 then commandString << " -2" end
572     if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
573
574     #x264 Options
575     if hash["x264Option"] != ""
576       commandString << " -x "
577       commandString << hash["x264Option"]
578     end
579     
580     # That's it, print to screen now
581     puts commandString
582     
583     #puts "*" * @columnWidth
584
585     puts  "\n"
586   end
587   
588   def generateCLIFolderParse( hash, depth ) # Shows the folder for wrappers to parse
589     commandString = ""
590     depth.times do
591       commandString << "   "
592     end
593     (depth+1).times do
594       commandString << "<"
595     end
596     commandString << " " << hash["PresetName"] << "\n\n"
597     puts commandString
598   end
599   
600   def generateCLIFolderCloserParse( depth )
601     commandString = ""
602     depth.times do
603       commandString << "   "
604     end
605     (depth+1).times do
606       commandString << ">"
607     end
608     commandString << "\n\n"
609     puts commandString
610   end
611   
612   def generateCLIParse(hash, depth) # Makes a CLI equivalent of all user presets, for wrappers to parse
613     commandString = ""
614     depth.times do
615       commandString << "   "
616     end
617     commandString << '+ ' << hash["PresetName"] << ":"
618         
619     #Video encoder
620     if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
621       commandString << " -e "
622       case hash["VideoEncoder"]
623       when /x264/
624         commandString << "x264"
625       when /XviD/
626         commandString << "xvid"
627       end
628     end
629
630     #VideoRateControl
631     case hash["VideoQualityType"]
632     when 0
633       commandString << " -S " << hash["VideoTargetSize"]
634     when 1
635       commandString << " -b " << hash["VideoAvgBitrate"]
636     when 2
637       commandString << " -q " << hash["VideoQualitySlider"].to_s
638     end
639
640     #FPS
641     if hash["VideoFramerate"] != "Same as source"
642       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
643         commandString << " -r " << "23.976"
644       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
645         commandString << " -r " << "29.97"
646       else
647         commandString << " -r " << hash["VideoFramerate"]
648       end
649     end
650     
651     #Audio tracks
652     commandString << " -a "
653     commandString << hash["Audio1Track"].to_s
654     if hash["Audio2Track"]
655       commandString << "," << hash["Audio2Track"].to_s
656     end
657     if hash["Audio3Track"]
658       commandString << "," << hash["Audio3Track"].to_s
659     end
660     if hash["Audio4Track"]
661       commandString << "," << hash["Audio4Track"].to_s
662     end
663     
664     #Audio encoders
665     commandString << " -E "
666     case hash["Audio1Encoder"]
667     when /AC3/
668       commandString << "ac3"
669     when /AAC/
670       commandString << "faac"
671     when /Vorbis/
672       commandString << "vorbis"
673     when /MP3/
674       commandString << "lame"
675     end
676     case hash["Audio2Encoder"]
677     when /AC3 /
678       commandString << ",ac3"
679     when /AAC/
680       commandString << ",faac"
681     when /Vorbis/
682       commandString << ",vorbis"
683     when /MP3/
684       commandString << ",lame"
685     end
686     case hash["Audio3Encoder"]
687     when /AC3 /
688       commandString << ",ac3"
689     when /AAC/
690       commandString << ",faac"
691     when /Vorbis/
692       commandString << ",vorbis"
693     when /MP3/
694       commandString << ",lame"
695     end
696     case hash["Audio4Encoder"]
697     when /AC3 /
698       commandString << ",ac3"
699     when /AAC/
700       commandString << ",faac"
701     when /Vorbis/
702       commandString << ",vorbis"
703     when /MP3/
704       commandString << ",lame"
705     end
706
707     #Audio bit rate
708     commandString << " -B "
709     commandString << hash["Audio1Bitrate"]
710     if hash["Audio2Bitrate"]
711       if hash["Audio2Encoder"] != "AC3 Passthru"
712         commandString << "," << hash["Audio2Bitrate"]
713       else
714         commandString << "," << "auto"
715       end
716     end
717     if hash["Audio3Bitrate"]
718       if hash["Audio3Encoder"] != "AC3 Passthru"
719         commandString << "," << hash["Audio3Bitrate"]
720       else
721         commandString << "," << "auto"
722       end
723     end
724     if hash["Audio4Bitrate"]
725       if hash["Audio4Encoder"] != "AC3 Passthru"
726         commandString << "," << hash["Audio4Bitrate"]
727       else
728         commandString << "," << "auto"
729       end
730     end
731
732     #Audio sample rate
733     commandString << " -R "
734     commandString << hash["Audio1Samplerate"]
735     if hash["Audio2Samplerate"]
736       commandString << "," << hash["Audio2Samplerate"]
737     end
738     if hash["Audio3Samplerate"]
739       commandString << "," << hash["Audio3Samplerate"]
740     end
741     if hash["Audio4Samplerate"]
742       commandString << "," << hash["Audio4Samplerate"]
743     end
744     
745     #Audio Mixdown
746     commandString << " -6 "
747     case hash["Audio1Mixdown"]
748     when /Mono/
749       commandString << "mono"
750     when /Stereo/
751       commandString << "stereo"
752     when /Dolby Surround/
753       commandString << "dpl1"
754     when /Dolby Pro Logic II/
755       commandString << "dpl2"
756     when /discrete/
757       commandString << "6ch"
758     when /Passthru/
759       commandString << "auto"
760     end
761     
762     if hash["Audio2Mixdown"]
763       case hash["Audio2Mixdown"]
764       when /Mono/
765         commandString << ",mono"
766       when /Stereo/
767         commandString << ",stereo"
768       when /Dolby Surround/
769         commandString << ",dpl1"
770       when /Dolby Pro Logic II/
771         commandString << ",dpl2"
772       when /discrete/
773         commandString << ",6ch"
774       when /Passthru/
775         commandString << ",auto"
776       end
777     end
778     
779     if hash["Audio3Mixdown"]
780       case hash["Audio3Mixdown"]
781       when /Mono/
782         commandString << ",mono"
783       when /Stereo/
784         commandString << ",stereo"
785       when /Dolby Surround/
786         commandString << ",dpl1"
787       when /Dolby Pro Logic II/
788         commandString << ",dpl2"
789       when /discrete/
790         commandString << ",6ch"
791       when /Passthru/
792         commandString << ",auto"
793       end
794     end
795     
796     if hash["Audio4Mixdown"]
797       case hash["Audio4Mixdown"]
798       when /Mono/
799         commandString << ",mono"
800       when /Stereo/
801         commandString << ",stereo"
802       when /Dolby Surround/
803         commandString << ",dpl1"
804       when /Dolby Pro Logic II/
805         commandString << ",dpl2"
806       when /discrete/
807         commandString << ",6ch"
808       when /Passthru/
809         commandString << ",auto"
810       end
811     end
812
813     
814     #Container
815     commandString << " -f "
816     case hash["FileFormat"]
817     when /MP4/
818       commandString << "mp4"
819     when /AVI/
820       commandString << "avi"
821     when /OGM/
822       commandString << "ogm"
823     when /MKV/
824       commandString << "mkv"
825     end
826     
827     #iPod MP4 atom
828     if hash["Mp4iPodCompatible"].to_i == 1
829       commandString << " -I"
830     end
831     
832     # 64-bit files
833     if hash["Mp4LargeFile"] == 1
834       commandString << " -4"
835     end
836     
837     #Cropping
838     if hash["PictureAutoCrop"] == 0
839       commandString << " --crop "
840       commandString << hash["PictureTopCrop"].to_s
841       commandString << ":"
842       commandString << hash["PictureBottomCrop"].to_s
843       commandString << ":"
844       commandString << hash["PictureLeftCrop"].to_s
845       commandString << ":"
846       commandString << hash["PictureRightCrop"].to_s
847     end
848     
849     #Dimensions
850     if hash["PictureWidth"] != 0
851       commandString << " -X "
852       commandString << hash["PictureWidth"].to_s
853     end
854     if hash["PictureHeight"] != 0
855       commandString << " -Y "
856       commandString << hash["PictureHeight"].to_s
857     end
858     
859     #Subtitles
860     if hash["Subtitles"] != "None"
861       commandString << " -s "
862       commandString << hash["Subtitles"]
863     end
864     
865     #Video Filters
866     if hash["UsesPictureFilters"] == 1
867       
868       case hash["PictureDeinterlace"]
869       when 1
870         commandString << " --deinterlace=\"fast\""
871       when 2
872         commandString << " --deinterlace=\slow\""
873       when 3
874         commandString << " --deinterlace=\"slower\""
875       when 4
876         commandString << " --deinterlace=\"slowest\""
877       end
878       
879       case hash["PictureDenoise"]
880       when 1
881         commandString << " --denoise=\"weak\""
882       when 2
883         commandString << " --denoise=\"medium\""
884       when 3
885         commandString << " --denoise=\"strong\""
886       end
887       
888       if hash["PictureDetelecine"] == 1 then commandString << " --detelecine" end
889       if hash["PictureDeblock"] == 1 then commandString << " --deblock" end
890       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
891       if hash["PictureDecomb"] == 1 then commandString << " --decomb" end
892     end
893
894     #Anamorphic
895     if hash["PicturePAR"] == 1
896       commandString << " -p"
897     elsif hash["PicturePAR"] == 2
898       commandString << " -P"
899     end
900     
901     #Booleans
902     if hash["ChapterMarkers"] == 1 then commandString << " -m" end
903     if hash["VideoGrayScale"] == 1 then commandString << " -g" end
904     if hash["VideoTwoPass"] == 1 then commandString << " -2" end
905     if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
906
907     #x264 Options
908     if hash["x264Option"] != ""
909       commandString << " -x "
910       commandString << hash["x264Option"]
911     end
912     
913     # That's it, print to screen now
914     puts commandString
915     
916     #puts "*" * @columnWidth
917
918     puts  "\n"
919   end
920
921   def generateAPIcalls(hash) # Makes a C version of the preset ready for coding into the CLI
922     
923     commandString = "if (!strcmp(preset_name, \"" << hash["PresetName"] << "\"))\n{\n    "
924     
925     #Filename suffix
926     case hash["FileFormat"]
927     when /MP4/
928       commandString << "mux = " << "HB_MUX_MP4;\n    "
929     when /AVI/
930       commandString << "mux = " << "HB_MUX_AVI;\n    "
931     when /OGM/
932       commandString << "mux = " << "HB_MUX_OGM;\n    "
933     when /MKV/
934       commandString << "mux = " << "HB_MUX_MKV;\n    "
935     end
936     
937     #iPod MP4 atom
938     if hash["Mp4iPodCompatible"].to_i == 1
939       commandString << "job->ipod_atom = 1;\n   "
940     end
941     
942     # 64-bit files
943     if hash["Mp4LargeFile"] == 1
944       commandString << "job->largeFileSize = 1;\n    "
945     end
946     
947     #Video encoder
948     if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
949       commandString << "vcodec = "
950       case hash["VideoEncoder"]
951       when /x264/
952         commandString << "HB_VCODEC_X264;\n    "
953       when /XviD/
954         commandString << "HB_VCODEC_XVID;\n    "        
955       end
956     end
957
958     #VideoRateControl
959     case hash["VideoQualityType"]
960     when 0
961       commandString << "size = " << hash["VideoTargetSize"] << ";\n    "
962     when 1
963       commandString << "job->vbitrate = " << hash["VideoAvgBitrate"] << ";\n    "
964     when 2
965       commandString << "job->vquality = " << hash["VideoQualitySlider"].to_s << ";\n    "
966       commandString << "job->crf = 1;\n    "
967     end
968
969     #FPS
970     if hash["VideoFramerate"] != "Same as source"
971       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
972         commandString << "job->vrate_base = " << "1126125;\n    "
973       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
974         commandString << "job->vrate_base = " << "900900;\n    "
975       # Gotta add the rest of the framerates for completion's sake.
976       end
977       commandString << "job->cfr = 1;\n    "
978     end
979     
980     #Audio tracks
981     commandString << "atracks = strdup(\""
982     commandString << hash["Audio1Track"].to_s
983     if hash["Audio2Track"]
984       commandString << "," << hash["Audio2Track"].to_s
985     end
986     if hash["Audio3Track"]
987       commandString << "," << hash["Audio3Track"].to_s
988     end
989     if hash["Audio4Track"]
990       commandString << "," << hash["Audio4Track"].to_s
991     end
992     commandString << "\");\n    "
993     
994     # Audio bitrate
995     commandString << "abitrates = strdup(\""
996     if hash["Audio1Encoder"] != "AC3 Passthru"
997       commandString << hash["Audio1Bitrate"]
998     else
999       commandString << "auto"
1000     end
1001     if hash["Audio2Bitrate"]
1002       if hash["Audio2Encoder"] != "AC3 Passthru"
1003         commandString << "," << hash["Audio2Bitrate"]
1004       else
1005         commandString << "," << "auto"
1006       end
1007     end
1008     if hash["Audio3Bitrate"]
1009       if hash["Audio3Encoder"] != "AC3 Passthru"
1010         commandString << "," << hash["Audio3Bitrate"]
1011       else
1012         commandString << "," << "auto"
1013       end
1014     end
1015     if hash["Audio4Bitrate"]
1016       if hash["Audio4Encoder"] != "AC3 Passthru"
1017         commandString << "," << hash["Audio4Bitrate"]
1018       else
1019         commandString << "," << "auto"
1020       end
1021     end
1022     commandString << "\");\n    "
1023         
1024     #Audio samplerate
1025     commandString << "arates = strdup(\""
1026     commandString << hash["Audio1Samplerate"]
1027     if hash["Audio2Samplerate"]
1028       commandString << "," << hash["Audio2Samplerate"]
1029     end
1030     if hash["Audio3Samplerate"]
1031       commandString << "," << hash["Audio3Samplerate"]
1032     end
1033     if hash["Audio4Samplerate"]
1034       commandString << "," << hash["Audio4Samplerate"]
1035     end
1036     commandString << "\");\n    "
1037       
1038     #Audio encoder
1039     commandString << "acodecs = strdup(\""
1040     case hash["Audio1Encoder"]
1041     when /AC3/
1042       commandString << "ac3"
1043     when /AAC/
1044       commandString << "faac"
1045     when /Vorbis/
1046       commandString << "vorbis"
1047     when /MP3/
1048       commandString << "lame"
1049     end
1050     case hash["Audio2Encoder"]
1051     when /AC3 /
1052       commandString << ",ac3"
1053     when /AAC/
1054       commandString << ",faac"
1055     when /Vorbis/
1056       commandString << ",vorbis"
1057     when /MP3/
1058       commandString << ",lame"
1059     end
1060     case hash["Audio3Encoder"]
1061     when /AC3 /
1062       commandString << ",ac3"
1063     when /AAC/
1064       commandString << ",faac"
1065     when /Vorbis/
1066       commandString << ",vorbis"
1067     when /MP3/
1068       commandString << ",lame"
1069     end
1070     case hash["Audio4Encoder"]
1071     when /AC3 /
1072       commandString << ",ac3"
1073     when /AAC/
1074       commandString << ",faac"
1075     when /Vorbis/
1076       commandString << ",vorbis"
1077     when /MP3/
1078       commandString << ",lame"
1079     end
1080     commandString << "\");\n    "
1081     
1082     #Audio mixdowns
1083     commandString << "mixdowns = strdup(\""
1084     case hash["Audio1Mixdown"]
1085     when /Mono/
1086       commandString << "mono"
1087     when /Stereo/
1088       commandString << "stereo"
1089     when /Dolby Surround/
1090       commandString << "dpl1"
1091     when /Dolby Pro Logic II/
1092       commandString << "dpl2"
1093     when /discrete/
1094       commandString << "6ch"
1095     when /Passthru/
1096       commandString << "auto"
1097     end
1098     if hash["Audio2Mixdown"]
1099       case hash["Audio2Mixdown"]
1100       when /Mono/
1101         commandString << ",mono"
1102       when /Stereo/
1103         commandString << ",stereo"
1104       when /Dolby Surround/
1105         commandString << ",dpl1"
1106       when /Dolby Pro Logic II/
1107         commandString << ",dpl2"
1108       when /discrete/
1109         commandString << ",6ch"
1110       when /Passthru/
1111         commandString << ",auto"
1112       end
1113     end
1114     if hash["Audio3Mixdown"]
1115       case hash["Audio3Mixdown"]
1116       when /Mono/
1117         commandString << ",mono"
1118       when /Stereo/
1119         commandString << ",stereo"
1120       when /Dolby Surround/
1121         commandString << ",dpl1"
1122       when /Dolby Pro Logic II/
1123         commandString << ",dpl2"
1124       when /discrete/
1125         commandString << ",6ch"
1126       when /Passthru/
1127         commandString << ",auto"
1128       end
1129     end
1130     if hash["Audio4Mixdown"]
1131       case hash["Audio4Mixdown"]
1132       when /Mono/
1133         commandString << ",mono"
1134       when /Stereo/
1135         commandString << ",stereo"
1136       when /Dolby Surround/
1137         commandString << ",dpl1"
1138       when /Dolby Pro Logic II/
1139         commandString << ",dpl2"
1140       when /discrete/
1141         commandString << ",6ch"
1142       when /Passthru/
1143         commandString << ",auto"
1144       end
1145     end
1146     commandString << "\");\n    "
1147     
1148     #Cropping
1149     if hash["PictureAutoCrop"] == 0
1150       commandString << "job->crop[0] = " << hash["PictureTopCrop"].to_s << ";\n    "
1151       commandString << "job->crop[1] = " << hash["PictureBottomCrop"].to_s << ";\n    "
1152       commandString << "job->crop[2] = " << hash["PictureLeftCrop"].to_s << ";\n    "
1153       commandString << "job->crop[4] - " << hash["PictureRightCrop"].to_s << ";\n    "
1154     end
1155     
1156     #Dimensions
1157     if hash["PictureWidth"] != 0
1158       commandString << "maxWidth = "
1159       commandString << hash["PictureWidth"].to_s << ";\n    "
1160     end
1161     if hash["PictureHeight"] != 0
1162       commandString << "maxHeight = "
1163       commandString << hash["PictureHeight"].to_s << ";\n    "
1164     end
1165     
1166     #Subtitles
1167     if hash["Subtitles"] != "None"
1168       commandString << "job->subtitle = "
1169       commandString << ( hash["Subtitles"].to_i - 1).to_s << ";\n    "
1170     end
1171     
1172     #x264 Options
1173     if hash["x264Option"] != ""
1174       commandString << "x264opts = strdup(\""
1175       commandString << hash["x264Option"] << "\");\n    "
1176     end
1177     
1178     #Video Filters
1179     if hash["UsesPictureFilters"] == 1
1180       
1181       case hash["PictureDeinterlace"]
1182       when 1
1183         commandString << "deinterlace = 1;\n    "
1184         commandString << "deinterlace_opt = \"-1\";\n    "
1185       when 2
1186         commandString << "deinterlace = 1;\n    "
1187         commandString << "deinterlace_opt = \"2\";\n    "
1188       when 3
1189         commandString << "deinterlace = 1;\n    "
1190         commandString << "deinterlace_opt = \"0\";\n    "
1191       when 4
1192         commandString << "deinterlace = 1;\n    "
1193         commandString << "deinterlace_opt = \"1:-1:1\";\n    "
1194       end
1195       
1196       case hash["PictureDenoise"]
1197       when 1
1198         commandString << "denoise = 1;\n    "
1199         commandString << "denoise_opt = \"2:1:2:3\";\n    "
1200       when 2
1201         commandString << "denoise = 1;\n    "
1202         commandString << "denoise_opt = \"3:2:2:3\";\n    "
1203       when 3
1204         commandString << "denoise = 1;\n    "
1205         commandString << "denoise_opt = \"7:7:5:5\";\n    "
1206       end
1207       
1208       if hash["PictureDetelecine"] == 1 then commandString << "detelecine = 1;\n    " end
1209       if hash["PictureDeblock"] == 1 then commandString << "deblock = 1;\n    " end
1210       if hash["VFR"].to_i == 1 then commandString << "vfr = 1;\n    " end
1211       if hash["PictureDecomb"] == 1 then commandString << "decomb = 1;\n    " end
1212       
1213     end
1214     
1215     #Anamorphic
1216     if hash["PicturePAR"] == 1
1217       commandString << "pixelratio = 1;\n    "
1218     elsif hash["PicturePAR"] == 2
1219       commandString << "pixelratio = 2;\n    "
1220     end
1221     
1222     #Booleans
1223     if hash["ChapterMarkers"] == 1 then commandString << "job->chapter_markers = 1;\n    " end
1224     if hash["VideoGrayScale"] == 1 then commandString << "job->grayscale = 1;\n    " end
1225     if hash["VideoTwoPass"] == 1 then commandString << "twoPass = 1;\n    " end
1226     if hash["VideoTurboTwoPass"] == 1 then commandString << "turbo_opts_enabled = 1;\n" end
1227     
1228     commandString << "}"
1229     
1230     # That's it, print to screen now
1231     puts commandString
1232     #puts "*" * @columnWidth
1233     puts  "\n"
1234   end
1235   
1236   def generateAPIFolderList( hash, depth )
1237     commandString = ""
1238     
1239     commandString << "    printf(\"\\n"
1240     depth.times do
1241       commandString << "   "
1242     end
1243     (depth+1).times do
1244       commandString << "<"
1245     end
1246     commandString << " " << hash["PresetName"]
1247     commandString << "\\n\");\n\n"    
1248     puts commandString
1249   end
1250   
1251   def generateAPIFolderCloserList( depth )
1252     commandString = ""
1253     
1254     commandString << "    printf(\"\\n"
1255     depth.times do
1256       commandString << "   "
1257     end
1258     (depth+1).times do
1259       commandString << ">"
1260     end
1261     commandString << "\\n\");\n\n"    
1262     puts commandString
1263   end
1264   
1265   def generateAPIList(hash, depth) # Makes a list of the CLI options a built-in CLI preset uses, for wrappers to parse
1266     commandString = ""
1267     commandString << "    printf(\"\\n"
1268     depth.times do
1269       commandString << "   "
1270     end
1271            
1272     commandString << "+ " << hash["PresetName"] << ": "
1273         
1274     #Video encoder
1275     if hash["VideoEncoder"] != "MPEG-4 (FFmpeg)"
1276       commandString << " -e "
1277       case hash["VideoEncoder"]
1278       when /x264/
1279         commandString << "x264 "
1280       when /XviD/
1281         commandString << "xvid "
1282       end
1283     end
1284
1285     #VideoRateControl
1286     case hash["VideoQualityType"]
1287     when 0
1288       commandString << " -S " << hash["VideoTargetSize"]
1289     when 1
1290       commandString << " -b " << hash["VideoAvgBitrate"]
1291     when 2
1292       commandString << " -q " << hash["VideoQualitySlider"].to_s
1293     end
1294
1295     #FPS
1296     if hash["VideoFramerate"] != "Same as source"
1297       if hash["VideoFramerate"] == "23.976 (NTSC Film)"
1298         commandString << " -r " << "23.976"
1299       elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
1300         commandString << " -r " << "29.97"
1301       else
1302         commandString << " -r " << hash["VideoFramerate"]
1303       end
1304     end
1305     
1306     #Audio tracks
1307     commandString << " -a "
1308     commandString << hash["Audio1Track"].to_s
1309     if hash["Audio2Track"]
1310       commandString << "," << hash["Audio2Track"].to_s
1311     end
1312     if hash["Audio3Track"]
1313       commandString << "," << hash["Audio3Track"].to_s
1314     end
1315     if hash["Audio4Track"]
1316       commandString << "," << hash["Audio4Track"].to_s
1317     end
1318     
1319     #Audio encoders
1320     commandString << " -E "
1321     case hash["Audio1Encoder"]
1322     when /AC3/
1323       commandString << "ac3"
1324     when /AAC/
1325       commandString << "faac"
1326     when /Vorbis/
1327       commandString << "vorbis"
1328     when /MP3/
1329       commandString << "lame"
1330     end
1331     case hash["Audio2Encoder"]
1332     when /AC3 /
1333       commandString << ",ac3"
1334     when /AAC/
1335       commandString << ",faac"
1336     when /Vorbis/
1337       commandString << ",vorbis"
1338     when /MP3/
1339       commandString << ",lame"
1340     end
1341     case hash["Audio3Encoder"]
1342     when /AC3 /
1343       commandString << ",ac3"
1344     when /AAC/
1345       commandString << ",faac"
1346     when /Vorbis/
1347       commandString << ",vorbis"
1348     when /MP3/
1349       commandString << ",lame"
1350     end
1351     case hash["Audio4Encoder"]
1352     when /AC3 /
1353       commandString << ",ac3"
1354     when /AAC/
1355       commandString << ",faac"
1356     when /Vorbis/
1357       commandString << ",vorbis"
1358     when /MP3/
1359       commandString << ",lame"
1360     end
1361
1362     #Audio bit rate
1363     commandString << " -B "
1364     commandString << hash["Audio1Bitrate"]
1365     if hash["Audio2Bitrate"]
1366       if hash["Audio2Encoder"] != "AC3 Passthru"
1367         commandString << "," << hash["Audio2Bitrate"]
1368       else
1369         commandString << "," << "auto"
1370       end
1371     end
1372     if hash["Audio3Bitrate"]
1373       if hash["Audio3Encoder"] != "AC3 Passthru"
1374         commandString << "," << hash["Audio3Bitrate"]
1375       else
1376         commandString << "," << "auto"
1377       end
1378     end
1379     if hash["Audio4Bitrate"]
1380       if hash["Audio4Encoder"] != "AC3 Passthru"
1381         commandString << "," << hash["Audio4Bitrate"]
1382       else
1383         commandString << "," << "auto"
1384       end
1385     end
1386
1387     #Audio sample rate
1388     commandString << " -R "
1389     commandString << hash["Audio1Samplerate"]
1390     if hash["Audio2Samplerate"]
1391       commandString << "," << hash["Audio2Samplerate"]
1392     end
1393     if hash["Audio3Samplerate"]
1394       commandString << "," << hash["Audio3Samplerate"]
1395     end
1396     if hash["Audio4Samplerate"]
1397       commandString << "," << hash["Audio4Samplerate"]
1398     end
1399     
1400     #Audio Mixdown
1401     commandString << " -6 "
1402     case hash["Audio1Mixdown"]
1403     when /Mono/
1404       commandString << "mono"
1405     when /Stereo/
1406       commandString << "stereo"
1407     when /Dolby Surround/
1408       commandString << "dpl1"
1409     when /Dolby Pro Logic II/
1410       commandString << "dpl2"
1411     when /discrete/
1412       commandString << "6ch"
1413     when /Passthru/
1414       commandString << "auto"
1415     end
1416     
1417     if hash["Audio2Mixdown"]
1418       case hash["Audio2Mixdown"]
1419       when /Mono/
1420         commandString << ",mono"
1421       when /Stereo/
1422         commandString << ",stereo"
1423       when /Dolby Surround/
1424         commandString << ",dpl1"
1425       when /Dolby Pro Logic II/
1426         commandString << ",dpl2"
1427       when /discrete/
1428         commandString << ",6ch"
1429       when /Passthru/
1430         commandString << ",auto"
1431       end
1432     end
1433     
1434     if hash["Audio3Mixdown"]
1435       case hash["Audio3Mixdown"]
1436       when /Mono/
1437         commandString << ",mono"
1438       when /Stereo/
1439         commandString << ",stereo"
1440       when /Dolby Surround/
1441         commandString << ",dpl1"
1442       when /Dolby Pro Logic II/
1443         commandString << ",dpl2"
1444       when /discrete/
1445         commandString << ",6ch"
1446       when /Passthru/
1447         commandString << ",auto"
1448       end
1449     end
1450     
1451     if hash["Audio4Mixdown"]
1452       case hash["Audio4Mixdown"]
1453       when /Mono/
1454         commandString << ",mono"
1455       when /Stereo/
1456         commandString << ",stereo"
1457       when /Dolby Surround/
1458         commandString << ",dpl1"
1459       when /Dolby Pro Logic II/
1460         commandString << ",dpl2"
1461       when /discrete/
1462         commandString << ",6ch"
1463       when /Passthru/
1464         commandString << ",auto"
1465       end
1466     end
1467     
1468     #Container
1469     commandString << " -f "
1470     case hash["FileFormat"]
1471     when /MP4/
1472       commandString << "mp4"
1473     when /AVI/
1474       commandString << "avi"
1475     when /OGM/
1476       commandString << "ogm"
1477     when /MKV/
1478       commandString << "mkv"
1479     end
1480     
1481     #iPod MP4 atom
1482     if hash["Mp4iPodCompatible"].to_i == 1
1483       commandString << " -I"
1484     end
1485     
1486     # 64-bit files
1487     if hash["Mp4LargeFile"] == 1
1488       commandString << " -4"
1489     end
1490     
1491     #Cropping
1492     if hash["PictureAutoCrop"] == 0
1493       commandString << " --crop "
1494       commandString << hash["PictureTopCrop"].to_s
1495       commandString << ":"
1496       commandString << hash["PictureBottomCrop"].to_s
1497       commandString << ":"
1498       commandString << hash["PictureLeftCrop"].to_s
1499       commandString << ":"
1500       commandString << hash["PictureRightCrop"].to_s
1501     end
1502     
1503     #Dimensions
1504     if hash["PictureWidth"] != 0
1505       commandString << " -X "
1506       commandString << hash["PictureWidth"].to_s
1507     end
1508     if hash["PictureHeight"] != 0
1509       commandString << " -Y "
1510       commandString << hash["PictureHeight"].to_s
1511     end
1512     
1513     #Subtitles
1514     if hash["Subtitles"] != "None"
1515       commandString << " -s "
1516       commandString << hash["Subtitles"]
1517     end
1518     
1519     #Video Filters
1520     if hash["UsesPictureFilters"] == 1
1521       
1522       case hash["PictureDeinterlace"]
1523       when 1
1524         commandString << " --deinterlace=\\\"fast\\\""
1525       when 2
1526         commandString << " --deinterlace=\\\slow\\\""
1527       when 3
1528         commandString << " --deinterlace=\\\"slower\\\""
1529       when 4
1530         commandString << " --deinterlace=\\\"slowest\\\""
1531       end
1532       
1533       case hash["PictureDenoise"]
1534       when 1
1535         commandString << " --denoise=\\\"weak\\\""
1536       when 2
1537         commandString << " --denoise=\\\"medium\\\""
1538       when 3
1539         commandString << " --denoise=\\\"strong\\\""
1540       end
1541       
1542       if hash["PictureDetelecine"] == 1 then commandString << " --detelecine" end
1543       if hash["PictureDeblock"] == 1 then commandString << " --deblock" end
1544       if hash["VFR"].to_i == 1 then commandString << " --vfr" end
1545       if hash["PictureDecomb"] == 1 then commandString << " --decomb" end
1546     end
1547     
1548     #Anamorphic
1549     if hash["PicturePAR"] == 1
1550       commandString << " -p"
1551     elsif hash["PicturePAR"] == 2
1552       commandString << " -P"
1553     end
1554     
1555     #Booleans
1556     if hash["ChapterMarkers"] == 1 then commandString << " -m" end
1557     if hash["VideoGrayScale"] == 1 then commandString << " -g" end
1558     if hash["VideoTwoPass"] == 1 then commandString << " -2" end
1559     if hash["VideoTurboTwoPass"] == 1 then commandString << " -T" end
1560     
1561       #x264 Options
1562       if hash["x264Option"] != ""
1563         commandString << " -x "
1564         commandString << hash["x264Option"]
1565       end
1566     
1567     commandString << "\\n\");"
1568     
1569     # That's it, print to screen now
1570     puts commandString
1571     puts  "\n"
1572   end
1573   
1574 end
1575
1576 # First grab the specified CLI options
1577 options = readOptions
1578
1579 # Only run if one of the useful CLI flags have been passed
1580 if options.cliraw == true || options.cliparse == true || options.api == true || options.apilist == true
1581   # This line is the ignition -- generates hashes of
1582   # presets and then displays them to the screen
1583   # with the options the user selects on the CLI. 
1584   Display.new( Presets.new.hashMasterList, options )
1585 else
1586   # Direct the user to the help
1587   puts "\n\tUsage: manicure.rb [options]"
1588   puts "\tSee help with -h or --help"
1589 end