From e701182da7ca15870d721cc4686e7d6911476f48 Mon Sep 17 00:00:00 2001 From: Xavier Coulon Date: Mon, 22 Nov 2021 19:39:59 +0100 Subject: [PATCH] feat(renderer): support table ID (#868) also, verifies that cross references work in list element continuations (#837) Fixes #867 Fixes #837 Signed-off-by: Xavier Coulon --- pkg/parser/ordered_list_test.go | 82 ++++++++-- pkg/parser/unordered_list_test.go | 144 +++++++++--------- pkg/renderer/sgml/html5/ordered_list_test.go | 125 +++++++++++++-- pkg/renderer/sgml/html5/table.go | 2 +- .../sgml/html5/unordered_list_test.go | 121 ++++++++------- pkg/renderer/sgml/table.go | 20 +-- pkg/renderer/sgml/xhtml5/table.go | 2 +- pkg/renderer/sgml/xhtml5/table_test.go | 55 ++++++- 8 files changed, 383 insertions(+), 168 deletions(-) diff --git a/pkg/parser/ordered_list_test.go b/pkg/parser/ordered_list_test.go index e4094d7d..f93ff415 100644 --- a/pkg/parser/ordered_list_test.go +++ b/pkg/parser/ordered_list_test.go @@ -281,7 +281,7 @@ var _ = Describe("ordered lists", func() { Context("elements without numbers", func() { - It("ordered list with simple unnumbered elements", func() { + It("with simple unnumbered elements", func() { source := `. a . b` @@ -344,7 +344,7 @@ var _ = Describe("ordered lists", func() { Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with unnumbered elements", func() { + It("with unnumbered elements", func() { source := `. element 1 . element 2` @@ -380,7 +380,7 @@ var _ = Describe("ordered lists", func() { Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with custom numbering on child elements with tabs ", func() { + It("with custom numbering on child elements with tabs ", func() { // note: the [upperroman] attribute must be at the beginning of the line source := `. element 1 .. element 1.1 @@ -491,7 +491,7 @@ var _ = Describe("ordered lists", func() { Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with all default styles and blank lines", func() { + It("with all default styles and blank lines", func() { source := `. level 1 .. level 2 @@ -588,7 +588,7 @@ var _ = Describe("ordered lists", func() { Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with all default styles and no blank line", func() { + It("with all default styles and no blank line", func() { source := `. level 1 .. level 2 ... level 3 @@ -680,7 +680,7 @@ var _ = Describe("ordered lists", func() { Context("numbered elements", func() { - It("ordered list with simple numbered elements", func() { + It("with simple numbered elements", func() { source := `1. a 2. b` expected := &types.Document{ @@ -830,7 +830,7 @@ var _ = Describe("ordered lists", func() { Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with numbered elements", func() { + It("with numbered elements", func() { source := `1. element 1 a. element 1.a 2. element 2 @@ -900,7 +900,7 @@ b. element 2.a` Context("list element continuation", func() { - It("ordered list with element continuation - case 1", func() { + It("case 1", func() { source := `. foo + ---- @@ -960,7 +960,7 @@ another delimited block Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with element continuation - case 2", func() { + It("case 2", func() { source := `. {blank} + ---- @@ -1019,7 +1019,7 @@ print("two") Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("ordered list with element continuation - case 3", func() { + It("case 3", func() { // continuation with "continued element" being a list element (ie, kinda invalid/empty continuation in the middle of a list) source := `. element 1 + @@ -1082,6 +1082,68 @@ a paragraph } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) + + It("case 4", func() { + source := `. cookie ++ +image::cookie.png[] ++ +. chocolate ++ +image::chocolate.png[]` + expected := &types.Document{ + Elements: []interface{}{ + &types.List{ + Kind: types.OrderedListKind, + Elements: []types.ListElement{ + &types.OrderedListElement{ + Style: types.Arabic, + Elements: []interface{}{ + &types.Paragraph{ + Elements: []interface{}{ + &types.StringElement{ + Content: "cookie", + }, + }, + }, + &types.ImageBlock{ + Location: &types.Location{ + Path: []interface{}{ + &types.StringElement{ + Content: "cookie.png", + }, + }, + }, + }, + }, + }, + &types.OrderedListElement{ + Style: types.Arabic, + Elements: []interface{}{ + &types.Paragraph{ + Elements: []interface{}{ + &types.StringElement{ + Content: "chocolate", + }, + }, + }, + &types.ImageBlock{ + Location: &types.Location{ + Path: []interface{}{ + &types.StringElement{ + Content: "chocolate.png", + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + Expect(ParseDocument(source)).To(MatchDocument(expected)) + }) }) }) }) diff --git a/pkg/parser/unordered_list_test.go b/pkg/parser/unordered_list_test.go index 44066804..51763305 100644 --- a/pkg/parser/unordered_list_test.go +++ b/pkg/parser/unordered_list_test.go @@ -997,7 +997,7 @@ on 2 lines, too.` Context("list element continuation", func() { - It("with item continuation - case 1", func() { + It("case 1", func() { source := `* foo + ---- @@ -1063,7 +1063,7 @@ another delimited block Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("with item continuation - case 2", func() { + It("case 2", func() { source := `.Unordered, complex * level 1 ** level 2 @@ -1199,7 +1199,7 @@ The {plus} symbol is on a new line. Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("with list element continuation - case 3", func() { + It("case 3", func() { source := `- here + _there_` @@ -1240,76 +1240,6 @@ _there_` Expect(ParseDocument(source)).To(MatchDocument(expected)) }) - It("without item continuation", func() { - source := `* foo - ----- -a delimited block ----- - -* bar - ----- -another delimited block -----` - expected := &types.Document{ - Elements: []interface{}{ - &types.List{ - Kind: types.UnorderedListKind, - Elements: []types.ListElement{ - &types.UnorderedListElement{ - BulletStyle: types.OneAsterisk, - CheckStyle: types.NoCheck, - Elements: []interface{}{ - &types.Paragraph{ - Elements: []interface{}{ - &types.StringElement{Content: "foo"}, - }, - }, - }, - }, - }, - }, - &types.DelimitedBlock{ - Kind: types.Listing, - Elements: []interface{}{ - &types.StringElement{ - Content: "a delimited block", - }, - }, - }, - &types.List{ - Kind: types.UnorderedListKind, - Elements: []types.ListElement{ - &types.UnorderedListElement{ - BulletStyle: types.OneAsterisk, - CheckStyle: types.NoCheck, - Elements: []interface{}{ - &types.Paragraph{ - Elements: []interface{}{ - &types.StringElement{Content: "bar"}, - }, - }, - }, - }, - }, - }, - &types.DelimitedBlock{ - Kind: types.Listing, - Elements: []interface{}{ - &types.StringElement{ - Content: "another delimited block", - }, - }, - }, - }, - } - Expect(ParseDocument(source)).To(MatchDocument(expected)) - }) - }) - - Context("attach to ancestor", func() { - It("attach to grandparent item", func() { source := `* grandparent list element ** parent list element @@ -1453,5 +1383,73 @@ paragraph attached to parent list element` Expect(ParseDocument(source)).To(MatchDocument(expected)) }) }) + + It("without item continuation", func() { + source := `* foo + +---- +a delimited block +---- + +* bar + +---- +another delimited block +----` + expected := &types.Document{ + Elements: []interface{}{ + &types.List{ + Kind: types.UnorderedListKind, + Elements: []types.ListElement{ + &types.UnorderedListElement{ + BulletStyle: types.OneAsterisk, + CheckStyle: types.NoCheck, + Elements: []interface{}{ + &types.Paragraph{ + Elements: []interface{}{ + &types.StringElement{Content: "foo"}, + }, + }, + }, + }, + }, + }, + &types.DelimitedBlock{ + Kind: types.Listing, + Elements: []interface{}{ + &types.StringElement{ + Content: "a delimited block", + }, + }, + }, + &types.List{ + Kind: types.UnorderedListKind, + Elements: []types.ListElement{ + &types.UnorderedListElement{ + BulletStyle: types.OneAsterisk, + CheckStyle: types.NoCheck, + Elements: []interface{}{ + &types.Paragraph{ + Elements: []interface{}{ + &types.StringElement{Content: "bar"}, + }, + }, + }, + }, + }, + }, + &types.DelimitedBlock{ + Kind: types.Listing, + Elements: []interface{}{ + &types.StringElement{ + Content: "another delimited block", + }, + }, + }, + }, + } + Expect(ParseDocument(source)).To(MatchDocument(expected)) + }) + }) }) diff --git a/pkg/renderer/sgml/html5/ordered_list_test.go b/pkg/renderer/sgml/html5/ordered_list_test.go index 1d72d4e8..cabb7066 100644 --- a/pkg/renderer/sgml/html5/ordered_list_test.go +++ b/pkg/renderer/sgml/html5/ordered_list_test.go @@ -88,7 +88,7 @@ lines

Expect(RenderHTML(source)).To(MatchHTML(expected)) }) - It("ordered list item reversed with explicit quoted numbering and start", func() { + It("item reversed with explicit quoted numbering and start", func() { source := `[lowerroman%reversed, start="5"] . item 1 . item 2` @@ -106,11 +106,13 @@ lines

Expect(RenderHTML(source)).To(MatchHTML(expected)) }) - It("with paragraph continuation", func() { - source := `. item 1 + Context("with list element continuation", func() { + + It("case 1", func() { + source := `. item 1 + foo` - expected := `
+ expected := `
  1. item 1

    @@ -121,16 +123,16 @@ foo`
` - Expect(RenderHTML(source)).To(MatchHTML(expected)) - }) + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) - It("with delimited block continuation", func() { - source := `. item 1 + It("case 2", func() { + source := `. item 1 + ---- foo ----` - expected := `
+ expected := `
  1. item 1

    @@ -143,7 +145,106 @@ foo
` - Expect(RenderHTML(source)).To(MatchHTML(expected)) + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("case 3", func() { + source := `. cookie ++ +image::cookie.png[] ++ +. chocolate ++ +image::chocolate.png[]` + expected := `
+
    +
  1. +

    cookie

    +
    +
    +cookie +
    +
    +
  2. +
  3. +

    chocolate

    +
    +
    +chocolate +
    +
    +
  4. +
+
+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("case 4", func() { + source := `. In the table, enter the data shown in <> ++ +[#non-uniform-mesh] +.Non-Uniform Mesh Parameters +[cols="3*^",options="header"] +|=== +|Dir (X,Y,Z) |Num Cells |Size +|X |10 |0.1 +|Y |10 |0.1 +|Y |5 |0.2 +|Z |10 |0.1 +|=== ++ +. Click *OK*` + expected := `
+
    +
  1. +

    In the table, enter the data shown in Non-Uniform Mesh Parameters

    + + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 1. Non-Uniform Mesh Parameters
    Dir (X,Y,Z)Num CellsSize

    X

    10

    0.1

    Y

    10

    0.1

    Y

    5

    0.2

    Z

    10

    0.1

    +
  2. +
  3. +

    Click OK

    +
  4. +
+
+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) }) It("with unnumbered items", func() { @@ -195,7 +296,7 @@ foo Expect(RenderHTML(source)).To(MatchHTML(expected)) }) - It("ordered list mixed with unordered list - simple case", func() { + It("mixed with unordered list - simple case", func() { source := `. Linux * Fedora * Ubuntu @@ -240,7 +341,7 @@ foo Expect(RenderHTML(source)).To(MatchHTML(expected)) }) - It("ordered list mixed with unordered list - complex case", func() { + It("mixed with unordered list - complex case", func() { source := `- unordered 1 1. ordered 1.1 a. ordered 1.1.a diff --git a/pkg/renderer/sgml/html5/table.go b/pkg/renderer/sgml/html5/table.go index e48a1432..67176eb7 100644 --- a/pkg/renderer/sgml/html5/table.go +++ b/pkg/renderer/sgml/html5/table.go @@ -1,7 +1,7 @@ package html5 const ( - tableTmpl = " Expect(RenderHTML(source)).To(MatchHTML(expected)) }) - It("simple unordered list with continuation", func() { - source := `* item 1 + Context("with list element continuation", func() { + + It("case 1", func() { + source := `* item 1 + foo * item 2` - expected := `
+ expected := `
  • item 1

    @@ -154,7 +156,63 @@ foo
` - Expect(RenderHTML(source)).To(MatchHTML(expected)) + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("case 2", func() { + source := `* foo ++ +---- +a delimited block +---- ++ +---- +another delimited block +---- +* bar +` + expected := `
+
    +
  • +

    foo

    +
    +
    +
    a delimited block
    +
    +
    +
    +
    +
    another delimited block
    +
    +
    +
  • +
  • +

    bar

    +
  • +
+
+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("case 3", func() { + source := `- here ++ +_there_ +` + expected := `
+
    +
  • +

    here

    +
    +

    there

    +
    +
  • +
+
+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) }) It("nested unordered lists without a title", func() { @@ -216,61 +274,6 @@ foo Expect(RenderHTML(source)).To(MatchHTML(expected)) }) - It("unordered list with item continuation - case 1", func() { - source := `* foo -+ ----- -a delimited block ----- -+ ----- -another delimited block ----- -* bar -` - expected := `
-
    -
  • -

    foo

    -
    -
    -
    a delimited block
    -
    -
    -
    -
    -
    another delimited block
    -
    -
    -
  • -
  • -

    bar

    -
  • -
-
-` - Expect(RenderHTML(source)).To(MatchHTML(expected)) - }) - - It("unordered list with item continuation - case 2", func() { - source := `- here -+ -_there_ -` - expected := `
-
    -
  • -

    here

    -
    -

    there

    -
    -
  • -
-
-` - Expect(RenderHTML(source)).To(MatchHTML(expected)) - }) - It("unordered list without item continuation", func() { source := `* foo ---- diff --git a/pkg/renderer/sgml/table.go b/pkg/renderer/sgml/table.go index 51e928b5..0cdbc65c 100644 --- a/pkg/renderer/sgml/table.go +++ b/pkg/renderer/sgml/table.go @@ -7,9 +7,7 @@ import ( "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" - "github.com/davecgh/go-spew/spew" "github.com/pkg/errors" - log "github.com/sirupsen/logrus" ) func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t *types.Table) (string, error) { @@ -94,6 +92,7 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t *types.Table) (strin } err = r.table.Execute(result, struct { Context *renderer.Context + ID string Title string Columns []*types.TableColumn TableNumber int @@ -110,6 +109,7 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t *types.Table) (strin Footer string }{ Context: ctx, + ID: r.renderElementID(t.Attributes), Title: title, Columns: columns, TableNumber: number, @@ -186,11 +186,11 @@ func (r *sgmlRenderer) renderTableFooter(ctx *renderer.Context, f *types.TableRo } func (r *sgmlRenderer) renderTableBody(ctx *renderer.Context, rows []*types.TableRow, columns []*types.TableColumn) (string, error) { - if log.IsLevelEnabled(log.DebugLevel) { - log.Debug("rendering table body") - log.Debugf("columns:\n%s", spew.Sdump(columns)) - log.Debugf("rows:\n%s", spew.Sdump(rows)) - } + // if log.IsLevelEnabled(log.DebugLevel) { + // log.Debug("rendering table body") + // log.Debugf("columns:\n%s", spew.Sdump(columns)) + // log.Debugf("rows:\n%s", spew.Sdump(rows)) + // } result := &strings.Builder{} content := &strings.Builder{} for _, row := range rows { @@ -242,9 +242,9 @@ func (r *sgmlRenderer) renderTableCell(ctx *renderer.Context, tmpl *template.Tem if err != nil { return "", errors.Wrap(err, "unable to render cell") } - if log.IsLevelEnabled(log.DebugLevel) { - log.Debugf("rendering cell with content '%s' and def %s", content, spew.Sdump(col)) - } + // if log.IsLevelEnabled(log.DebugLevel) { + // log.Debugf("rendering cell with content '%s' and def %s", content, spew.Sdump(col)) + // } err = tmpl.Execute(result, struct { Context *renderer.Context Content string diff --git a/pkg/renderer/sgml/xhtml5/table.go b/pkg/renderer/sgml/xhtml5/table.go index 2e87452e..ed79a032 100644 --- a/pkg/renderer/sgml/xhtml5/table.go +++ b/pkg/renderer/sgml/xhtml5/table.go @@ -1,7 +1,7 @@ package xhtml5 const ( - tableTmpl = "
,>\"]\n|===\n|===" - source := "[cols=\"2*^.^,<,.>,>\"]\n|===\n|h1|h2|h3|h4|h5\n\n|one|two|three|four|five\n|===" expected := `
@@ -618,6 +616,59 @@ var _ = Describe("tables", func() {
+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("with id and title", func() { + source := `[#non-uniform-mesh] +.Non-Uniform Mesh Parameters +[cols="3*^",options="header"] +|=== +|Dir (X,Y,Z) |Num Cells |Size +|X |10 |0.1 +|Y |10 |0.1 +|Y |5 |0.2 +|Z |10 |0.1 +|===` + + expected := ` + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Non-Uniform Mesh Parameters
Dir (X,Y,Z)Num CellsSize

X

10

0.1

Y

10

0.1

Y

5

0.2

Z

10

0.1

` Expect(RenderHTML(source)).To(MatchHTML(expected)) })