shithub: hugo

Download patch

ref: 199816fddd6f16b4a3e9a737530c7738f0da1b24
parent: 919bc9210a69c801c7304c0b529df93d1dca27aa
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Mon Aug 14 04:42:30 EDT 2017

hugolib: Extract replaceDivider logic

To its own function and add a test and a benchmark for it.

--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -484,9 +484,26 @@
 	internalSummaryDivider = []byte("HUGOMORE42")
 )
 
+// replaceDivider replaces the <!--more--> with an internal value and returns
+// whether the contentis truncated or not.
+// Note: The content slice will be modified if needed.
+func replaceDivider(content, from, to []byte) ([]byte, bool) {
+	sections := bytes.Split(content, from)
+
+	// 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.
+	truncated := (len(sections) == 2 &&
+		len(bytes.Trim(sections[1], " \n\r")) > 0)
+
+	return bytes.Join(sections, to), truncated
+
+}
+
 // We have to replace the <!--more--> with something that survives all the
 // rendering engines.
-// TODO(bep) inline replace
 func (p *Page) replaceDivider(content []byte) []byte {
 	summaryDivider := helpers.SummaryDivider
 	// TODO(bep) handle better.
@@ -493,17 +510,12 @@
 	if p.Ext() == "org" || p.Markup == "org" {
 		summaryDivider = []byte("# more")
 	}
-	sections := bytes.Split(content, 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)
+	replaced, truncated := replaceDivider(content, summaryDivider, internalSummaryDivider)
 
-	return bytes.Join(sections, internalSummaryDivider)
+	p.Truncated = truncated
+
+	return replaced
 }
 
 // Returns the page as summary and main if a user defined split is provided.
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -1096,6 +1096,60 @@
 	}
 }
 
+func TestReplaceDivider(t *testing.T) {
+	t.Parallel()
+
+	tests := []struct {
+		content           string
+		from              string
+		to                string
+		expectedContent   string
+		expectedTruncated bool
+	}{
+		{"none", "a", "b", "none", false},
+		{"summary divider content", "divider", "HUGO", "summary HUGO content", true},
+		{"summary\n\ndivider", "divider", "HUGO", "summary\n\nHUGO", false},
+		{"summary\n\ndivider\n\r", "divider", "HUGO", "summary\n\nHUGO\n\r", false},
+	}
+
+	for i, test := range tests {
+		replaced, truncated := replaceDivider([]byte(test.content), []byte(test.from), []byte(test.to))
+
+		if truncated != test.expectedTruncated {
+			t.Fatalf("[%d] Expected truncated to be %t, was %t", i, test.expectedTruncated, truncated)
+		}
+
+		if string(replaced) != test.expectedContent {
+			t.Fatalf("[%d] Expected content to be %q, was %q", i, test.expectedContent, replaced)
+		}
+	}
+}
+
+func BenchmarkReplaceDivider(b *testing.B) {
+	divider := "HUGO_DIVIDER"
+	from, to := []byte(divider), []byte("HUGO_REPLACED")
+
+	withDivider := make([][]byte, b.N)
+	noDivider := make([][]byte, b.N)
+
+	for i := 0; i < b.N; i++ {
+		withDivider[i] = []byte(strings.Repeat("Summary ", 5) + "\n" + divider + "\n" + strings.Repeat("Word ", 300))
+		noDivider[i] = []byte(strings.Repeat("Word ", 300))
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, t1 := replaceDivider(withDivider[i], from, to)
+		_, t2 := replaceDivider(noDivider[i], from, to)
+		if !t1 {
+			b.Fatal("Should be truncated")
+		}
+		if t2 {
+			b.Fatal("Should not be truncated")
+		}
+	}
+}
+
 func TestPagePaths(t *testing.T) {
 	t.Parallel()
 
--