/
f_slugify.go
62 lines (59 loc) · 1.57 KB
/
f_slugify.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
package main
import (
"errors"
"fmt"
"regexp"
"strings"
"unicode"
"code.google.com/p/go.text/unicode/norm"
)
func init() {
allowed := []*unicode.RangeTable{unicode.Letter, unicode.Number}
dashes := regexp.MustCompile("-+")
funcMap["slugify"] = &tmplFuncStruct{
short: "Transform text to a slugified version. You can optionally specify a unicode normalization rule (NFC, NFD, NFKC, NFKD). Default is NFC.",
examples: []string{
`{{ "Hello WORLD!" | %s }}`,
`{{ "Hello W/O-R_L~D!" | %s }}`,
` NFC: {{ "Hello áçćèńtš!" | %[1]s "NFC" }}
NFD: {{ "Hello áçćèńtš!" | %[1]s "NFD" }}
NFKC: {{ "Hello áçćèńtš!" | %[1]s "NFKC" }}
NFKD: {{ "Hello áçćèńtš!" | %[1]s "NFKD" }}`,
},
fn: func(in ...string) (string, error) {
var src, mode string
switch len(in) {
case 1:
src = in[0]
case 2:
src = in[1]
mode = in[0]
default:
return "", errors.New("Expecting 1 or 2 arguments.")
}
switch strings.ToUpper(mode) {
case "NFC", "C", "":
src = norm.NFC.String(src)
case "NFD", "D":
src = norm.NFD.String(src)
case "NFKC", "KC":
src = norm.NFKC.String(src)
case "NFKD", "KD":
src = norm.NFKD.String(src)
default:
return "", fmt.Errorf("Unknown normalisation '%s'.", mode)
}
var runes []rune
for _, r := range src {
if unicode.IsOneOf(allowed, r) || r == '-' || r == '_' || r == '~' {
runes = append(runes, r)
} else if unicode.IsSpace(r) {
runes = append(runes, '-')
}
}
return strings.ToLower(
dashes.ReplaceAllString(string(runes), "-"),
), nil
},
}
}