lib/optparse.rb in optparse-0.2.0 vs lib/optparse.rb in optparse-0.3.0
- old
+ new
@@ -48,11 +48,11 @@
#
# == OptionParser
#
# === New to \OptionParser?
#
-# See the {Tutorial}[./doc/optparse/tutorial_rdoc.html].
+# See the {Tutorial}[optparse/tutorial.rdoc].
#
# === Introduction
#
# OptionParser is a class for command-line option analysis. It is much more
# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
@@ -418,16 +418,16 @@
# completion for command line options.
#
# === Further documentation
#
# The above examples, along with the accompanying
-# {Tutorial}[./doc/optparse/tutorial_rdoc.html],
+# {Tutorial}[optparse/tutorial.rdoc],
# should be enough to learn how to use this class.
# If you have any questions, file a ticket at http://bugs.ruby-lang.org.
#
class OptionParser
- OptionParser::Version = "0.2.0"
+ OptionParser::Version = "0.3.0"
# :stopdoc:
NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
@@ -672,10 +672,33 @@
yield("#{opt}", desc.join(""))
end
end
end
+ def pretty_print_contents(q) # :nodoc:
+ if @block
+ q.text ":" + @block.source_location.join(":") + ":"
+ first = false
+ else
+ first = true
+ end
+ [@short, @long].each do |list|
+ list.each do |opt|
+ if first
+ q.text ":"
+ first = false
+ end
+ q.breakable
+ q.text opt
+ end
+ end
+ end
+
+ def pretty_print(q) # :nodoc:
+ q.object_group(self) {pretty_print_contents(q)}
+ end
+
#
# Switch that takes no arguments.
#
class NoArgument < self
@@ -691,10 +714,14 @@
end
def self.pattern
Object
end
+
+ def pretty_head # :nodoc:
+ "NoArgument"
+ end
end
#
# Switch that takes an argument.
#
@@ -708,10 +735,14 @@
raise MissingArgument if argv.empty?
arg = argv.shift
end
conv_arg(*parse_arg(arg, &method(:raise)))
end
+
+ def pretty_head # :nodoc:
+ "Required"
+ end
end
#
# Switch that can omit argument.
#
@@ -725,22 +756,26 @@
conv_arg(*parse_arg(arg, &error))
else
conv_arg(arg)
end
end
+
+ def pretty_head # :nodoc:
+ "Optional"
+ end
end
#
- # Switch that takes an argument, which does not begin with '-'.
+ # Switch that takes an argument, which does not begin with '-' or is '-'.
#
class PlacedArgument < self
#
- # Returns nil if argument is not present or begins with '-'.
+ # Returns nil if argument is not present or begins with '-' and is not '-'.
#
def parse(arg, argv, &error)
- if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
+ if !(val = arg) and (argv.empty? or /\A-./ =~ (val = argv[0]))
return nil, block, nil
end
opt = (val = parse_arg(val, &error))[1]
val = conv_arg(*val)
if opt and !arg
@@ -748,10 +783,14 @@
else
val[0] = nil
end
val
end
+
+ def pretty_head # :nodoc:
+ "Placed"
+ end
end
end
#
# Simple option list providing mapping from short and/or long option
@@ -779,10 +818,21 @@
@short = OptionMap.new
@long = OptionMap.new
@list = []
end
+ def pretty_print(q) # :nodoc:
+ q.group(1, "(", ")") do
+ @list.each do |sw|
+ next unless Switch === sw
+ q.group(1, "(" + sw.pretty_head, ")") do
+ sw.pretty_print_contents(q)
+ end
+ end
+ end
+ end
+
#
# See OptionParser.accept.
#
def accept(t, pat = /.*/m, &block)
if pat
@@ -1096,10 +1146,11 @@
@banner = banner
@summary_width = width
@summary_indent = indent
@default_argv = ARGV
@require_exact = false
+ @raise_unknown = true
add_officious
yield self if block_given?
end
def add_officious # :nodoc:
@@ -1173,10 +1224,13 @@
# Whether to require that options match exactly (disallows providing
# abbreviated long option as short option).
attr_accessor :require_exact
+ # Whether to raise at unknown option.
+ attr_accessor :raise_unknown
+
#
# Heading banner preceding summary.
#
def banner
unless @banner
@@ -1291,10 +1345,33 @@
# Returns option summary string.
#
def help; summarize("#{banner}".sub(/\n?\z/, "\n")) end
alias to_s help
+ def pretty_print(q) # :nodoc:
+ q.object_group(self) do
+ first = true
+ if @stack.size > 2
+ @stack.each_with_index do |s, i|
+ next if i < 2
+ next if s.list.empty?
+ if first
+ first = false
+ q.text ":"
+ end
+ q.breakable
+ s.pretty_print(q)
+ end
+ end
+ end
+ end
+
+ def inspect # :nodoc:
+ require 'pp'
+ pretty_print_inspect
+ end
+
#
# Returns option summary list.
#
def to_a; summarize("#{banner}".split(/^/)) end
@@ -1427,11 +1504,11 @@
short << q
when /^=/
style = notwice(default_style.guess(arg = o), style, 'style')
default_pattern, conv = search(:atype, Object) unless default_pattern
else
- desc.push(o)
+ desc.push(o) if o && !o.empty?
end
end
default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
if !(short.empty? and long.empty?)
@@ -1564,13 +1641,15 @@
opt, rest = $1, $2
opt.tr!('_', '-')
begin
sw, = complete(:long, opt, true)
if require_exact && !sw.long.include?(arg)
+ throw :terminate, arg unless raise_unknown
raise InvalidOption, arg
end
rescue ParseError
+ throw :terminate, arg unless raise_unknown
raise $!.set_option(arg, true)
end
begin
opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
val = cb.call(val) if cb
@@ -1598,10 +1677,11 @@
sw, = complete(:long, opt)
eq ||= !rest
end
end
rescue ParseError
+ throw :terminate, arg unless raise_unknown
raise $!.set_option(arg, true)
end
begin
opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
rescue ParseError
@@ -1828,14 +1908,17 @@
#
# +filename+ defaults to basename of the program without suffix in a
# directory ~/.options, then the basename with '.options' suffix
# under XDG and Haiku standard places.
#
- def load(filename = nil)
+ # The optional +into+ keyword argument works exactly like that accepted in
+ # method #parse.
+ #
+ def load(filename = nil, into: nil)
unless filename
basename = File.basename($0, '.*')
- return true if load(File.expand_path(basename, '~/.options')) rescue nil
+ return true if load(File.expand_path(basename, '~/.options'), into: into) rescue nil
basename << ".options"
return [
# XDG
ENV['XDG_CONFIG_HOME'],
'~/.config',
@@ -1843,14 +1926,14 @@
# Haiku
'~/config/settings',
].any? {|dir|
next if !dir or dir.empty?
- load(File.expand_path(basename, dir)) rescue nil
+ load(File.expand_path(basename, dir), into: into) rescue nil
}
end
begin
- parse(*IO.readlines(filename).each {|s| s.chomp!})
+ parse(*File.readlines(filename, chomp: true), into: into)
true
rescue Errno::ENOENT, Errno::ENOTDIR
false
end
end