Skip to content

Commit

Permalink
table: provide a way to control HTML rendering; fixes #119
Browse files Browse the repository at this point in the history
  • Loading branch information
jedib0t committed May 17, 2020
1 parent 3554271 commit a9fb51e
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 32 deletions.
8 changes: 7 additions & 1 deletion table/README.md
Expand Up @@ -362,11 +362,17 @@ to get:
### ... HTML Table

```golang
t.Style().HTML = table.HTMLOptions{
CSSClass: "game-of-thrones",
EmptyColumn: " ",
EscapeText: true,
Newline: "<br/>",
}
t.RenderHTML()
```
to get:
```html
<table class="go-pretty-table">
<table class="game-of-thrones">
<thead>
<tr>
<th align="right">#</th>
Expand Down
78 changes: 49 additions & 29 deletions table/render_html.go
Expand Up @@ -65,7 +65,7 @@ func (t *Table) RenderHTML() string {
if t.htmlCSSClass != "" {
out.WriteString(t.htmlCSSClass)
} else {
out.WriteString(DefaultHTMLCSSClass)
out.WriteString(t.style.HTML.CSSClass)
}
out.WriteString("\">\n")
t.htmlRenderTitle(&out)
Expand All @@ -86,18 +86,49 @@ func (t *Table) htmlRenderCaption(out *strings.Builder) {
}
}

func (t *Table) htmlRenderColumnAttributes(out *strings.Builder, row rowStr, colIdx int, hint renderHint) {
// determine the HTML "align"/"valign" property values
align := t.getAlign(colIdx, hint).HTMLProperty()
vAlign := t.getVAlign(colIdx, hint).HTMLProperty()
// determine the HTML "class" property values for the colors
class := t.getColumnColors(colIdx, hint).HTMLProperty()

if align != "" {
out.WriteRune(' ')
out.WriteString(align)
}
if class != "" {
out.WriteRune(' ')
out.WriteString(class)
}
if vAlign != "" {
out.WriteRune(' ')
out.WriteString(vAlign)
}
}

func (t *Table) htmlRenderColumnAutoIndex(out *strings.Builder, hint renderHint) {
if hint.isHeaderRow {
out.WriteString(" <th>")
out.WriteString(t.style.HTML.EmptyColumn)
out.WriteString("</th>\n")
} else if hint.isFooterRow {
out.WriteString(" <td>")
out.WriteString(t.style.HTML.EmptyColumn)
out.WriteString("</td>\n")
} else {
out.WriteString(" <td align=\"right\">")
out.WriteString(fmt.Sprint(hint.rowNumber))
out.WriteString("</td>\n")
}
}

func (t *Table) htmlRenderRow(out *strings.Builder, row rowStr, hint renderHint) {
out.WriteString(" <tr>\n")
for colIdx := 0; colIdx < t.numColumns; colIdx++ {
// auto-index column
if colIdx == 0 && t.autoIndex {
if hint.isHeaderRow {
out.WriteString(" <th>&nbsp;</th>\n")
} else if hint.isFooterRow {
out.WriteString(" <td>&nbsp;</td>\n")
} else {
out.WriteString(fmt.Sprintf(" <td align=\"right\">%d</td>\n", hint.rowNumber))
}
t.htmlRenderColumnAutoIndex(out, hint)
}

// get the column contents
Expand All @@ -112,32 +143,21 @@ func (t *Table) htmlRenderRow(out *strings.Builder, row rowStr, hint renderHint)
colTagName = "th"
}

// determine the HTML "align"/"valign" property values
align := t.getAlign(colIdx, hint).HTMLProperty()
vAlign := t.getVAlign(colIdx, hint).HTMLProperty()
// determine the HTML "class" property values for the colors
class := t.getColumnColors(colIdx, hint).HTMLProperty()

// write the row
out.WriteString(" <")
out.WriteString(colTagName)
if align != "" {
out.WriteRune(' ')
out.WriteString(align)
}
if class != "" {
out.WriteRune(' ')
out.WriteString(class)
}
if vAlign != "" {
out.WriteRune(' ')
out.WriteString(vAlign)
}
t.htmlRenderColumnAttributes(out, row, colIdx, hint)
out.WriteString(">")
if len(colStr) > 0 {
out.WriteString(strings.Replace(html.EscapeString(colStr), "\n", "<br/>", -1))
if len(colStr) == 0 {
out.WriteString(t.style.HTML.EmptyColumn)
} else {
out.WriteString("&nbsp;")
if t.style.HTML.EscapeText {
colStr = html.EscapeString(colStr)
}
if t.style.HTML.Newline != "\n" {
colStr = strings.Replace(colStr, "\n", t.style.HTML.Newline, -1)
}
out.WriteString(colStr)
}
out.WriteString("</")
out.WriteString(colTagName)
Expand Down
69 changes: 68 additions & 1 deletion table/render_html_test.go
Expand Up @@ -152,6 +152,7 @@ func TestTable_RenderHTML_Colored(t *testing.T) {
tw.AppendFooter(testFooter)
tw.SetCaption(testCaption)
tw.SetTitle(testTitle1)
tw.Style().HTML.CSSClass = "go-pretty-table-colored"
colorsBlackOnWhite := text.Colors{text.BgWhite, text.FgBlack}
tw.SetColumnConfigs([]ColumnConfig{
{
Expand Down Expand Up @@ -181,7 +182,7 @@ func TestTable_RenderHTML_Colored(t *testing.T) {
},
})

expectedOut := `<table class="go-pretty-table">
expectedOut := `<table class="go-pretty-table-colored">
<caption class="title">Game of Thrones</caption>
<thead>
<tr>
Expand Down Expand Up @@ -233,7 +234,73 @@ func TestTable_RenderHTML_Colored(t *testing.T) {
</tfoot>
<caption class="caption" style="caption-side: bottom;">A Song of Ice and Fire</caption>
</table>`
assert.Equal(t, expectedOut, tw.RenderHTML())
}

func TestTable_RenderHTML_CustomStyle(t *testing.T) {
tw := NewWriter()
tw.AppendHeader(testHeader)
tw.AppendRow(Row{1, "Arya", "Stark", 3000, "<a href=\"https://duckduckgo.com/?q=arya+stark+not+today\">Not today.</a>"})
tw.AppendRow(Row{1, "Jon", "Snow", 2000, "You know\nnothing,\nJon Snow!"})
tw.AppendRow(Row{300, "Tyrion", "Lannister", 5000})
tw.AppendFooter(testFooter)
tw.SetAutoIndex(true)
tw.Style().HTML = HTMLOptions{
CSSClass: "game-of-thrones",
EmptyColumn: "<!-- test -->&nbsp;",
EscapeText: false,
Newline: "<!-- newline -->",
}
tw.SetOutputMirror(os.Stdout)

expectedOut := `<table class="game-of-thrones">
<thead>
<tr>
<th><!-- test -->&nbsp;</th>
<th align="right">#</th>
<th>First Name</th>
<th>Last Name</th>
<th align="right">Salary</th>
<th><!-- test -->&nbsp;</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">1</td>
<td align="right">1</td>
<td>Arya</td>
<td>Stark</td>
<td align="right">3000</td>
<td><a href="https://duckduckgo.com/?q=arya+stark+not+today">Not today.</a></td>
</tr>
<tr>
<td align="right">2</td>
<td align="right">1</td>
<td>Jon</td>
<td>Snow</td>
<td align="right">2000</td>
<td>You know<!-- newline -->nothing,<!-- newline -->Jon Snow!</td>
</tr>
<tr>
<td align="right">3</td>
<td align="right">300</td>
<td>Tyrion</td>
<td>Lannister</td>
<td align="right">5000</td>
<td><!-- test -->&nbsp;</td>
</tr>
</tbody>
<tfoot>
<tr>
<td><!-- test -->&nbsp;</td>
<td align="right"><!-- test -->&nbsp;</td>
<td><!-- test -->&nbsp;</td>
<td>Total</td>
<td align="right">10000</td>
<td><!-- test -->&nbsp;</td>
</tr>
</tfoot>
</table>`
assert.Equal(t, expectedOut, tw.RenderHTML())
}

Expand Down

0 comments on commit a9fb51e

Please sign in to comment.