diff options
author | Noah Campbell <noahcampbell@gmail.com> | 2013-09-18 20:15:46 +0400 |
---|---|---|
committer | Noah Campbell <noahcampbell@gmail.com> | 2013-09-18 20:15:46 +0400 |
commit | d8e1834910d2b845ee5066571a61be49a7a1451c (patch) | |
tree | 7ef6b512842a2ea44327cacab18a1d585d81dcef /parser/page.go | |
parent | a82efe5bb131f1d4a811d3220c2ce40d56aa9eaf (diff) |
Fix parsing edge case of frontmatter
When the frontmatter contains a - (or other delimiter) close to the
closing frontmatter delimiter, frontmatter detection would fail.
Diffstat (limited to 'parser/page.go')
-rw-r--r-- | parser/page.go | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/parser/page.go b/parser/page.go index 2df4ce635..eb8672bd4 100644 --- a/parser/page.go +++ b/parser/page.go @@ -2,9 +2,9 @@ package parser import ( "bufio" - "fmt" "bytes" "errors" + "fmt" "io" "unicode" ) @@ -164,22 +164,34 @@ func determineDelims(firstLine []byte) (left, right []byte) { } func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatter, err error) { - var level int = 0 - var sameDelim = bytes.Equal(left, right) + var ( + c byte + level int = 0 + bytesRead int = 0 + sameDelim = bytes.Equal(left, right) + ) + wr := new(bytes.Buffer) for { - c, err := r.ReadByte() - if err != nil { - return nil, err + if c, err = r.ReadByte(); err != nil { + return nil, fmt.Errorf("Unable to read frontmatter at filepos %d: %s", bytesRead, err) } + bytesRead += 1 switch c { case left[0]: - match, err := matches(r, wr, []byte{c}, left) - if err != nil { + var ( + buf []byte = []byte{c} + remaining []byte + ) + + if remaining, err = r.Peek(len(left) - 1); err != nil { return nil, err } - if match { + + buf = append(buf, remaining...) + + if bytes.Equal(buf, left) { if sameDelim { if level == 0 { level = 1 @@ -190,6 +202,19 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatt level += 1 } } + + if _, err = wr.Write([]byte{c}); err != nil { + return nil, err + } + + if level == 0 { + if _, err = r.Read(remaining); err != nil { + return nil, err + } + if _, err = wr.Write(remaining); err != nil { + return nil, err + } + } case right[0]: match, err := matches(r, wr, []byte{c}, right) if err != nil { @@ -216,6 +241,10 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatt return nil, errors.New("Could not find front matter.") } +func matches_quick(buf, expected []byte) (ok bool, err error) { + return bytes.Equal(expected, buf), nil +} + func matches(r *bufio.Reader, wr io.Writer, c, expected []byte) (ok bool, err error) { if len(expected) == 1 { if _, err = wr.Write(c); err != nil { @@ -223,16 +252,13 @@ func matches(r *bufio.Reader, wr io.Writer, c, expected []byte) (ok bool, err er } return bytes.Equal(c, expected), nil } + buf := make([]byte, len(expected)-1) - if _, err = r.Read(buf); err != nil { + if buf, err = r.Peek(len(expected) - 1); err != nil { return } buf = append(c, buf...) - if _, err = wr.Write(buf); err != nil { - return - } - return bytes.Equal(expected, buf), nil } |