Module: Rubino::Documents::Table
- Defined in:
- lib/rubino/documents/table.rb
Overview
The ONE Markdown table emitter shared by the csv and xlsx converters (the reuse seam the plan calls for). Takes an array of rows (each an array of cell values) and emits a GFM pipe table: the first row is the header, a ‘|—|` separator follows, then the body. Pipes and newlines inside cells are escaped so a cell value can’t break the table grid. Rows are capped so a runaway spreadsheet can’t emit a million-line table into context.
Constant Summary collapse
- MAX_ROWS =
Hard cap on emitted body rows; over the cap we truncate and note it.
1000
Class Method Summary collapse
-
.cell(value) ⇒ Object
Escapes a cell so pipes/newlines can’t break the table.
-
.emit(rows, max_rows: MAX_ROWS) ⇒ Object
rows: Array<Array> – first row is the header.
- .pad(row, width) ⇒ Object
- .row_line(cells) ⇒ Object
- .separator(width) ⇒ Object
Class Method Details
.cell(value) ⇒ Object
Escapes a cell so pipes/newlines can’t break the table. nil -> “”.
54 55 56 57 58 59 60 |
# File 'lib/rubino/documents/table.rb', line 54 def cell(value) value.to_s .gsub("\\", "\\\\\\\\") .gsub("|", "\\|") .gsub(/\r\n?|\n/, "<br>") .strip end |
.emit(rows, max_rows: MAX_ROWS) ⇒ Object
rows: Array<Array> – first row is the header. Returns a GFM table String, or “” when there are no rows.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/rubino/documents/table.rb', line 19 def emit(rows, max_rows: MAX_ROWS) rows = Array(rows).compact return "" if rows.empty? width = rows.map { |r| Array(r).length }.max return "" if width.nil? || width.zero? header = pad(rows.first, width) body = rows.drop(1) truncated = body.length > max_rows body = body.first(max_rows) if truncated lines = [] lines << row_line(header) lines << separator(width) body.each { |r| lines << row_line(pad(r, width)) } out = lines.join("\n") out += "\n\n_(#{rows.length - 1 - max_rows} more rows truncated)_" if truncated out end |
.pad(row, width) ⇒ Object
40 41 42 43 |
# File 'lib/rubino/documents/table.rb', line 40 def pad(row, width) cells = Array(row).map { |c| cell(c) } cells.fill("", cells.length...width) end |
.row_line(cells) ⇒ Object
45 46 47 |
# File 'lib/rubino/documents/table.rb', line 45 def row_line(cells) "| #{cells.join(" | ")} |" end |
.separator(width) ⇒ Object
49 50 51 |
# File 'lib/rubino/documents/table.rb', line 49 def separator(width) "|#{(["---"] * width).join("|")}|" end |