Skip to content

Commit

Permalink
feature(renderer): Support customizable table captions (#689)
Browse files Browse the repository at this point in the history
First baby step in table styling, this uses the same approach
used for image captions, only for tables.
  • Loading branch information
gdamore authored Jul 4, 2020
1 parent c51cc09 commit 4c8b1fd
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 5 deletions.
4 changes: 3 additions & 1 deletion pkg/renderer/sgml/html5/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package html5
const (
// TODO: These class settings need to be overridable via attributes
tableTmpl = "<table class=\"tableblock frame-all grid-all stretch{{ if .Roles }} {{ .Roles }}{{ end }}\">\n" +
"{{ if .Title }}<caption class=\"title\">Table {{ .TableNumber }}. {{ .Title }}</caption>\n{{ end }}" +
"{{ if .Title }}<caption class=\"title\">{{ .Caption }}{{ .Title }}</caption>\n{{ end }}" +
"{{ if .Body }}" +
"<colgroup>\n" +
"{{ range $i, $w := .CellWidths }}<col style=\"width: {{ $w }}%;\">\n{{ end}}" +
Expand All @@ -19,6 +19,8 @@ const (

tableRowTmpl = "<tr>\n{{ .Content }}</tr>\n"

tableCaptionTmpl = "Table {{ .TableNumber }}. "

// TODO: review these alignment choices ... should they be overrideable?

tableHeaderCellTmpl = "<th class=\"tableblock halign-left valign-top\">{{ .Content }}</th>\n"
Expand Down
38 changes: 38 additions & 0 deletions pkg/renderer/sgml/html5/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,44 @@ var _ = Describe("tables", func() {
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("table with title, custom caption", func() {
source := `.table title
[caption="Example I. "]
|===
|Column heading 1 |Column heading 2
|Column 1, row 1
|Column 2, row 1
|Column 1, row 2
|Column 2, row 2
|===`
expected := `<table class="tableblock frame-all grid-all stretch">
<caption class="title">Example I. table title</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Column heading 1</th>
<th class="tableblock halign-left valign-top">Column heading 2</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 1, row 1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 2, row 1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 1, row 2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 2, row 2</p></td>
</tr>
</tbody>
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("empty table ", func() {
source := `|===
|===`
Expand Down
1 change: 1 addition & 0 deletions pkg/renderer/sgml/html5/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ var templates = sgml.Templates{
SuperscriptText: superscriptTextTmpl,
Table: tableTmpl,
TableBody: tableBodyTmpl,
TableCaption: tableCaptionTmpl,
TableCell: tableCellTmpl,
TableHeader: tableHeaderTmpl,
TableHeaderCell: tableHeaderCellTmpl,
Expand Down
2 changes: 1 addition & 1 deletion pkg/renderer/sgml/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (r *sgmlRenderer) renderImageBlock(ctx *renderer.Context, img types.ImageBl
if _, found := img.Attributes.GetAsString(types.AttrTitle); found {
number = ctx.GetAndIncrementImageCounter()

if s, ok := img.Attributes.GetAsString(types.AttrImageCaption); ok {
if s, ok := img.Attributes.GetAsString(types.AttrCaption); ok {
caption.WriteString(s)
} else {
err := r.imageCaption.Execute(caption, struct {
Expand Down
2 changes: 2 additions & 0 deletions pkg/renderer/sgml/sgml_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type sgmlRenderer struct {
superscriptText *textTemplate
table *textTemplate
tableBody *textTemplate
tableCaption *textTemplate
tableCell *textTemplate
tableHeader *textTemplate
tableHeaderCell *textTemplate
Expand Down Expand Up @@ -148,6 +149,7 @@ func (r *sgmlRenderer) prepareTemplates() error {
r.superscriptText, err = r.newTemplate("superscript", tmpls.SuperscriptText, err)
r.table, err = r.newTemplate("table", tmpls.Table, err)
r.tableBody, err = r.newTemplate("table-body", tmpls.TableBody, err)
r.tableCaption, err = r.newTemplate("table-caption", tmpls.TableCaption, err)
r.tableCell, err = r.newTemplate("table-cell", tmpls.TableCell, err)
r.tableHeader, err = r.newTemplate("table-header", tmpls.TableHeader, err)
r.tableHeaderCell, err = r.newTemplate("table-header-cell", tmpls.TableHeaderCell, err)
Expand Down
20 changes: 20 additions & 0 deletions pkg/renderer/sgml/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (

func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string, error) {
result := &strings.Builder{}
caption := &strings.Builder{}

// inspect first line to obtain cell width ratio
widths := []string{}
if len(t.Lines) > 0 {
Expand All @@ -33,8 +35,24 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string
log.Debugf("current total width: %v -> %v", total, widths[n-1])
}
number := 0
title := r.renderElementTitle(t.Attributes)

if t.Attributes.Has(types.AttrTitle) {
number = ctx.GetAndIncrementTableCounter()
if s, ok := t.Attributes.GetAsString(types.AttrCaption); ok {
caption.WriteString(s)
} else {
err := r.tableCaption.Execute(caption, struct {
TableNumber int
Title sanitized
}{
TableNumber: number,
Title: title,
})
if err != nil {
return "", errors.Wrap(err, "unable to format table caption")
}
}
}

header, err := r.renderTableHeader(ctx, t.Header)
Expand All @@ -52,6 +70,7 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string
Title sanitized
CellWidths []string
TableNumber int
Caption string
Roles sanitized
Header string
Body string
Expand All @@ -60,6 +79,7 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string
Title: r.renderElementTitle(t.Attributes),
CellWidths: widths,
TableNumber: number,
Caption: caption.String(),
Roles: r.renderElementRoles(t.Attributes),
Header: header,
Body: body,
Expand Down
1 change: 1 addition & 0 deletions pkg/renderer/sgml/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Templates struct {
SuperscriptText string
Table string
TableBody string
TableCaption string
TableCell string
TableHeader string
TableHeaderCell string
Expand Down
2 changes: 1 addition & 1 deletion pkg/renderer/sgml/xhtml5/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package xhtml5

const (
tableTmpl = "<table class=\"tableblock frame-all grid-all stretch{{ if .Roles }} {{ .Roles }}{{ end }}\">\n" +
"{{ if .Title }}<caption class=\"title\">Table {{ .TableNumber }}. {{ .Title }}</caption>\n{{ end }}" +
"{{ if .Title }}<caption class=\"title\">{{ .Caption }}{{ .Title }}</caption>\n{{ end }}" +
"{{ if .Body }}" +
"<colgroup>\n" +
"{{ range $i, $w := .CellWidths }}<col style=\"width: {{ $w }}%;\"/>\n{{ end}}" +
Expand Down
38 changes: 38 additions & 0 deletions pkg/renderer/sgml/xhtml5/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,44 @@ var _ = Describe("tables", func() {
Expect(RenderXHTML(source)).To(MatchHTML(expected))
})

It("table with title, custom caption", func() {
source := `.table title
[caption="Example I. "]
|===
|Column heading 1 |Column heading 2
|Column 1, row 1
|Column 2, row 1
|Column 1, row 2
|Column 2, row 2
|===`
expected := `<table class="tableblock frame-all grid-all stretch">
<caption class="title">Example I. table title</caption>
<colgroup>
<col style="width: 50%;"/>
<col style="width: 50%;"/>
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Column heading 1</th>
<th class="tableblock halign-left valign-top">Column heading 2</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 1, row 1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 2, row 1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 1, row 2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Column 2, row 2</p></td>
</tr>
</tbody>
</table>`
Expect(RenderXHTML(source)).To(MatchHTML(expected))
})

It("empty table ", func() {
source := `|===
|===`
Expand Down
4 changes: 2 additions & 2 deletions pkg/types/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ const (
AttrImageTitle = "title"
// AttrImageWindow the `window` attribute, which becomes the target for the link
AttrImageWindow = "window"
// AttrImageCaption is the image caption for block images
AttrImageCaption = "caption"
// AttrImageFloat is for image float
AttrImageFloat = "float"
// AttrImageAlign is for image alignment
Expand All @@ -97,6 +95,8 @@ const (
AttrOptions = "options"
// AttrOpts alias for AttrOptions
AttrOpts = "opts"
// AttrCaption is the caption for block images, tables, and so forth
AttrCaption = "caption"
// AttrStyle block or list style
AttrStyle = "style"
// AttrPositional2 positional parameter 2
Expand Down

0 comments on commit 4c8b1fd

Please sign in to comment.