1package pages
2
3import (
4 "fmt"
5 "html"
6 "html/template"
7 "reflect"
8 "strings"
9
10 "github.com/dustin/go-humanize"
11)
12
13func funcMap() template.FuncMap {
14 return template.FuncMap{
15 "split": func(s string) []string {
16 return strings.Split(s, "\n")
17 },
18 "splitOn": func(s, sep string) []string {
19 return strings.Split(s, sep)
20 },
21 "add": func(a, b int) int {
22 return a + b
23 },
24 "sub": func(a, b int) int {
25 return a - b
26 },
27 "cond": func(cond interface{}, a, b string) string {
28 if cond == nil {
29 return b
30 }
31
32 if boolean, ok := cond.(bool); boolean && ok {
33 return a
34 }
35
36 return b
37 },
38 "didOrHandle": func(did, handle string) string {
39 if handle != "" {
40 return fmt.Sprintf("@%s", handle)
41 } else {
42 return did
43 }
44 },
45 "assoc": func(values ...string) ([][]string, error) {
46 if len(values)%2 != 0 {
47 return nil, fmt.Errorf("invalid assoc call, must have an even number of arguments")
48 }
49 pairs := make([][]string, 0)
50 for i := 0; i < len(values); i += 2 {
51 pairs = append(pairs, []string{values[i], values[i+1]})
52 }
53 return pairs, nil
54 },
55 "append": func(s []string, values ...string) []string {
56 s = append(s, values...)
57 return s
58 },
59 "timeFmt": humanize.Time,
60 "byteFmt": humanize.Bytes,
61 "length": func(slice interface{}) int {
62 v := reflect.ValueOf(slice)
63 if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {
64 return v.Len()
65 }
66 return 0
67 },
68 "splitN": func(s, sep string, n int) []string {
69 return strings.SplitN(s, sep, n)
70 },
71 "escapeHtml": func(s string) template.HTML {
72 if s == "" {
73 return template.HTML("<br>")
74 }
75 return template.HTML(s)
76 },
77 "unescapeHtml": func(s string) string {
78 return html.UnescapeString(s)
79 },
80 "nl2br": func(text string) template.HTML {
81 return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1))
82 },
83 "unwrapText": func(text string) string {
84 paragraphs := strings.Split(text, "\n\n")
85
86 for i, p := range paragraphs {
87 lines := strings.Split(p, "\n")
88 paragraphs[i] = strings.Join(lines, " ")
89 }
90
91 return strings.Join(paragraphs, "\n\n")
92 },
93 "sequence": func(n int) []struct{} {
94 return make([]struct{}, n)
95 },
96 "subslice": func(slice interface{}, start, end int) interface{} {
97 v := reflect.ValueOf(slice)
98 if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
99 return nil
100 }
101 if start < 0 || start > v.Len() || end > v.Len() || start > end {
102 return nil
103 }
104 return v.Slice(start, end).Interface()
105 },
106 "markdown": func(text string) template.HTML {
107 return template.HTML(renderMarkdown(text))
108 },
109 }
110}