/
terminaltable.go
74 lines (66 loc) · 1.61 KB
/
terminaltable.go
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
47
48
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
package formatdata
import (
"io"
"github.com/shibukawa/stringwidth"
)
var tableVLine = []rune("│")[0]
const (
tableTop = 0
tableHeader = 1
tableMiddle = 2
tableBottom = 3
)
var tableHorizonChars = [][]rune{
[]rune("┌┬┐─"),
[]rune("╞╪╡═"),
[]rune("├┼┤─"),
[]rune("└┴┘─"),
}
func renderSliceAsTerminalTable(table [][]any, tr *tableRenderer, eastAsianAmbiguousAsWide bool, out io.Writer) {
// todo: EastAsianAmbiguous: true
maxWidths, renderCells := calcTableSize(table, tr, eastAsianAmbiguousAsWide)
repeat := func(r rune, length int) {
for i := 0; i < length; i++ {
io.WriteString(out, string(r))
}
}
drawHorizontal := func(t int) {
chars := tableHorizonChars[t]
io.WriteString(out, tr.borderStart)
io.WriteString(out, string(chars[0]))
for i, m := range maxWidths {
if i != 0 {
io.WriteString(out, string(chars[1]))
}
repeat(chars[3], m+2)
}
io.WriteString(out, string(chars[2]))
io.WriteString(out, tr.borderEnd)
out.Write([]byte{'\n'})
}
drawHorizontal(tableTop)
for r, row := range renderCells {
io.WriteString(out, tr.border(string(tableVLine)))
for i, w := range maxWidths {
var c string
if i < len(row) {
c = row[i]
}
out.Write([]byte{' '})
io.WriteString(out, c)
repeat(' ', 1+w-stringwidth.Calc(c, stringwidth.Opt{
IsAmbiguousWide: eastAsianAmbiguousAsWide,
}))
io.WriteString(out, tr.border(string(tableVLine)))
}
out.Write([]byte{'\n'})
switch r {
case len(renderCells) - 1:
drawHorizontal(tableBottom)
case 0:
drawHorizontal(tableHeader)
default:
drawHorizontal(tableMiddle)
}
}
}