Class: Railbow::Table::Renderer

Inherits:
Object
  • Object
show all
Includes:
Railbow::TextUtils
Defined in:
lib/railbow/table/renderer.rb

Constant Summary collapse

RESET =
"\e[0m"
WHITE =
"\e[97m"
GHOST_BG =

deep red/maroon background - stands out as abnormal

"\e[48;5;52m"
GHOST_FG =

warm pink foreground for contrast

"\e[38;5;217m"
DIMMED_FG =

muted grey - a row that is not currently in effect

"\e[38;5;242m"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Railbow::TextUtils

#display_width, #strip_ansi, #truncate_str

Constructor Details

#initialize(columns:, theme:, compact: {}, aliases: {}, min_widths: nil) ⇒ Renderer

min_widths raises the resolved width of each column to at least the given value, which is how several tables rendered in one run line their columns up with each other. An explicit compact maxw still wins.



22
23
24
25
26
27
28
29
# File 'lib/railbow/table/renderer.rb', line 22

def initialize(columns:, theme:, compact: {}, aliases: {}, min_widths: nil)
  @compact = compact
  @aliases = aliases
  @min_widths = min_widths
  @reverse_col_aliases = aliases[:columns]&.invert || {}
  @columns = apply_hidden_columns(columns)
  @theme = theme
end

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



17
18
19
# File 'lib/railbow/table/renderer.rb', line 17

def columns
  @columns
end

#themeObject (readonly)

Returns the value of attribute theme.



17
18
19
# File 'lib/railbow/table/renderer.rb', line 17

def theme
  @theme
end

Instance Method Details

#column_widths(rows) ⇒ Object

The widths this table would resolve to on its own. Callers rendering several tables together take the per-column maximum and feed it back as min_widths.



34
35
36
37
38
# File 'lib/railbow/table/renderer.rb', line 34

def column_widths(rows)
  return [] if columns.empty?

  resolve_widths(prepare_rows(rows))
end

#fixed_width(widths) ⇒ Object

Width of everything left of the last column. The last column flexes to the terminal, so this is where furniture drawn around the table (a section rule, say) can stop without running past it.



43
44
45
46
47
# File 'lib/railbow/table/renderer.rb', line 43

def fixed_width(widths)
  return 0 if columns.empty? || widths.nil? || widths.empty?

  compute_prefix_width(widths, columns.size - 1)
end

#render(rows, separators: {}, highlight_rows: Set.new, ghost_rows: Set.new, dim_rows: Set.new, tick_rows: Set.new, tick_col: nil) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/railbow/table/renderer.rb', line 49

def render(rows, separators: {}, highlight_rows: Set.new, ghost_rows: Set.new, dim_rows: Set.new, tick_rows: Set.new, tick_col: nil)
  return "" if columns.empty?

  rows = prepare_rows(rows)
  resolved = resolve_widths(rows)

  # In oneline mode, truncate non-sticky non-last columns at resolved width
  if @compact[:oneline]
    rows = rows.map { |row|
      row.each_with_index.map { |cell, i|
        col = columns[i]
        if col && i < columns.size - 1 && !col.sticky && !col.truncate
          truncate_str(cell.to_s, resolved[i])
        else
          cell
        end
      }
    }
  end
  lines = []
  lines << render_header(resolved) unless @compact[:noheader]
  rows.each_with_index do |row, i|
    tc = (tick_rows.include?(i) && tick_col) ? tick_col : nil
    if separators.key?(i) && theme.format_separator
      lines << render_separator_row(separators[i], resolved, tick_col: tc)
      tc = nil # tick already shown on separator row
    end
    formatted = render_row(row, resolved, tick_col: tc, highlight: highlight_rows.include?(i),
      ghost: ghost_rows.include?(i), dim: dim_rows.include?(i))
    lines << formatted
  end
  lines.join("\n")
end