Skip to content

Commit

Permalink
feature(renderer): Top level table styling
Browse files Browse the repository at this point in the history
This provides top-level support for attributes to style the
entire table (frame, grid, float, stripes, width, autowidth).

The cols attribute is still not handled, meaning that it is
still not possible to configure column widths.
  • Loading branch information
gdamore committed Jul 4, 2020
1 parent 4c8b1fd commit 4dc3cd7
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 41 deletions.
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Although it does not support the full Asciidoc/Asciidoctor syntax, Libasciidoc a
* Unordered lists including bullet styles
* Labeled lists, including `[horizontal]` and `[qanda]` styles
* Nesting of links of different types & attributes
* Tables (basic support: header line and cells on multiple lines)
* Tables (basic support: header line and cells on multiple lines, top-level table styles)
* Horizontal rules (thematic breaks) and page breaks
* Table of contents
* YAML front-matter
Expand Down
8 changes: 4 additions & 4 deletions pkg/parser/attributes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var _ = Describe("attributes", func() {
Blocks: []interface{}{
types.ImageBlock{
Attributes: types.Attributes{
types.AttrImageWidth: "200",
types.AttrWidth: "200",
},
Location: types.Location{
Path: []interface{}{
Expand Down Expand Up @@ -195,7 +195,7 @@ var _ = Describe("attributes", func() {
Attributes: types.Attributes{
types.AttrImageAlt: `Quoted, Here`,
types.AttrImageHeight: "100", // last one wins
types.AttrImageWidth: "1",
types.AttrWidth: "1",
},
Location: types.Location{
Path: []interface{}{
Expand All @@ -215,7 +215,7 @@ var _ = Describe("attributes", func() {
Attributes: types.Attributes{
types.AttrImageAlt: `Quoted, Here`,
types.AttrImageHeight: "100", // last one wins
types.AttrImageWidth: "1",
types.AttrWidth: "1",
"test1": "123",
"test2": "second test", // shows trailing pad removed
},
Expand All @@ -237,7 +237,7 @@ var _ = Describe("attributes", func() {
Attributes: types.Attributes{
types.AttrImageAlt: `Quoted, Here`,
types.AttrImageHeight: "100", // last one wins
types.AttrImageWidth: "1",
types.AttrWidth: "1",
"test1": "123",
"test2": `second "test"`, // shows trailing pad removed
},
Expand Down
16 changes: 8 additions & 8 deletions pkg/parser/icon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ var _ = Describe("icons", func() {
{
types.Icon{
Class: "caution",
Attributes: types.Attributes{types.AttrImageTitle: "bogus"},
Attributes: types.Attributes{types.AttrTitle: "bogus"},
},
},
},
Expand Down Expand Up @@ -146,9 +146,9 @@ var _ = Describe("icons", func() {
types.Icon{
Class: "caution",
Attributes: types.Attributes{
types.AttrID: "anchor",
types.AttrCustomID: true,
types.AttrImageTitle: "White Fang",
types.AttrID: "anchor",
types.AttrCustomID: true,
types.AttrTitle: "White Fang",
},
},
},
Expand All @@ -169,10 +169,10 @@ var _ = Describe("icons", func() {
types.Icon{
Class: "caution",
Attributes: types.Attributes{
types.AttrID: "anchor",
types.AttrCustomID: true,
types.AttrImageTitle: "White Fang",
types.AttrIconSize: "fw",
types.AttrID: "anchor",
types.AttrCustomID: true,
types.AttrTitle: "White Fang",
types.AttrIconSize: "fw",
},
},
},
Expand Down
10 changes: 5 additions & 5 deletions pkg/parser/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ image::images/foo.png[the foo.png image, 600, 400]`
types.AttrTitle: "A title to foobar",
types.AttrInlineLink: "http://foo.bar",
types.AttrImageAlt: "the foo.png image",
types.AttrImageWidth: "600",
types.AttrWidth: "600",
types.AttrImageHeight: "400",
},
Location: types.Location{
Expand Down Expand Up @@ -453,8 +453,8 @@ image::{imagesdir}/foo.png[]`
{
types.InlineImage{
Attributes: types.Attributes{
types.AttrImageAlt: "the foo.png image",
types.AttrImageWidth: "600",
types.AttrImageAlt: "the foo.png image",
types.AttrWidth: "600",
},
Location: types.Location{
Path: []interface{}{
Expand All @@ -480,7 +480,7 @@ image::{imagesdir}/foo.png[]`
types.InlineImage{
Attributes: types.Attributes{
types.AttrImageAlt: "the foo.png image",
types.AttrImageWidth: "600",
types.AttrWidth: "600",
types.AttrImageHeight: "400",
},
Location: types.Location{
Expand Down Expand Up @@ -586,7 +586,7 @@ image::{imagesdir}/foo.png[]`
types.InlineImage{
Attributes: types.Attributes{
types.AttrImageAlt: "foo",
types.AttrImageWidth: "600",
types.AttrWidth: "600",
types.AttrImageHeight: "400",
types.AttrID: "myid",
types.AttrCustomID: true,
Expand Down
4 changes: 2 additions & 2 deletions pkg/parser/paragraph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ image::foo.png[]`
types.ImageBlock{
Attributes: types.Attributes{
types.AttrImageAlt: "verse",
types.AttrImageWidth: "john doe",
types.AttrWidth: "john doe",
types.AttrImageHeight: "verse title",
},
Location: types.Location{
Expand Down Expand Up @@ -846,7 +846,7 @@ image::foo.png[]`
},
Attributes: types.Attributes{
types.AttrImageAlt: "quote",
types.AttrImageWidth: "john doe",
types.AttrWidth: "john doe",
types.AttrImageHeight: "quote title",
},
},
Expand Down
4 changes: 2 additions & 2 deletions pkg/parser/parser.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/renderer/sgml/element_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (r *sgmlRenderer) renderElementRoles(attrs types.Attributes) sanitized {
func (r *sgmlRenderer) renderImageRoles(attrs types.Attributes) sanitized {
var roles []string

if val, ok := attrs.GetAsString(types.AttrImageFloat); ok {
if val, ok := attrs.GetAsString(types.AttrFloat); ok {
roles = append(roles, val)
}
if val, ok := attrs.GetAsString(types.AttrImageAlign); ok {
Expand Down
12 changes: 9 additions & 3 deletions pkg/renderer/sgml/html5/table.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
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" +
tableTmpl = "<table class=\"tableblock" +
" frame-{{ .Frame }} grid-{{ .Grid }}" +
"{{ if .Stripes }} stripes-{{ .Stripes }}{{ end }}" +
"{{ if .Fit }} {{ .Fit }}{{ end }}" +
"{{ if .Float }} {{ .Float }}{{ end }}" +
"{{ if .Roles }} {{ .Roles }}{{ end }}\"" +
"{{ if .Width }} style=\"width: {{ .Width }}%;\"{{ end }}" +
">\n" +
"{{ if .Title }}<caption class=\"title\">{{ .Caption }}{{ .Title }}</caption>\n{{ end }}" +
"{{ if .Body }}" +
"<colgroup>\n" +
Expand All @@ -21,7 +27,7 @@ const (

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

// TODO: review these alignment choices ... should they be overrideable?
// TODO: cell styling via attributes

tableHeaderCellTmpl = "<th class=\"tableblock halign-left valign-top\">{{ .Content }}</th>\n"

Expand Down
56 changes: 56 additions & 0 deletions pkg/renderer/sgml/html5/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,60 @@ var _ = Describe("tables", func() {
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("autowidth ", func() {
source := "[%autowidth]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all fit-content">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("fixed width (number)", func() {
source := "[width=75]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all" style="width: 75%;">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("fixed width (percent)", func() {
source := "[width=75%]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all" style="width: 75%;">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("fixed width (100 percent)", func() {
source := "[width=100%]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all stretch">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("fixed width (> 100 percent)", func() {
source := "[width=205]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all stretch">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("fixed width overrides fit", func() {
source := "[%autowidth,width=25]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all" style="width: 25%;">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("fixed width overrides fit (> 100 percent)", func() {
source := "[%autowidth,width=205]\n|===\n|==="
expected := `<table class="tableblock frame-all grid-all stretch">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

It("grid, frames, float, stripes", func() {
source := "[%autowidth,grid=rows,frame=sides,stripes=hover,float=right]\n|===\n|==="
expected := `<table class="tableblock frame-sides grid-rows stripes-hover fit-content right">
</table>`
Expect(RenderHTML(source)).To(MatchHTML(expected))
})

})
4 changes: 2 additions & 2 deletions pkg/renderer/sgml/icon.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ func (r *sgmlRenderer) renderIcon(ctx *renderer.Context, icon types.Icon, admoni
}{
Class: icon.Class,
Alt: icon.Attributes.GetAsStringWithDefault(types.AttrImageAlt, strings.Title(icon.Class)),
Title: icon.Attributes.GetAsStringWithDefault(types.AttrImageTitle, title),
Width: icon.Attributes.GetAsStringWithDefault(types.AttrImageWidth, ""),
Title: icon.Attributes.GetAsStringWithDefault(types.AttrTitle, title),
Width: icon.Attributes.GetAsStringWithDefault(types.AttrWidth, ""),
Height: icon.Attributes.GetAsStringWithDefault(types.AttrImageHeight, ""),
Size: icon.Attributes.GetAsStringWithDefault(types.AttrIconSize, ""),
Rotate: icon.Attributes.GetAsStringWithDefault(types.AttrIconRotate, ""),
Expand Down
4 changes: 2 additions & 2 deletions pkg/renderer/sgml/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (r *sgmlRenderer) renderImageBlock(ctx *renderer.Context, img types.ImageBl
Roles: r.renderImageRoles(img.Attributes),
Href: img.Attributes.GetAsStringWithDefault(types.AttrInlineLink, ""),
Alt: img.Attributes.GetAsStringWithDefault(types.AttrImageAlt, ""),
Width: img.Attributes.GetAsStringWithDefault(types.AttrImageWidth, ""),
Width: img.Attributes.GetAsStringWithDefault(types.AttrWidth, ""),
Height: img.Attributes.GetAsStringWithDefault(types.AttrImageHeight, ""),
Path: img.Location.String(),
})
Expand All @@ -80,7 +80,7 @@ func (r *sgmlRenderer) renderInlineImage(img types.InlineImage) (string, error)
Title: r.renderElementTitle(img.Attributes),
Roles: r.renderImageRoles(img.Attributes),
Alt: img.Attributes.GetAsStringWithDefault(types.AttrImageAlt, ""),
Width: img.Attributes.GetAsStringWithDefault(types.AttrImageWidth, ""),
Width: img.Attributes.GetAsStringWithDefault(types.AttrWidth, ""),
Height: img.Attributes.GetAsStringWithDefault(types.AttrImageHeight, ""),
Path: img.Location.String(),
})
Expand Down
37 changes: 37 additions & 0 deletions pkg/renderer/sgml/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,31 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string
}
number := 0
title := r.renderElementTitle(t.Attributes)
fit := "stretch"
frame := t.Attributes.GetAsStringWithDefault(types.AttrFrame, "all")
grid := t.Attributes.GetAsStringWithDefault(types.AttrGrid, "all")
float := t.Attributes.GetAsStringWithDefault(types.AttrFloat, "")
stripes := t.Attributes.GetAsStringWithDefault(types.AttrStripes, "")

width, _ := strconv.Atoi(
strings.TrimSuffix(t.Attributes.GetAsStringWithDefault(types.AttrWidth, ""), "%"))

// These are derived from asciidoctor, and our rules here:
// * Width can be a number or a percentage
// * If width is >= 100, then it becomes "stretch" role, and we clear it
// * If width is any other number (besides 0), we do not use the fitting role,
// and instead use an explicit style for the width.
// * If width is unset, and %autowidth is set, then we use a fit-content role.
// * If none of the above cases are true, we use stretch role (default)
if t.Attributes.HasOption("autowidth") {
fit = "fit-content"
}
if width >= 100 {
width = 0
fit = "stretch"
} else if width > 0 {
fit = ""
}

if t.Attributes.Has(types.AttrTitle) {
number = ctx.GetAndIncrementTableCounter()
Expand Down Expand Up @@ -71,6 +96,12 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string
CellWidths []string
TableNumber int
Caption string
Frame string
Grid string
Fit string
Float string
Stripes string
Width int
Roles sanitized
Header string
Body string
Expand All @@ -81,6 +112,12 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string
TableNumber: number,
Caption: caption.String(),
Roles: r.renderElementRoles(t.Attributes),
Frame: frame,
Grid: grid,
Fit: fit,
Float: float,
Stripes: stripes,
Width: width,
Header: header,
Body: body,
})
Expand Down
9 changes: 8 additions & 1 deletion pkg/renderer/sgml/xhtml5/table.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package xhtml5

const (
tableTmpl = "<table class=\"tableblock frame-all grid-all stretch{{ if .Roles }} {{ .Roles }}{{ end }}\">\n" +
tableTmpl = "<table class=\"tableblock" +
" frame-{{ .Frame }} grid-{{ .Grid }}" +
"{{ if .Stripes }} stripes-{{ .Stripes }}{{ end }}" +
"{{ if .Fit }} {{ .Fit }}{{ end }}" +
"{{ if .Float }} {{ .Float }}{{ end }}" +
"{{ if .Roles }} {{ .Roles }}{{ end }}\"" +
"{{ if .Width }} style=\"width: {{ .Width }}%;\"{{ end }}" +
">\n" +
"{{ if .Title }}<caption class=\"title\">{{ .Caption }}{{ .Title }}</caption>\n{{ end }}" +
"{{ if .Body }}" +
"<colgroup>\n" +
Expand Down
Loading

0 comments on commit 4dc3cd7

Please sign in to comment.