From e157d695810811e17b8794b026b1e0e86d2c7024 Mon Sep 17 00:00:00 2001 From: Xavier Coulon Date: Thu, 5 May 2022 08:28:07 +0200 Subject: [PATCH] feat(renderer): support elements in titles (#1017) support elements such as links, etc. follow-up of #999 Fixes #956 Signed-off-by: Xavier Coulon --- .../sgml/delimited_block_admonition.go | 4 +-- pkg/renderer/sgml/delimited_block_example.go | 4 +-- pkg/renderer/sgml/delimited_block_fenced.go | 2 +- pkg/renderer/sgml/delimited_block_listing.go | 4 +-- .../sgml/delimited_block_markdown_quote.go | 2 +- pkg/renderer/sgml/delimited_block_quote.go | 4 +-- pkg/renderer/sgml/delimited_block_sidebar.go | 2 +- pkg/renderer/sgml/delimited_block_source.go | 2 +- pkg/renderer/sgml/delimited_block_verse.go | 4 +-- .../html5/delimited_block_listing_test.go | 15 +++++++++++ pkg/renderer/sgml/image.go | 4 +-- pkg/renderer/sgml/list.go | 8 +++--- pkg/renderer/sgml/literal_blocks.go | 4 +-- pkg/renderer/sgml/paragraph.go | 26 +++++++++++-------- pkg/renderer/sgml/table.go | 2 +- 15 files changed, 53 insertions(+), 34 deletions(-) diff --git a/pkg/renderer/sgml/delimited_block_admonition.go b/pkg/renderer/sgml/delimited_block_admonition.go index 0691e7a0..536425e5 100644 --- a/pkg/renderer/sgml/delimited_block_admonition.go +++ b/pkg/renderer/sgml/delimited_block_admonition.go @@ -29,7 +29,7 @@ func (r *sgmlRenderer) renderAdmonitionBlock(ctx *renderer.Context, b *types.Del if err != nil { return "", errors.Wrap(err, "unable to render fenced block content") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -77,7 +77,7 @@ func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p *types if err != nil { return "", errors.Wrap(err, "unable to render fenced block content") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_example.go b/pkg/renderer/sgml/delimited_block_example.go index 723ade20..a26a86d5 100644 --- a/pkg/renderer/sgml/delimited_block_example.go +++ b/pkg/renderer/sgml/delimited_block_example.go @@ -42,7 +42,7 @@ func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b *types.Delimi number = ctx.GetAndIncrementExampleBlockCounter() c = strings.ReplaceAll(c, "{counter:example-number}", strconv.Itoa(number)) } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -78,7 +78,7 @@ func (r *sgmlRenderer) renderExampleParagraph(ctx *renderer.Context, p *types.Pa if err != nil { return "", errors.Wrap(err, "unable to render fenced block content") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_fenced.go b/pkg/renderer/sgml/delimited_block_fenced.go index eacf6ea4..5594f2d8 100644 --- a/pkg/renderer/sgml/delimited_block_fenced.go +++ b/pkg/renderer/sgml/delimited_block_fenced.go @@ -24,7 +24,7 @@ func (r *sgmlRenderer) renderFencedBlock(ctx *renderer.Context, b *types.Delimit if err != nil { return "", errors.Wrap(err, "unable to render fenced block roles") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_listing.go b/pkg/renderer/sgml/delimited_block_listing.go index c41c58ac..0b180606 100644 --- a/pkg/renderer/sgml/delimited_block_listing.go +++ b/pkg/renderer/sgml/delimited_block_listing.go @@ -26,7 +26,7 @@ func (r *sgmlRenderer) renderListingBlock(ctx *renderer.Context, b *types.Delimi if err != nil { return "", errors.Wrap(err, "unable to render listing block roles") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -57,7 +57,7 @@ func (r *sgmlRenderer) renderListingParagraph(ctx *renderer.Context, p *types.Pa if err != nil { return "", errors.Wrap(err, "unable to render listing block roles") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_markdown_quote.go b/pkg/renderer/sgml/delimited_block_markdown_quote.go index dfd3815a..9f295b69 100644 --- a/pkg/renderer/sgml/delimited_block_markdown_quote.go +++ b/pkg/renderer/sgml/delimited_block_markdown_quote.go @@ -22,7 +22,7 @@ func (r *sgmlRenderer) renderMarkdownQuoteBlock(ctx *renderer.Context, b *types. if err != nil { return "", errors.Wrap(err, "unable to render fenced block content") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_quote.go b/pkg/renderer/sgml/delimited_block_quote.go index 19b21131..49e0c67d 100644 --- a/pkg/renderer/sgml/delimited_block_quote.go +++ b/pkg/renderer/sgml/delimited_block_quote.go @@ -23,7 +23,7 @@ func (r *sgmlRenderer) renderQuoteBlock(ctx *renderer.Context, b *types.Delimite if err != nil { return "", errors.Wrap(err, "unable to render fenced block content") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -58,7 +58,7 @@ func (r *sgmlRenderer) renderQuoteParagraph(ctx *renderer.Context, p *types.Para if err != nil { return "", errors.Wrap(err, "unable to render quote paragraph lines") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_sidebar.go b/pkg/renderer/sgml/delimited_block_sidebar.go index ae8dd4dc..e0ff962f 100644 --- a/pkg/renderer/sgml/delimited_block_sidebar.go +++ b/pkg/renderer/sgml/delimited_block_sidebar.go @@ -20,7 +20,7 @@ func (r *sgmlRenderer) renderSidebarBlock(ctx *renderer.Context, b *types.Delimi if err != nil { return "", errors.Wrap(err, "unable to render fenced block content") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_source.go b/pkg/renderer/sgml/delimited_block_source.go index d2f031bb..ef78630c 100644 --- a/pkg/renderer/sgml/delimited_block_source.go +++ b/pkg/renderer/sgml/delimited_block_source.go @@ -35,7 +35,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b *types.Delimit } } } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/delimited_block_verse.go b/pkg/renderer/sgml/delimited_block_verse.go index ee62c92c..52a8cc67 100644 --- a/pkg/renderer/sgml/delimited_block_verse.go +++ b/pkg/renderer/sgml/delimited_block_verse.go @@ -28,7 +28,7 @@ func (r *sgmlRenderer) renderVerseBlock(ctx *renderer.Context, b *types.Delimite if err != nil { return "", errors.Wrap(err, "unable to render verse block") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -63,7 +63,7 @@ func (r *sgmlRenderer) renderVerseParagraph(ctx *renderer.Context, p *types.Para if err != nil { return "", errors.Wrap(err, "unable to render verse block") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/html5/delimited_block_listing_test.go b/pkg/renderer/sgml/html5/delimited_block_listing_test.go index dbb172e1..fd119587 100644 --- a/pkg/renderer/sgml/html5/delimited_block_listing_test.go +++ b/pkg/renderer/sgml/html5/delimited_block_listing_test.go @@ -188,6 +188,21 @@ import

<a> an import

+` + Expect(RenderHTML(source)).To(MatchHTML(expected)) + }) + + It("with quoted text and link in title", func() { + source := `.a *link* to https://github.com[GitHub] +---- +content +----` + expected := `
+ +
+
content
+
+
` Expect(RenderHTML(source)).To(MatchHTML(expected)) }) diff --git a/pkg/renderer/sgml/image.go b/pkg/renderer/sgml/image.go index 75d50be6..829773c6 100644 --- a/pkg/renderer/sgml/image.go +++ b/pkg/renderer/sgml/image.go @@ -16,7 +16,7 @@ import ( func (r *sgmlRenderer) renderImageBlock(ctx *renderer.Context, img *types.ImageBlock) (string, error) { result := &strings.Builder{} - title, err := r.renderElementTitle(img.Attributes) + title, err := r.renderElementTitle(ctx, img.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render image") } @@ -99,7 +99,7 @@ func (r *sgmlRenderer) renderInlineImage(ctx *renderer.Context, img *types.Inlin if err != nil { return "", errors.Wrap(err, "unable to render image") } - title, err := r.renderElementTitle(img.Attributes) + title, err := r.renderElementTitle(ctx, img.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/list.go b/pkg/renderer/sgml/list.go index 4cc5b12e..b6a43773 100644 --- a/pkg/renderer/sgml/list.go +++ b/pkg/renderer/sgml/list.go @@ -50,7 +50,7 @@ func (r *sgmlRenderer) renderOrderedList(ctx *renderer.Context, l *types.List) ( if err != nil { return "", errors.Wrap(err, "unable to render ordered list roles") } - title, err := r.renderElementTitle(l.Attributes) + title, err := r.renderElementTitle(ctx, l.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -152,7 +152,7 @@ func (r *sgmlRenderer) renderUnorderedList(ctx *renderer.Context, l *types.List) if err != nil { return "", errors.Wrap(err, "unable to render unordered list roles") } - title, err := r.renderElementTitle(l.Attributes) + title, err := r.renderElementTitle(ctx, l.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -220,7 +220,7 @@ func (r *sgmlRenderer) renderLabeledList(ctx *renderer.Context, l *types.List) ( if err != nil { return "", errors.Wrap(err, "unable to render labeled list roles") } - title, err := r.renderElementTitle(l.Attributes) + title, err := r.renderElementTitle(ctx, l.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render labeled list roles") } @@ -305,7 +305,7 @@ func (r *sgmlRenderer) renderCalloutList(ctx *renderer.Context, l *types.List) ( if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } - title, err := r.renderElementTitle(l.Attributes) + title, err := r.renderElementTitle(ctx, l.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/literal_blocks.go b/pkg/renderer/sgml/literal_blocks.go index d5eaaf99..1b709bf4 100644 --- a/pkg/renderer/sgml/literal_blocks.go +++ b/pkg/renderer/sgml/literal_blocks.go @@ -21,7 +21,7 @@ func (r *sgmlRenderer) renderLiteralBlock(ctx *renderer.Context, b *types.Delimi if err != nil { return "", errors.Wrap(err, "unable to render literal block roles") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } @@ -59,7 +59,7 @@ func (r *sgmlRenderer) renderLiteralParagraph(ctx *renderer.Context, b *types.Pa if err != nil { return "", errors.Wrap(err, "unable to render literal block roles") } - title, err := r.renderElementTitle(b.Attributes) + title, err := r.renderElementTitle(ctx, b.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render callout list roles") } diff --git a/pkg/renderer/sgml/paragraph.go b/pkg/renderer/sgml/paragraph.go index c2e548e3..640d9d27 100644 --- a/pkg/renderer/sgml/paragraph.go +++ b/pkg/renderer/sgml/paragraph.go @@ -53,7 +53,7 @@ func (r *sgmlRenderer) renderRegularParagraph(ctx *renderer.Context, p *types.Pa if err != nil { return "", errors.Wrap(err, "unable to render paragraph roles") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render paragraph roles") } @@ -105,7 +105,7 @@ func (r *sgmlRenderer) renderEmbeddedParagraph(ctx *renderer.Context, p *types.P if err != nil { return "", errors.Wrap(err, "unable to render delimited block paragraph content") } - title, err := r.renderElementTitle(p.Attributes) + title, err := r.renderElementTitle(ctx, p.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render delimited block paragraph content") } @@ -142,16 +142,20 @@ func renderCheckStyle(style interface{}) string { } } -func (r *sgmlRenderer) renderElementTitle(attrs types.Attributes) (string, error) { - if title, found, err := attrs.GetAsString(types.AttrTitle); err != nil { - return "", err - } else if found { - result := EscapeString(strings.TrimSpace(title)) - // log.Debugf("rendered title: '%s'", result) - return result, nil +func (r *sgmlRenderer) renderElementTitle(ctx *renderer.Context, attrs types.Attributes) (string, error) { + title, found := attrs[types.AttrTitle] + if !found { + log.Debug("no title to render") + return "", nil + } + switch title := title.(type) { + case string: + return title, nil + case []interface{}: + return r.renderElements(ctx, title) + default: + return "", errors.New("unable to render title") } - log.Debug("no title to render") - return "", nil } type lineRenderer struct { diff --git a/pkg/renderer/sgml/table.go b/pkg/renderer/sgml/table.go index 0cdbc65c..752bc47c 100644 --- a/pkg/renderer/sgml/table.go +++ b/pkg/renderer/sgml/table.go @@ -86,7 +86,7 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t *types.Table) (strin if err != nil { return "", errors.Wrap(err, "unable to render table roles") } - title, err := r.renderElementTitle(t.Attributes) + title, err := r.renderElementTitle(ctx, t.Attributes) if err != nil { return "", errors.Wrap(err, "unable to render table title") }