Skip to content

Commit

Permalink
helpers: Fix TrimShortHTML when used with AsciiDoc content
Browse files Browse the repository at this point in the history
  • Loading branch information
jmooring authored and bep committed Apr 14, 2024
1 parent 8e50ccf commit 6049ba9
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 33 deletions.
30 changes: 16 additions & 14 deletions helpers/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down
31 changes: 17 additions & 14 deletions helpers/content_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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")
}
}

Expand Down
2 changes: 1 addition & 1 deletion hugolib/page__content.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions hugolib/page__per_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tpl/transform/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit 6049ba9

Please sign in to comment.