-
Notifications
You must be signed in to change notification settings - Fork 13
/
frontmatter.go
101 lines (91 loc) · 2.3 KB
/
frontmatter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package frontmatter
import (
"fmt"
"reflect"
"sort"
"strings"
"github.com/osteele/liquid/evaluator"
)
// FrontMatter wraps a map to provide interface functions
type FrontMatter map[string]interface{}
// Bool returns m[k] if it's a bool; else defaultValue.
func (fm FrontMatter) Bool(k string, defaultValue bool) bool {
if val, found := fm[k]; found {
if v, ok := val.(bool); ok {
return v
}
}
return defaultValue
}
// Get returns m[k] if present; else defaultValue.
func (fm FrontMatter) Get(k string, defaultValue interface{}) interface{} {
if val, found := fm[k]; found {
return val
}
return defaultValue
}
// String returns m[k] if it's a string or can be stringified; else defaultValue.
func (fm FrontMatter) String(k string, defaultValue string) string {
if val, found := fm[k]; found {
switch v := val.(type) {
case string:
return v
case fmt.Stringer:
return v.String()
}
}
return defaultValue
}
// StringArray returns m[k] if it's a []string or string array
func (fm FrontMatter) StringArray(k string) []string {
if value, ok := fm[k]; ok {
switch value := value.(type) {
case []string:
return value
case []interface{}:
a := make([]string, len(value))
for i, item := range value {
a[i] = fmt.Sprintf("%s", item)
}
return a
case string:
return []string{value}
}
}
return nil
}
// SortedStringArray returns a sorts list of strings from a
// frontmatter variable that is either a string (in which case it
// is a ws-separated list of words), or a list of strings.
//
// This is the format for page categories and tags.
func (fm FrontMatter) SortedStringArray(key string) []string {
var result []string
switch v := fm[key].(type) {
case string:
result = strings.Fields(v)
case []interface{}:
if c, e := evaluator.Convert(v, reflect.TypeOf(result)); e == nil {
result = c.([]string)
}
case []string:
result = v
}
sort.Strings(result)
return result
}
// Merge creates a new FrontMatter that merges its arguments,
// from first to last.
func Merge(fms ...FrontMatter) FrontMatter {
result := FrontMatter{}
for _, fm := range fms {
for k, v := range fm {
result[k] = v
}
}
return result
}
// Merged returns a new FrontMatter.
func (fm FrontMatter) Merged(fms ...FrontMatter) FrontMatter {
return Merge(append([]FrontMatter{fm}, fms...)...)
}