diff --git a/pkg/renderer/sgml/html5/table.go b/pkg/renderer/sgml/html5/table.go index ec346a86..44bfb1b0 100644 --- a/pkg/renderer/sgml/html5/table.go +++ b/pkg/renderer/sgml/html5/table.go @@ -3,7 +3,7 @@ package html5 const ( // TODO: These class settings need to be overridable via attributes tableTmpl = "\n" + - "{{ if .Title }}\n{{ end }}" + + "{{ if .Title }}\n{{ end }}" + "{{ if .Body }}" + "\n" + "{{ range $i, $w := .CellWidths }}\n{{ end}}" + @@ -19,6 +19,8 @@ const ( tableRowTmpl = "\n{{ .Content }}\n" + tableCaptionTmpl = "Table {{ .TableNumber }}. " + // TODO: review these alignment choices ... should they be overrideable? tableHeaderCellTmpl = "\n" diff --git a/pkg/renderer/sgml/html5/table_test.go b/pkg/renderer/sgml/html5/table_test.go index a0095e04..8a09e666 100644 --- a/pkg/renderer/sgml/html5/table_test.go +++ b/pkg/renderer/sgml/html5/table_test.go @@ -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 {{ .TableNumber }}. {{ .Title }}{{ .Caption }}{{ .Title }}
{{ .Content }}
+ ++++ + + + + + + + + + + + + + + + + +
Example I. table title
Column heading 1Column heading 2

Column 1, row 1

Column 2, row 1

Column 1, row 2

Column 2, row 2

` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + It("empty table ", func() { source := `|=== |===` diff --git a/pkg/renderer/sgml/html5/templates.go b/pkg/renderer/sgml/html5/templates.go index 1c6561bc..e0c2d833 100644 --- a/pkg/renderer/sgml/html5/templates.go +++ b/pkg/renderer/sgml/html5/templates.go @@ -69,6 +69,7 @@ var templates = sgml.Templates{ SuperscriptText: superscriptTextTmpl, Table: tableTmpl, TableBody: tableBodyTmpl, + TableCaption: tableCaptionTmpl, TableCell: tableCellTmpl, TableHeader: tableHeaderTmpl, TableHeaderCell: tableHeaderCellTmpl, diff --git a/pkg/renderer/sgml/image.go b/pkg/renderer/sgml/image.go index a596f40e..c4333f95 100644 --- a/pkg/renderer/sgml/image.go +++ b/pkg/renderer/sgml/image.go @@ -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 { diff --git a/pkg/renderer/sgml/sgml_renderer.go b/pkg/renderer/sgml/sgml_renderer.go index 774f86c1..1bbb0ca9 100644 --- a/pkg/renderer/sgml/sgml_renderer.go +++ b/pkg/renderer/sgml/sgml_renderer.go @@ -69,6 +69,7 @@ type sgmlRenderer struct { superscriptText *textTemplate table *textTemplate tableBody *textTemplate + tableCaption *textTemplate tableCell *textTemplate tableHeader *textTemplate tableHeaderCell *textTemplate @@ -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) diff --git a/pkg/renderer/sgml/table.go b/pkg/renderer/sgml/table.go index 56fcc275..8bf13d11 100644 --- a/pkg/renderer/sgml/table.go +++ b/pkg/renderer/sgml/table.go @@ -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 { @@ -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) @@ -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 @@ -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, diff --git a/pkg/renderer/sgml/templates.go b/pkg/renderer/sgml/templates.go index cf03764c..0e361277 100644 --- a/pkg/renderer/sgml/templates.go +++ b/pkg/renderer/sgml/templates.go @@ -62,6 +62,7 @@ type Templates struct { SuperscriptText string Table string TableBody string + TableCaption string TableCell string TableHeader string TableHeaderCell string diff --git a/pkg/renderer/sgml/xhtml5/table.go b/pkg/renderer/sgml/xhtml5/table.go index 4bb7df47..2edfeec4 100644 --- a/pkg/renderer/sgml/xhtml5/table.go +++ b/pkg/renderer/sgml/xhtml5/table.go @@ -2,7 +2,7 @@ package xhtml5 const ( tableTmpl = "\n" + - "{{ if .Title }}\n{{ end }}" + + "{{ if .Title }}\n{{ end }}" + "{{ if .Body }}" + "\n" + "{{ range $i, $w := .CellWidths }}\n{{ end}}" + diff --git a/pkg/renderer/sgml/xhtml5/table_test.go b/pkg/renderer/sgml/xhtml5/table_test.go index 3eecdf4f..a487abcf 100644 --- a/pkg/renderer/sgml/xhtml5/table_test.go +++ b/pkg/renderer/sgml/xhtml5/table_test.go @@ -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 {{ .TableNumber }}. {{ .Title }}{{ .Caption }}{{ .Title }}
+ ++++ + + + + + + + + + + + + + + + + +
Example I. table title
Column heading 1Column heading 2

Column 1, row 1

Column 2, row 1

Column 1, row 2

Column 2, row 2

` + Expect(RenderXHTML(source)).To(MatchHTML(expected)) + }) + It("empty table ", func() { source := `|=== |===` diff --git a/pkg/types/attributes.go b/pkg/types/attributes.go index c3c7d28d..85acac4f 100644 --- a/pkg/types/attributes.go +++ b/pkg/types/attributes.go @@ -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 @@ -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