Allow for any (short) line begining or ending with html comment
authorSven Dowideit <SvenDowideit@home.org.au>
Wed, 23 Sep 2015 04:43:17 +0000 (14:43 +1000)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 25 Sep 2015 16:32:32 +0000 (18:32 +0200)
Fixes #1428

hugolib/page_test.go
parser/page.go

index 9a1b67fa1a165af11721eb023f258948e8a1caae..c3506d48d4b7ae769ffe77c2ade11d2833289869 100644 (file)
@@ -22,6 +22,10 @@ const (
        SIMPLE_PAGE                      = "---\ntitle: Simple\n---\nSimple Page\n"
        INVALID_FRONT_MATTER_MISSING     = "This is a test"
        RENDER_NO_FRONT_MATTER           = "<!doctype><html><head></head><body>This is a test</body></html>"
+       CONTENT_WITH_COMMENTED_FM        = "<!--\n+++\ntitle = \"Network configuration\"\ndescription = \"Docker networking\"\nkeywords = [\"network\"]\n[menu.main]\nparent= \"smn_administrate\"\n+++\n-->\n\n# Network configuration\n\n##\nSummary"
+       CONTENT_WITH_COMMENTED_TEXT_FM   = "<!--[metaData]>\n+++\ntitle = \"Network configuration\"\ndescription = \"Docker networking\"\nkeywords = [\"network\"]\n[menu.main]\nparent= \"smn_administrate\"\n+++\n<![end-metadata]-->\n\n# Network configuration\n\n##\nSummary"
+       CONTENT_WITH_COMMENTED_LONG_FM   = "<!--[metaData123456789012345678901234567890]>\n+++\ntitle = \"Network configuration\"\ndescription = \"Docker networking\"\nkeywords = [\"network\"]\n[menu.main]\nparent= \"smn_administrate\"\n+++\n<![end-metadata]-->\n\n# Network configuration\n\n##\nSummary"
+       CONTENT_WITH_COMMENTED_LONG2_FM  = "<!--[metaData]>\n+++\ntitle = \"Network configuration\"\ndescription = \"Docker networking\"\nkeywords = [\"network\"]\n[menu.main]\nparent= \"smn_administrate\"\n+++\n<![end-metadata123456789012345678901234567890]-->\n\n# Network configuration\n\n##\nSummary"
        INVALID_FRONT_MATTER_SHORT_DELIM = `
 --
 title: Short delim start
@@ -661,6 +665,10 @@ func TestShouldRenderContent(t *testing.T) {
                // TODO how to deal with malformed frontmatter.  In this case it'll be rendered as markdown.
                {INVALID_FRONT_MATTER_SHORT_DELIM, true},
                {RENDER_NO_FRONT_MATTER, false},
+               {CONTENT_WITH_COMMENTED_FM, true},
+               {CONTENT_WITH_COMMENTED_TEXT_FM, true},
+               {CONTENT_WITH_COMMENTED_LONG_FM, false},
+               {CONTENT_WITH_COMMENTED_LONG2_FM, true},
        }
 
        for _, test := range tests {
index c3d34a7f0f43fad8b9a91274d2fc21ac26e43038..302ef488ff381b60cb6f24665305858330b5a647 100644 (file)
@@ -6,20 +6,23 @@ import (
        "fmt"
        "io"
        "regexp"
+       "strings"
        "unicode"
 )
 
 const (
-       HTML_LEAD       = "<"
-       YAML_LEAD       = "-"
-       YAML_DELIM_UNIX = "---\n"
-       YAML_DELIM_DOS  = "---\r\n"
-       YAML_DELIM      = "---"
-       TOML_LEAD       = "+"
-       TOML_DELIM_UNIX = "+++\n"
-       TOML_DELIM_DOS  = "+++\r\n"
-       TOML_DELIM      = "+++"
-       JSON_LEAD       = "{"
+       HTML_LEAD          = "<"
+       YAML_LEAD          = "-"
+       YAML_DELIM_UNIX    = "---\n"
+       YAML_DELIM_DOS     = "---\r\n"
+       YAML_DELIM         = "---"
+       TOML_LEAD          = "+"
+       TOML_DELIM_UNIX    = "+++\n"
+       TOML_DELIM_DOS     = "+++\r\n"
+       TOML_DELIM         = "+++"
+       JSON_LEAD          = "{"
+       HTML_COMMENT_START = "<!--"
+       HTML_COMMENT_END   = "-->"
 )
 
 var (
@@ -79,6 +82,9 @@ func ReadFrom(r io.Reader) (p Page, err error) {
        if err = chompWhitespace(reader); err != nil && err != io.EOF {
                return
        }
+       if err = chompFrontmatterStartComment(reader); err != nil && err != io.EOF {
+               return
+       }
 
        firstLine, err := peekLine(reader)
        if err != nil && err != io.EOF {
@@ -120,6 +126,65 @@ func chompWhitespace(r io.RuneScanner) (err error) {
        }
 }
 
+func chompFrontmatterStartComment(r *bufio.Reader) (err error) {
+       candidate, err := r.Peek(32)
+       if err != nil {
+               return err
+       }
+
+       str := string(candidate)
+       if strings.HasPrefix(str, HTML_COMMENT_START) {
+               lineEnd := strings.IndexAny(str, "\n")
+               if lineEnd == -1 {
+                       //TODO: if we can't find it, Peek more?
+                       return nil
+               }
+               testStr := strings.TrimSuffix(str[0:lineEnd], "\r")
+               if strings.Index(testStr, HTML_COMMENT_END) != -1 {
+                       return nil
+               }
+               buf := make([]byte, lineEnd)
+               if _, err = r.Read(buf); err != nil {
+                       return
+               }
+               if err = chompWhitespace(r); err != nil {
+                       return err
+               }
+       }
+
+       return nil
+}
+
+func chompFrontmatterEndComment(r *bufio.Reader) (err error) {
+       candidate, err := r.Peek(32)
+       if err != nil {
+               return err
+       }
+
+       str := string(candidate)
+       lineEnd := strings.IndexAny(str, "\n")
+       if lineEnd == -1 {
+               return nil
+       }
+       testStr := strings.TrimSuffix(str[0:lineEnd], "\r")
+       if strings.Index(testStr, HTML_COMMENT_START) != -1 {
+               return nil
+       }
+
+       //TODO: if we can't find it, Peek more?
+       if strings.HasSuffix(testStr, HTML_COMMENT_END) {
+               buf := make([]byte, lineEnd)
+               if _, err = r.Read(buf); err != nil {
+                       return
+               }
+               if err = chompWhitespace(r); err != nil {
+                       return err
+               }
+       }
+
+       return nil
+}
+
 func peekLine(r *bufio.Reader) (line []byte, err error) {
        firstFive, err := r.Peek(5)
        if err != nil {
@@ -254,11 +319,13 @@ func extractFrontMatterDelims(r *bufio.Reader, left, right []byte) (fm FrontMatt
 
                if level == 0 {
                        // Consumes white spaces immediately behind frontmatter
-                       if err = chompWhitespace(r); err != nil {
-                               if err != io.EOF {
-                                       return nil, err
-                               }
+                       if err = chompWhitespace(r); err != nil && err != io.EOF {
+                               return nil, err
                        }
+                       if err = chompFrontmatterEndComment(r); err != nil && err != io.EOF {
+                               return nil, err
+                       }
+
                        return buf.Bytes(), nil
                }
        }