Created
June 5, 2024 04:54
-
-
Save matteopic/8948f3e87523baa46d1831f03a12a4b2 to your computer and use it in GitHub Desktop.
Provides a way to construct a markdown table by adding rows and then outputting the table in markdown format with properly aligned columns.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package export | |
import ( | |
"bytes" | |
"io" | |
"strings" | |
"unicode/utf8" | |
) | |
type MarkdownTable struct { | |
widths []int | |
rows [][]string | |
} | |
func (mkt *MarkdownTable) AddRow(data ...string) { | |
if len(data) > len(mkt.widths) { | |
newWidths := make([]int, len(data)) | |
copy(newWidths, mkt.widths) | |
mkt.widths = newWidths | |
} | |
for cell_index, cell := range data { | |
max_width := mkt.widths[cell_index] | |
width := utf8.RuneCountInString(cell) | |
if width > max_width { | |
mkt.widths[cell_index] = width | |
} | |
} | |
newRows := append(mkt.rows, data) | |
mkt.rows = newRows | |
} | |
func (mkt MarkdownTable) WriteTo(w io.Writer) (int64, error) { | |
sep := []byte("|") | |
padding := []byte(" ") | |
eol := []byte("\n") | |
buffer := new(bytes.Buffer) | |
var written int64 | |
for row_index, row := range mkt.rows { | |
buffer.Reset() | |
for cell_index, cell := range row { | |
if cell_index == 0 { | |
buffer.Write(sep) | |
buffer.Write(padding) | |
} else { | |
buffer.Write(padding) | |
buffer.Write(sep) | |
buffer.Write(padding) | |
} | |
txtLenght := utf8.RuneCountInString(cell) | |
cellLength := mkt.widths[cell_index] | |
buffer.WriteString(cell) | |
fillLength := cellLength - txtLenght | |
fill := strings.Repeat(" ", fillLength) | |
buffer.WriteString(fill) | |
} | |
buffer.Write(padding) | |
buffer.Write(sep) | |
buffer.Write(eol) | |
if row_index == 0 { | |
mkt.writeHeaderSeparator(buffer) | |
} | |
count, err := buffer.WriteTo(w) | |
written += count | |
if err != nil { | |
return written, err | |
} | |
} | |
return written, nil | |
} | |
func (mkt MarkdownTable) writeHeaderSeparator(w io.Writer) { | |
sep := []byte("|") | |
eol := []byte("\n") | |
for _, width := range mkt.widths { | |
w.Write(sep) | |
fill := strings.Repeat("-", width+2) | |
w.Write([]byte(fill)) | |
} | |
w.Write(sep) | |
w.Write(eol) | |
} | |
func NewMarkdownTable() *MarkdownTable { | |
widths := make([]int, 0) | |
rows := make([][]string, 0) | |
mkt := MarkdownTable{rows: rows, widths: widths} | |
return &mkt | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package export | |
import ( | |
"bytes" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
) | |
func TestBasic(t *testing.T) { | |
mkt := NewMarkdownTable() | |
mkt.AddRow("Lorem", "ipsum", "dolor", "sit", "amet") | |
mkt.AddRow("consectetur", "adipiscing", "elit", "", "") | |
bb := new(bytes.Buffer) | |
mkt.WriteTo(bb) | |
txt := bb.String() | |
expected := "" + | |
"| Lorem | ipsum | dolor | sit | amet |\n" + | |
"|-------------|------------|-------|-----|------|\n" + | |
"| consectetur | adipiscing | elit | | |\n" | |
assert.Equal(t, expected, txt) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment