Skip to content

Commit 8717a60

Browse files
bmonbep
authored andcommitted
Change SummaryLength to be configurable (#3924)
Move SummaryLength into the ContentSpec struct and refactor the relevant summary functions to be methods of ContentSpec. The new summaryLength struct member is configurable by the summaryLength config value, and the default remains 70. Also updates hugolib/page to use the refactored methods. Resolves #3734
1 parent 2818878 commit 8717a60

File tree

5 files changed

+32
-21
lines changed

5 files changed

+32
-21
lines changed

‎docs/content/getting-started/configuration.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ googleAnalytics: ""
111111
# if true, auto-detect Chinese/Japanese/Korean Languages in the content. (.Summary and .WordCount can work properly in CJKLanguage)
112112
hasCJKLanguage: false
113113
languageCode: ""
114+
# the length of text to show in a .Summary
115+
summaryLength: 70
114116
layoutDir: "layouts"
115117
# Enable Logging
116118
log: false
@@ -252,6 +254,8 @@ googleAnalytics = ""
252254
# if true, auto-detect Chinese/Japanese/Korean Languages in the content. (.Summary and .WordCount can work properly in CJKLanguage)
253255
hasCJKLanguage = false
254256
languageCode = ""
257+
# the length of text to show in a .Summary
258+
summaryLength: 70
255259
layoutDir = "layouts"
256260
# Enable Logging
257261
log = false

‎helpers/content.go‎

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ import (
3636
"strings"
3737
)
3838

39-
// SummaryLength is the length of the summary that Hugo extracts from a content.
40-
var SummaryLength = 70
41-
4239
// SummaryDivider denotes where content summarization should end. The default is "<!--more-->".
4340
var SummaryDivider = []byte("<!--more-->")
4441

@@ -47,6 +44,8 @@ type ContentSpec struct {
4744
blackfriday map[string]interface{}
4845
footnoteAnchorPrefix string
4946
footnoteReturnLinkContents string
47+
// SummaryLength is the length of the summary that Hugo extracts from a content.
48+
summaryLength int
5049

5150
Highlight func(code, lang, optsStr string) (string, error)
5251
defatultPygmentsOpts map[string]string
@@ -61,6 +60,7 @@ func NewContentSpec(cfg config.Provider) (*ContentSpec, error) {
6160
blackfriday: cfg.GetStringMap("blackfriday"),
6261
footnoteAnchorPrefix: cfg.GetString("footnoteAnchorPrefix"),
6362
footnoteReturnLinkContents: cfg.GetString("footnoteReturnLinkContents"),
63+
summaryLength: cfg.GetInt("summaryLength"),
6464

6565
cfg: cfg,
6666
}
@@ -480,20 +480,20 @@ func totalWordsOld(s string) int {
480480
}
481481

482482
// TruncateWordsByRune truncates words by runes.
483-
func TruncateWordsByRune(words []string, max int) (string, bool) {
483+
func (c *ContentSpec) TruncateWordsByRune(words []string) (string, bool) {
484484
count := 0
485485
for index, word := range words {
486-
if count >= max {
486+
if count >= c.summaryLength {
487487
return strings.Join(words[:index], " "), true
488488
}
489489
runeCount := utf8.RuneCountInString(word)
490490
if len(word) == runeCount {
491491
count++
492-
} else if count+runeCount < max {
492+
} else if count+runeCount < c.summaryLength {
493493
count += runeCount
494494
} else {
495495
for ri := range word {
496-
if count >= max {
496+
if count >= c.summaryLength {
497497
truncatedWords := append(words[:index], word[:ri])
498498
return strings.Join(truncatedWords, " "), true
499499
}
@@ -507,8 +507,7 @@ func TruncateWordsByRune(words []string, max int) (string, bool) {
507507

508508
// TruncateWordsToWholeSentence takes content and truncates to whole sentence
509509
// limited by max number of words. It also returns whether it is truncated.
510-
func TruncateWordsToWholeSentence(s string, max int) (string, bool) {
511-
510+
func (c *ContentSpec) TruncateWordsToWholeSentence(s string) (string, bool) {
512511
var (
513512
wordCount = 0
514513
lastWordIndex = -1
@@ -519,7 +518,7 @@ func TruncateWordsToWholeSentence(s string, max int) (string, bool) {
519518
wordCount++
520519
lastWordIndex = i
521520

522-
if wordCount >= max {
521+
if wordCount >= c.summaryLength {
523522
break
524523
}
525524

@@ -551,24 +550,24 @@ func isEndOfSentence(r rune) bool {
551550
}
552551

553552
// Kept only for benchmark.
554-
func truncateWordsToWholeSentenceOld(content string, max int) (string, bool) {
553+
func (c *ContentSpec) truncateWordsToWholeSentenceOld(content string) (string, bool) {
555554
words := strings.Fields(content)
556555

557-
if max >= len(words) {
556+
if c.summaryLength >= len(words) {
558557
return strings.Join(words, " "), false
559558
}
560559

561-
for counter, word := range words[max:] {
560+
for counter, word := range words[c.summaryLength:] {
562561
if strings.HasSuffix(word, ".") ||
563562
strings.HasSuffix(word, "?") ||
564563
strings.HasSuffix(word, ".\"") ||
565564
strings.HasSuffix(word, "!") {
566-
upper := max + counter + 1
565+
upper := c.summaryLength + counter + 1
567566
return strings.Join(words[:upper], " "), (upper < len(words))
568567
}
569568
}
570569

571-
return strings.Join(words[:max], " "), true
570+
return strings.Join(words[:c.summaryLength], " "), true
572571
}
573572

574573
func getAsciidocExecPath() string {

‎helpers/content_test.go‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,23 @@ func TestBytesToHTML(t *testing.T) {
7676
var benchmarkTruncateString = strings.Repeat("This is a sentence about nothing.", 20)
7777

7878
func BenchmarkTestTruncateWordsToWholeSentence(b *testing.B) {
79+
c := newTestContentSpec()
7980
b.ResetTimer()
8081
for i := 0; i < b.N; i++ {
81-
TruncateWordsToWholeSentence(benchmarkTruncateString, SummaryLength)
82+
c.TruncateWordsToWholeSentence(benchmarkTruncateString)
8283
}
8384
}
8485

8586
func BenchmarkTestTruncateWordsToWholeSentenceOld(b *testing.B) {
87+
c := newTestContentSpec()
8688
b.ResetTimer()
8789
for i := 0; i < b.N; i++ {
88-
truncateWordsToWholeSentenceOld(benchmarkTruncateString, SummaryLength)
90+
c.truncateWordsToWholeSentenceOld(benchmarkTruncateString)
8991
}
9092
}
9193

9294
func TestTruncateWordsToWholeSentence(t *testing.T) {
95+
c := newTestContentSpec()
9396
type test struct {
9497
input, expected string
9598
max int
@@ -104,9 +107,11 @@ func TestTruncateWordsToWholeSentence(t *testing.T) {
104107
{"To be. Or not to be. That's the question.", "To be.", 1, true},
105108
{" \nThis is not a sentence\nAnd this is another", "This is not a sentence", 4, true},
106109
{"", "", 10, false},
110+
{"This... is a more difficult test?", "This... is a more difficult test?", 1, false},
107111
}
108112
for i, d := range data {
109-
output, truncated := TruncateWordsToWholeSentence(d.input, d.max)
113+
c.summaryLength = d.max
114+
output, truncated := c.TruncateWordsToWholeSentence(d.input)
110115
if d.expected != output {
111116
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
112117
}
@@ -118,6 +123,7 @@ func TestTruncateWordsToWholeSentence(t *testing.T) {
118123
}
119124

120125
func TestTruncateWordsByRune(t *testing.T) {
126+
c := newTestContentSpec()
121127
type test struct {
122128
input, expected string
123129
max int
@@ -139,7 +145,8 @@ func TestTruncateWordsByRune(t *testing.T) {
139145
{" \nThis is not a sentence\n ", "This is not", 3, true},
140146
}
141147
for i, d := range data {
142-
output, truncated := TruncateWordsByRune(strings.Fields(d.input), d.max)
148+
c.summaryLength = d.max
149+
output, truncated := c.TruncateWordsByRune(strings.Fields(d.input))
143150
if d.expected != output {
144151
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
145152
}

‎hugolib/config.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func loadDefaultSettingsFor(v *viper.Viper) error {
135135
v.SetDefault("newContentEditor", "")
136136
v.SetDefault("paginate", 10)
137137
v.SetDefault("paginatePath", "page")
138+
v.SetDefault("summaryLength", 70)
138139
v.SetDefault("blackfriday", c.NewBlackfriday())
139140
v.SetDefault("rSSUri", "index.xml")
140141
v.SetDefault("rssLimit", -1)

‎hugolib/page.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,9 +677,9 @@ func (p *Page) setAutoSummary() error {
677677
var summary string
678678
var truncated bool
679679
if p.isCJKLanguage {
680-
summary, truncated = helpers.TruncateWordsByRune(p.PlainWords(), helpers.SummaryLength)
680+
summary, truncated = p.s.ContentSpec.TruncateWordsByRune(p.PlainWords())
681681
} else {
682-
summary, truncated = helpers.TruncateWordsToWholeSentence(p.Plain(), helpers.SummaryLength)
682+
summary, truncated = p.s.ContentSpec.TruncateWordsToWholeSentence(p.Plain())
683683
}
684684
p.Summary = template.HTML(summary)
685685
p.Truncated = truncated

0 commit comments

Comments
 (0)