Class: Pablo
- Inherits:
-
Object
- Object
- Pablo
- Includes:
- Helpers
- Defined in:
- lib/pablo.rb,
lib/pablo/help.rb,
lib/pablo/color.rb,
lib/pablo/token.rb,
lib/pablo/always.rb,
lib/pablo/errors.rb,
lib/pablo/option.rb,
lib/pablo/parser.rb,
lib/pablo/command.rb,
lib/pablo/helpers.rb,
lib/pablo/version.rb,
lib/pablo/arguments.rb,
lib/pablo/expansion.rb
Overview
DON’T PANIC License 1.1 ###########
Don’t panic, this piece of software is free, i.e. you can do with it whatever you like, including, but not limited to:
* using it
* copying it
* (re)distributing it
* burning/burying/shredding it
* eating it
* using it to obtain world domination
* and ignoring it
Under the sole condition that you
* CONSIDER buying the author a strong
brownian motion producer, say a nice
hot cup of tea, should you ever meet
him in person.
Defined Under Namespace
Modules: Helpers Classes: Always, Arguments, Command, HelpCommand, LicenseCommand, MissingArgumentError, Option, Parser, Token, VersionCommand, WrongArgumentError
Constant Summary collapse
- VERSION =
'1.0.3'
Instance Attribute Summary collapse
-
#args ⇒ Object
Returns the value of attribute args.
-
#commands ⇒ Object
Returns the value of attribute commands.
-
#expand ⇒ Object
Returns the value of attribute expand.
-
#options ⇒ Object
Returns the value of attribute options.
-
#registered ⇒ Object
Returns the value of attribute registered.
-
#tokens ⇒ Object
Returns the value of attribute tokens.
Instance Method Summary collapse
-
#always(&block) ⇒ Object
Define arbitrary code to always run at that stage of parsing.
-
#ambiguity(&block) ⇒ Object
The block given to this method will be called each time an argument could not be expanded because there were multiple parsers that matched it.
-
#ambiguity_command ⇒ Object
Creates standard ambiguity output.
-
#colorize(string, type) ⇒ Object
Colorize the given
string
of the giventype
. -
#colorizing(&block) ⇒ Object
Runs the given
block
, whenever something needs to be given color. -
#command(*args, &block) ⇒ Object
(also: #cmd)
Define a command.
-
#consume_all? ⇒ Boolean
Whether or not commands should consume all arguments after they parsed something.
-
#desc(d) ⇒ Object
Set the short description of the next parser.
-
#expand!(arg) ⇒ Object
Expands the given argument if possible.
-
#expands?(type) ⇒ Boolean
Whether or not the given
type
is subject to expansion. -
#help(command = nil) ⇒ Object
Print the help screen.
-
#help_command(options = {}, &block) ⇒ Object
Creates the standard help command.
-
#initialize(opts = Hash.new) ⇒ Pablo
constructor
-
opts
: options for Pablo * :command_consumes_all => true|false Forces toplevel commands (not) to consume all arguments after being applied.
-
-
#license ⇒ Object
Print license and stop processing.
-
#license_command(options = {}, &block) ⇒ Object
Creates the standard license command.
-
#load_yaml(yml) ⇒ Object
Loads whole parsers and global options from a YAML source.
-
#longdesc(l) ⇒ Object
Set the long description of the next parser.
-
#missing_argument(*args) ⇒ Object
Displays a message about a missing argument and exits parsing.
-
#option(*args, &block) ⇒ Object
(also: #opt)
Define an option.
-
#parse(args) ⇒ Object
Starts the parsing process on the given
args
, according to the registered parsers. -
#put_header ⇒ Object
Prints the standard header for most Pablo output.
-
#run=(object) ⇒ Object
Sets the run object for this pablo instance.
-
#run_object ⇒ Object
Returns the object which keeps all the instance methods corresponding to the defined parsers - or
nil
if none was given. -
#token(*args, &block) ⇒ Object
(also: #tok)
Define a token.
-
#toplevel? ⇒ Boolean
Whether or not we dwell at toplevel currently.
-
#usage(u) ⇒ Object
Set the usage information of the next parser.
-
#version ⇒ Object
Print version screen and stop processing.
-
#version_command(options = {}, &block) ⇒ Object
Creates the standard version command.
-
#wrong_argument(*args) ⇒ Object
Displays a message about a wrong argument (format) and exits parsing.
Constructor Details
#initialize(opts = Hash.new) ⇒ Pablo
-
opts
: options for Pablo-
:command_consumes_all => true|false Forces toplevel commands (not) to consume all arguments after being applied. I’m still looking for a better name for that option, so it may be subject to change.
-
:expand => true|false|Array Turns on the automatic abbreviation expansion mechanism for
-
all parsers (true)
-
no parsers (false)
-
a specific parser (Array containing :commands and/or :options)
-
-
:program => String The name of the Program to be displayed by
help
andversion
. -
:version => String The version of the Program to be displayed by
version
andhelp
. -
:usage => String The usage information of the Program to be displayed by
help
, e.g.[<command>] [<options>]
-
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/pablo.rb', line 85 def initialize opts = Hash.new @opts = { :command_consumes_all => true, :expand => false }.merge(opts) () @finalize = @colorize = @cur = nil @toplevel, @args, @pending = true, nil, Hash.new @expand, @ambiguity, @registered = Array.new, nil, Array.new @options, @commands, @tokens = Hash.new, Hash.new, Hash.new end |
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
62 63 64 |
# File 'lib/pablo.rb', line 62 def args @args end |
#commands ⇒ Object
Returns the value of attribute commands.
63 64 65 |
# File 'lib/pablo.rb', line 63 def commands @commands end |
#expand ⇒ Object
Returns the value of attribute expand.
64 65 66 |
# File 'lib/pablo.rb', line 64 def @expand end |
#options ⇒ Object
Returns the value of attribute options.
63 64 65 |
# File 'lib/pablo.rb', line 63 def @options end |
#registered ⇒ Object
Returns the value of attribute registered.
64 65 66 |
# File 'lib/pablo.rb', line 64 def registered @registered end |
#tokens ⇒ Object
Returns the value of attribute tokens.
63 64 65 |
# File 'lib/pablo.rb', line 63 def tokens @tokens end |
Instance Method Details
#always(&block) ⇒ Object
Define arbitrary code to always run at that stage of parsing.
196 197 198 |
# File 'lib/pablo.rb', line 196 def always &block exec(Pablo::Always, &block) end |
#ambiguity(&block) ⇒ Object
The block given to this method will be called each time an argument could not be expanded because there were multiple parsers that matched it. The block will be passed the argument and an Array containing the matching parser names as parameters.
52 53 54 55 |
# File 'lib/pablo/expansion.rb', line 52 def ambiguity &block raise "Pablo#ambiguity needs a block to do something sensible" unless block_given? @ambiguity = block end |
#ambiguity_command ⇒ Object
Creates standard ambiguity output.
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/pablo/help.rb', line 91 def ambiguity_command ambiguity do |arg,arr| $stdout.puts "Ambiguous argument '#{arg}'. Could be any of:" arr.each do |name| $stdout.puts " * #{name}" end throw :abort end end |
#colorize(string, type) ⇒ Object
Colorize the given string
of the given type
. See Pablo#colorize for valid values of type
. If no colorization function is given, the string
is returned uncolored.
46 47 48 49 50 51 52 53 54 |
# File 'lib/pablo/color.rb', line 46 def colorize string, type if type == :text string.gsub(/\$([^$]+)\$/ )do |match| colorize(match[1..-2], :em) end else @colorize.nil? ? string : (@colorize.call(string, type)) end end |
#colorizing(&block) ⇒ Object
Runs the given block
, whenever something needs to be given color. The block will be given the following arguments:
-
The string to colorize
-
A symbol indicating the type of the String. The color should be guessed from that. Can be any of:
-
:h1 - First class heading
-
:h2 - Second class heading
-
:usage - Usage information
-
:em - Highlighted word
-
36 37 38 39 |
# File 'lib/pablo/color.rb', line 36 def colorizing &block raise "colorize expects a block" unless block_given? @colorize = block end |
#command(*args, &block) ⇒ Object Also known as: cmd
Define a command. args
must be:
-
at least one name for the command
-
a hash of options:
-
:default The default value to be set if the command is not recognized.
-
:consume_all => true|false Whether (or not) the command should consume_all remaining arguments after it has been recognized
-
:consume => Fixnum|String|Regexp|Array
-
Fixnum: consume the next n arguments
-
String: consume if the next argument equals that String. Else the option will not match.
-
Regexp: consume if the next argument matches that Regexp. Else the option will not match.
-
Array: consume next
arr.length
arguments if they equal those given in the Array.
-
-
:expand => Proc A Proc that will be passed a single argument String and a single name of the token as parameters and has to return a Boolean indicating whether or not the String is an abbreviation of that name.
-
141 142 143 |
# File 'lib/pablo.rb', line 141 def command *args, &block exec(Pablo::Command, *args, &block) end |
#consume_all? ⇒ Boolean
Whether or not commands should consume all arguments after they parsed something.
269 270 271 |
# File 'lib/pablo.rb', line 269 def consume_all? @opts[:command_consumes_all] end |
#desc(d) ⇒ Object
Set the short description of the next parser.
202 203 204 |
# File 'lib/pablo.rb', line 202 def desc d @pending[:desc] = d end |
#expand!(arg) ⇒ Object
Expands the given argument if possible.
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/pablo/expansion.rb', line 34 def arg arr = @expand.find_all { |e| e.start_with?(arg) } case arr.length when 1 then arr[0] when 0 then arg else @ambiguity.call(arg, arr) unless @ambiguity.nil? arg end end |
#expands?(type) ⇒ Boolean
Whether or not the given type
is subject to expansion.
28 29 30 |
# File 'lib/pablo/expansion.rb', line 28 def type @opts[:expand] == true or @opts[:expand] == type end |
#help(command = nil) ⇒ Object
Print the help screen.
-
command == nil: program help
-
else: specific command’s help
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/pablo/help.rb', line 107 def help command = nil if command.nil? put_header $stdout.puts "\n #{colorize(@opts[:program], :em)} #{colorize(@opts[:usage], :usage)}\n" unless @opts[:usage].nil? $stdout.puts "\n#{indent colorize(@opts[:longdesc], :text), 3}" unless @opts[:longdesc].nil? cmdlen = @registered.collect(&:names_to_user).max_by(&:length).length [:commands, :options].each do |type| parsers = @registered.find_all { |p| p.klass_to_sym == type } unless parsers.empty? $stdout.puts $stdout.puts ' ' + colorize("#{type.to_s.capitalize}:", :h2) parsers.each { |p| p.desc ? $stdout.puts(" #{colorize(p.names_to_user.ljust(cmdlen), :em)} : #{colorize(p.desc, :text)}") : $stdout.puts(' ' + colorize(p.names_to_user.ljust(cmdlen), :em)) } end end tokens = @registered.find_all { |p| p.is_a? Pablo::Token and not p.desc.nil? } unless tokens.empty? $stdout.puts $stdout.puts ' ' + colorize("Tokens:", :h2) tokens.each { |t| $stdout.puts " #{colorize(t.names_to_user.ljust(cmdlen), :em)} : #{t.desc}" } end else command = (command) found = @registered.find do |item| if not item.names_to_rex.nil? and item.names_to_rex =~ command put_header $stdout.print "\n " + colorize(item.names_to_user, :em) $stdout.print ' ' + colorize(item.usage, :usage) unless item.usage.nil? $stdout.puts "\n\n" $stdout.puts indent(colorize(item.longdesc, :text), 1) unless item.longdesc.nil? true else false end end if found.nil? $stdout.puts "Sorry, but I don't know '#{colorize(command, :em)}'." $stdout.puts "Try running '#{colorize('help', :em)}' without parameters to get a list of all the commands, options etc." end end end |
#help_command(options = {}, &block) ⇒ Object
Creates the standard help command.
80 81 82 83 84 85 86 87 |
# File 'lib/pablo/help.rb', line 80 def help_command = {}, &block desc('Displays this message.') unless @pending[:desc] longdesc("Shows a simple help message for this program.\n" + "If a command is given as well, a more detailed message about that\n" + "particular command is shown (such as this one).") unless @pending[:longdesc] usage('[<command>]') unless @pending[:usage] exec(Pablo::HelpCommand, :help, , &block) end |
#license ⇒ Object
Print license and stop processing. Nothing else.
171 172 173 174 175 176 177 |
# File 'lib/pablo/help.rb', line 171 def license if File.exist? @opts[:license].to_s open(@opts[:license]) { |f| $stdout.puts f.read } else $stdout.puts colorize(@opts[:license], :text) end end |
#license_command(options = {}, &block) ⇒ Object
Creates the standard license command.
64 65 66 67 68 |
# File 'lib/pablo/help.rb', line 64 def license_command = {}, &block desc('Shows the license of this program.') unless @pending[:desc] longdesc("Displays information about the license of this program.") unless @pending[:longdesc] exec(Pablo::LicenseCommand, :license, , &block) end |
#load_yaml(yml) ⇒ Object
Loads whole parsers and global options from a YAML source. yml
can either be a String of YAML or the path of a YAML file.
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/pablo.rb', line 221 def load_yaml yml yml = open(yml).read() if File.exist?(yml) opts = YAML::load(yml) parsers = opts.delete(:parsers) @opts.merge!(opts) parsers.each do |p| type = [:command, :token, :option, :help_command, :ambiguity_command, :license_command, :version_command].find { |s| !p[s].nil? } unless type.nil? args = p.delete(type) if args.is_a? Array then args << p else args = [p] end type == :ambiguity_command ? self.send(type) : self.send(type, *args) end end end |
#longdesc(l) ⇒ Object
Set the long description of the next parser.
208 209 210 |
# File 'lib/pablo.rb', line 208 def longdesc l @pending[:longdesc] = l end |
#missing_argument(*args) ⇒ Object
Displays a message about a missing argument and exits parsing.
56 57 58 |
# File 'lib/pablo/errors.rb', line 56 def missing_argument *args raise MissingArgumentError.new @cur.last_match, *args end |
#option(*args, &block) ⇒ Object Also known as: opt
Define an option. args
must be:
-
at least one name for the command
-
a hash of options:
-
:default The default value to be set if the option is not recognized.
-
:negative => true|false|String If
true
, the option will have a counterpart named –no<name>. If a String, the option will have a counterpart named –<string><name>. -
:consume => Fixnum|String|Regexp|Array
-
Fixnum: consume the next n arguments
-
String: consume if the next argument equals that String. Else the option will not match.
-
Regexp: consume if the next argument matches that Regexp. Else the option will not match.
-
Array: consume next
arr.length
arguments if they equal those given in the Array.
-
-
:expand => Proc A Proc that will be passed a single argument String and a single name of the token as parameters and has to return a Boolean indicating whether or not the String is an abbreviation of that name.
-
169 170 171 |
# File 'lib/pablo.rb', line 169 def option *args, &block exec(Pablo::Option, *args, &block) end |
#parse(args) ⇒ Object
Starts the parsing process on the given args
, according to the registered parsers.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/pablo.rb', line 102 def parse args @toplevel, @args = false, Pablo::Arguments.new(args) catch :abort do begin @registered.each { |parser| @cur = parser parser.parse(@args) } true rescue MissingArgumentError, WrongArgumentError => e $stderr.puts e. false end end end |
#put_header ⇒ Object
Prints the standard header for most Pablo output.
181 182 183 184 185 186 187 188 |
# File 'lib/pablo/help.rb', line 181 def put_header unless @opts[:program].nil? str = "#{@opts[:program]}" str << " #{@opts[:version]}" unless @opts[:version].nil? str << " - #{@opts[:desc]}" unless @opts[:desc].nil? $stdout.puts ' ' + colorize(str, :h1) end end |
#run=(object) ⇒ Object
Sets the run object for this pablo instance.
255 256 257 |
# File 'lib/pablo.rb', line 255 def run= object @opts[:run] = object end |
#run_object ⇒ Object
Returns the object which keeps all the instance methods corresponding to the defined parsers - or nil
if none was given
262 263 264 |
# File 'lib/pablo.rb', line 262 def run_object @opts[:run] end |
#token(*args, &block) ⇒ Object Also known as: tok
Define a token. args
must be:
-
at least one name for the command
-
a hash of options:
-
:default The default value to be set if the token is not recognized.
-
:consume => Fixnum|String|Regexp|Array
-
Fixnum: consume the next n arguments
-
String: consume if the next argument equals that String. Else the option will not match.
-
Regexp: consume if the next argument matches that Regexp. Else the option will not match.
-
Array: consume next
arr.length
arguments if they equal those given in the Array.
-
-
189 190 191 |
# File 'lib/pablo.rb', line 189 def token *args, &block exec(Pablo::Token, *args, &block) end |
#toplevel? ⇒ Boolean
Whether or not we dwell at toplevel currently. Only valid within a Command, Option, Token etc, but NOT within this class.
249 250 251 |
# File 'lib/pablo.rb', line 249 def toplevel? @toplevel end |
#usage(u) ⇒ Object
Set the usage information of the next parser.
214 215 216 |
# File 'lib/pablo.rb', line 214 def usage u @pending[:usage] = u end |
#version ⇒ Object
Print version screen and stop processing.
164 165 166 167 |
# File 'lib/pablo/help.rb', line 164 def version $stdout.puts colorize("#{@opts[:program]} #{@opts[:version]}", :h1) $stdout.puts @opts[:capabilities].join(' ') unless @opts[:capabilities].nil? end |
#version_command(options = {}, &block) ⇒ Object
Creates the standard version command.
72 73 74 75 76 |
# File 'lib/pablo/help.rb', line 72 def version_command = {}, &block desc('Shows the version of this program.') unless @pending[:desc] longdesc("Displays information about the version of this program.") unless @pending[:longdesc] exec(Pablo::VersionCommand, :version, , &block) end |
#wrong_argument(*args) ⇒ Object
Displays a message about a wrong argument (format) and exits parsing.
63 64 65 |
# File 'lib/pablo/errors.rb', line 63 def wrong_argument *args raise WrongArgumentError.new @cur.last_match, *args end |