-
Notifications
You must be signed in to change notification settings - Fork 1
/
print.go
94 lines (80 loc) · 2.05 KB
/
print.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package table
import (
"io"
"os"
"strings"
)
// PrintOptions contains options, used when table is printed
type PrintOptions struct {
Writer io.Writer
ColumnSeparator string
NoDecoration bool
NoHeader bool
HeaderBorder string
}
// PrintStandard outputs table into standard output using standard options
func PrintStandard(t Interface) error {
return Print(t, PrintOptions{ColumnSeparator: " | ", HeaderBorder: "-", Writer: os.Stdout})
}
// Print function outputs table using provided printing options
func Print(t Interface, opt PrintOptions) error {
// Checking defaults
if opt.Writer == nil {
opt.Writer = os.Stdout
}
if len(opt.ColumnSeparator) == 0 {
opt.ColumnSeparator = " | "
}
// Compiling table
compiled, err := Compile(t)
if err != nil {
return err
}
// Calculating total width
totalWidth := (len(compiled.Headers) - 1) * len(opt.ColumnSeparator)
for _, w := range compiled.Widths {
totalWidth += w
}
// Printing headers
if !opt.NoHeader {
for i, h := range compiled.Headers {
if i > 0 {
opt.Writer.Write([]byte(opt.ColumnSeparator))
}
opt.Writer.Write([]byte(TextAlignCenter(h, compiled.Widths[i], len(h))))
}
opt.Writer.Write([]byte("\n"))
if len(opt.HeaderBorder) > 0 {
opt.Writer.Write([]byte(strings.Repeat(opt.HeaderBorder, totalWidth)))
opt.Writer.Write([]byte("\n"))
}
}
// Printing
for _, row := range compiled.Data {
for i, col := range row {
if i > 0 {
opt.Writer.Write([]byte(opt.ColumnSeparator))
}
opt.Writer.Write([]byte(actual(!opt.NoDecoration, col).PrintFormat(compiled.Widths[i])))
}
opt.Writer.Write([]byte("\n"))
}
return nil
}
type decorated interface {
Cell
Decorated() Cell
}
// actual recursively inspects cell and decoration mode and returns most suitable cell to display
func actual(decorationEnabled bool, c Cell) Cell {
if decorationEnabled {
// Decoration is enabled - using cell as-is
return c
}
cc, ok := c.(decorated)
if !ok {
// Provided cell is not decorated - using as-is
return c
}
return actual(false, cc.Decorated())
}