mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
helpers: Fix TrimShortHTML when used with AsciiDoc content
Fixes #12369
This commit is contained in:
parent
8e50ccfae7
commit
6049ba99f0
5 changed files with 40 additions and 33 deletions
|
@ -36,11 +36,6 @@ import (
|
||||||
"github.com/gohugoio/hugo/config"
|
"github.com/gohugoio/hugo/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
openingPTag = []byte("<p>")
|
|
||||||
closingPTag = []byte("</p>")
|
|
||||||
)
|
|
||||||
|
|
||||||
// ContentSpec provides functionality to render markdown content.
|
// ContentSpec provides functionality to render markdown content.
|
||||||
type ContentSpec struct {
|
type ContentSpec struct {
|
||||||
Converters markup.ConverterProvider
|
Converters markup.ConverterProvider
|
||||||
|
@ -242,19 +237,26 @@ func (c *ContentSpec) TruncateWordsToWholeSentence(s string) (string, bool) {
|
||||||
return strings.TrimSpace(s[:endIndex]), endIndex < len(s)
|
return strings.TrimSpace(s[:endIndex]), endIndex < len(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrimShortHTML removes the <p>/</p> tags from HTML input in the situation
|
// TrimShortHTML removes the outer tags from HTML input where (a) the opening
|
||||||
// where said tags are the only <p> tags in the input and enclose the content
|
// tag is present only once with the input, and (b) the opening and closing
|
||||||
// of the input (whitespace excluded).
|
// tags wrap the input after white space removal.
|
||||||
func (c *ContentSpec) TrimShortHTML(input []byte) []byte {
|
func (c *ContentSpec) TrimShortHTML(input []byte, markup string) []byte {
|
||||||
if bytes.Count(input, openingPTag) == 1 {
|
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)
|
input = bytes.TrimSpace(input)
|
||||||
if bytes.HasPrefix(input, openingPTag) && bytes.HasSuffix(input, closingPTag) {
|
if bytes.HasPrefix(input, openingTag) && bytes.HasSuffix(input, closingTag) {
|
||||||
input = bytes.TrimPrefix(input, openingPTag)
|
input = bytes.TrimPrefix(input, openingTag)
|
||||||
input = bytes.TrimSuffix(input, closingPTag)
|
input = bytes.TrimSuffix(input, closingTag)
|
||||||
input = bytes.TrimSpace(input)
|
input = bytes.TrimSpace(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,24 +26,27 @@ import (
|
||||||
|
|
||||||
func TestTrimShortHTML(t *testing.T) {
|
func TestTrimShortHTML(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
input, output []byte
|
markup string
|
||||||
|
input []byte
|
||||||
|
output []byte
|
||||||
}{
|
}{
|
||||||
{[]byte(""), []byte("")},
|
{"markdown", []byte(""), []byte("")},
|
||||||
{[]byte("Plain text"), []byte("Plain text")},
|
{"markdown", []byte("Plain text"), []byte("Plain text")},
|
||||||
// This seems wrong. Why touch it if it doesn't have p tag?
|
{"markdown", []byte("<p>Simple paragraph</p>"), []byte("Simple paragraph")},
|
||||||
// {[]byte(" \t\n Whitespace text\n\n"), []byte("Whitespace text")},
|
{"markdown", []byte("\n \n \t <p> \t Whitespace\nHTML \n\t </p>\n\t"), []byte("Whitespace\nHTML")},
|
||||||
{[]byte("<p>Simple paragraph</p>"), []byte("Simple paragraph")},
|
{"markdown", []byte("<p>Multiple</p><p>paragraphs</p>"), []byte("<p>Multiple</p><p>paragraphs</p>")},
|
||||||
{[]byte("\n \n \t <p> \t Whitespace\nHTML \n\t </p>\n\t"), []byte("Whitespace\nHTML")},
|
{"markdown", []byte("<p>Nested<p>paragraphs</p></p>"), []byte("<p>Nested<p>paragraphs</p></p>")},
|
||||||
{[]byte("<p>Multiple</p><p>paragraphs</p>"), []byte("<p>Multiple</p><p>paragraphs</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>")},
|
||||||
{[]byte("<p>Nested<p>paragraphs</p></p>"), []byte("<p>Nested<p>paragraphs</p></p>")},
|
// Issue 11698
|
||||||
{[]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>")},
|
{"markdown", []byte("<h2 id=`a`>b</h2>\n\n<p>c</p>"), []byte("<h2 id=`a`>b</h2>\n\n<p>c</p>")},
|
||||||
// Issue #11698
|
// Issue 12369
|
||||||
{[]byte("<h2 id=`a`>b</h2>\n\n<p>c</p>"), []byte("<h2 id=`a`>b</h2>\n\n<p>c</p>")},
|
{"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)
|
c := newTestContentSpec(nil)
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
output := c.TrimShortHTML(test.input)
|
output := c.TrimShortHTML(test.input, test.markup)
|
||||||
if !bytes.Equal(test.output, output) {
|
if !bytes.Equal(test.output, output) {
|
||||||
t.Errorf("Test %d failed. Expected %q got %q", i, 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)
|
c := newTestContentSpec(nil)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
c.TrimShortHTML([]byte("<p>Simple paragraph</p>"))
|
c.TrimShortHTML([]byte("<p>Simple paragraph</p>"), "markdown")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -778,7 +778,7 @@ func (c *cachedContent) contentPlain(ctx context.Context, cp *pageContentOutput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
result.summary = helpers.BytesToHTML(html)
|
||||||
} else {
|
} else {
|
||||||
var summary string
|
var summary string
|
||||||
|
|
|
@ -363,9 +363,11 @@ func (pco *pageContentOutput) RenderString(ctx context.Context, args ...any) (te
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Display == "inline" {
|
if opts.Display == "inline" {
|
||||||
// We may have to rethink this in the future when we get other
|
markup := pco.po.p.m.pageConfig.Markup
|
||||||
// renderers.
|
if opts.Markup != "" {
|
||||||
rendered = pco.po.p.s.ContentSpec.TrimShortHTML(rendered)
|
markup = pco.po.p.s.ContentSpec.ResolveMarkup(opts.Markup)
|
||||||
|
}
|
||||||
|
rendered = pco.po.p.s.ContentSpec.TrimShortHTML(rendered, markup)
|
||||||
}
|
}
|
||||||
|
|
||||||
return template.HTML(string(rendered)), nil
|
return template.HTML(string(rendered)), nil
|
||||||
|
|
|
@ -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.
|
// 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
|
return helpers.BytesToHTML(bb), nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue