Class: Dry::CLI::Help::Formatter

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/cli/help/formatter.rb

Overview

The pieces every help screen is made of: headings, paragraphs and definition lists, wrapped to one width and painted with one palette.

Text wraps before it is painted, so escape codes never count toward a line's length.

Defined Under Namespace

Classes: Row

Constant Summary collapse

INDENT =
"  "
GAP =
2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, io, terminal_width: Terminal.width) ⇒ Formatter

Returns a new instance of Formatter.

Parameters:

  • config (Configuration)
  • io (IO) —

    where the screen prints, which decides color :auto

  • terminal_width (Integer) (defaults to: Terminal.width)


31
32
33
34
35
# File 'lib/dry/cli/help/formatter.rb', line 31

def initialize(config, io, terminal_width: Terminal.width)
  @config = config
  @width = config.wrap_width(terminal_width)
  @pastel = ::Pastel.new(enabled: Colors.enabled_for?(config.color, io))
end

Instance Attribute Details

#config ⇒ Configuration (readonly)

Returns:



23
24
25
# File 'lib/dry/cli/help/formatter.rb', line 23

def config
  @config
end

#width ⇒ Integer? (readonly)

Returns the column text wraps at, nil when it does not.

Returns:

  • (Integer, nil) —

    the column text wraps at, nil when it does not



26
27
28
# File 'lib/dry/cli/help/formatter.rb', line 26

def width
  @width
end

Instance Method Details

#column_for(rows) ⇒ Integer

The description column for a set of rows: the longest term that has a description, but never more than half the wrap width. A term with nothing beside it has nothing to align.

Parameters:

  • rows (Array<Row>)

Returns:

  • (Integer)


81
82
83
84
# File 'lib/dry/cli/help/formatter.rb', line 81

def column_for(rows)
  longest = rows.reject { it.text.to_s.empty? }.map { it.term.length }.max || 0
  width ? [longest, width / 2].min : longest
end

#definitions(rows, column) ⇒ Array<String>

Parameters:

Returns:

  • (Array<String>)


89
90
91
# File 'lib/dry/cli/help/formatter.rb', line 89

def definitions(rows, column)
  rows.flat_map { definition(it, column) }
end

#heading(section) ⇒ String

Parameters:

  • section (Symbol)

Returns:

  • (String)


48
49
50
# File 'lib/dry/cli/help/formatter.rb', line 48

def heading(section)
  title(config.headings.fetch(section))
end

#paint(text, element) ⇒ String

Parameters:

Returns:

  • (String)


40
41
42
43
44
# File 'lib/dry/cli/help/formatter.rb', line 40

def paint(text, element)
  return text if element.nil?

  @pastel.decorate(text, *config.styles.fetch(element))
end

#paragraph(text, indent: "") ⇒ Array<String>

Returns wrapped lines; blank lines carry no indent.

Parameters:

  • text (String, nil)
  • indent (String) (defaults to: "")

Returns:

  • (Array<String>) —

    wrapped lines; blank lines carry no indent



69
70
71
72
73
# File 'lib/dry/cli/help/formatter.rb', line 69

def paragraph(text, indent: "")
  Text.lines(text, width && (width - indent.length)).map do |line|
    line.empty? ? line : indent + line
  end
end

#title(text) ⇒ String

A heading in the configured case and style, for any text.

Parameters:

  • text (String)

Returns:

  • (String)


56
57
58
59
60
61
62
63
64
# File 'lib/dry/cli/help/formatter.rb', line 56

def title(text)
  cased = case config.heading_case
          when :UPPERCASE then text.upcase
          when :lowercase then text.downcase
          when :Capitalize then text.sub(/\A\p{Ll}/, &:upcase)
          else text
          end
  paint(cased, :heading)
end