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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
package table
import (
"strings"
"unicode/utf8"
"github.com/JohannesKaufmann/html-to-markdown/v2/converter"
"golang.org/x/net/html"
)
func (p *tablePlugin) renderTable(ctx converter.Context, w converter.Writer, n *html.Node) converter.RenderStatus {
table := p.collectTableContent(ctx, n)
if table == nil {
// Sometime we just cannot render the table.
// Either because it is an empty table OR
// because there are newlines inside the content (which would break the table).
return converter.RenderTryNext
}
// Sometimes we pad the cells with extra spaces (e.g. "| text |").
// For that we first need to know the maximum width of every column.
counts := calculateMaxCounts(table.Rows)
// Sometimes a row contains less cells that another row.
// We then fill it up with empty cells (e.g. "| text | |").
table.Rows = fillUpRows(table.Rows, len(counts))
// - - - - - - - - - - - - - - - - - - - - - - - - - - //
w.WriteString("\n\n")
// - - - Header - - - //
p.writeRow(w, counts, table.Rows[0])
w.WriteString("\n")
p.writeHeaderUnderline(w, table.Alignments, counts)
w.WriteString("\n")
// - - - Body - - - //
for _, cells := range table.Rows[1:] {
p.writeRow(w, counts, cells)
w.WriteString("\n")
}
// - - - Caption - - - //
if table.Caption != nil {
w.WriteString("\n\n")
w.Write(table.Caption)
}
// - - - - - - //
w.WriteString("\n\n")
return converter.RenderSuccess
}
func getAlignmentFor(alignments []string, index int) string {
if index > len(alignments)-1 {
return ""
}
return alignments[index]
}
func (s *tablePlugin) writeHeaderUnderline(w converter.Writer, alignments []string, counts []int) {
for i, maxLength := range counts {
align := getAlignmentFor(alignments, i)
isFirstCell := i == 0
if isFirstCell {
w.WriteString("|")
}
if align == "left" || align == "center" {
w.WriteString(":")
} else {
w.WriteString("-")
}
w.WriteString(strings.Repeat("-", maxLength))
if align == "right" || align == "center" {
w.WriteString(":")
} else {
w.WriteString("-")
}
w.WriteString("|")
}
}
func (s *tablePlugin) writeRow(w converter.Writer, counts []int, cells [][]byte) {
for i, cell := range cells {
isFirstCell := i == 0
if isFirstCell {
w.WriteString("|")
}
w.WriteString(" ")
w.Write(cell)
currentCount := utf8.RuneCount(cell)
filler := counts[i] - currentCount
if filler > 0 {
w.WriteString(strings.Repeat(" ", filler))
}
w.WriteString(" |")
}
}
|