From efe6d2e37a88f3116680be728f952d635cfd25ee Mon Sep 17 00:00:00 2001 From: Xavier Coulon Date: Mon, 20 Jun 2022 18:57:40 +0200 Subject: [PATCH] feat(parser): support cross references to images within tables Fixes #1049 Signed-off-by: Xavier Coulon --- pkg/parser/cross_reference_test.go | 52 +++++++++++++++++++ pkg/parser/delimited_block_open_test.go | 20 +++---- pkg/parser/table_test.go | 20 ++++--- .../sgml/html5/cross_reference_test.go | 31 +++++++++++ pkg/types/types.go | 28 ++++++++++ 5 files changed, 134 insertions(+), 17 deletions(-) diff --git a/pkg/parser/cross_reference_test.go b/pkg/parser/cross_reference_test.go index 0b4a7397..6b53baea 100644 --- a/pkg/parser/cross_reference_test.go +++ b/pkg/parser/cross_reference_test.go @@ -325,6 +325,58 @@ some content` Expect(ParseDocument(source)).To(MatchDocument(expected)) }) + It("to image in table cell", func() { + source := `a reference to <> + +|=== +a| +[#cookie] +.A cookie +image::cookie.png[Cookie] +|===` + expected := &types.Document{ + Elements: []interface{}{ + &types.Paragraph{ + Elements: []interface{}{ + &types.StringElement{ + Content: "a reference to ", + }, + &types.InternalCrossReference{ + ID: "cookie", + }, + }, + }, + &types.Table{ + Rows: []*types.TableRow{ + { + Cells: []*types.TableCell{ + { + Format: "a", + Elements: []interface{}{ + &types.ImageBlock{ + Attributes: types.Attributes{ + types.AttrID: "cookie", + types.AttrTitle: "A cookie", + types.AttrImageAlt: "Cookie", + }, + Location: &types.Location{ + Path: "cookie.png", + }, + }, + }, + }, + }, + }, + }, + }, + }, + ElementReferences: types.ElementReferences{ + "cookie": "A cookie", + }, + } + Expect(ParseDocument(source)).To(MatchDocument(expected)) + }) + It("to attached element in a list", func() { source := `a reference to <> diff --git a/pkg/parser/delimited_block_open_test.go b/pkg/parser/delimited_block_open_test.go index 63f0cc83..154dacae 100644 --- a/pkg/parser/delimited_block_open_test.go +++ b/pkg/parser/delimited_block_open_test.go @@ -44,12 +44,12 @@ some content [cols="2*^"] |=== a| -[#id] -.A title +[#image-id] +.An image image::image.png[] a| -[#another-id] -.Another title +[#another-image-id] +.Another image image::another-image.png[] |=== --` @@ -81,8 +81,8 @@ image::another-image.png[] Elements: []interface{}{ &types.ImageBlock{ Attributes: types.Attributes{ - types.AttrID: "id", - types.AttrTitle: "A title", + types.AttrID: "image-id", + types.AttrTitle: "An image", }, Location: &types.Location{ Path: "image.png", @@ -95,8 +95,8 @@ image::another-image.png[] Elements: []interface{}{ &types.ImageBlock{ Attributes: types.Attributes{ - types.AttrID: "another-id", - types.AttrTitle: "Another title", + types.AttrID: "another-image-id", + types.AttrTitle: "Another image", }, Location: &types.Location{ Path: "another-image.png", @@ -112,7 +112,9 @@ image::another-image.png[] }, }, ElementReferences: types.ElementReferences{ - "block-id": "Block Title", + "block-id": "Block Title", + "image-id": "An image", + "another-image-id": "Another image", }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) diff --git a/pkg/parser/table_test.go b/pkg/parser/table_test.go index fea94da1..d73eb560 100644 --- a/pkg/parser/table_test.go +++ b/pkg/parser/table_test.go @@ -1387,12 +1387,12 @@ image::another-image.png[] source := `[cols="2*^"] |=== a| -[#id] -.A title +[#image-id] +.An image image::image.png[] a| -[#another-id] -.Another title +[#another-image-id] +.Another image image::another-image.png[] |===` expected := &types.Document{ @@ -1416,8 +1416,8 @@ image::another-image.png[] Elements: []interface{}{ &types.ImageBlock{ Attributes: types.Attributes{ - types.AttrID: "id", - types.AttrTitle: "A title", + types.AttrID: "image-id", + types.AttrTitle: "An image", }, Location: &types.Location{ Path: "image.png", @@ -1430,8 +1430,8 @@ image::another-image.png[] Elements: []interface{}{ &types.ImageBlock{ Attributes: types.Attributes{ - types.AttrID: "another-id", - types.AttrTitle: "Another title", + types.AttrID: "another-image-id", + types.AttrTitle: "Another image", }, Location: &types.Location{ Path: "another-image.png", @@ -1444,6 +1444,10 @@ image::another-image.png[] }, }, }, + ElementReferences: types.ElementReferences{ + "image-id": "An image", + "another-image-id": "Another image", + }, } Expect(ParseDocument(source)).To(MatchDocument(expected)) }) diff --git a/pkg/renderer/sgml/html5/cross_reference_test.go b/pkg/renderer/sgml/html5/cross_reference_test.go index b87821db..34b31788 100644 --- a/pkg/renderer/sgml/html5/cross_reference_test.go +++ b/pkg/renderer/sgml/html5/cross_reference_test.go @@ -186,6 +186,37 @@ image::cookie.jpg[]`
Figure 1. A cookie
+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("to image in table cell", func() { + source := `a reference to <> + +|=== +a| +[#cookie] +.A cookie +image::cookie.png[Cookie] +|===` + expected := `
+

a reference to A cookie

+
+
+++ + + + + + +
` Expect(RenderHTML(source)).To(MatchHTML(expected)) }) diff --git a/pkg/types/types.go b/pkg/types/types.go index 82df71e9..852b4a48 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -3796,6 +3796,34 @@ func (t *Table) Reference(refs ElementReferences) { if id != "" && title != nil { refs[id] = title } + // also, traverse all cells to find referencable content + if t.Header != nil { + for _, c := range t.Header.Cells { + for _, e := range c.Elements { + if e, ok := e.(Referencable); ok { + e.Reference(refs) + } + } + } + } + for _, r := range t.Rows { + for _, c := range r.Cells { + for _, e := range c.Elements { + if e, ok := e.(Referencable); ok { + e.Reference(refs) + } + } + } + } + if t.Footer != nil { + for _, c := range t.Footer.Cells { + for _, e := range c.Elements { + if e, ok := e.(Referencable); ok { + e.Reference(refs) + } + } + } + } } type HAlign string