mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-27 14:13:48 +03: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:
parent
5b48f784ae
commit
003403ecbc
2 changed files with 59 additions and 19 deletions
|
@ -34,25 +34,30 @@ func extractFrontMatter(input string) (map[string]interface{}, string, error) {
|
|||
firstLine = strings.TrimSpace(firstLine)
|
||||
|
||||
// see what kind of front matter there is, if any
|
||||
var closingFence string
|
||||
var closingFence []string
|
||||
var fmParser func([]byte) (map[string]interface{}, error)
|
||||
switch firstLine {
|
||||
case yamlFrontMatterFenceOpen:
|
||||
fmParser = yamlFrontMatter
|
||||
closingFence = yamlFrontMatterFenceClose
|
||||
case tomlFrontMatterFenceOpen:
|
||||
fmParser = tomlFrontMatter
|
||||
closingFence = tomlFrontMatterFenceClose
|
||||
case jsonFrontMatterFenceOpen:
|
||||
fmParser = jsonFrontMatter
|
||||
closingFence = jsonFrontMatterFenceClose
|
||||
default:
|
||||
for _, fmType := range supportedFrontMatterTypes {
|
||||
if firstLine == fmType.FenceOpen {
|
||||
closingFence = fmType.FenceClose
|
||||
fmParser = fmType.ParseFunc
|
||||
}
|
||||
}
|
||||
|
||||
if fmParser == nil {
|
||||
// no recognized front matter; whole document is body
|
||||
return nil, input, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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
|
||||
body := input[fmEndFenceStart+len(closingFence):]
|
||||
body := input[fmEndFenceStart+len(fmEndFence):]
|
||||
|
||||
return fm, body, nil
|
||||
}
|
||||
|
@ -96,8 +101,26 @@ type parsedMarkdownDoc struct {
|
|||
Body string `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
yamlFrontMatterFenceOpen, yamlFrontMatterFenceClose = "---", "---"
|
||||
tomlFrontMatterFenceOpen, tomlFrontMatterFenceClose = "+++", "+++"
|
||||
jsonFrontMatterFenceOpen, jsonFrontMatterFenceClose = "{", "}"
|
||||
)
|
||||
type frontMatterType struct {
|
||||
FenceOpen string
|
||||
FenceClose []string
|
||||
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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -290,11 +290,13 @@ func TestSplitFrontMatter(t *testing.T) {
|
|||
for i, test := range []struct {
|
||||
input string
|
||||
expect string
|
||||
body string
|
||||
}{
|
||||
{
|
||||
// yaml with windows newline
|
||||
input: "---\r\ntitle: Welcome\r\n---\r\n# Test\\r\\n",
|
||||
expect: `Welcome`,
|
||||
body: "\r\n# Test\\r\\n",
|
||||
},
|
||||
{
|
||||
// yaml
|
||||
|
@ -303,6 +305,16 @@ title: Welcome
|
|||
---
|
||||
### Test`,
|
||||
expect: `Welcome`,
|
||||
body: "\n### Test",
|
||||
},
|
||||
{
|
||||
// yaml with dots for closer
|
||||
input: `---
|
||||
title: Welcome
|
||||
...
|
||||
### Test`,
|
||||
expect: `Welcome`,
|
||||
body: "\n### Test",
|
||||
},
|
||||
{
|
||||
// toml
|
||||
|
@ -311,6 +323,7 @@ title = "Welcome"
|
|||
+++
|
||||
### Test`,
|
||||
expect: `Welcome`,
|
||||
body: "\n### Test",
|
||||
},
|
||||
{
|
||||
// json
|
||||
|
@ -319,12 +332,16 @@ title = "Welcome"
|
|||
}
|
||||
### Test`,
|
||||
expect: `Welcome`,
|
||||
body: "\n### Test",
|
||||
},
|
||||
} {
|
||||
result, _ := context.funcSplitFrontMatter(test.input)
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue