Wordpress summaries
authorRoss Lawley <ross.lawley@gmail.com>
Wed, 21 Aug 2013 09:37:14 +0000 (10:37 +0100)
committerNoah Campbell <noahcampbell@gmail.com>
Fri, 23 Aug 2013 23:46:19 +0000 (16:46 -0700)
Allow full control of summaries which can be rendered as html rather
than text.  Using a `<!--more-->` html comment in your markdown / rst
you can indiciate where the summary should end and have the summary
converted to html.

Signed-off-by: Noah Campbell <noahcampbell@gmail.com>
Conflicts:
hugolib/page_test.go

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

index c814a62897c89a7d62bfe5870c3110180c820b86..9695f6310835fc43aab0476f04000152f5748b59 100644 (file)
@@ -20,6 +20,7 @@ import (
        "github.com/kr/pretty"
        "html/template"
        "os"
+       "os/exec"
        "reflect"
        "regexp"
        "strconv"
@@ -28,6 +29,8 @@ import (
 )
 
 var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]")
+var summaryLength = 70
+var summaryDivider = []byte("<!--more-->")
 
 // TODO: Make these wrappers private
 // Wrapper around Fprintf taking verbose flag in account.
@@ -329,3 +332,32 @@ func TruncateWordsToWholeSentence(s string, max int) string {
 func MakePermalink(domain string, path string) string {
        return strings.TrimRight(domain, "/") + "/" + strings.TrimLeft(path, "/")
 }
+
+func getSummaryString(content []byte) ([]byte, bool) {
+       if (bytes.Contains(content, summaryDivider)) {
+               return bytes.Split(content, summaryDivider)[0], false
+       } else {
+               plainContent := StripHTML(StripShortcodes(string(content)))
+               return []byte(TruncateWordsToWholeSentence(plainContent, summaryLength)), true
+       }
+}
+
+func getRstContent(content []byte) string {
+       cleanContent := bytes.Replace(content, summaryDivider, []byte(""), 1)
+
+       cmd := exec.Command("rst2html.py", "--leave-comments")
+       cmd.Stdin = bytes.NewReader(cleanContent)
+       var out bytes.Buffer
+       cmd.Stdout = &out
+       if err := cmd.Run(); err != nil {
+               fmt.Println(err)
+       }
+
+       rstLines := strings.Split(out.String(), "\n")
+       for i, line := range rstLines {
+               if strings.HasPrefix(line, "<body>") {
+                       rstLines = (rstLines[i+1 : len(rstLines)-3])
+               }
+       }
+       return strings.Join(rstLines, "\n")
+}
index ef3b2f4f6955ab2b089024d18dd9c160aa111bb7..2f0c866eed7698b341b8ac97285758743add0bb7 100644 (file)
@@ -26,7 +26,6 @@ import (
        "io/ioutil"
        "launchpad.net/goyaml"
        "os"
-       "os/exec"
        "path/filepath"
        "sort"
        "strings"
@@ -55,8 +54,6 @@ type Page struct {
        Node
 }
 
-const summaryLength = 70
-
 type File struct {
        FileName, OutFile, Extension string
 }
@@ -476,27 +473,25 @@ func (page *Page) parse(reader io.Reader) error {
 func (page *Page) convertMarkdown(lines io.Reader) {
        b := new(bytes.Buffer)
        b.ReadFrom(lines)
-       content := string(blackfriday.MarkdownCommon(b.Bytes()))
-       page.Content = template.HTML(content)
-       page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength))
+       content := b.Bytes()
+       page.Content = template.HTML(string(blackfriday.MarkdownCommon(content)))
+       summary, plain := getSummaryString(content)
+       if plain {
+               page.Summary = template.HTML(string(summary))
+       } else {
+               page.Summary = template.HTML(string(blackfriday.MarkdownCommon(summary)))
+       }
 }
 
 func (page *Page) convertRestructuredText(lines io.Reader) {
-       cmd := exec.Command("rst2html.py")
-       cmd.Stdin = lines
-       var out bytes.Buffer
-       cmd.Stdout = &out
-       if err := cmd.Run(); err != nil {
-               fmt.Println(err)
-       }
-
-       rstLines := strings.Split(out.String(), "\n")
-       for i, line := range rstLines {
-               if strings.HasPrefix(line, "<body>") {
-                       rstLines = (rstLines[i+1 : len(rstLines)-3])
-               }
+       b := new(bytes.Buffer)
+       b.ReadFrom(lines)
+       content := b.Bytes()
+       page.Content = template.HTML(getRstContent(content))
+       summary, plain := getSummaryString(content)
+       if plain {
+               page.Summary = template.HTML(string(summary))
+       } else {
+               page.Summary = template.HTML(getRstContent(summary))
        }
-       content := strings.Join(rstLines, "\n")
-       page.Content = template.HTML(content)
-       page.Summary = template.HTML(TruncateWordsToWholeSentence(StripHTML(StripShortcodes(content)), summaryLength))
 }
index d55edac6205c356dc914086f6e01df2dac4be1be..ec1695fb7bb127d9cedf68eee25d46034bc27c4a 100644 (file)
@@ -91,6 +91,15 @@ layout: buzfoo
 ---
 type and layout set`
 
+var SIMPLE_PAGE_WITH_SUMMARY_DELIMITER = `---
+title: Simple
+---
+Simple Page
+
+<!--more-->
+Some more text
+`
+
 func checkError(t *testing.T, err error, expected string) {
        if err == nil {
                t.Fatalf("err is nil")
@@ -130,6 +139,12 @@ func checkPageContent(t *testing.T, page *Page, content string) {
        }
 }
 
+func checkPageSummary(t *testing.T, page *Page, summary string) {
+       if page.Summary != template.HTML(summary) {
+               t.Fatalf("Page summary is: `%s`.  Expected `%s`", page.Summary, summary)
+       }
+}
+
 func checkPageType(t *testing.T, page *Page, pageType string) {
        if page.Type() != pageType {
                t.Fatalf("Page type is: %s.  Expected: %s", page.Type(), pageType)
@@ -149,6 +164,19 @@ func TestCreateNewPage(t *testing.T) {
        }
        checkPageTitle(t, p, "Simple")
        checkPageContent(t, p, "<p>Simple Page</p>\n")
+       checkPageSummary(t, p, "Simple Page")
+       checkPageType(t, p, "page")
+       checkPageLayout(t, p, "page/single.html")
+}
+
+func TestPageWithDelimiter(t *testing.T) {
+       p, err := ReadFrom(strings.NewReader(SIMPLE_PAGE_WITH_SUMMARY_DELIMITER), "simple")
+       if err != nil {
+               t.Fatalf("Unable to create a page with frontmatter and body content: %s", err)
+       }
+       checkPageTitle(t, p, "Simple")
+       checkPageContent(t, p, "<p>Simple Page</p>\n\n<!--more-->\n\n<p>Some more text</p>\n")
+       checkPageSummary(t, p, "<p>Simple Page</p>\n")
        checkPageType(t, p, "page")
        checkPageLayout(t, p, "page/single.html")
 }