github.com/kyleu/dbaudit@v0.0.2-0.20240321155047-ff2f2c940496/app/util/markdown.go (about) 1 // Package util - Content managed by Project Forge, see [projectforge.md] for details. 2 package util 3 4 import ( 5 "github.com/pkg/errors" 6 "github.com/samber/lo" 7 ) 8 9 func MarkdownTable(header []string, rows [][]string, linebreak string) (string, error) { 10 maxes := lo.Map(header, func(h string, _ int) int { 11 return len(h) 12 }) 13 for vi, v := range rows { 14 if len(v) != len(header) { 15 return "", errors.Errorf("row [%d] contains [%d] fields, but [%d] header fields were provided", vi, len(v), len(header)) 16 } 17 lo.ForEach(v, func(cellVal string, cellIdx int) { 18 if cellIdx <= len(maxes)-1 && len(cellVal) > maxes[cellIdx] { 19 maxes[cellIdx] = len(cellVal) 20 } 21 }) 22 } 23 24 ret := NewStringSlice(make([]string, 0, len(rows))) 25 add := func(x []string) { 26 line := "| " 27 lo.ForEach(x, func(v string, vi int) { 28 mx := 0 29 if vi < len(maxes) { 30 mx = maxes[vi] 31 } 32 line += StringPad(v, mx) 33 if vi < len(x)-1 { 34 line += " | " 35 } 36 }) 37 line += " |" 38 ret.Push(line) 39 } 40 41 add(header) 42 43 divider := "|-" 44 lo.ForEach(maxes, func(m int, mi int) { 45 lo.Times(m, func(_ int) struct{} { 46 divider += "-" 47 return struct{}{} 48 }) 49 if mi < len(maxes)-1 { 50 divider += "-|-" 51 } 52 }) 53 divider += "-|" 54 ret.Push(divider) 55 56 lo.ForEach(rows, func(row []string, _ int) { 57 add(row) 58 }) 59 return ret.Join(linebreak), nil 60 } 61 62 func MarkdownTableParse(md string) ([]string, [][]string) { 63 var header []string 64 var rows [][]string 65 for idx, line := range StringSplitLines(md) { 66 split := StringSplitAndTrim(line, "|") 67 if idx == 0 { 68 header = split 69 } else if idx == 1 { 70 // spacer, noop 71 } else { 72 rows = append(rows, split) 73 } 74 } 75 return header, rows 76 }