From 99fbc75e7abe3c1e8ce58e91634cc46c44fa920c Mon Sep 17 00:00:00 2001 From: Anton Staaf Date: Thu, 26 Jan 2017 11:58:25 -0800 Subject: [PATCH] hugolib: Fix regression of .Truncated evaluation in manual summaries This fixes the behavior of .Truncated that was introduced with commit bef496b97e1dc2df8c52b080152d539a58752801 which was later broken. The desired behavior is that .Truncated would evaluate to false when there was nothing after the user defined summary marker. This also adds a simple unit test to ensure that this feature isn't broken again. The check for content after the user defined summary marker is done on the raw content instead of the working copy because some of the markup renderers add elements after the marker, making it difficult to determine if there is actually any content. The behavior (evaluating to false when there is no content, just summary) is also now documented. --- docs/content/content/summaries.md | 1 + hugolib/handler_page.go | 6 +--- hugolib/page.go | 40 ++++++++++++---------- hugolib/page_test.go | 57 +++++++++++++++++++------------ 4 files changed, 59 insertions(+), 45 deletions(-) diff --git a/docs/content/content/summaries.md b/docs/content/content/summaries.md index e64d43331..0f2e6433b 100644 --- a/docs/content/content/summaries.md +++ b/docs/content/content/summaries.md @@ -33,6 +33,7 @@ Alternatively, you may add the <!--more--><!--more--> exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored. +If there is nothing but spaces and newlines after the summary divider then `.Truncated` will be false. ## Showing Summaries diff --git a/hugolib/handler_page.go b/hugolib/handler_page.go index 01c041ffc..a47758f84 100644 --- a/hugolib/handler_page.go +++ b/hugolib/handler_page.go @@ -14,7 +14,6 @@ package hugolib import ( - "bytes" "fmt" "github.com/spf13/hugo/helpers" @@ -127,10 +126,7 @@ func commonConvert(p *Page) HandledResult { p.workContent = helpers.Emojify(p.workContent) } - // We have to replace the with something that survives all the - // rendering engines. - // TODO(bep) inline replace - p.workContent = bytes.Replace(p.workContent, []byte(helpers.SummaryDivider), internalSummaryDivider, 1) + p.workContent = p.replaceDivider(p.workContent) p.workContent = p.renderContent(p.workContent) return HandledResult{err: nil} diff --git a/hugolib/page.go b/hugolib/page.go index f532758d8..6af6a2da5 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -414,6 +414,23 @@ var ( internalSummaryDivider = []byte("HUGOMORE42") ) +// We have to replace the with something that survives all the +// rendering engines. +// TODO(bep) inline replace +func (p *Page) replaceDivider(content []byte) []byte { + sections := bytes.Split(content, helpers.SummaryDivider) + + // If the raw content has nothing but whitespace after the summary + // marker then the page shouldn't be marked as truncated. This check + // is simplest against the raw content because different markup engines + // (rst and asciidoc in particular) add div and p elements after the + // summary marker. + p.Truncated = (len(sections) == 2 && + len(bytes.Trim(sections[1], " \n\r")) > 0) + + return bytes.Join(sections, internalSummaryDivider) +} + // Returns the page as summary and main if a user defined split is provided. func (p *Page) setUserDefinedSummaryIfProvided(rawContentCopy []byte) (*summaryContent, error) { @@ -428,12 +445,6 @@ func (p *Page) setUserDefinedSummaryIfProvided(rawContentCopy []byte) (*summaryC return nil, nil } - p.Truncated = true - if len(sc.content) < 20 { - // only whitespace? - p.Truncated = len(bytes.Trim(sc.content, " \n\r")) > 0 - } - p.Summary = helpers.BytesToHTML(sc.summary) return sc, nil @@ -441,9 +452,8 @@ func (p *Page) setUserDefinedSummaryIfProvided(rawContentCopy []byte) (*summaryC // Make this explicit so there is no doubt about what is what. type summaryContent struct { - summary []byte - content []byte - contentWithoutSummary []byte + summary []byte + content []byte } func splitUserDefinedSummaryAndContent(markup string, c []byte) (sc *summaryContent, err error) { @@ -467,7 +477,6 @@ func splitUserDefinedSummaryAndContent(markup string, c []byte) (sc *summaryCont startMarkup []byte endMarkup []byte addDiv bool - divStart = []byte("
") ) switch markup { @@ -499,20 +508,16 @@ func splitUserDefinedSummaryAndContent(markup string, c []byte) (sc *summaryCont withoutDivider := bytes.TrimSpace(append(c[:startDivider], c[endDivider:]...)) var ( - contentWithoutSummary []byte - summary []byte + summary []byte ) if len(withoutDivider) > 0 { - contentWithoutSummary = bytes.TrimSpace(withoutDivider[endSummary:]) summary = bytes.TrimSpace(withoutDivider[:endSummary]) } if addDiv { // For the rst summary = append(append([]byte(nil), summary...), []byte("
")...) - // TODO(bep) include the document class, maybe - contentWithoutSummary = append(divStart, contentWithoutSummary...) } if err != nil { @@ -520,9 +525,8 @@ func splitUserDefinedSummaryAndContent(markup string, c []byte) (sc *summaryCont } sc = &summaryContent{ - summary: summary, - content: withoutDivider, - contentWithoutSummary: contentWithoutSummary, + summary: summary, + content: withoutDivider, } return diff --git a/hugolib/page_test.go b/hugolib/page_test.go index 0fa622e33..d86a7b2d2 100644 --- a/hugolib/page_test.go +++ b/hugolib/page_test.go @@ -164,6 +164,14 @@ title: Simple Summary Same Line Some more text +` + + simplePageWithSummaryDelimiterOnlySummary = `--- +title: Simple +--- +Summary text + + ` simplePageWithAllCJKRunes = `--- @@ -665,46 +673,42 @@ func TestCreateNewPage(t *testing.T) { func TestSplitSummaryAndContent(t *testing.T) { t.Parallel() for i, this := range []struct { - markup string - content string - expectedSummary string - expectedContent string - expectedContentWithoutSummary string + markup string + content string + expectedSummary string + expectedContent string }{ {"markdown", `

Summary Same LineHUGOMORE42

-

Some more text

`, "

Summary Same Line

", "

Summary Same Line

\n\n

Some more text

", "

Some more text

"}, +

Some more text

`, "

Summary Same Line

", "

Summary Same Line

\n\n

Some more text

"}, {"asciidoc", `

sn

HUGOMORE42Some more text

`, "

sn

", - "

sn

Some more text

", - "

Some more text

"}, + "

sn

Some more text

"}, {"rst", "

Summary Next Line

HUGOMORE42Some more text

", "

Summary Next Line

", - "

Summary Next Line

Some more text

", - "

Some more text

"}, - {"markdown", "

a

b

HUGOMORE42c

", "

a

b

", "

a

b

c

", "

c

"}, - {"markdown", "

a

b

cHUGOMORE42

", "

a

b

c

", "

a

b

c

", ""}, - {"markdown", "

a

bHUGOMORE42

c

", "

a

b

", "

a

b

c

", "

c

"}, - {"markdown", "

aHUGOMORE42

b

c

", "

a

", "

a

b

c

", "

b

c

"}, - {"markdown", " HUGOMORE42 ", "", "", ""}, - {"markdown", "HUGOMORE42", "", "", ""}, - {"markdown", "

HUGOMORE42", "

", "

", ""}, - {"markdown", "HUGOMORE42

", "", "

", "

"}, - {"markdown", "\n\n

HUGOMORE42

\n", "

", "

", ""}, + "

Summary Next Line

Some more text

"}, + {"markdown", "

a

b

HUGOMORE42c

", "

a

b

", "

a

b

c

"}, + {"markdown", "

a

b

cHUGOMORE42

", "

a

b

c

", "

a

b

c

"}, + {"markdown", "

a

bHUGOMORE42

c

", "

a

b

", "

a

b

c

"}, + {"markdown", "

aHUGOMORE42

b

c

", "

a

", "

a

b

c

"}, + {"markdown", " HUGOMORE42 ", "", ""}, + {"markdown", "HUGOMORE42", "", ""}, + {"markdown", "

HUGOMORE42", "

", "

"}, + {"markdown", "HUGOMORE42

", "", "

"}, + {"markdown", "\n\n

HUGOMORE42

\n", "

", "

"}, // Issue #2586 // Note: Hugo will not split mid-sentence but will look for the closest // paragraph end marker. This may be a change from Hugo 0.16, but it makes sense. {"markdown", `

this is an example HUGOMORE42of the issue.

`, "

this is an example of the issue.

", - "

this is an example of the issue.

", ""}, + "

this is an example of the issue.

"}, // Issue: #2538 {"markdown", fmt.Sprintf(`

%s

HUGOMORE42

%s

`, strings.Repeat("A", 10), strings.Repeat("B", 31)), fmt.Sprintf(`

%s

`, strings.Repeat("A", 10)), fmt.Sprintf(`

%s

%s

`, strings.Repeat("A", 10), strings.Repeat("B", 31)), - fmt.Sprintf(`

%s

`, strings.Repeat("B", 31)), }, } { @@ -714,7 +718,6 @@ func TestSplitSummaryAndContent(t *testing.T) { require.NotNil(t, sc, fmt.Sprintf("[%d] Nil %s", i, this.markup)) require.Equal(t, this.expectedSummary, string(sc.summary), fmt.Sprintf("[%d] Summary markup %s", i, this.markup)) require.Equal(t, this.expectedContent, string(sc.content), fmt.Sprintf("[%d] Content markup %s", i, this.markup)) - require.Equal(t, this.expectedContentWithoutSummary, string(sc.contentWithoutSummary), fmt.Sprintf("[%d] Content without summary, markup %s", i, this.markup)) } } @@ -850,6 +853,16 @@ func TestPageWithMoreTag(t *testing.T) { testAllMarkdownEnginesForPages(t, assertFunc, nil, simplePageWithSummaryDelimiterSameLine) } +func TestPageWithMoreTagOnlySummary(t *testing.T) { + + assertFunc := func(t *testing.T, ext string, pages Pages) { + p := pages[0] + checkTruncation(t, p, false, "page with summary delimiter at end") + } + + testAllMarkdownEnginesForPages(t, assertFunc, nil, simplePageWithSummaryDelimiterOnlySummary) +} + func TestPageWithDate(t *testing.T) { t.Parallel() cfg, fs := newTestCfg()