diff options
author | Jim McDonald <[email protected]> | 2019-04-05 18:11:04 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2019-04-05 19:11:04 +0200 |
commit | 3a62d54745e2cbfda6772390830042908d725c71 (patch) | |
tree | d039be3ac163530fa292c0bfbd50f364fad57808 /helpers | |
parent | ebab291c0e321d23b098684bacaf830a3979e310 (diff) | |
download | hugo-3a62d54745e2cbfda6772390830042908d725c71.tar.gz hugo-3a62d54745e2cbfda6772390830042908d725c71.zip |
hugolib: Consider summary in front matter for .Summary
Add the ability to have a `summary` page variable that overrides
the auto-generated summary. Logic for obtaining summary becomes:
* if summary divider is present in content, use the text above it
* if summary variables is present in page metadata, use that
* auto-generate summary from first _x_ words of the content
Fixes #5800
Diffstat (limited to 'helpers')
-rw-r--r-- | helpers/content.go | 21 | ||||
-rw-r--r-- | helpers/content_test.go | 22 |
2 files changed, 43 insertions, 0 deletions
diff --git a/helpers/content.go b/helpers/content.go index be5090c21..3892647bb 100644 --- a/helpers/content.go +++ b/helpers/content.go @@ -42,6 +42,12 @@ import ( // SummaryDivider denotes where content summarization should end. The default is "<!--more-->". var SummaryDivider = []byte("<!--more-->") +var ( + openingPTag = []byte("<p>") + closingPTag = []byte("</p>") + paragraphIndicator = []byte("<p") +) + // ContentSpec provides functionality to render markdown content. type ContentSpec struct { BlackFriday *BlackFriday @@ -580,6 +586,21 @@ 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 { + first := bytes.Index(input, paragraphIndicator) + last := bytes.LastIndex(input, paragraphIndicator) + if first == last { + input = bytes.TrimSpace(input) + input = bytes.TrimPrefix(input, openingPTag) + input = bytes.TrimSuffix(input, closingPTag) + input = bytes.TrimSpace(input) + } + return input +} + func isEndOfSentence(r rune) bool { return r == '.' || r == '?' || r == '!' || r == '"' || r == '\n' } diff --git a/helpers/content_test.go b/helpers/content_test.go index 1dd4a2fb8..709c81142 100644 --- a/helpers/content_test.go +++ b/helpers/content_test.go @@ -29,6 +29,28 @@ import ( const tstHTMLContent = "<!DOCTYPE html><html><head><script src=\"http://two/foobar.js\"></script></head><body><nav><ul><li hugo-nav=\"section_0\"></li><li hugo-nav=\"section_1\"></li></ul></nav><article>content <a href=\"http://two/foobar\">foobar</a>. Follow up</article><p>This is some text.<br>And some more.</p></body></html>" +func TestTrimShortHTML(t *testing.T) { + tests := []struct { + input, output []byte + }{ + {[]byte(""), []byte("")}, + {[]byte("Plain text"), []byte("Plain text")}, + {[]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>")}, + } + + c := newTestContentSpec() + for i, test := range tests { + output := c.TrimShortHTML(test.input) + if bytes.Compare(test.output, output) != 0 { + t.Errorf("Test %d failed. Expected %q got %q", i, test.output, output) + } + } +} + func TestStripHTML(t *testing.T) { type test struct { input, expected string |