0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2025-01-06 22:40:31 -05:00

templates: Add support for dots to close yaml frontmatter (#3498)

* templates: Add support for dots to close yaml frontmatter

* templates: Fix regression in body output
This commit is contained in:
Francis Lavoie 2020-06-15 14:38:51 -04:00 committed by GitHub
parent 5b48f784ae
commit 003403ecbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 19 deletions

View file

@ -34,25 +34,30 @@ func extractFrontMatter(input string) (map[string]interface{}, string, error) {
firstLine = strings.TrimSpace(firstLine) firstLine = strings.TrimSpace(firstLine)
// see what kind of front matter there is, if any // see what kind of front matter there is, if any
var closingFence string var closingFence []string
var fmParser func([]byte) (map[string]interface{}, error) var fmParser func([]byte) (map[string]interface{}, error)
switch firstLine { for _, fmType := range supportedFrontMatterTypes {
case yamlFrontMatterFenceOpen: if firstLine == fmType.FenceOpen {
fmParser = yamlFrontMatter closingFence = fmType.FenceClose
closingFence = yamlFrontMatterFenceClose fmParser = fmType.ParseFunc
case tomlFrontMatterFenceOpen: }
fmParser = tomlFrontMatter }
closingFence = tomlFrontMatterFenceClose
case jsonFrontMatterFenceOpen: if fmParser == nil {
fmParser = jsonFrontMatter
closingFence = jsonFrontMatterFenceClose
default:
// no recognized front matter; whole document is body // no recognized front matter; whole document is body
return nil, input, nil return nil, input, nil
} }
// find end of front matter // find end of front matter
fmEndFenceStart := strings.Index(input[firstLineEnd:], "\n"+closingFence) var fmEndFence string
fmEndFenceStart := -1
for _, fence := range closingFence {
index := strings.Index(input[firstLineEnd:], "\n"+fence)
if index >= 0 {
fmEndFenceStart = index
fmEndFence = fence
}
}
if fmEndFenceStart < 0 { if fmEndFenceStart < 0 {
return nil, "", fmt.Errorf("unterminated front matter") return nil, "", fmt.Errorf("unterminated front matter")
} }
@ -66,7 +71,7 @@ func extractFrontMatter(input string) (map[string]interface{}, string, error) {
} }
// the rest is the body // the rest is the body
body := input[fmEndFenceStart+len(closingFence):] body := input[fmEndFenceStart+len(fmEndFence):]
return fm, body, nil return fm, body, nil
} }
@ -96,8 +101,26 @@ type parsedMarkdownDoc struct {
Body string `json:"body,omitempty"` Body string `json:"body,omitempty"`
} }
const ( type frontMatterType struct {
yamlFrontMatterFenceOpen, yamlFrontMatterFenceClose = "---", "---" FenceOpen string
tomlFrontMatterFenceOpen, tomlFrontMatterFenceClose = "+++", "+++" FenceClose []string
jsonFrontMatterFenceOpen, jsonFrontMatterFenceClose = "{", "}" ParseFunc func(input []byte) (map[string]interface{}, error)
) }
var supportedFrontMatterTypes = []frontMatterType{
{
FenceOpen: "---",
FenceClose: []string{"---", "..."},
ParseFunc: yamlFrontMatter,
},
{
FenceOpen: "+++",
FenceClose: []string{"+++"},
ParseFunc: tomlFrontMatter,
},
{
FenceOpen: "{",
FenceClose: []string{"}"},
ParseFunc: jsonFrontMatter,
},
}

View file

@ -290,11 +290,13 @@ func TestSplitFrontMatter(t *testing.T) {
for i, test := range []struct { for i, test := range []struct {
input string input string
expect string expect string
body string
}{ }{
{ {
// yaml with windows newline // yaml with windows newline
input: "---\r\ntitle: Welcome\r\n---\r\n# Test\\r\\n", input: "---\r\ntitle: Welcome\r\n---\r\n# Test\\r\\n",
expect: `Welcome`, expect: `Welcome`,
body: "\r\n# Test\\r\\n",
}, },
{ {
// yaml // yaml
@ -303,6 +305,16 @@ title: Welcome
--- ---
### Test`, ### Test`,
expect: `Welcome`, expect: `Welcome`,
body: "\n### Test",
},
{
// yaml with dots for closer
input: `---
title: Welcome
...
### Test`,
expect: `Welcome`,
body: "\n### Test",
}, },
{ {
// toml // toml
@ -311,6 +323,7 @@ title = "Welcome"
+++ +++
### Test`, ### Test`,
expect: `Welcome`, expect: `Welcome`,
body: "\n### Test",
}, },
{ {
// json // json
@ -319,12 +332,16 @@ title = "Welcome"
} }
### Test`, ### Test`,
expect: `Welcome`, expect: `Welcome`,
body: "\n### Test",
}, },
} { } {
result, _ := context.funcSplitFrontMatter(test.input) result, _ := context.funcSplitFrontMatter(test.input)
if result.Meta["title"] != test.expect { if result.Meta["title"] != test.expect {
t.Errorf("Test %d: Expected %s, found %s. Input was SplitFrontMatter(%s)", i, test.expect, result.Meta["title"], test.input) t.Errorf("Test %d: Expected %s, found %s. Input was SplitFrontMatter(%s)", i, test.expect, result.Meta["title"], test.input)
} }
if result.Body != test.body {
t.Errorf("Test %d: Expected body %s, found %s. Input was SplitFrontMatter(%s)", i, test.body, result.Body, test.input)
}
} }
} }