From 23c1ee982e2d3795001879a4527581f33875cd33 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 9 Jan 2019 00:46:44 -0800 Subject: [PATCH] add `alignTable`, `parseTableCells` to align/format a tab(etc) delimited table (#10182) * add compiler/unittest_light.nim for easy diffing: assertEquals and mismatch * fixup * add alignTable, parseTableCells --- compiler/asciitables.nim | 83 ++++++++++++++++++++++ compiler/unittest_light.nim | 37 ++++++++++ tests/compiler/nim.cfg | 7 ++ tests/compiler/tasciitables.nim | 109 +++++++++++++++++++++++++++++ tests/compiler/tunittest_light.nim | 55 +++++++++++++++ 5 files changed, 291 insertions(+) create mode 100644 compiler/asciitables.nim create mode 100644 compiler/unittest_light.nim create mode 100644 tests/compiler/nim.cfg create mode 100644 tests/compiler/tasciitables.nim create mode 100644 tests/compiler/tunittest_light.nim diff --git a/compiler/asciitables.nim b/compiler/asciitables.nim new file mode 100644 index 000000000..c25d54bde --- /dev/null +++ b/compiler/asciitables.nim @@ -0,0 +1,83 @@ +#[ +move to std/asciitables.nim once stable, or to a nimble paackage +once compiler can depend on nimble +]# + +type Cell* = object + text*: string + width*, row*, col*, ncols*, nrows*: int + +iterator parseTableCells*(s: string, delim = '\t'): Cell = + ## iterates over all cells in a `delim`-delimited `s`, after a 1st + ## pass that computes number of rows, columns, and width of each column. + var widths: seq[int] + var cell: Cell + template update() = + if widths.len<=cell.col: + widths.setLen cell.col+1 + widths[cell.col] = cell.width + else: + widths[cell.col] = max(widths[cell.col], cell.width) + cell.width = 0 + + for a in s: + case a + of '\n': + update() + cell.col = 0 + cell.row.inc + elif a == delim: + update() + cell.col.inc + else: + # todo: consider multi-width chars when porting to non-ascii implementation + cell.width.inc + if s.len > 0 and s[^1] != '\n': + update() + + cell.ncols = widths.len + cell.nrows = cell.row + 1 + cell.row = 0 + cell.col = 0 + cell.width = 0 + + template update2() = + cell.width = widths[cell.col] + yield cell + cell.text = "" + cell.width = 0 + cell.col.inc + + template finishRow() = + for col in cell.col.. 0 and s[^1] != '\n': + finishRow() + +proc alignTable*(s: string, delim = '\t', fill = ' ', sep = " "): string = + ## formats a `delim`-delimited `s` representing a table; each cell is aligned + ## to a width that's computed for each column; consecutive columns are + ## delimted by `sep`, and alignment space is filled using `fill`. + ## More customized formatting can be done by calling `parseTableCells` directly. + for cell in parseTableCells(s, delim): + result.add cell.text + for i in cell.text.len..