Skip to content
/ hugo Public
forked from gohugoio/hugo

Commit

Permalink
markup/goldmark: Fix blockquote render hook text parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
jmooring committed Dec 9, 2024
1 parent b8c15f2 commit 4fbb4a8
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 23 deletions.
23 changes: 17 additions & 6 deletions markup/goldmark/blockquotes/blockquotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (r *htmlRenderer) renderBlockquote(w util.BufWriter, src []byte, node ast.N
ordinal := ctx.GetAndIncrementOrdinal(ast.KindBlockquote)

typ := typeRegular
alert := resolveBlockQuoteAlert(string(text))
alert := resolveBlockQuoteAlert(text)
if alert.typ != "" {
typ = typeAlert
}
Expand All @@ -85,10 +85,21 @@ func (r *htmlRenderer) renderBlockquote(w util.BufWriter, src []byte, node ast.N
}

if typ == typeAlert {
// Trim preamble: <p>[!NOTE]<br>\n but preserve leading paragraph.
// We could possibly complicate this by moving this to the parser, but
// keep it simple for now.
text = "<p>" + text[strings.Index(text, "\n")+1:]
// Parse the blockquote content to determine the alert text. The alert
// text begins after the first newline, but we need to add an opening p
// tag if the first line of the blockquote content does not have a
// closing p tag. At some point we might want to move this to the
// parser.
before, after, found := strings.Cut(strings.TrimSpace(text), "\n")
if found {
if strings.HasSuffix(before, "</p>") {
text = after
} else {
text = "<p>" + after
}
} else {
text = ""
}
}

bqctx := &blockquoteContext{
Expand Down Expand Up @@ -165,7 +176,7 @@ func resolveBlockQuoteAlert(s string) blockQuoteAlert {
m := blockQuoteAlertRe.FindStringSubmatch(s)
if len(m) == 4 {
title := strings.TrimSpace(m[3])
title = strings.TrimRight(title, "</p>")
title = strings.TrimSuffix(title, "</p>")
return blockQuoteAlert{
typ: strings.ToLower(m[1]),
sign: m[2],
Expand Down
126 changes: 109 additions & 17 deletions markup/goldmark/blockquotes/blockquotes_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ Content: {{ .Content }}
title: "p1"
---
> [!NOTE]
> [!NOTE]
> This is a note with some whitespace after the alert type.
> [!TIP]
> This is a tip.
Expand All @@ -64,29 +63,26 @@ title: "p1"
> This is a tip with attributes.
{class="foo bar" id="baz"}
> [!NOTE]
> [!NOTE]
> Note triggering showing the position.
{showpos="true"}
> [!nOtE]
> [!nOtE]
> Mixed case alert type.
`

b := hugolib.Test(t, files)
b.AssertFileContentExact("public/p1/index.html",
"Blockquote Alert: |<p>This is a note with some whitespace after the alert type.</p>\n|alert|",
"Blockquote Alert: |<p>This is a note with some whitespace after the alert type.</p>|alert|",
"Blockquote Alert: |<p>This is a tip.</p>",
"Blockquote Alert: |<p>This is a caution with some whitespace before the alert type.</p>\n|alert|",
"Blockquote Alert: |<p>This is a caution with some whitespace before the alert type.</p>|alert|",
"Blockquote: |<p>A regular blockquote.</p>\n|regular|",
"Blockquote Alert Attributes: |<p>This is a tip with attributes.</p>\n|map[class:foo bar id:baz]|",
filepath.FromSlash("/content/p1.md:20:3"),
"Blockquote Alert Page: |<p>This is a tip with attributes.</p>\n|p1|p1|",
"Blockquote Alert Attributes: |<p>This is a tip with attributes.</p>|map[class:foo bar id:baz]|",
filepath.FromSlash("/content/p1.md:19:3"),
"Blockquote Alert Page: |<p>This is a tip with attributes.</p>|p1|p1|",

// Issue 12767.
"Blockquote Alert: |<p>Mixed case alert type.</p>\n|alert",
"Blockquote Alert: |<p>Mixed case alert type.</p>|alert",
)
}

Expand Down Expand Up @@ -142,17 +138,113 @@ title: "Home"
{{ .Content }}
-- layouts/_default/_markup/render-blockquote.html --
AlertType: {{ .AlertType }}|AlertTitle: {{ .AlertTitle }}|AlertSign: {{ .AlertSign | safeHTML }}|Text: {{ .Text }}|
`

b := hugolib.Test(t, files)
b.AssertFileContentExact("public/index.html",
"AlertType: tip|AlertTitle: Callouts can have custom titles|AlertSign: |",
"AlertType: tip|AlertTitle: Title-only callout|AlertSign: |",
"AlertType: faq|AlertTitle: Foldable negated callout|AlertSign: -|Text: <p>Yes! In a foldable callout, the contents are hidden when the callout is collapsed</p>\n|",
"AlertType: faq|AlertTitle: Foldable callout|AlertSign: +|Text: <p>Yes! In a foldable callout, the contents are hidden when the callout is collapsed</p>\n|",
"AlertType: danger|AlertTitle: |AlertSign: |Text: <p>Do not approach or handle without protective gear.</p>\n|",
"AlertType: faq|AlertTitle: Foldable negated callout|AlertSign: -|Text: <p>Yes! In a foldable callout, the contents are hidden when the callout is collapsed</p>|",
"AlertType: faq|AlertTitle: Foldable callout|AlertSign: +|Text: <p>Yes! In a foldable callout, the contents are hidden when the callout is collapsed</p>|",
"AlertType: danger|AlertTitle: |AlertSign: |Text: <p>Do not approach or handle without protective gear.</p>|",
"AlertTitle: Can callouts be nested?|",
"AlertTitle: You can even use multiple layers of nesting.|",
)
}

// Issue 12913
// Issue 13119
func TestBlockquoteRenderHookTextParsing(t *testing.T) {
t.Parallel()

files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
-- layouts/index.html --
{{ .Content }}
-- layouts/_default/_markup/render-blockquote.html --
AlertType: {{ .AlertType }}|AlertTitle: {{ .AlertTitle }}|Text: {{ .Text }}|
-- content/_index.md --
---
title: home
---
> [!one]
> [!two] title
> [!three]
> line 1
> [!four] title
> line 1
> [!five]
> line 1
> line 2
> [!six] title
> line 1
> line 2
> [!seven]
> - list item
> [!eight] title
> - list item
> [!nine]
> line 1
> - list item
> [!ten] title
> line 1
> - list item
> [!eleven]
> line 1
> - list item
>
> line 2
> [!twelve] title
> line 1
> - list item
>
> line 2
> [!thirteen]
> ![alt](a.jpg)
> [!fourteen] title
> ![alt](a.jpg)
> [!fifteen] _title_
> [!sixteen] _title_
> line one
`

b := hugolib.Test(t, files)

b.AssertFileContent("public/index.html",
"AlertType: one|AlertTitle: |Text: |",
"AlertType: two|AlertTitle: title|Text: |",
"AlertType: three|AlertTitle: |Text: <p>line 1</p>|",
"AlertType: four|AlertTitle: title|Text: <p>line 1</p>|",
"AlertType: five|AlertTitle: |Text: <p>line 1\nline 2</p>|",
"AlertType: six|AlertTitle: title|Text: <p>line 1\nline 2</p>|",
"AlertType: seven|AlertTitle: |Text: <ul>\n<li>list item</li>\n</ul>|",
"AlertType: eight|AlertTitle: title|Text: <ul>\n<li>list item</li>\n</ul>|",
"AlertType: nine|AlertTitle: |Text: <p>line 1</p>\n<ul>\n<li>list item</li>\n</ul>|",
"AlertType: ten|AlertTitle: title|Text: <p>line 1</p>\n<ul>\n<li>list item</li>\n</ul>|",
"AlertType: eleven|AlertTitle: |Text: <p>line 1</p>\n<ul>\n<li>list item</li>\n</ul>\n<p>line 2</p>|",
"AlertType: twelve|AlertTitle: title|Text: <p>line 1</p>\n<ul>\n<li>list item</li>\n</ul>\n<p>line 2</p>|",
"AlertType: thirteen|AlertTitle: |Text: <p><img src=\"a.jpg\" alt=\"alt\"></p>|",
"AlertType: fourteen|AlertTitle: title|Text: <p><img src=\"a.jpg\" alt=\"alt\"></p>|",
"AlertType: fifteen|AlertTitle: <em>title</em>|Text: |",
"AlertType: sixteen|AlertTitle: <em>title</em>|Text: <p>line one</p>|",
)
}

0 comments on commit 4fbb4a8

Please sign in to comment.