"strings"
)
-// SummaryLength is the length of the summary that Hugo extracts from a content.
-var SummaryLength = 70
-
// SummaryDivider denotes where content summarization should end. The default is "<!--more-->".
var SummaryDivider = []byte("<!--more-->")
blackfriday map[string]interface{}
footnoteAnchorPrefix string
footnoteReturnLinkContents string
+ // SummaryLength is the length of the summary that Hugo extracts from a content.
+ summaryLength int
Highlight func(code, lang, optsStr string) (string, error)
defatultPygmentsOpts map[string]string
blackfriday: cfg.GetStringMap("blackfriday"),
footnoteAnchorPrefix: cfg.GetString("footnoteAnchorPrefix"),
footnoteReturnLinkContents: cfg.GetString("footnoteReturnLinkContents"),
+ summaryLength: cfg.GetInt("summaryLength"),
cfg: cfg,
}
}
// TruncateWordsByRune truncates words by runes.
-func TruncateWordsByRune(words []string, max int) (string, bool) {
+func (c *ContentSpec) TruncateWordsByRune(words []string) (string, bool) {
count := 0
for index, word := range words {
- if count >= max {
+ if count >= c.summaryLength {
return strings.Join(words[:index], " "), true
}
runeCount := utf8.RuneCountInString(word)
if len(word) == runeCount {
count++
- } else if count+runeCount < max {
+ } else if count+runeCount < c.summaryLength {
count += runeCount
} else {
for ri := range word {
- if count >= max {
+ if count >= c.summaryLength {
truncatedWords := append(words[:index], word[:ri])
return strings.Join(truncatedWords, " "), true
}
// TruncateWordsToWholeSentence takes content and truncates to whole sentence
// limited by max number of words. It also returns whether it is truncated.
-func TruncateWordsToWholeSentence(s string, max int) (string, bool) {
-
+func (c *ContentSpec) TruncateWordsToWholeSentence(s string) (string, bool) {
var (
wordCount = 0
lastWordIndex = -1
wordCount++
lastWordIndex = i
- if wordCount >= max {
+ if wordCount >= c.summaryLength {
break
}
}
// Kept only for benchmark.
-func truncateWordsToWholeSentenceOld(content string, max int) (string, bool) {
+func (c *ContentSpec) truncateWordsToWholeSentenceOld(content string) (string, bool) {
words := strings.Fields(content)
- if max >= len(words) {
+ if c.summaryLength >= len(words) {
return strings.Join(words, " "), false
}
- for counter, word := range words[max:] {
+ for counter, word := range words[c.summaryLength:] {
if strings.HasSuffix(word, ".") ||
strings.HasSuffix(word, "?") ||
strings.HasSuffix(word, ".\"") ||
strings.HasSuffix(word, "!") {
- upper := max + counter + 1
+ upper := c.summaryLength + counter + 1
return strings.Join(words[:upper], " "), (upper < len(words))
}
}
- return strings.Join(words[:max], " "), true
+ return strings.Join(words[:c.summaryLength], " "), true
}
func getAsciidocExecPath() string {
var benchmarkTruncateString = strings.Repeat("This is a sentence about nothing.", 20)
func BenchmarkTestTruncateWordsToWholeSentence(b *testing.B) {
+ c := newTestContentSpec()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- TruncateWordsToWholeSentence(benchmarkTruncateString, SummaryLength)
+ c.TruncateWordsToWholeSentence(benchmarkTruncateString)
}
}
func BenchmarkTestTruncateWordsToWholeSentenceOld(b *testing.B) {
+ c := newTestContentSpec()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- truncateWordsToWholeSentenceOld(benchmarkTruncateString, SummaryLength)
+ c.truncateWordsToWholeSentenceOld(benchmarkTruncateString)
}
}
func TestTruncateWordsToWholeSentence(t *testing.T) {
+ c := newTestContentSpec()
type test struct {
input, expected string
max int
{"To be. Or not to be. That's the question.", "To be.", 1, true},
{" \nThis is not a sentence\nAnd this is another", "This is not a sentence", 4, true},
{"", "", 10, false},
+ {"This... is a more difficult test?", "This... is a more difficult test?", 1, false},
}
for i, d := range data {
- output, truncated := TruncateWordsToWholeSentence(d.input, d.max)
+ c.summaryLength = d.max
+ output, truncated := c.TruncateWordsToWholeSentence(d.input)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
}
func TestTruncateWordsByRune(t *testing.T) {
+ c := newTestContentSpec()
type test struct {
input, expected string
max int
{" \nThis is not a sentence\n ", "This is not", 3, true},
}
for i, d := range data {
- output, truncated := TruncateWordsByRune(strings.Fields(d.input), d.max)
+ c.summaryLength = d.max
+ output, truncated := c.TruncateWordsByRune(strings.Fields(d.input))
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}