initial commit
This commit is contained in:
168
table.go
Normal file
168
table.go
Normal file
@ -0,0 +1,168 @@
|
||||
package tprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.tordarus.net/tordarus/gmath"
|
||||
"git.tordarus.net/tordarus/slices"
|
||||
)
|
||||
|
||||
type Table struct {
|
||||
head [][]string
|
||||
|
||||
rowSep bool
|
||||
headheight int
|
||||
maxcols int
|
||||
|
||||
colwidth []int
|
||||
rowheight []int
|
||||
|
||||
data [][][]string
|
||||
}
|
||||
|
||||
func NewTable(head ...string) *Table {
|
||||
thead := slices.Map(head, func(s string) []string { return strings.Split(s, "\n") })
|
||||
return &Table{
|
||||
head: thead,
|
||||
colwidth: slices.Map(head, func(s string) int { return strLen(s) }),
|
||||
headheight: len(Search(thead, maxLengthSlice[string])),
|
||||
rowheight: []int{},
|
||||
maxcols: len(thead),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) AddRow(row ...interface{}) {
|
||||
irow := slices.Map(row, func(v interface{}) []string { return strings.Split(fmt.Sprint(v), "\n") })
|
||||
t.data = append(t.data, irow)
|
||||
|
||||
rowheight := len(Search(irow, maxLengthSlice[string]))
|
||||
t.rowheight = append(t.rowheight, rowheight)
|
||||
if rowheight > 1 {
|
||||
t.rowSep = true
|
||||
}
|
||||
|
||||
t.maxcols = gmath.Max(t.maxcols, len(irow))
|
||||
|
||||
for i, cell := range irow {
|
||||
maxLineLength := strLen(Search(cell, maxLengthStr))
|
||||
if i < len(t.colwidth) {
|
||||
t.colwidth[i] = gmath.Max(t.colwidth[i], maxLineLength)
|
||||
} else {
|
||||
t.colwidth = append(t.colwidth, maxLineLength)
|
||||
}
|
||||
|
||||
if i >= len(t.head) {
|
||||
headname := "unknown column"
|
||||
t.head = append(t.head, []string{headname})
|
||||
t.colwidth[i] = gmath.Max(t.colwidth[i], strLen(headname))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) StringNoHead() string {
|
||||
b := new(strings.Builder)
|
||||
|
||||
b.WriteRune('┏')
|
||||
for i, colwidth := range t.colwidth {
|
||||
b.WriteString(strings.Repeat("━", colwidth))
|
||||
if i < len(t.colwidth)-1 {
|
||||
b.WriteRune('┯')
|
||||
}
|
||||
}
|
||||
b.WriteRune('┓')
|
||||
b.WriteRune('\n')
|
||||
|
||||
for i, row := range t.data {
|
||||
t.printRow(b, row, t.rowheight[i])
|
||||
if t.rowSep && i < len(t.data)-1 {
|
||||
t.addNextCellLine(b)
|
||||
}
|
||||
}
|
||||
|
||||
t.addLastCellLine(b)
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (t *Table) String() string {
|
||||
b := new(strings.Builder)
|
||||
|
||||
b.WriteRune('┏')
|
||||
for i, colwidth := range t.colwidth {
|
||||
b.WriteString(strings.Repeat("━", colwidth))
|
||||
if i < len(t.colwidth)-1 {
|
||||
b.WriteRune('┯')
|
||||
}
|
||||
}
|
||||
b.WriteRune('┓')
|
||||
b.WriteRune('\n')
|
||||
|
||||
t.printRow(b, t.head, t.headheight)
|
||||
|
||||
b.WriteRune('┣')
|
||||
for i, colwidth := range t.colwidth {
|
||||
b.WriteString(strings.Repeat("━", colwidth))
|
||||
if i < len(t.colwidth)-1 {
|
||||
b.WriteRune('┿')
|
||||
}
|
||||
}
|
||||
b.WriteRune('┫')
|
||||
b.WriteRune('\n')
|
||||
|
||||
for i, row := range t.data {
|
||||
t.printRow(b, row, t.rowheight[i])
|
||||
if t.rowSep && i < len(t.data)-1 {
|
||||
t.addNextCellLine(b)
|
||||
}
|
||||
}
|
||||
|
||||
t.addLastCellLine(b)
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (t *Table) printRow(b *strings.Builder, rowData [][]string, rowHeight int) {
|
||||
for lineIndex := 0; lineIndex < rowHeight; lineIndex++ {
|
||||
b.WriteRune('┃')
|
||||
for colIndex := 0; colIndex < t.maxcols; colIndex++ {
|
||||
line := ""
|
||||
|
||||
if colIndex < len(rowData) {
|
||||
cell := rowData[colIndex]
|
||||
if lineIndex < len(cell) {
|
||||
line = cell[lineIndex]
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteString(fmt.Sprint(padStringRight(line, ' ', t.colwidth[colIndex])))
|
||||
if colIndex < t.maxcols-1 {
|
||||
b.WriteRune('│')
|
||||
}
|
||||
}
|
||||
b.WriteString("┃\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) addNextCellLine(b *strings.Builder) {
|
||||
b.WriteRune('┠')
|
||||
for i, colwidth := range t.colwidth {
|
||||
b.WriteString(strings.Repeat("─", colwidth))
|
||||
if i < len(t.colwidth)-1 {
|
||||
b.WriteRune('┼')
|
||||
}
|
||||
}
|
||||
b.WriteRune('┨')
|
||||
b.WriteRune('\n')
|
||||
}
|
||||
|
||||
func (t *Table) addLastCellLine(b *strings.Builder) {
|
||||
b.WriteRune('┗')
|
||||
for i, colwidth := range t.colwidth {
|
||||
b.WriteString(strings.Repeat("━", colwidth))
|
||||
if i < len(t.colwidth)-1 {
|
||||
b.WriteRune('┷')
|
||||
}
|
||||
}
|
||||
b.WriteString("┛\n")
|
||||
}
|
Reference in New Issue
Block a user