class TTY::Option::Formatter
Constants
- DEFAULT_NAME_SELECTOR
- DEFAULT_ORDER
- DEFAULT_PARAM_DISPLAY
- DEFAULT_WIDTH
- ELLIPSIS
- NEWLINE
- NOOP_PROC
- SHORT_OPT_LENGTH
- SPACE
Attributes
Public Class Methods
@api public
# File lib/tty/option/formatter.rb, line 23 def self.help(parameters, usage, **config, &block) new(parameters, usage, **config).help(&block) end
Create a help formatter
@param [Parameters]
@api public
# File lib/tty/option/formatter.rb, line 34 def initialize(parameters, usage, param_display: DEFAULT_PARAM_DISPLAY, width: DEFAULT_WIDTH, order: DEFAULT_ORDER, indent: 0) @parameters = parameters @usage = usage @param_display = param_display @order = order @width = width @indent = indent @space_indent = SPACE * indent @param_indent = indent + 2 @section_names = { usage: "Usage:", arguments: "Arguments:", keywords: "Keywords:", options: "Options:", env: "Environment:", examples: "Examples:" } end
Public Instance Methods
A formatted help usage information
@yieldparam [TTY::Option::Sections] sections
@return [String]
@api public
# File lib/tty/option/formatter.rb, line 61 def help sections = Sections.new sections.add(:header, help_header) if @usage.header? sections.add(:banner, help_banner) sections.add(:description, help_description) if @usage.desc? if @parameters.arguments.any?(&:display?) sections.add(:arguments, help_arguments) end if @parameters.keywords.any?(&:display?) sections.add(:keywords, help_keywords) end if @parameters.options? sections.add(:options, help_options) end if @parameters.environments.any?(&:display?) sections.add(:environments, help_environments) end sections.add(:examples, help_examples) if @usage.example? sections.add(:footer, help_footer) if @usage.footer? yield(sections) if block_given? formatted = sections.reject(&:empty?).join(NEWLINE) formatted.end_with?(NEWLINE) ? formatted : formatted + NEWLINE end
# File lib/tty/option/formatter.rb, line 105 def help_arguments "#{NEWLINE}#{@space_indent}#{@section_names[:arguments]}#{NEWLINE}" + format_section(@parameters.arguments, ->(param) do @param_display.(param.name) end) end
# File lib/tty/option/formatter.rb, line 101 def help_description "#{NEWLINE}#{format_description}" end
# File lib/tty/option/formatter.rb, line 124 def help_environments "#{NEWLINE}#{@space_indent}#{@section_names[:env]}#{NEWLINE}" + format_section(@order.(@parameters.environments)) end
# File lib/tty/option/formatter.rb, line 129 def help_examples "#{NEWLINE}#{@space_indent}#{@section_names[:examples]}#{NEWLINE}" + format_examples end
# File lib/tty/option/formatter.rb, line 93 def help_header "#{format_multiline(@usage.header, @indent)}#{NEWLINE}" end
# File lib/tty/option/formatter.rb, line 112 def help_keywords "#{NEWLINE}#{@space_indent}#{@section_names[:keywords]}#{NEWLINE}" + format_section(@parameters.keywords, ->(param) do kwarg_param_display(param).split("=").map(&@param_display).join("=") end) end
# File lib/tty/option/formatter.rb, line 119 def help_options "#{NEWLINE}#{@space_indent}#{@section_names[:options]}#{NEWLINE}" + format_options end
Private Instance Methods
Provide an argument summary
@api private
# File lib/tty/option/formatter.rb, line 171 def format_argument_usage(arg) arg_name = @param_display.(arg.name) format_parameter_usage(arg, arg_name) end
Format arguments
@api private
# File lib/tty/option/formatter.rb, line 158 def format_arguments_usage return "" unless @parameters.arguments? @parameters.arguments.reduce([]) do |acc, arg| next acc if arg.hidden? acc << format_argument_usage(arg) end.join(SPACE) end
Format default value
@api private
# File lib/tty/option/formatter.rb, line 357 def format_default(param) return if !param.default? || [true, false].include?(param.default) if param.default.is_a?(String) format(" (default %p)", param.default) else format(" (default %s)", param.default) end end
Format multiline description
@api private
# File lib/tty/option/formatter.rb, line 284 def format_description format_multiline(@usage.desc, @indent) end
Format examples section
@api private
# File lib/tty/option/formatter.rb, line 370 def format_examples format_multiline(@usage.example, @param_indent) end
Provide a keyword summary
@api private
# File lib/tty/option/formatter.rb, line 210 def format_keyword_usage(kwarg) param_name = kwarg_param_display(kwarg, @param_display) format_parameter_usage(kwarg, param_name) end
Format keywords usage
@api private
# File lib/tty/option/formatter.rb, line 197 def format_keywords_usage return "" unless @parameters.keywords? @parameters.keywords.reduce([]) do |acc, kwarg| next acc if kwarg.hidden? acc << format_keyword_usage(kwarg) end.join(SPACE) end
Format multiline content
@api private
# File lib/tty/option/formatter.rb, line 377 def format_multiline(lines, indent) last_index = lines.size - 1 lines.map.with_index do |line, i| line.map do |part| part.split(NEWLINE).map do |p| wrap(p, indent: indent, width: width, indent_first: true) end.join(NEWLINE) end.join(NEWLINE) + (last_index != i ? NEWLINE : "") end.join(NEWLINE) end
Format an option
@api private
# File lib/tty/option/formatter.rb, line 310 def format_option(option, longest_length, any_short) line = [@space_indent] desc = [] indent = @indent if any_short short_option = option.short? ? option.short_name : SPACE line << format("%#{SHORT_OPT_LENGTH}s", short_option) indent += SHORT_OPT_LENGTH end # short & long option separator line << ((option.short? && option.long?) ? ", " : " ") indent += 2 if option.long? if option.desc? line << format("%-#{longest_length}s", option.long) else line << option.long end else line << format("%-#{longest_length}s", SPACE) end indent += longest_length if option.desc? desc << " #{option.desc}" end indent += 2 if option.permit? desc << format(" (permitted: %s)", option.permit.join(",")) end if (default = format_default(option)) desc << default end line << wrap(desc.join, indent: indent, width: width) line.join end
Returns all the options formatted to fit 80 columns
@return [String]
@api private
# File lib/tty/option/formatter.rb, line 293 def format_options return "" if @parameters.options.empty? longest_option = @parameters.options.map(&:long) .compact.max_by(&:length).length any_short = @parameters.options.map(&:short).compact.any? ordered_options = @order.(@parameters.options) ordered_options.reduce([]) do |acc, option| next acc if option.hidden? acc << format_option(option, longest_option, any_short) end.join(NEWLINE) end
Format parameter usage
@api private
# File lib/tty/option/formatter.rb, line 179 def format_parameter_usage(param, param_name) args = [] if 0 < param.arity args << "[" if param.optional? args << param_name (param.arity - 1).times { args << " #{param_name}" } args << "]" if param.optional? args.join else (param.arity.abs - 1).times { args << param_name } args << "[#{param_name}#{ELLIPSIS}]" args.join(SPACE) end end
Format a parameter section in the help display
@param [String] parameters_name
the name of parameter type
@param [Proc] name_selector
selects a name from the parameter, by defeault the name
@return [String]
@api private
# File lib/tty/option/formatter.rb, line 241 def format_section(params, name_selector = DEFAULT_NAME_SELECTOR) longest_param = params.map(&name_selector).compact.max_by(&:length).length params.reduce([]) do |acc, param| next acc if param.hidden? acc << format_section_parameter(param, longest_param, name_selector) end.join(NEWLINE) end
Format a section parameter line
@return [String]
@api private
# File lib/tty/option/formatter.rb, line 256 def format_section_parameter(param, longest_param, name_selector) line = [] desc = [] indent = @param_indent + longest_param + 2 param_name = name_selector.(param) if param.desc? line << format("%s%-#{longest_param}s", SPACE * @param_indent, param_name) desc << " #{param.desc}" else line << format("%s%s", SPACE * @param_indent, param_name) end if param.permit? desc << format(" (permitted: %s)", param.permit.join(", ")) end if (default = format_default(param)) desc << default end line << wrap(desc.join, indent: indent, width: width) line.join end
Provide a default usage banner
@api private
# File lib/tty/option/formatter.rb, line 143 def format_usage usage = @space_indent + @section_names[:usage] + SPACE output = [] output << @usage.program output << " #{@usage.commands.join(" ")}" if @usage.command? output << " [#{@param_display.("options")}]" if @parameters.options? output << " [#{@param_display.("environment")}]" if @parameters.environments? output << " #{format_arguments_usage}" if @parameters.arguments? output << " #{format_keywords_usage}" if @parameters.keywords? usage + wrap(output.join, indent: usage.length, width: width) end
Provide a keyword argument display format
@api private
# File lib/tty/option/formatter.rb, line 218 def kwarg_param_display(kwarg, param_display = NOOP_PROC) kwarg_name = param_display.(kwarg.name) conv_name = case kwarg.convert when Proc, NilClass kwarg_name else param_display.(kwarg.convert) end "#{kwarg_name}=#{conv_name}" end