gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
75.94k stars 7.54k forks source link

Some Obsidian styled alerts result in invalid HTML #12828

Closed McShelby closed 2 months ago

McShelby commented 2 months ago

Given the following Markdown:

> [!caution] Callouts can have custom titles
> Like this one.

> [!caution] Title-only callout

> [!note]- Are callouts foldable?
> Yes! In a foldable callout, the contents are hidden when the callout is collapsed

> [!note]+ Are callouts foldable?
> Yes! In a foldable callout, the contents are hidden when the callout is collapsed

> [!info] Can callouts be nested?
> > [!important] Yes!, they can.
> > > [!tip]  You can even use multiple layers of nesting.

and the following render-blockquote.html

{{ warnf "%s" .AlertTitle }}

somtimes results in a closing </p> at the end of the title

WARN  Callouts can have custom titles
WARN  Title-only callout</p>
WARN  Are callouts foldable?
WARN  You can even use multiple layers of nesting.</p>
WARN  Yes!, they can.</p>
WARN  Can callouts be nested?</p>

What version of Hugo are you using (hugo version)?

$ hugo version
hugo v0.134.0-77df7bbbff8ce6b56ed693270088de973a87d5ce+extended windows/amd64 BuildDate=2024-09-03T09:54:22Z VendorInfo=gohugoio

Does this issue reproduce with the latest release?

Yes

LicketySpliket commented 2 months ago

Not a super frequent contributor to Hugo, but I think the issue is in the following lines:

(blockquotes.go:162)

var blockQuoteAlertRe = regexp.MustCompile(`^<p>\[!([a-zA-Z]+)\](-|\+)?[^\S\r\n]?([^\n]*)\n?`)

func resolveBlockQuoteAlert(s string) blockQuoteAlert {
    m := blockQuoteAlertRe.FindStringSubmatch(s)
    if len(m) == 4 {
        return blockQuoteAlert{
            typ:   strings.ToLower(m[1]),
            sign:  m[2],
            title: m[3],
        }
    }

    return blockQuoteAlert{}
}

This Regex terminates the title group at \n, not </p>, so the </p> gets included and passed to the renderer. I fixed it by using this Regex: ^<p>\[!([a-zA-Z]+)\](-|\+)?[^\S\r\n]?([^(\n|<\/p>)]*)\n?. It checks for termination of the title group at both \n and </p>.

bep commented 2 months ago

@LicketySpliket thanks, I tested your regexp, and it didn't pass all the test cases. I opted for a ... simplar non-regexp approach.

LicketySpliket commented 2 months ago

No worries bep, thanks for testing it.

github-actions[bot] commented 1 month ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.