Class: TableTennis::Stage::Render
- Defined in:
- lib/table_tennis/stage/render.rb
Overview
This is the final stage of the rending pipeline - take our layout information, the table cells, and the painted styles to render the table as a string. This is the slowest part of rendering since there is a lot of ansi/string manipulation.
This is also where config.search is applied.
Constant Summary collapse
- BOX =
[ "╭─┬─╮", # 0 "│ │ │", # 1 "├─┼─┤", # 2 "╰─┴─╯", # 3 ]
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#paint(str, style) ⇒ Object
helpers.
- #pipe ⇒ Object
- #render_cell(value, r, c, default_cell_style) ⇒ Object
- #render_empty ⇒ Object
- #render_row(r) ⇒ Object
- #render_separator(l, m, r) ⇒ Object
-
#render_title ⇒ Object
render different parts of the table.
- #run(io) ⇒ Object
- #search ⇒ Object
-
#search_cell(value) ⇒ Object
add ansi codes for search.
Methods inherited from Base
Methods included from Util::Inspectable
Constructor Details
This class inherits a constructor from TableTennis::Stage::Base
Instance Method Details
#paint(str, style) ⇒ Object
helpers
142 143 144 145 146 |
# File 'lib/table_tennis/stage/render.rb', line 142 def paint(str, style) # delegate painting to the theme, if color is enabled str = theme.paint(str, style) if config.color str end |
#pipe ⇒ Object
148 |
# File 'lib/table_tennis/stage/render.rb', line 148 def pipe = paint(PIPE, :chrome) |
#render_cell(value, r, c, default_cell_style) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/table_tennis/stage/render.rb', line 72 def render_cell(value, r, c, default_cell_style) # calculate whitespace based on plaintext whitespace = columns[c].width - Util::Strings.width(value) # cell > column > default > cell (row styles are applied elsewhere) style = nil style ||= data.get_style(r:, c:) style ||= data.get_style(c:) style ||= default_cell_style style ||= :cell # add ansi codes for search value = search_cell(value) if search # add ansi codes for links if config.color && (link = data.links[[r, c]]) value = theme.link(value, link) end # pad and paint if whitespace > 0 spaces = " " * whitespace value = if columns[c].alignment == :left "#{value}#{spaces}" else "#{spaces}#{value}" end end paint(value, style) end |
#render_empty ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/table_tennis/stage/render.rb', line 115 def render_empty title, body = config.title || "empty table", "no data" width = [title, body].map(&:length).max # helpers sep_row = ->(l, c, r) do paint("#{l}#{c * (width + 2)}#{r}", :chrome) end text_row = ->(str, style) do inner = paint(str.center(width), style) paint("#{pipe} #{inner} #{pipe}", Theme::BG) end # go [].tap do _1 << sep_row.call(NW, BAR, NE) _1 << text_row.call(title, data.get_style(r: :title) || :cell) _1 << sep_row.call(W, BAR, E) _1 << text_row.call(body, :chrome) _1 << sep_row.call(SW, BAR, SE) end.join("\n") end |
#render_row(r) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/table_tennis/stage/render.rb', line 57 def render_row(r) row_style = data.get_style(r:) # assemble line by rendering cells enum = (r != :header) ? rows[r].each : columns.map(&:header) joiner = config.separators ? " #{pipe} " : " " line = enum.map.with_index do |value, c| render_cell(value, r, c, row_style) end.join(joiner) line = "#{pipe} #{line} #{pipe}" # afterward, apply row color paint(line, row_style || Theme::BG) end |
#render_separator(l, m, r) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/table_tennis/stage/render.rb', line 103 def render_separator(l, m, r) m = "" if !config.separators line = [].tap do |buf| columns.each.with_index do |column, c| buf << ((c == 0) ? l : m) buf << (BAR * (column.width + 2)) end buf << r end.join paint(paint(line, :chrome), Theme::BG) end |
#render_title ⇒ Object
render different parts of the table
49 50 51 52 53 54 55 |
# File 'lib/table_tennis/stage/render.rb', line 49 def render_title title_width = data.table_width - 4 title = Util::Strings.truncate(config.title, title_width) title_style = data.get_style(r: :title) || :cell line = paint(Util::Strings.center(title, title_width), title_style || :cell) paint("#{pipe} #{line} #{pipe}", Theme::BG) end |
#run(io) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/table_tennis/stage/render.rb', line 25 def run(io) # edge case - empty if rows.empty? || columns.empty? io.puts render_empty return end if config.title io.puts render_separator(NW, BAR, NE) io.puts render_title io.puts render_separator(W, N, E) if config.separators else io.puts render_separator(NW, N, NE) end io.puts render_row(:header) io.puts render_separator(W, C, E) if config.separators rows.each_index { io.puts render_row(_1) } io.puts render_separator(SW, S, SE) end |
#search ⇒ Object
151 152 153 154 155 156 |
# File 'lib/table_tennis/stage/render.rb', line 151 def search case config.search when String then /#{Regexp.escape(config.search)}/i when Regexp then config.search end end |
#search_cell(value) ⇒ Object
add ansi codes for search
160 161 162 163 164 165 |
# File 'lib/table_tennis/stage/render.rb', line 160 def search_cell(value) return value if !value.match?(search) # edge case - we can't gsub a painted cell, it can mess up the escaping value = Util::Strings.unpaint(value) value.gsub(search) { paint(_1, :search) } end |