class CLAide::Command::Banner

Creates the formatted banner to present as help of the provided command class.

Constants

DESCRIPTION_SPACES

@return [Fixnum] The minimum between a name and its description.

MAX_WIDTH

@return [Fixnum] The maximum width of the text.

SUBCOMMAND_BULLET_SIZE

@return [Fixnum] The minimum between a name and its description.

TEXT_INDENT

@return [String] The indentation of the text.

Attributes

command[RW]

@return [Class] The command for which the banner should be created.

Public Class Methods

new(command) click to toggle source

@param [Class] command @see command

# File lib/claide/command/banner.rb, line 15
def initialize(command)
  @command = command
end

Public Instance Methods

formatted_banner() click to toggle source

@return [String] The banner for the command.

# File lib/claide/command/banner.rb, line 21
def formatted_banner
  sections = [
    ['Usage',    formatted_usage_description],
    ['Commands', formatted_subcommand_summaries],
    ['Options',  formatted_options_description],
  ]
  banner = sections.map do |(title, body)|
    [prettify_title("#{title}:"), body] unless body.empty?
  end.compact.join("\n\n")
  banner
end

Private Instance Methods

compute_max_name_width() click to toggle source

@return [Fixnum] The width of the largest command name or of the

largest option name. Used to align all the descriptions.
# File lib/claide/command/banner.rb, line 203
def compute_max_name_width
  widths = []
  widths << command.options.map { |option| option.first.size }
  widths << subcommands_for_banner.map do |cmd|
    cmd.command.size + SUBCOMMAND_BULLET_SIZE
  end.max
  widths.flatten.compact.max || 1
end
entry_description(name, description, name_width) click to toggle source

@return [String] The line describing a single entry (subcommand or

option).
# File lib/claide/command/banner.rb, line 124
def entry_description(name, description, name_width)
  max_name_width = compute_max_name_width
  desc_start = max_name_width + (TEXT_INDENT - 2) + DESCRIPTION_SPACES
  result = ' ' * (TEXT_INDENT - 2)
  result << name
  result << ' ' * DESCRIPTION_SPACES
  result << ' ' * (max_name_width - name_width)
  result << TextWrapper.wrap_with_indent(description,
                                         desc_start,
                                         MAX_WIDTH)
end
formatted_options_description() click to toggle source

@return [String] The section describing the options of the command.

# File lib/claide/command/banner.rb, line 113
def formatted_options_description
  options = command.options
  options.map do |name, description|
    pretty_name = prettify_option_name(name)
    entry_description(pretty_name, description, name.size)
  end.join("\n")
end
formatted_subcommand_summaries() click to toggle source

@return [String] The section describing the subcommands of the command.

@note The plus sign emphasizes the that the subcommands are added to

the command. The square brackets conveys a sense of direction
and indicates the gravitational force towards the default
command.
# File lib/claide/command/banner.rb, line 100
def formatted_subcommand_summaries
  subcommands = subcommands_for_banner
  subcommands.map do |subcommand|
    name = subcommand.command
    bullet = (name == command.default_subcommand) ? '>' : '+'
    name = "#{bullet} #{name}"
    pretty_name = prettify_subcommand(name)
    entry_description(pretty_name, subcommand.summary, name.size)
  end.join("\n")
end
formatted_usage_description() click to toggle source

@return [String] The section describing the usage of the command.

# File lib/claide/command/banner.rb, line 56
def formatted_usage_description
  message = command.description || command.summary || ''
  message = TextWrapper.wrap_formatted_text(message,
                                            TEXT_INDENT,
                                            MAX_WIDTH)
  message = prettify_message(command, message)
  "#{signature}\n\n#{message}"
end
prettify_message(command, message) click to toggle source

@return [String] A decorated command description.

# File lib/claide/command/banner.rb, line 175
def prettify_message(command, message)
  message = message.dup
  command.arguments.each do |arg|
    arg.names.each do |name|
      message.gsub!("`#{name.gsub(/\.{3}$/, '')}`", '\0'.ansi.magenta)
    end
  end
  command.options.each do |(name, _description)|
    message.gsub!("`#{name}`", '\0'.ansi.blue)
  end
  message
end
prettify_option_name(name) click to toggle source

@return [String] A decorated textual representation of the option name.

# File lib/claide/command/banner.rb, line 155
def prettify_option_name(name)
  name.chomp.ansi.blue
end
prettify_signature(command, subcommand, argument) click to toggle source

@return [String] A decorated textual representation of the command.

# File lib/claide/command/banner.rb, line 161
def prettify_signature(command, subcommand, argument)
  components = [
    [command, :green],
    [subcommand, :green],
    [argument, :magenta],
  ]
  components.reduce('') do |memo, (string, ansi_key)|
    next memo if !string || string.empty?
    memo << ' ' << string.ansi.apply(ansi_key)
  end.lstrip
end
prettify_subcommand(name) click to toggle source

@return [String] A decorated textual representation of the subcommand

name.
# File lib/claide/command/banner.rb, line 148
def prettify_subcommand(name)
  name.chomp.ansi.green
end
prettify_title(title) click to toggle source

@return [String] A decorated title.

# File lib/claide/command/banner.rb, line 141
def prettify_title(title)
  title.ansi.underline
end
signature() click to toggle source

@return [String] The signature of the command.

# File lib/claide/command/banner.rb, line 67
def signature
  full_command = command.full_command
  sub_command = signature_sub_command
  arguments = signature_arguments
  result = prettify_signature(full_command, sub_command, arguments)
  result.insert(0, '$ ')
  result.insert(0, ' ' * (TEXT_INDENT - '$ '.size))
end
signature_arguments() click to toggle source

@return [String] The arguments of the signature.

# File lib/claide/command/banner.rb, line 85
def signature_arguments
  command.arguments.map do |arg|
    names = arg.names.join('|')
    names.concat(' ' + Argument::ELLIPSIS) if arg.repeatable?
    arg.required? ? names : "[#{names}]"
  end.join(' ')
end
signature_sub_command() click to toggle source

@return [String] The subcommand indicator of the signature.

# File lib/claide/command/banner.rb, line 78
def signature_sub_command
  return '[COMMAND]' if command.default_subcommand
  return 'COMMAND' if command.subcommands.any?
end
subcommands_for_banner() click to toggle source

@return [Array<String>] The list of the subcommands to use in the

banner.
# File lib/claide/command/banner.rb, line 194
def subcommands_for_banner
  command.subcommands_for_command_lookup.reject do |subcommand|
    subcommand.summary.nil?
  end.sort_by(&:command)
end