Module: Dry::CLI::Help::Text

Defined in:
lib/dry/cli/help/text.rb,
sig/dry/cli/help.rbs

Overview

Word wrapping for descriptions, epilogues and anything else a user writes.

Class Method Summary collapse

Class Method Details

.fill(text, width) ⇒ Array<String>

Greedy fill of one paragraph.

Returns:

  • (Array<String>)


54
55
56
57
58
59
60
61
62
# File 'lib/dry/cli/help/text.rb', line 54

def fill(text, width)
  text.split.each_with_object([]) do |word, lines|
    if lines.empty? || lines.last.length + 1 + word.length > width
      lines << word.dup
    else
      lines.last << " " << word
    end
  end
end

.lines(text, width) ⇒ Array<String>

Split text into lines no wider than width.

Paragraphs split on blank lines and reflow, so a heredoc wraps to the terminal instead of keeping the line breaks of the editor it was written in. A line starting with whitespace prints verbatim, which keeps indented lists and code intact. Consecutive blank lines collapse to one. A word longer than width gets a line to itself.

Parameters:

  • text (String, nil)
  • width (Integer, nil) —

    nil keeps every line as written

Returns:

  • (Array<String>) —

    lines, with "" between paragraphs



21
22
23
24
25
26
# File 'lib/dry/cli/help/text.rb', line 21

def lines(text, width)
  source = text.to_s.sub(/\A(?:[ \t]*\n)+/, "").rstrip
  return source.lines(chomp: true) if width.nil?

  reflow(source, width)
end

.reflow(source, width) ⇒ Array<String>

Returns:

  • (Array<String>)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/dry/cli/help/text.rb', line 29

def reflow(source, width)
  output = []
  paragraph = []
  flush = lambda do
    output.concat(fill(paragraph.join(" "), width)) unless paragraph.empty?
    paragraph.clear
  end

  source.each_line(chomp: true) do |line|
    if line.strip.empty?
      flush.call
      output << "" unless output.last == ""
    elsif line.start_with?(" ", "\t")
      flush.call
      output << line.rstrip
    else
      paragraph << line.strip
    end
  end
  flush.call
  output
end