]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
helpers: Fix TrimShortHTML when used with AsciiDoc content
authorJoe Mooring <joe.mooring@veriphor.com>
Sun, 14 Apr 2024 04:17:39 +0000 (21:17 -0700)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 14 Apr 2024 15:53:05 +0000 (17:53 +0200)
Fixes #12369

helpers/content.go
helpers/content_test.go
hugolib/page__content.go
hugolib/page__per_output.go
tpl/transform/transform.go

index 889294382ce9721b2c5aff5ab7573854d8b1a387..be79ad540835e9b0bad1564cf1d2a1db2fba6f83 100644 (file)
@@ -36,11 +36,6 @@ import (
        "github.com/gohugoio/hugo/config"
 )
 
-var (
-       openingPTag = []byte("<p>")
-       closingPTag = []byte("</p>")
-)
-
 // ContentSpec provides functionality to render markdown content.
 type ContentSpec struct {
        Converters          markup.ConverterProvider
@@ -242,19 +237,26 @@ func (c *ContentSpec) TruncateWordsToWholeSentence(s string) (string, bool) {
        return strings.TrimSpace(s[:endIndex]), endIndex < len(s)
 }
 
-// TrimShortHTML removes the <p>/</p> tags from HTML input in the situation
-// where said tags are the only <p> tags in the input and enclose the content
-// of the input (whitespace excluded).
-func (c *ContentSpec) TrimShortHTML(input []byte) []byte {
-       if bytes.Count(input, openingPTag) == 1 {
+// TrimShortHTML removes the outer tags from HTML input where (a) the opening
+// tag is present only once with the input, and (b) the opening and closing
+// tags wrap the input after white space removal.
+func (c *ContentSpec) TrimShortHTML(input []byte, markup string) []byte {
+       openingTag := []byte("<p>")
+       closingTag := []byte("</p>")
+
+       if markup == "asciidocext" {
+               openingTag = []byte("<div class=\"paragraph\">\n<p>")
+               closingTag = []byte("</p>\n</div>")
+       }
+
+       if bytes.Count(input, openingTag) == 1 {
                input = bytes.TrimSpace(input)
-               if bytes.HasPrefix(input, openingPTag) && bytes.HasSuffix(input, closingPTag) {
-                       input = bytes.TrimPrefix(input, openingPTag)
-                       input = bytes.TrimSuffix(input, closingPTag)
+               if bytes.HasPrefix(input, openingTag) && bytes.HasSuffix(input, closingTag) {
+                       input = bytes.TrimPrefix(input, openingTag)
+                       input = bytes.TrimSuffix(input, closingTag)
                        input = bytes.TrimSpace(input)
                }
        }
-
        return input
 }
 
index 53e18e727e95d69efb5887da59e4ebcc8de5979a..f1cbfad04c708241d667e11f2929865688032791 100644 (file)
@@ -26,24 +26,27 @@ import (
 
 func TestTrimShortHTML(t *testing.T) {
        tests := []struct {
-               input, output []byte
+               markup string
+               input  []byte
+               output []byte
        }{
-               {[]byte(""), []byte("")},
-               {[]byte("Plain text"), []byte("Plain text")},
-               // This seems wrong. Why touch it if it doesn't have p tag?
-               // {[]byte("  \t\n Whitespace text\n\n"), []byte("Whitespace text")},
-               {[]byte("<p>Simple paragraph</p>"), []byte("Simple paragraph")},
-               {[]byte("\n  \n \t  <p> \t Whitespace\nHTML  \n\t </p>\n\t"), []byte("Whitespace\nHTML")},
-               {[]byte("<p>Multiple</p><p>paragraphs</p>"), []byte("<p>Multiple</p><p>paragraphs</p>")},
-               {[]byte("<p>Nested<p>paragraphs</p></p>"), []byte("<p>Nested<p>paragraphs</p></p>")},
-               {[]byte("<p>Hello</p>\n<ul>\n<li>list1</li>\n<li>list2</li>\n</ul>"), []byte("<p>Hello</p>\n<ul>\n<li>list1</li>\n<li>list2</li>\n</ul>")},
-               // Issue #11698
-               {[]byte("<h2 id=`a`>b</h2>\n\n<p>c</p>"), []byte("<h2 id=`a`>b</h2>\n\n<p>c</p>")},
+               {"markdown", []byte(""), []byte("")},
+               {"markdown", []byte("Plain text"), []byte("Plain text")},
+               {"markdown", []byte("<p>Simple paragraph</p>"), []byte("Simple paragraph")},
+               {"markdown", []byte("\n  \n \t  <p> \t Whitespace\nHTML  \n\t </p>\n\t"), []byte("Whitespace\nHTML")},
+               {"markdown", []byte("<p>Multiple</p><p>paragraphs</p>"), []byte("<p>Multiple</p><p>paragraphs</p>")},
+               {"markdown", []byte("<p>Nested<p>paragraphs</p></p>"), []byte("<p>Nested<p>paragraphs</p></p>")},
+               {"markdown", []byte("<p>Hello</p>\n<ul>\n<li>list1</li>\n<li>list2</li>\n</ul>"), []byte("<p>Hello</p>\n<ul>\n<li>list1</li>\n<li>list2</li>\n</ul>")},
+               // Issue 11698
+               {"markdown", []byte("<h2 id=`a`>b</h2>\n\n<p>c</p>"), []byte("<h2 id=`a`>b</h2>\n\n<p>c</p>")},
+               // Issue 12369
+               {"markdown", []byte("<div class=\"paragraph\">\n<p>foo</p>\n</div>"), []byte("<div class=\"paragraph\">\n<p>foo</p>\n</div>")},
+               {"asciidocext", []byte("<div class=\"paragraph\">\n<p>foo</p>\n</div>"), []byte("foo")},
        }
 
        c := newTestContentSpec(nil)
        for i, test := range tests {
-               output := c.TrimShortHTML(test.input)
+               output := c.TrimShortHTML(test.input, test.markup)
                if !bytes.Equal(test.output, output) {
                        t.Errorf("Test %d failed. Expected %q got %q", i, test.output, output)
                }
@@ -54,7 +57,7 @@ func BenchmarkTrimShortHTML(b *testing.B) {
        c := newTestContentSpec(nil)
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
-               c.TrimShortHTML([]byte("<p>Simple paragraph</p>"))
+               c.TrimShortHTML([]byte("<p>Simple paragraph</p>"), "markdown")
        }
 }
 
index 54f7be9618a16a25b2a84b6ed1ee40964b5c7e3f..799fc89b67598626623a743aa54b819ab0e8677b 100644 (file)
@@ -778,7 +778,7 @@ func (c *cachedContent) contentPlain(ctx context.Context, cp *pageContentOutput)
                        if err != nil {
                                return nil, err
                        }
-                       html := cp.po.p.s.ContentSpec.TrimShortHTML(b.Bytes())
+                       html := cp.po.p.s.ContentSpec.TrimShortHTML(b.Bytes(), cp.po.p.m.pageConfig.Markup)
                        result.summary = helpers.BytesToHTML(html)
                } else {
                        var summary string
index 7220c86fe43fabe5640383d02d1efc17eb62aff2..fac719ea95965ed7bad36f97eded252be7ef3094 100644 (file)
@@ -363,9 +363,11 @@ func (pco *pageContentOutput) RenderString(ctx context.Context, args ...any) (te
        }
 
        if opts.Display == "inline" {
-               // We may have to rethink this in the future when we get other
-               // renderers.
-               rendered = pco.po.p.s.ContentSpec.TrimShortHTML(rendered)
+               markup := pco.po.p.m.pageConfig.Markup
+               if opts.Markup != "" {
+                       markup = pco.po.p.s.ContentSpec.ResolveMarkup(opts.Markup)
+               }
+               rendered = pco.po.p.s.ContentSpec.TrimShortHTML(rendered, markup)
        }
 
        return template.HTML(string(rendered)), nil
index 7054c6988f27e766cb6c916c9db161c1c8ca6179..5ef9bff218ddfb3a2a1b12832bd461a4023574c4 100644 (file)
@@ -167,7 +167,7 @@ func (ns *Namespace) Markdownify(ctx context.Context, s any) (template.HTML, err
        }
 
        // Strip if this is a short inline type of text.
-       bb := ns.deps.ContentSpec.TrimShortHTML([]byte(ss))
+       bb := ns.deps.ContentSpec.TrimShortHTML([]byte(ss), "markdown")
 
        return helpers.BytesToHTML(bb), nil
 }