shithub: hugo

Download patch

ref: 554375b2addc4b4425bb4d3f154374b027c113cf
parent: 1de19926640ffc2baa43a9691b5d277a7f22cf49
author: Noah Campbell <[email protected]>
date: Sat Aug 24 17:27:41 EDT 2013

Using new parser.

--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -21,6 +21,7 @@
 	"fmt"
 	"github.com/BurntSushi/toml"
 	"github.com/theplant/blackfriday"
+	"github.com/noahcampbell/akebia/parser"
 	"html/template"
 	"io"
 	"io/ioutil"
@@ -30,7 +31,6 @@
 	"sort"
 	"strings"
 	"time"
-	"unicode"
 )
 
 var _ = filepath.Base("")
@@ -158,32 +158,6 @@
 	p.FuzzyWordCount = int((p.WordCount+100)/100) * 100
 }
 
-func splitPageContent(data []byte, start string, end string) ([]string, []string) {
-	lines := strings.Split(string(data), "\n")
-	datum := lines[0:]
-
-	var found = 0
-	if start != end {
-		for i, line := range lines {
-
-			if strings.HasPrefix(line, start) {
-				found += 1
-			}
-
-			if strings.HasPrefix(line, end) {
-				found -= 1
-			}
-
-			if found == 0 {
-				datum = lines[0 : i+1]
-				lines = lines[i+1:]
-				break
-			}
-		}
-	}
-	return datum, lines
-}
-
 func (p *Page) Permalink() template.HTML {
 	if len(strings.TrimSpace(p.Slug)) > 0 {
 		if p.Site.Config.UglyUrls {
@@ -207,6 +181,7 @@
 
 func (page *Page) handleTomlMetaData(datum []byte) (interface{}, error) {
 	m := map[string]interface{}{}
+	datum = removeTomlIdentifier(datum)
 	if _, err := toml.Decode(string(datum), &m); err != nil {
 		return m, fmt.Errorf("Invalid TOML in %s \nError parsing page meta data: %s", page.FileName, err)
 	}
@@ -213,6 +188,10 @@
 	return m, nil
 }
 
+func removeTomlIdentifier(datum []byte) []byte {
+	return bytes.Replace(datum, []byte("+++"), []byte(""), -1)
+}
+
 func (page *Page) handleYamlMetaData(datum []byte) (interface{}, error) {
 	m := map[string]interface{}{}
 	if err := goyaml.Unmarshal(datum, &m); err != nil {
@@ -303,73 +282,6 @@
 	return nil
 }
 
-var ErrDetectingFrontMatter = errors.New("unable to detect front matter")
-var ErrMatchingStartingFrontMatterDelimiter = errors.New("unable to match beginning front matter delimiter")
-var ErrMatchingEndingFrontMatterDelimiter = errors.New("unable to match ending front matter delimiter")
-
-func (page *Page) parseFrontMatter(data *bufio.Reader) (err error) {
-
-	if err = checkEmpty(data); err != nil {
-		return
-	}
-
-	var mark rune
-	if mark, err = chompWhitespace(data); err != nil {
-		return
-	}
-
-	f := page.detectFrontMatter(mark)
-	if f == nil {
-		return ErrDetectingFrontMatter
-	}
-
-	if found, err := beginFrontMatter(data, f); err != nil || !found {
-		return ErrMatchingStartingFrontMatterDelimiter
-	}
-
-	var frontmatter = new(bytes.Buffer)
-	for {
-		line, _, err := data.ReadLine()
-		if err != nil {
-			if err == io.EOF {
-				return ErrMatchingEndingFrontMatterDelimiter
-			}
-			return err
-		}
-
-		if bytes.Equal(line, f.markend) {
-			if f.includeMark {
-				frontmatter.Write(line)
-			}
-			break
-		}
-
-		frontmatter.Write(line)
-		frontmatter.Write([]byte{'\n'})
-	}
-
-	metadata, err := f.parse(frontmatter.Bytes())
-	if err != nil {
-		return
-	}
-
-	if err = page.update(metadata); err != nil {
-		return
-	}
-
-	return
-}
-
-func checkEmpty(data *bufio.Reader) (err error) {
-	if _, _, err = data.ReadRune(); err != nil {
-		return errors.New("unable to locate front matter")
-	}
-	if err = data.UnreadRune(); err != nil {
-		return errors.New("unable to unread first charactor in page buffer.")
-	}
-	return
-}
-
 type frontmatterType struct {
 	markstart, markend []byte
 	parse              func([]byte) (interface{}, error)
@@ -389,37 +301,6 @@
 	}
 }
 
-func beginFrontMatter(data *bufio.Reader, f *frontmatterType) (bool, error) {
-	var err error
-	var peek []byte
-	if f.includeMark {
-		peek, err = data.Peek(len(f.markstart))
-	} else {
-		peek = make([]byte, len(f.markstart))
-		_, err = data.Read(peek)
-	}
-	if err != nil {
-		return false, err
-	}
-	return bytes.Equal(peek, f.markstart), nil
-}
-
-func chompWhitespace(data *bufio.Reader) (r rune, err error) {
-	for {
-		r, _, err = data.ReadRune()
-		if err != nil {
-			return
-		}
-		if unicode.IsSpace(r) {
-			continue
-		}
-		if err := data.UnreadRune(); err != nil {
-			return r, errors.New("unable to unread first charactor in front matter.")
-		}
-		return r, nil
-	}
-}
-
 func (p *Page) Render(layout ...string) template.HTML {
 	curLayout := ""
 
@@ -454,18 +335,30 @@
 }
 
 func (page *Page) parse(reader io.Reader) error {
-	data := bufio.NewReader(reader)
+	p, err := parser.ReadFrom(reader)
+	if err != nil {
+		return err
+	}
 
-	err := page.parseFrontMatter(data)
+	front := p.FrontMatter()
+	if len(front) == 0 {
+		return errors.New("Unable to locate frontmatter")
+	}
+	fm := page.detectFrontMatter(rune(front[0]))
+	meta, err := fm.parse(front)
 	if err != nil {
 		return err
 	}
 
+	if err = page.update(meta); err != nil {
+		return err
+	}
+
 	switch page.Markup {
 	case "md":
-		page.convertMarkdown(data)
+		page.convertMarkdown(bytes.NewReader(p.Content()))
 	case "rst":
-		page.convertRestructuredText(data)
+		page.convertRestructuredText(bytes.NewReader(p.Content()))
 	}
 	return nil
 }
--- a/hugolib/page_index_test.go
+++ b/hugolib/page_index_test.go
@@ -44,7 +44,7 @@
 	} {
 		p, err := ReadFrom(strings.NewReader(test), "page/with/index")
 		if err != nil {
-			t.Fatalf("Failed parsing page: %s", err)
+			t.Fatalf("Failed parsing %q: %s", test, err)
 		}
 
 		param := p.GetParam("tags")
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -124,7 +124,7 @@
 		t.Fatalf("Expected ReadFrom to return an error when an empty buffer is passed.")
 	}
 
-	checkError(t, err, "unable to locate front matter")
+	checkError(t, err, "EOF")
 }
 
 func checkPageTitle(t *testing.T, page *Page, title string) {
@@ -202,9 +202,9 @@
 		r   string
 		err string
 	}{
-		{INVALID_FRONT_MATTER_SHORT_DELIM, "unable to match beginning front matter delimiter"},
-		{INVALID_FRONT_MATTER_SHORT_DELIM_ENDING, "unable to match ending front matter delimiter"},
-		{INVALID_FRONT_MATTER_MISSING, "unable to detect front matter"},
+		{INVALID_FRONT_MATTER_SHORT_DELIM, "Unable to locate frontmatter"},
+		{INVALID_FRONT_MATTER_SHORT_DELIM_ENDING, "EOF"},
+		{INVALID_FRONT_MATTER_MISSING, "Unable to locate frontmatter"},
 	}
 	for _, test := range tests {
 		_, err := ReadFrom(strings.NewReader(test.r), "invalid/front/matter/short/delim")