Module: Terminal::Text

Defined in:
lib/terminal/text.rb,
lib/terminal/text/formatter.rb,
lib/terminal/text/char_width.rb

Overview

Unicode-aware text processing utilities for display width calculation, word-wrapping, and formatted text output.

All methods correctly handle multi-byte Unicode characters, East Asian wide characters, emoji, combining marks, and ANSI escape codes.

Examples:

Measure display width

Terminal::Text.width('Hello')     # => 5
Terminal::Text.width("\u{1F600}") # => 2  (emoji)

Word-wrap text

Terminal::Text.lines('Hello World, this is a test', width: 12)
# => ["Hello World,", "this is a", "test"]

See Also:

Defined Under Namespace

Classes: Formatter

Constant Summary collapse

UNICODE_VERSION =

supported Unicode Standard version

'18.0.0'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.ambiguous_char_width ⇒ Integer

Display width used for East Asian ambiguous-width characters.

Examples:

Terminal::Text.ambiguous_char_width     # => 1
Terminal::Text.ambiguous_char_width = 2 # for CJK terminals

Returns:

  • (Integer) —

    default: 1



32
33
34
# File 'lib/terminal/text.rb', line 32

def ambiguous_char_width
  @ambiguous_char_width
end

Class Method Details

.each_line(*str, limit: nil, bbcode: true, ansi: true, ignore_newline: false) ⇒ Object Also known as: each

Deprecated.

Use lines and iterate over the result.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/terminal/text.rb', line 142

def each_line(
  *str,
  limit: nil,
  bbcode: true,
  ansi: true,
  ignore_newline: false,
  &
)
  warn(
    '[DEPRECATED] `each_line` is deprecated – use `.lines.each` instead',
    category: :deprecated,
    uplevel: 1
  )
  lines(
    *str,
    bbcode:,
    ansi:,
    spaces: true,
    eol: !ignore_newline,
    width: limit
  ).each(&)
end

.each_line_with_size(*str, limit: nil, bbcode: true, ansi: true, ignore_newline: false) ⇒ Object Also known as: each_with_size

Deprecated.

Use lines_with_size and iterate over the result.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/terminal/text.rb', line 175

def each_line_with_size(
  *str,
  limit: nil,
  bbcode: true,
  ansi: true,
  ignore_newline: false,
  &
)
  warn(
    '[DEPRECATED] `each_line_with_size` is deprecated ' \
      '– use `.lines_with_size.each` instead',
    category: :deprecated,
    uplevel: 1
  )

  lines_with_size(
    *str,
    bbcode:,
    ansi:,
    spaces: true,
    eol: !ignore_newline,
    width: limit
  ).each(&)
end

.fmt ⇒ Array<String>

Format text with alignment.

Examples:

Terminal::Text.fmt('Hi', align: :center, width: 10)
# => ["    Hi    "]

Parameters:

  • str (Array<#to_s>) —

    text to process

  • ansi (true, false) —

    recognize ANSI escape codes

  • bbcode (true, false) —

    process BBCode markup

  • spaces (true, false) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

  • eol (true, false) —

    preserve line endings; when false newlines are treated as spaces

  • align (Symbol, nil) —

    text alignment: :left, :right, :center, or nil (no fill)

  • width (#to_i, nil) —

    output line width in columns

  • height (#to_i, nil) —

    number of output lines; negative values take lines from the end; 0 returns [""]

Returns:

  • (Array<String>) —

    formatted output lines

Raises:

  • (ArgumentError) —

    if width is zero or negative

See Also:



131
# File 'lib/terminal/text.rb', line 131

def fmt(...) = Formatter.fmt(...)

.format ⇒ Array<String>

Format text with alignment, padding, and decorations.

Examples:

Terminal::Text.format(
  'Hello World', width: 9, align: :left, prefix: '| ', suffix: ' |'
)
# => ["| Hello     |", "| World     |"]

Parameters:

  • str (Array<#to_s>) —

    text to process

  • ansi (true, false) —

    recognize ANSI escape codes

  • bbcode (true, false) —

    process BBCode markup

  • spaces (true, false) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

  • eol (true, false) —

    preserve line endings; when false newlines are treated as spaces

  • align (Symbol, nil) —

    text alignment: :left, :right, :center, or nil (no fill)

  • width (#to_i, nil) —

    output line width in columns

  • height (#to_i, nil) —

    number of output lines; negative values take lines from the end; 0 returns [""]

  • padding (#to_i, Array, nil) —

    CSS-style padding

    • 1 value: all sides;
    • 2 values: [vertical, horizontal];
    • 3 values: [top, horizontal, bottom];
    • 4 values: [top, right, bottom, left]
  • prefix (#to_s, nil) —

    string prepended to each line

  • suffix (#to_s, nil) —

    string appended to each line

Returns:

  • (Array<String>) —

    formatted output lines

Raises:

  • (ArgumentError) —

    if width is zero or negative

See Also:



118
# File 'lib/terminal/text.rb', line 118

def format(...) = Formatter.format(...)

.lines(*str, bbcode: true, ansi: true, spaces: true, eol: true, width: nil) ⇒ Array<String>

Split text into lines as strings.

Examples:

Terminal::Text.lines('Hello World', width: 5)
# => ["Hello", "World"]

With BBCode

Terminal::Text.lines('[bold]Hello[/] World', width: 5)
# => ["\e[1mHello\e[m", "World"]

Parameters:

  • str (Array<#to_s>) —

    text to process

  • ansi (true, false) (defaults to: true) —

    recognize ANSI escape codes

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

  • spaces (true, false) (defaults to: true) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

  • eol (true, false) (defaults to: true) —

    preserve line endings; when false newlines are treated as spaces

  • width (#to_i, nil) (defaults to: nil) —

    maximum line width in columns

Returns:

  • (Array<String>)

See Also:



94
95
96
97
98
99
100
101
102
103
# File 'lib/terminal/text.rb', line 94

def lines(
  *str,
  bbcode: true,
  ansi: true,
  spaces: true,
  eol: true,
  width: nil
)
  Formatter.new(*str, bbcode:, ansi:, spaces:, eol:).lines(width:)
end

.lines_with_size(*str, bbcode: true, ansi: true, spaces: true, eol: true, width: nil) ⇒ Array<String, Integer>

Split text into lines with their display widths.

Examples:

Terminal::Text.lines_with_size('Hello World', width: 5)
# => [["Hello", 5], ["World", 5]]

Parameters:

  • str (Array<#to_s>) —

    text to process

  • ansi (true, false) (defaults to: true) —

    recognize ANSI escape codes

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

  • spaces (true, false) (defaults to: true) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

  • eol (true, false) (defaults to: true) —

    preserve line endings; when false newlines are treated as spaces

  • width (#to_i, nil) (defaults to: nil) —

    maximum line width in columns; nil returns unwrapped lines

Returns:

  • (Array<String, Integer>) —

    pairs of [line_text, display_width]



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/terminal/text.rb', line 67

def lines_with_size(
  *str,
  bbcode: true,
  ansi: true,
  spaces: true,
  eol: true,
  width: nil
)
  Formatter.new(*str, bbcode:, ansi:, spaces:, eol:).lines_with_size(
    width:
  )
end

.max_line_width(*str, ansi: true, bbcode: true, spaces: true, eol: true, **opts) ⇒ Integer

Calculate the maximum display width of any line.

Examples:

Terminal::Text.max_line_width("short\na longer line")
# => 13

Parameters:

  • str (Array<#to_s>) —

    text to process

  • ansi (true, false) (defaults to: true) —

    recognize ANSI escape codes

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

  • spaces (true, false) (defaults to: true) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

  • eol (true, false) (defaults to: true) —

    preserve line endings; when false newlines are treated as spaces

Returns:

  • (Integer) —

    widest line in columns, 0 when empty



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/terminal/text.rb', line 209

def max_line_width(
  *str,
  ansi: true,
  bbcode: true,
  spaces: true,
  eol: true,
  **opts
)
  # backward compatibility:
  if opts.key?(:ignore_newline)
    eol = opts[:ignore_newline] ? false : true
    warn(
      "Parameter ':ignore_newline' will become obsolete - " \
        "use 'eol: #{eol.inspect}' instead",
      category: :deprecated
    )
  end

  Formatter.new(*str, bbcode:, ansi:, spaces:, eol:).max_line_width
end

.width(str, bbcode: true, spaces: true) ⇒ Integer

Calculate the display width of a string in terminal columns.

Examples:

Terminal::Text.width('Hello')                          # => 5
Terminal::Text.width('[bold]Hi[/bold]')                # => 2
Terminal::Text.width('[bold]Hi[/bold]', bbcode: false) # => 15

Parameters:

  • str (#to_s) —

    the string to measure

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

  • spaces (true, false) (defaults to: true) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

Returns:

  • (Integer) —

    display width in columns



51
52
53
54
55
56
# File 'lib/terminal/text.rb', line 51

def width(str, bbcode: true, spaces: true)
  Formatter
    .new(str, bbcode:, spaces:, ansi: false, eol: false)
    .lines_with_size
    .dig(0, -1) || 0
end