Module: RubyCoded::Chat::Renderer::RichText
Overview
Helpers for building and serializing rich text using ratatui text lines/spans.
Constant Summary
collapse
- BASE_TEXT_STYLES =
{
system: { fg: :dark_gray, modifiers: [:italic] },
user_label: { fg: :cyan, modifiers: [:bold] },
tool_call: { fg: :yellow, modifiers: [:bold] },
tool_pending: { fg: :magenta, modifiers: [:bold] },
tool_result: { fg: :green },
thinking_title: { fg: :blue, modifiers: [:bold] }
}.freeze
Instance Method Summary
collapse
-
#base_text_style(role) ⇒ Object
-
#code_block_style ⇒ Object
-
#code_language_line(language) ⇒ Object
-
#inline_code_style ⇒ Object
-
#merge_style(style, foreground: nil, background: nil, modifiers: []) ⇒ Object
-
#parse_rich_line(raw_line, state, role) ⇒ Object
-
#parse_rich_text(text, role: :assistant) ⇒ Object
-
#rich_line_for(raw_line, in_code_block, role) ⇒ Object
-
#rich_line_plain(line) ⇒ Object
-
#rich_text_lines(text, role: :assistant) ⇒ Object
-
#rich_text_plain(lines) ⇒ Object
-
#toggle_code_fence(raw_line, state) ⇒ Object
#append_bold_span!, #append_code_span!, #append_italic_span!, #append_styled_span!, #inline_spans, #next_inline_marker
Instance Method Details
#base_text_style(role) ⇒ Object
78
79
80
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 78
def base_text_style(role)
@tui.style(**BASE_TEXT_STYLES.fetch(role, { modifiers: [] }))
end
|
#code_block_style ⇒ Object
86
87
88
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 86
def code_block_style
@tui.style(fg: :green, bg: :black)
end
|
#code_language_line(language) ⇒ Object
57
58
59
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 57
def code_language_line(language)
@tui.line(spans: [@tui.span(content: "[#{language}]", style: @tui.style(fg: :yellow, modifiers: [:bold]))])
end
|
#inline_code_style ⇒ Object
82
83
84
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 82
def inline_code_style
@tui.style(fg: :yellow, bg: :dark_gray)
end
|
#merge_style(style, foreground: nil, background: nil, modifiers: []) ⇒ Object
61
62
63
64
65
66
67
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 61
def merge_style(style, foreground: nil, background: nil, modifiers: [])
@tui.style(
fg: foreground || style&.fg,
bg: background || style&.bg,
modifiers: ((style&.modifiers || []) + modifiers).uniq
)
end
|
#parse_rich_line(raw_line, state, role) ⇒ Object
34
35
36
37
38
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 34
def parse_rich_line(raw_line, state, role)
return toggle_code_fence(raw_line, state) if raw_line.start_with?("```")
state[:lines] << rich_line_for(raw_line, state[:in_code_block], role)
end
|
#parse_rich_text(text, role: :assistant) ⇒ Object
28
29
30
31
32
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 28
def parse_rich_text(text, role: :assistant)
state = { lines: [], in_code_block: false }
text.split("\n", -1).each { |raw_line| parse_rich_line(raw_line, state, role) }
state[:lines]
end
|
#rich_line_for(raw_line, in_code_block, role) ⇒ Object
51
52
53
54
55
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 51
def rich_line_for(raw_line, in_code_block, role)
return @tui.line(spans: inline_spans(raw_line, role: role)) unless in_code_block
@tui.line(spans: [@tui.span(content: raw_line, style: code_block_style)])
end
|
#rich_line_plain(line) ⇒ Object
22
23
24
25
26
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 22
def rich_line_plain(line)
return line.to_s unless line.respond_to?(:spans)
Array(line.spans).map { |span| span.respond_to?(:content) ? span.content.to_s : span.to_s }.join
end
|
#rich_text_lines(text, role: :assistant) ⇒ Object
12
13
14
15
16
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 12
def rich_text_lines(text, role: :assistant)
return [] if text.nil? || text.empty?
parse_rich_text(text, role: role)
end
|
#rich_text_plain(lines) ⇒ Object
18
19
20
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 18
def rich_text_plain(lines)
Array(lines).map { |line| rich_line_plain(line) }.join("\n")
end
|
#toggle_code_fence(raw_line, state) ⇒ Object
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/ruby_coded/chat/renderer/rich_text.rb', line 40
def toggle_code_fence(raw_line, state)
if state[:in_code_block]
state[:in_code_block] = false
return
end
state[:in_code_block] = true
language = raw_line.delete_prefix("```").strip
state[:lines] << code_language_line(language) unless language.empty?
end
|