1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
import std/[strutils, enumerate, sequtils, terminal]
type Column* = object
text*: string
color*: ForegroundColor
type Line* = object
columns*: seq[Column]
attachments*: seq[string]
proc prefixSpaceCount(s: seq[Column]): int =
return foldl(s[0..s.len-2], a + b.text.len, 0) + (2 * s.len-2)
proc pad(table: seq[Line], max: seq[int]): seq[Line] =
for line in table:
var resLine = newSeq[Column]()
var resAttach = newSeq[string]()
for i, field in enumerate(line.columns):
resLine.add(Column(text:field.text & repeat(' ', max[i] - field.text.len), color: field.color))
if line.attachments.len > 0:
let spaces = prefixSpaceCount(resLine)
for attachment in line.attachments:
resAttach.add(repeat(" ", spaces) & attachment)
result.add(Line(columns: resLine, attachments: resAttach))
proc columnize(table: seq[Line]): seq[Line] =
if table.len == 0: return table
var max = newSeq[int](table[0].columns.len)
for line in table:
for i, field in enumerate(line.columns):
if field.text.len > max[i]:
max[i] = field.text.len
result = pad(table, max)
proc writeColumns(line: Line) =
for column in line.columns[0 .. ^2]:
stdout.styledWrite(column.color, column.text & " ")
stdout.styledWrite(line.columns[^1].color, line.columns[^1].text)
proc echo*(table: seq[Line]) =
let lines = columnize(table)
for line in lines:
writeColumns(line)
stdout.writeLine("")
for attachment in line.attachments:
stdout.styledWriteLine(fgMagenta, attachment)
|