Badges / coveralls (push) Successful in 1m1s
Reviewed-on: #33 Co-authored-by: Natercio Moniz <[email protected]>
70 lines
2.7 KiB
Go
70 lines
2.7 KiB
Go
package html
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/jedib0t/go-pretty/v6/table"
|
|
"github.com/nmoniz/any2anexoj/internal"
|
|
"github.com/nmoniz/any2anexoj/internal/writing/internal/tabledef"
|
|
)
|
|
|
|
// htmlCSSClass is the CSS class list put on the rendered report table.
|
|
const htmlCSSClass = "table table-striped table-hover table-bordered"
|
|
|
|
// widthIndex is the weight of the auto-index (row number) column; the other
|
|
// column weights come from tabledef's width budgets.
|
|
const widthIndex = 6
|
|
|
|
// htmlColumnWeights lists one weight per rendered column, starting with the
|
|
// auto-index column, mirroring the column order of tabledef.Build so the
|
|
// HTML table keeps columns in the same strict proportion to each other as
|
|
// the terminal layout.
|
|
var htmlColumnWeights = []int{
|
|
widthIndex,
|
|
tabledef.WidthCountry, tabledef.WidthOther, tabledef.WidthOther, tabledef.WidthOther, tabledef.WidthOther, tabledef.WidthEuros,
|
|
tabledef.WidthOther, tabledef.WidthOther, tabledef.WidthOther, tabledef.WidthEuros,
|
|
tabledef.WidthEuros, tabledef.WidthEuros, tabledef.WidthCountry,
|
|
}
|
|
|
|
// renderTableFragment renders aw as the Bootstrap-styled HTML <table>
|
|
// fragment embedded in the document. The table gets a fixed layout with
|
|
// strictly proportional column widths, so the browser — not this package —
|
|
// decides when a header or cell wraps: on wide screens everything fits on
|
|
// one line, on narrow ones it wraps automatically.
|
|
func (hw *Writer) renderTableFragment(aw *internal.AggregatorWriter) string {
|
|
t := tabledef.Build(hw.translator, aw)
|
|
t.Style().HTML = table.HTMLOptions{
|
|
CSSClass: htmlCSSClass,
|
|
EscapeText: true,
|
|
Newline: "<br/>",
|
|
EmptyColumn: " ",
|
|
}
|
|
html := t.RenderHTML()
|
|
|
|
// go-pretty cannot emit table-level attributes or a <colgroup>, so splice
|
|
// them into its output: the fixed layout makes the colgroup's relative
|
|
// widths authoritative instead of content-driven column sizing.
|
|
openTag := `<table class="` + htmlCSSClass + `">`
|
|
fixedTag := `<table class="` + htmlCSSClass + `" style="table-layout: fixed">` + "\n" + colgroupHTML()
|
|
return strings.Replace(html, openTag, fixedTag, 1)
|
|
}
|
|
|
|
// colgroupHTML returns a <colgroup> with one <col> per rendered column, each
|
|
// sized strictly in proportion to its weight. With the fixed table layout
|
|
// applied in renderTableFragment these widths are authoritative: wide
|
|
// viewports fit headers on a single line, narrow ones wrap automatically.
|
|
func colgroupHTML() string {
|
|
var total int
|
|
for _, w := range htmlColumnWeights {
|
|
total += w
|
|
}
|
|
var sb strings.Builder
|
|
sb.WriteString("<colgroup>")
|
|
for _, w := range htmlColumnWeights {
|
|
fmt.Fprintf(&sb, `<col style="width: %.2f%%">`, float64(w)/float64(total)*100)
|
|
}
|
|
sb.WriteString("</colgroup>")
|
|
return sb.String()
|
|
}
|