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:
```
<!--
+++
title = "hello"
+++
-->
```
Fixes #5478
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=
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
)
}
+// https://github.com/gohugoio/hugo/issues/5478
+func TestPageWithCommentedOutFrontMatter(t *testing.T) {
+ b := newTestSitesBuilder(t)
+ b.WithSimpleConfigFile()
+
+ b.WithContent("page.md", `<!--
++++
+title = "hello"
++++
+-->
+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:<p>This is the content.</p>",
+ )
+
+}
+
// TODO(bep) this may be useful for other tests.
func compareObjects(a interface{}, b interface{}) bool {
aStr := strings.Split(fmt.Sprintf("%v", a), "")
// page items
TypeHTMLStart // document starting with < as first non-whitespace
- TypeHTMLComment // We ignore leading comments
TypeLeadSummaryDivider // <!--more-->, # more
TypeFrontMatterYAML
TypeFrontMatterTOML
summaryDivider []byte
// Set when we have parsed any summary divider
summaryDividerChecked bool
+ // Whether we're in a HTML comment.
+ isInHTMLComment bool
lexerShortcodeState
delimYAML = []byte("---")
delimOrg = []byte("#+")
htmlCommentStart = []byte("<!--")
- htmlCOmmentEnd = []byte("-->")
+ htmlCommentEnd = []byte("-->")
)
func (l *pageLexer) next() rune {
return consumed
}
+func (l *pageLexer) consumeToNextLine() {
+ for {
+ r := l.next()
+ if r == eof || isEndOfLine(r) {
+ return
+ }
+ }
+}
+
func (l *pageLexer) consumeSpace() {
for {
r := l.next()
}
func lexMainSection(l *pageLexer) stateFunc {
+ if l.isInHTMLComment {
+ return lexEndFromtMatterHTMLComment
+ }
+
// Fast forward as far as possible.
var l1, l2 int
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)
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!
{"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", "<!--\n---\nfoo: \"bar\"\n---\n-->\nSome text.\n", []Item{nti(TypeHTMLComment, "<!--\n---\nfoo: \"bar\"\n---\n-->"), tstSomeText, tstEOF}},
+ {"YAML commented out front matter", "<!--\n---\nfoo: \"bar\"\n---\n-->\nSome text.\n", []Item{nti(TypeIgnore, "<!--\n"), tstFrontMatterYAML, nti(TypeIgnore, "-->"), tstSomeText, tstEOF}},
+ {"YAML commented out front matter, no end", "<!--\n---\nfoo: \"bar\"\n---\nSome text.\n", []Item{nti(TypeIgnore, "<!--\n"), tstFrontMatterYAML, nti(tError, "starting HTML comment with no end")}},
// Note that we keep all bytes as they are, but we need to handle CRLF
{"YAML front matter CRLF", "---\r\nfoo: \"bar\"\r\n---\n\nSome text.\n", []Item{tstFrontMatterYAMLCRLF, tstSomeText, tstEOF}},
{"TOML front matter", "+++\nfoo = \"bar\"\n+++\n\nSome text.\n", []Item{tstFrontMatterTOML, tstSomeText, tstEOF}},
func TestFrontMatter(t *testing.T) {
t.Parallel()
for i, test := range frontMatterTests {
-
items := collect([]byte(test.input), false, lexIntroSection)
if !equal(items, test.items) {
got := crLfReplacer.Replace(fmt.Sprint(items))