From 2295594970d4e9c9bb7cca006826423b13be6fd5 Mon Sep 17 00:00:00 2001 From: Niklas Fasching Date: Wed, 19 Dec 2018 18:14:27 +0100 Subject: [PATCH] Refactor FrontMatter parsing to better fit hugo requirements --- org/document.go | 23 ++++++++++++++--------- org/document_test.go | 41 ++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/org/document.go b/org/document.go index 2935875..2168aca 100644 --- a/org/document.go +++ b/org/document.go @@ -30,6 +30,7 @@ type Writer interface { } type Node interface{} +type FrontMatter = map[string]interface{} type lexFn = func(line string) (t token, ok bool) type parseFn = func(*Document, int, stopFn) (int, Node) @@ -57,13 +58,14 @@ var lexFns = []lexFn{ var nilToken = token{"nil", -1, "", nil} -var DefaultFrontMatterHandler = func(k, v string) interface{} { - switch k { - case "TAGS", "CATEGORIES", "ALIASES": - return strings.Fields(v) +func FrontMatterHandler(fm FrontMatter, k, v string) error { + switch k := strings.ToLower(k); k { + case "tags", "categories", "aliases": + fm[k] = strings.Fields(v) default: - return v + fm[k] = v } + return nil } func NewDocument() *Document { @@ -118,9 +120,9 @@ func (d *Document) SetPath(path string) *Document { return d } -func (d *Document) FrontMatter(input io.Reader, f func(string, string) interface{}) (_ map[string]interface{}, err error) { +func GetFrontMatter(input io.Reader, f func(FrontMatter, string, string) error) (_ FrontMatter, err error) { + d := NewDocument() defer func() { - d.tokens = nil if recovered := recover(); recovered != nil { err = fmt.Errorf("could not parse input: %s", recovered) } @@ -133,9 +135,12 @@ func (d *Document) FrontMatter(input io.Reader, f func(string, string) interface t := d.tokens[i] return t.kind != "keyword" && !(t.kind == "text" && t.content == "") }) - frontMatter := make(map[string]interface{}, len(d.BufferSettings)) + frontMatter := make(FrontMatter, len(d.BufferSettings)) for k, v := range d.BufferSettings { - frontMatter[k] = f(k, v) + err := f(frontMatter, k, v) + if err != nil { + return nil, err + } } return frontMatter, err } diff --git a/org/document_test.go b/org/document_test.go index 95e35c7..9406eed 100644 --- a/org/document_test.go +++ b/org/document_test.go @@ -9,18 +9,18 @@ import ( type frontMatterTest struct { name string input string - handler func(string, string) interface{} + handler func(FrontMatter, string, string) error expected map[string]interface{} } var frontMatterTests = []frontMatterTest{ {`basic`, `#+TITLE: The Title`, - DefaultFrontMatterHandler, - map[string]interface{}{"TITLE": "The Title"}}, + FrontMatterHandler, + map[string]interface{}{"title": "The Title"}}, {`empty`, `* No frontmatter here`, - DefaultFrontMatterHandler, + FrontMatterHandler, map[string]interface{}{}}, {`custom handler`, ` @@ -29,17 +29,18 @@ var frontMatterTests = []frontMatterTest{ #+TAGS: foo bar `, - func(k, v string) interface{} { - switch k { - case "TITLE": - return "Thanks For All The Fish" + func(fm FrontMatter, k, v string) error { + switch k := strings.ToLower(k); k { + case "title": + fm[k] = "Thanks For All The Fish" + return nil default: - return DefaultFrontMatterHandler(k, v) + return FrontMatterHandler(fm, k, v) } }, map[string]interface{}{ - "TITLE": "Thanks For All The Fish", - "TAGS": []string{"foo", "bar"}, + "title": "Thanks For All The Fish", + "tags": []string{"foo", "bar"}, }}, {`multiple + ignored keyword`, ` @@ -49,22 +50,28 @@ var frontMatterTests = []frontMatterTest{ #+OTHER: some other keyword #+TAGS: this will become []string + #+ALIASES: foo bar + #+ALIASES: baz bam + #+categories: foo bar + something that's not a keyword or a text line without content #+SUBTITLE: The Subtitle`, - DefaultFrontMatterHandler, + FrontMatterHandler, map[string]interface{}{ - "TITLE": "The Title", - "AUTHOR": "The Author", - "OTHER": "some other keyword", - "TAGS": []string{"this", "will", "become", "[]string"}, + "title": "The Title", + "author": "The Author", + "other": "some other keyword", + "tags": []string{"this", "will", "become", "[]string"}, + "aliases": []string{"foo", "bar", "baz", "bam"}, + "categories": []string{"foo", "bar"}, }, }, } func TestParseFrontMatter(t *testing.T) { for _, test := range frontMatterTests { - actual, err := NewDocument().FrontMatter(strings.NewReader(test.input), test.handler) + actual, err := GetFrontMatter(strings.NewReader(test.input), test.handler) if err != nil { t.Errorf("%s\n got error: %s", test.name, err) continue