table header

This commit is contained in:
Timon Ringwald 2022-08-25 16:55:19 +02:00
parent a5076cac48
commit 708c1e5d7a
3 changed files with 79 additions and 31 deletions

View File

@ -6,7 +6,6 @@ import (
"git.milar.in/milarin/gmath"
"git.milar.in/milarin/slices"
"github.com/fatih/color"
)
type Table struct {
@ -64,28 +63,30 @@ func (t *Table) AddRow(row ...interface{}) {
func (t *Table) String() string {
b := new(strings.Builder)
b.WriteRune('')
b.WriteRune('')
for i, colwidth := range t.colwidth {
b.WriteString(strings.Repeat("", colwidth))
b.WriteString(strings.Repeat("", colwidth))
if i < len(t.colwidth)-1 {
b.WriteRune('')
b.WriteRune('')
}
}
b.WriteRune('')
b.WriteRune('')
b.WriteRune('\n')
bold := color.New(color.Bold)
t.printRow(b, bold.Sprint, t.head, t.headheight)
t.printRow(b, t.head, t.headheight)
if len(t.data) > 0 {
t.addNextCellLine(b)
} else {
t.addLastCellLine(b)
return b.String()
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, fmt.Sprint, row, t.rowheight[i])
t.printRow(b, row, t.rowheight[i])
if t.rowSep && i < len(t.data)-1 {
t.addNextCellLine(b)
}
@ -96,9 +97,9 @@ func (t *Table) String() string {
return b.String()
}
func (t *Table) printRow(b *strings.Builder, printFunc func(...interface{}) string, rowData [][]string, rowHeight int) {
func (t *Table) printRow(b *strings.Builder, rowData [][]string, rowHeight int) {
for lineIndex := 0; lineIndex < rowHeight; lineIndex++ {
b.WriteRune('')
b.WriteRune('')
for colIndex := 0; colIndex < t.maxcols; colIndex++ {
line := ""
@ -109,33 +110,34 @@ func (t *Table) printRow(b *strings.Builder, printFunc func(...interface{}) stri
}
}
b.WriteString(printFunc(padStringRight(line, ' ', t.colwidth[colIndex])))
b.WriteRune('│')
b.WriteString(fmt.Sprint(padStringRight(line, ' ', t.colwidth[colIndex])))
if colIndex < t.maxcols-1 {
b.WriteRune('│')
}
}
b.WriteRune('\n')
b.WriteString("┃\n")
}
}
func (t *Table) addNextCellLine(b *strings.Builder) {
b.WriteRune('')
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('')
b.WriteRune('\n')
}
func (t *Table) addLastCellLine(b *strings.Builder) {
b.WriteRune('')
b.WriteRune('')
for i, colwidth := range t.colwidth {
b.WriteString(strings.Repeat("", colwidth))
b.WriteString(strings.Repeat("", colwidth))
if i < len(t.colwidth)-1 {
b.WriteRune('')
b.WriteRune('')
}
}
b.WriteRune('┘')
b.WriteRune('\n')
b.WriteString("┛\n")
}

35
table_header.go Normal file
View File

@ -0,0 +1,35 @@
package tprint
import (
"strings"
"git.milar.in/milarin/slices"
)
// TODO FormatHeaderTable is a quick hack
// a better solution would be to support nested tables.
// in that case, a header table is just a table with a singe col, single header row and single data row
func FormatHeaderTable(header string, table *Table) string {
b := new(strings.Builder)
tab := table.String()
splits := strings.Split(tab, "\n")
tabwidth := strLen(splits[0])
b.WriteRune('┏')
b.WriteString(strings.Repeat("━", tabwidth-2))
b.WriteString("┓\n┃")
b.WriteString(padStringCenter(header, ' ', tabwidth-2))
b.WriteString("┃\n")
b.WriteRune('┣')
b.WriteString(splits[0][3 : len(splits[0])-3])
b.WriteString("┫\n")
slices.Each(splits[1:], func(s string) {
b.WriteString(s)
b.WriteRune('\n')
})
return b.String()
}

View File

@ -1,6 +1,7 @@
package tprint
import (
"fmt"
"strings"
"unicode"
)
@ -23,16 +24,15 @@ func strLen(str string) int {
l := 0
runes := []rune(str)
colored := false
for i := 0; i < len(runes); i++ {
// skip control sequences
if unicode.IsControl(runes[i]) {
if colored {
i += 3
} else {
i += 4
for j := i; j < len(runes)-1 && runes[j] != 'm'; j++ {
i = j
}
colored = !colored
i++
continue
}
@ -46,3 +46,14 @@ func padStringRight(str string, pad rune, length int) string {
padding := length - strLen(str)
return str + strings.Repeat(string(pad), padding)
}
func padStringLeft(str string, pad rune, length int) string {
padding := length - strLen(str)
return strings.Repeat(string(pad), padding) + str
}
func padStringCenter(str string, pad rune, length int) string {
l := strLen(str)
fmt.Println(l, length)
return padStringLeft(padStringRight(str, pad, (length-l)/2+l), pad, length)
}