Created
January 15, 2015 18:14
-
-
Save RoUS/da894705ec30cf6f5d4c to your computer and use it in GitHub Desktop.
OptionParser helper to wrap long option descriptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Long OptionParser descriptions don't get nicely wrapped by it, so | |
# this method does the appropriate fill, wrap, and indent. | |
# | |
# @license Apache 2.0 | |
# | |
# @overload wrap(*args) | |
# @param [Array<Hash,String>] args | |
# The argument list can include multiple strings and hashes. | |
# | |
# Any hashes get merged and checked for options. See the nearby | |
# documentation for the +wrap(opts)+ overload description. (YARD | |
# [the documentation tool] doesn't provide for describing options in | |
# anything other than a +@param+ of type +Hash+.) | |
# | |
# Each string in the array starts a new line of text, and will be | |
# wrapped within the constraints. | |
# | |
# @overload wrap(opts) | |
# @param [Hash] opts | |
# @option opts [Integer] :firstcol (41) | |
# Left margin for wrapped & indented text. | |
# @option opts [Integer] :width (38) | |
# Total width for filled & wrapped text; does *not* include the | |
# indentation. | |
# | |
# @example | |
# wrap({ :firstcol=>1, :width=>14 }, 'a', 'b', 'c') | |
# => "a\nb\n\c" | |
# | |
# @example | |
# wrap({ :firstcol=>1, :width=>14 }, 'Some rather longer text to wrap.') | |
# => "Some rather\nlonger text to\nwrap." | |
# | |
# @example | |
# wrap({ :firstcol=>1, :width=>14 }, 'Some', 'rather longer text to wrap.') | |
# => "Some\nrather longer\ntext to wrap." | |
# | |
# @return [String] | |
# Returns a string with embedded newlines and indentation suitable to | |
# pass as description text to an OptionParser option handler. | |
# | |
def self.wrap(*args) | |
defaults = { | |
:firstcol => 38, | |
:width => 41, | |
} | |
# | |
# Pull any hashes out of the argument list and merge them with our | |
# defaults to make up the final settings for this call. | |
# | |
(options, args) = args.partition { |elt| elt.kind_of?(Hash) } | |
options = [ defaults, options ].flatten.reduce(:merge) | |
firstcol = options[:firstcol].to_i | |
width = options[:width].to_i | |
# | |
# We accumulate the lines of text into an array, which we'll convert | |
# to a string for the return value. | |
# | |
result = [] | |
(lines, other) = args.partition { |elt| elt.kind_of?(String) } | |
lines.each do |line| | |
if (line.length <= width) | |
result << line | |
else | |
# | |
# Break out the words so we can wrap them as needed, since the | |
# total string is longer than the allowed width. | |
# | |
words = line.strip.split(%r!\s+!) | |
newline = '' | |
while (! words.empty?) | |
while ((newline.length + words[0].length + 1) <= width) | |
newline << ' ' unless (newline.length.zero?) | |
newline << words.shift | |
break if (words.empty?) | |
end | |
newline = words.shift if (newline == '') | |
result << newline | |
newline = '' | |
end | |
end | |
end | |
interstice = "\n" + (' ' * (firstcol - 1)) | |
# | |
# We don't indent the beginning of the string; OptionParser's help | |
# mode will do that automatically. | |
# | |
return result.join(interstice).strip | |
end # def wrap |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment