Fix .WordCount, .FuzzyWordCount, .ReadingTime when summary marker is set
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 27 Apr 2018 08:17:01 +0000 (10:17 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 29 Apr 2018 08:58:58 +0000 (10:58 +0200)
This bug was introduced in Hugo 0.40. It is when you use the `<!--more-->` summary marker.

Note that this affects the word stats only. The related `PlainWords`, `Plain`, `Content` all return correct values.

Fixes #4675
Fixes #4682

helpers/content.go
hugolib/page.go
hugolib/page_test.go

index f12a55ba8dcf2498bf2c3ebd974e4e918cac985f..d42995519f477c72f1c4b56178600ad054a403e8 100644 (file)
@@ -493,7 +493,10 @@ func totalWordsOld(s string) int {
 }
 
 // TruncateWordsByRune truncates words by runes.
-func (c *ContentSpec) TruncateWordsByRune(words []string) (string, bool) {
+func (c *ContentSpec) TruncateWordsByRune(in []string) (string, bool) {
+       words := make([]string, len(in))
+       copy(words, in)
+
        count := 0
        for index, word := range words {
                if count >= c.summaryLength {
index 9d25cd49a2f82337444218188a260b359a1e8f26..2e008ece9b42d70e6202f47a09a56515ef67af2d 100644 (file)
@@ -982,22 +982,33 @@ func (p *Page) ReadFrom(buf io.Reader) (int64, error) {
 }
 
 func (p *Page) WordCount() int {
-       p.analyzePage()
+       p.initContentPlainAndMeta()
        return p.wordCount
 }
 
 func (p *Page) ReadingTime() int {
-       p.analyzePage()
+       p.initContentPlainAndMeta()
        return p.readingTime
 }
 
 func (p *Page) FuzzyWordCount() int {
-       p.analyzePage()
+       p.initContentPlainAndMeta()
        return p.fuzzyWordCount
 }
 
-func (p *Page) analyzePage() {
+func (p *Page) initContentPlainAndMeta() {
        p.initContent()
+       p.initPlain(true)
+       p.initPlainWords(true)
+       p.initMeta()
+}
+
+func (p *Page) initContentAndMeta() {
+       p.initContent()
+       p.initMeta()
+}
+
+func (p *Page) initMeta() {
        p.pageMetaInit.Do(func() {
                if p.isCJKLanguage {
                        p.wordCount = 0
index 6b2f2976492f07228d54017c77878a9841b80291..985373a90a58f906502add36243e1092792410c3 100644 (file)
@@ -1735,6 +1735,101 @@ tags:
        }
 }
 
+// https://github.com/gohugoio/hugo/issues/4675
+func TestWordCountAndSimilarVsSummary(t *testing.T) {
+
+       t.Parallel()
+       assert := require.New(t)
+
+       single := []string{"_default/single.html", `
+WordCount: {{ .WordCount }}
+FuzzyWordCount: {{ .FuzzyWordCount }}
+ReadingTime: {{ .ReadingTime }}
+Len Plain: {{ len .Plain }}
+Len PlainWords: {{ len .PlainWords }}
+Truncated: {{ .Truncated }}
+Len Summary: {{ len .Summary }}
+Len Content: {{ len .Content }}
+`}
+
+       b := newTestSitesBuilder(t)
+       b.WithSimpleConfigFile().WithTemplatesAdded(single...).WithContent("p1.md", fmt.Sprintf(`---
+title: p1      
+---
+
+%s
+
+`, strings.Repeat("word ", 510)),
+
+               "p2.md", fmt.Sprintf(`---
+title: p2
+---
+This is a summary.
+
+<!--more-->
+
+%s
+
+`, strings.Repeat("word ", 310)),
+               "p3.md", fmt.Sprintf(`---
+title: p3
+isCJKLanguage: true
+---
+Summary: In Chinese, 好 means good.
+
+<!--more-->
+
+%s
+
+`, strings.Repeat("好", 200)),
+               "p4.md", fmt.Sprintf(`---
+title: p4
+isCJKLanguage: false
+---
+Summary: In Chinese, 好 means good.
+
+<!--more-->
+
+%s
+
+`, strings.Repeat("好", 200)),
+
+               "p5.md", fmt.Sprintf(`---
+title: p4
+isCJKLanguage: true
+---
+Summary: In Chinese, 好 means good.
+
+%s
+
+`, strings.Repeat("好", 200)),
+               "p6.md", fmt.Sprintf(`---
+title: p4
+isCJKLanguage: false
+---
+Summary: In Chinese, 好 means good.
+
+%s
+
+`, strings.Repeat("好", 200)),
+       )
+
+       b.CreateSites().Build(BuildCfg{})
+
+       assert.Equal(1, len(b.H.Sites))
+       require.Len(t, b.H.Sites[0].RegularPages, 6)
+
+       b.AssertFileContent("public/p1/index.html", "WordCount: 510\nFuzzyWordCount: 600\nReadingTime: 3\nLen Plain: 2550\nLen PlainWords: 510\nTruncated: false\nLen Summary: 2549\nLen Content: 2557")
+
+       b.AssertFileContent("public/p2/index.html", "WordCount: 314\nFuzzyWordCount: 400\nReadingTime: 2\nLen Plain: 1570\nLen PlainWords: 314\nTruncated: true\nLen Summary: 34\nLen Content: 1592")
+
+       b.AssertFileContent("public/p3/index.html", "WordCount: 206\nFuzzyWordCount: 300\nReadingTime: 1\nLen Plain: 639\nLen PlainWords: 7\nTruncated: true\nLen Summary: 52\nLen Content: 661")
+       b.AssertFileContent("public/p4/index.html", "WordCount: 7\nFuzzyWordCount: 100\nReadingTime: 1\nLen Plain: 639\nLen PlainWords: 7\nTruncated: true\nLen Summary: 52\nLen Content: 661")
+       b.AssertFileContent("public/p5/index.html", "WordCount: 206\nFuzzyWordCount: 300\nReadingTime: 1\nLen Plain: 638\nLen PlainWords: 7\nTruncated: true\nLen Summary: 229\nLen Content: 653")
+       b.AssertFileContent("public/p6/index.html", "WordCount: 7\nFuzzyWordCount: 100\nReadingTime: 1\nLen Plain: 638\nLen PlainWords: 7\nTruncated: false\nLen Summary: 637\nLen Content: 653")
+
+}
+
 func BenchmarkParsePage(b *testing.B) {
        s := newTestSite(b)
        f, _ := os.Open("testdata/redis.cn.md")