From 7540a62834d4465af8936967e430a9e05a1e1359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Wed, 28 Nov 2018 10:21:54 +0100 Subject: [PATCH] parser/pageparser: Fix handling of commented out front matter When the page parser was rewritten in 0.51, this was interpreted literally, but commented out front matter is used in the wild to "hide it from GitHub", e.g: ``` ``` Fixes #5478 --- go.sum | 1 + hugolib/page_content.go | 2 - hugolib/page_test.go | 27 ++++++++++++++ parser/pageparser/item.go | 1 - parser/pageparser/pagelexer.go | 43 ++++++++++++++++++---- parser/pageparser/pageparser_intro_test.go | 4 +- 6 files changed, 65 insertions(+), 13 deletions(-) diff --git a/go.sum b/go.sum index 9f5b5bea306..951e4c6f924 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,7 @@ github.com/magefile/mage v1.4.0 h1:RI7B1CgnPAuu2O9lWszwya61RLmfL0KCdo+QyyI/Bhk= github.com/magefile/mage v1.4.0/go.mod h1:IUDi13rsHje59lecXokTfGX0QIzO45uVPlXnJYsXepA= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6 h1:LZhVjIISSbj8qLf2qDPP0D8z0uvOWAW5C85ly5mJW6c= github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= diff --git a/hugolib/page_content.go b/hugolib/page_content.go index 75124a1df9e..a363249d5fd 100644 --- a/hugolib/page_content.go +++ b/hugolib/page_content.go @@ -83,8 +83,6 @@ Loop: switch { case it.Type == pageparser.TypeIgnore: - case it.Type == pageparser.TypeHTMLComment: - // Ignore. This is only a leading Front matter comment. case it.Type == pageparser.TypeHTMLStart: // This is HTML without front matter. It can still have shortcodes. p.renderable = false diff --git a/hugolib/page_test.go b/hugolib/page_test.go index f9c26754b06..cd8bd8ffc53 100644 --- a/hugolib/page_test.go +++ b/hugolib/page_test.go @@ -1586,6 +1586,33 @@ CONTENT:{{ .Content }} ) } +// https://github.com/gohugoio/hugo/issues/5478 +func TestPageWithCommentedOutFrontMatter(t *testing.T) { + b := newTestSitesBuilder(t) + b.WithSimpleConfigFile() + + b.WithContent("page.md", ` +This is the content. +`) + + b.WithTemplatesAdded("layouts/_default/single.html", ` +Title: {{ .Title }} +Content:{{ .Content }} +`) + + b.CreateSites().Build(BuildCfg{}) + + b.AssertFileContent("public/page/index.html", + "Title: hello", + "Content:

This is the content.

", + ) + +} + // TODO(bep) this may be useful for other tests. func compareObjects(a interface{}, b interface{}) bool { aStr := strings.Split(fmt.Sprintf("%v", a), "") diff --git a/parser/pageparser/item.go b/parser/pageparser/item.go index 644c20e8732..b9d47b16e25 100644 --- a/parser/pageparser/item.go +++ b/parser/pageparser/item.go @@ -108,7 +108,6 @@ const ( // page items TypeHTMLStart // document starting with < as first non-whitespace - TypeHTMLComment // We ignore leading comments TypeLeadSummaryDivider // , # more TypeFrontMatterYAML TypeFrontMatterTOML diff --git a/parser/pageparser/pagelexer.go b/parser/pageparser/pagelexer.go index 94c1ff26bc9..5802c318bb9 100644 --- a/parser/pageparser/pagelexer.go +++ b/parser/pageparser/pagelexer.go @@ -53,6 +53,8 @@ type pageLexer struct { summaryDivider []byte // Set when we have parsed any summary divider summaryDividerChecked bool + // Whether we're in a HTML comment. + isInHTMLComment bool lexerShortcodeState @@ -120,7 +122,7 @@ var ( delimYAML = []byte("---") delimOrg = []byte("#+") htmlCommentStart = []byte("") + htmlCommentEnd = []byte("-->") ) func (l *pageLexer) next() rune { @@ -195,6 +197,15 @@ func (l *pageLexer) consumeCRLF() bool { return consumed } +func (l *pageLexer) consumeToNextLine() { + for { + r := l.next() + if r == eof || isEndOfLine(r) { + return + } + } +} + func (l *pageLexer) consumeSpace() { for { r := l.next() @@ -206,6 +217,10 @@ func (l *pageLexer) consumeSpace() { } func lexMainSection(l *pageLexer) stateFunc { + if l.isInHTMLComment { + return lexEndFromtMatterHTMLComment + } + // Fast forward as far as possible. var l1, l2 int @@ -312,16 +327,15 @@ LOOP: case r == byteOrderMark: l.emit(TypeIgnore) case !isSpace(r) && !isEndOfLine(r): - // No front matter. if r == '<' { l.backup() if l.hasPrefix(htmlCommentStart) { - right := l.index(htmlCOmmentEnd) - if right == -1 { - return l.errorf("starting HTML comment with no end") - } - l.pos += right + len(htmlCOmmentEnd) - l.emit(TypeHTMLComment) + // This may be commented out front mattter, which should + // still be read. + l.consumeToNextLine() + l.isInHTMLComment = true + l.emit(TypeIgnore) + continue LOOP } else { if l.pos > l.start { l.emit(tText) @@ -341,6 +355,19 @@ LOOP: return lexMainSection } +func lexEndFromtMatterHTMLComment(l *pageLexer) stateFunc { + l.isInHTMLComment = false + right := l.index(htmlCommentEnd) + if right == -1 { + return l.errorf("starting HTML comment with no end") + } + l.pos += right + len(htmlCommentEnd) + l.emit(TypeIgnore) + + // Now move on to the shortcodes. + return lexMainSection +} + func lexDone(l *pageLexer) stateFunc { // Done! diff --git a/parser/pageparser/pageparser_intro_test.go b/parser/pageparser/pageparser_intro_test.go index ba48a3ee3f3..901b216c8aa 100644 --- a/parser/pageparser/pageparser_intro_test.go +++ b/parser/pageparser/pageparser_intro_test.go @@ -60,7 +60,8 @@ var frontMatterTests = []lexerTest{ {"No front matter", "\nSome text.\n", []Item{tstSomeText, tstEOF}}, {"YAML front matter", "---\nfoo: \"bar\"\n---\n\nSome text.\n", []Item{tstFrontMatterYAML, tstSomeText, tstEOF}}, {"YAML empty front matter", "---\n---\n\nSome text.\n", []Item{nti(TypeFrontMatterYAML, ""), tstSomeText, tstEOF}}, - {"YAML commented out front matter", "\nSome text.\n", []Item{nti(TypeHTMLComment, ""), tstSomeText, tstEOF}}, + {"YAML commented out front matter", "\nSome text.\n", []Item{nti(TypeIgnore, ""), tstSomeText, tstEOF}}, + {"YAML commented out front matter, no end", "