Class: Terminal::Text::Formatter
- Inherits:
-
Object
- Object
- Terminal::Text::Formatter
- Defined in:
- lib/terminal/text/formatter.rb
Overview
Processes text with BBCode markup and ANSI escape codes into display-width-aware lines. Supports Unicode-aware word-wrapping, alignment, padding, and prefix/suffix decorations.
Class Method Summary collapse
-
.[](*str, with_size: false, ansi: true, bbcode: true, spaces: true, eol: true, width: nil) ⇒ Array<String, Integer>
Parse text into lines, optionally with display widths.
-
.fmt(*str, ansi: true, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil) ⇒ Array<String>
Format text with alignment.
-
.format(*str, ansi: true, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil) ⇒ Array<String>
Format text with alignment, padding, and decorations.
Instance Method Summary collapse
-
#empty? ⇒ true, false
Whether the formatter has any content.
-
#fmt(width: nil, height: nil, align: nil) ⇒ Array<String>
Format lines with alignment.
-
#format(align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil) ⇒ Array<String>
Format lines with alignment, padding, and decorations.
-
#initialize(*str, ansi: true, bbcode: true, spaces: true, eol: true) ⇒ Formatter
constructor
Create a new formatter with given text and options.
-
#lines(width: nil) ⇒ Array<String>
Word-wrap and return lines as strings.
-
#lines_with_size(width: nil) ⇒ Array<String, Integer>
Word-wrap and return lines with their display widths.
-
#max_line_width ⇒ Integer
Maximum display width of any line.
Constructor Details
#initialize(*str, ansi: true, bbcode: true, spaces: true, eol: true) ⇒ Formatter
Create a new formatter with given text and options.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/terminal/text/formatter.rb', line 118 def initialize(*str, ansi: true, bbcode: true, spaces: true, eol: true) @lex = [] return if str.empty? ansi ? _generate_ansi(str, bbcode) : _generate(str, bbcode) return if @lex.empty? @keep_paragraph = true @lex = _ignore_whitespace unless spaces case eol when false, nil @lex = _ignore_newline when :no_paragraph @keep_paragraph = false end end |
Class Method Details
.[](*str, with_size: false, ansi: true, bbcode: true, spaces: true, eol: true, width: nil) ⇒ Array<String, Integer>
Parse text into lines, optionally with display widths.
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/terminal/text/formatter.rb', line 39 def self.[]( *str, with_size: false, ansi: true, bbcode: true, spaces: true, eol: true, width: nil ) ret = new(*str, ansi:, bbcode:, spaces:, eol:).lines_with_size(width:) with_size ? ret : ret.map(&:first) end |
.fmt(*str, ansi: true, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil) ⇒ Array<String>
Format text with alignment.
95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/terminal/text/formatter.rb', line 95 def self.fmt( *str, ansi: true, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil ) new(*str, ansi:, bbcode:, spaces:, eol:).fmt(align:, width:, height:) end |
.format(*str, ansi: true, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil) ⇒ Array<String>
Format text with alignment, padding, and decorations.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/terminal/text/formatter.rb', line 60 def self.format( *str, ansi: true, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil ) new(*str, ansi:, bbcode:, spaces:, eol:).format( align:, width:, height:, padding:, prefix:, suffix: ) end |
Instance Method Details
#empty? ⇒ true, false
Whether the formatter has any content.
305 |
# File 'lib/terminal/text/formatter.rb', line 305 def empty? = @lex.empty? |
#fmt(width: nil, height: nil, align: nil) ⇒ Array<String>
Format lines with alignment.
Like #format without padding, prefix, and suffix.
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/terminal/text/formatter.rb', line 272 def fmt(width: nil, height: nil, align: nil) if height return [] if (height = height.to_i) == 0 height = -height if (tail = (height < 0)) end lines = if width w = (width = width.to_i) raise(ArgumentError, "invalid width - #{width.inspect}") if w < 1 _limited(w) else @unlimited || _unlimited end return [+''] if lines.empty? lines = tail ? lines.last(height) : lines.take(height) if height w ||= lines.max_by(&:last)[-1] # unless width return lines.map(&:first) unless align space = SPACE_CACHE.dup return lines.map { |l, s| "#{space[w - s]}#{l}" } if align == :right return lines.map { |l, s| "#{l}#{space[w - s]}" } if align != :center lines.map do |l, s| rs = ((s = w - s) / 2.0).round rs < 1 ? l : "#{space[s - rs]}#{l}#{space[rs]}" end end |
#format(align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil) ⇒ Array<String>
Format lines with alignment, padding, and decorations.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/terminal/text/formatter.rb', line 191 def format( align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil ) if padding.nil? && prefix.nil? && suffix.nil? return fmt(align:, width:, height:) end top, right, bottom, left = _padding(padding) if height return [] if (height = height.to_i) == 0 if height < 0 tail = true height = -height end height -= top height -= -bottom return [] if height < 1 end space = SPACE_CACHE.dup if width w = (width = width.to_i) - left - right raise(ArgumentError, "invalid width - #{width.inspect}") if w < 1 lws = _limited(w) lws = tail ? lws.last(height) : lws.take(height) if height empty = "#{prefix}#{space[width]}#{suffix}" if top + bottom > 0 else lws = @unlimited || _unlimited lws = tail ? lws.last(height) : lws.take(height) if height w = lws.empty? ? 0 : lws.max_by(&:last)[-1] if top + bottom > 0 empty = "#{prefix}#{space[w + left + right]}#{suffix}" end end ret = [] ret.fill(empty, 0, top) if top > 0 left = left < 1 ? prefix.to_s : "#{prefix}#{space[left]}" right = right < 1 ? suffix.to_s : "#{space[right]}#{suffix}" case align when nil, false lws.each { |l, _| ret << "#{left}#{l}#{right}" } when :right lws.each { |l, s| ret << "#{left}#{space[w - s]}#{l}#{right}" } when :center lws.each do |l, s| rs = ((s = w - s) / 2.0).round next ret << "#{left}#{l}#{right}" if rs < 1 ret << "#{left}#{space[s - rs]}#{l}#{space[rs]}#{right}" end else lws.each { |l, s| ret << "#{left}#{l}#{space[w - s]}#{right}" } end return ret.fill(empty, ret.size, bottom) if bottom > 0 ret.empty? ? ret << '' : ret end |
#lines(width: nil) ⇒ Array<String>
Word-wrap and return lines as strings.
162 |
# File 'lib/terminal/text/formatter.rb', line 162 def lines(width: nil) = lines_with_size(width:).map(&:first) |
#lines_with_size(width: nil) ⇒ Array<String, Integer>
Word-wrap and return lines with their display widths.
145 146 147 148 149 150 |
# File 'lib/terminal/text/formatter.rb', line 145 def lines_with_size(width: nil) return [] if @lex.empty? return @unlimited || _unlimited unless width (w = width.to_i) > 0 and return _limited(w) raise(ArgumentError, "invalid width - #{width.inspect}") end |
#max_line_width ⇒ Integer
Maximum display width of any line.
314 315 316 317 |
# File 'lib/terminal/text/formatter.rb', line 314 def max_line_width @max_line_width ||= (@lex.empty? ? 0 : (@unlimited || _unlimited).max_by(&:last)[-1]) end |