Module: Slk::Support::TextWrapper

Defined in:
lib/slk/support/text_wrapper.rb

Overview

Text wrapping utilities with ANSI escape code awareness

Class Method Summary collapse

Class Method Details

.process_paragraph(paragraph, result, first_line_width, continuation_width) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/slk/support/text_wrapper.rb', line 23

def process_paragraph(paragraph, result, first_line_width, continuation_width)
  if paragraph.empty?
    result << ''
  else
    current_first_width = result.empty? ? first_line_width : continuation_width
    result << wrap_paragraph(paragraph, current_first_width, continuation_width)
  end
end

.process_word(word, state) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/slk/support/text_wrapper.rb', line 40

def process_word(word, state)
  if state[:current_line].empty?
    state[:current_line] = word
  elsif visible_length(state[:current_line]) + visible_length(word) <= state[:current_width]
    state[:current_line] += word
  else
    start_new_line(word, state)
  end
end

.start_new_line(word, state) ⇒ Object



50
51
52
53
54
# File 'lib/slk/support/text_wrapper.rb', line 50

def start_new_line(word, state)
  state[:lines] << state[:current_line]
  state[:current_line] = word.lstrip
  state[:current_width] = state[:rest_width]
end

.visible_length(text) ⇒ Object

Calculate visible length of text (excluding ANSI escape codes)



10
11
12
# File 'lib/slk/support/text_wrapper.rb', line 10

def visible_length(text)
  text.gsub(/\e\[[0-9;]*m/, '').length
end

.wrap(text, first_line_width, continuation_width) ⇒ Object

Wrap text to width, handling first line differently and preserving existing newlines



15
16
17
18
19
20
21
# File 'lib/slk/support/text_wrapper.rb', line 15

def wrap(text, first_line_width, continuation_width)
  result = []
  text.each_line do |paragraph|
    process_paragraph(paragraph.chomp, result, first_line_width, continuation_width)
  end
  result.join("\n")
end

.wrap_paragraph(text, first_width, rest_width) ⇒ Object

Wrap a single paragraph (no internal newlines)



33
34
35
36
37
38
# File 'lib/slk/support/text_wrapper.rb', line 33

def wrap_paragraph(text, first_width, rest_width)
  state = { lines: [], current_line: '', current_width: first_width, rest_width: rest_width }
  text.split(/(\s+)/).each { |word| process_word(word, state) }
  state[:lines] << state[:current_line] unless state[:current_line].empty?
  state[:lines].join("\n")
end