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
| package util
import ( "github.com/pkg/errors" "github.com/samber/lo" )
func MarkdownTable(header []string, rows [][]string, linebreak string) (string, error) { maxes := lo.Map(header, func(h string, _ int) int { return len(h) }) for vi, v := range rows { if len(v) != len(header) { return "", errors.Errorf("row [%d] contains [%d] fields, but [%d] header fields were provided", vi, len(v), len(header)) } lo.ForEach(v, func(cellVal string, cellIdx int) { if cellIdx <= len(maxes)-1 && len(cellVal) > maxes[cellIdx] { maxes[cellIdx] = len(cellVal) } }) }
ret := NewStringSlice(make([]string, 0, len(rows))) add := func(x []string) { line := "| " lo.ForEach(x, func(v string, vi int) { var mx int if vi < len(maxes) { mx = maxes[vi] } line += StringPad(v, mx) if vi < len(x)-1 { line += " | " } }) line += " |" ret.Push(line) }
add(header)
divider := "|-" lo.ForEach(maxes, func(m int, mi int) { lo.Times(m, func(_ int) struct{} { divider += "-" return EmptyStruct }) if mi < len(maxes)-1 { divider += "-|-" } }) divider += "-|" ret.Push(divider)
lo.ForEach(rows, func(row []string, _ int) { add(row) }) return ret.Join(linebreak), nil }
func MarkdownTableParse(md string) ([]string, [][]string) { var header []string var rows [][]string for idx, line := range StringSplitLines(md) { split := StringSplitAndTrim(line, "|") if idx == 0 { header = split } else if idx != 1 { rows = append(rows, split) } } return header, rows }
|