-
Notifications
You must be signed in to change notification settings - Fork 0
/
string.go
195 lines (162 loc) · 5.99 KB
/
string.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package tplfuncs
import (
"fmt"
htmlTemplate "html/template"
"regexp"
"strings"
textTemplate "text/template"
"github.com/hexops/gotextdiff"
"github.com/hexops/gotextdiff/myers"
"github.com/hexops/gotextdiff/span"
"github.com/iancoleman/strcase"
)
// StringHelpers returns a text template FuncMap with math related functions
func StringHelpers() textTemplate.FuncMap {
return textTemplate.FuncMap{
// string checks
"stringContains": stringContainsFunc,
"stringHasPrefix": stringHasPrefixFunc,
"stringHasSuffix": stringHasSuffixFunc,
"eqIgnoreCase": eqIgnoreCaseFunc,
"eqFold": eqFoldFunc,
// string manipulation
"trim": trimFunc,
"trimPrefix": trimPrefixFunc,
"trimSuffix": trimSuffixFunc,
"replace": replaceFunc,
"regexpReplace": regexpReplaceFunc,
// string casing
"toUpperCase": toUpperCaseFunc,
"toLowerCase": toLowerCaseFunc,
"toCamelCase": toCamelCaseFunc,
"toLowerCamelCase": toLowerCamelCaseFunc,
"toSnakeCase": toSnakeCaseFunc,
"toKebabCase": toKebabCaseFunc,
// clean string
"toFilename": stringToFilenameFunc,
"toURL": stringToURLFunc,
"deHTML": deHTMLFunc,
// diff
"diff": diffFunc,
}
}
// StringHelpersHTML returns an HTML template FuncMap with math related functions
func StringHelpersHTML() htmlTemplate.FuncMap {
return htmlTemplate.FuncMap(StringHelpers())
}
// Doc: `trim` removes all leading and trailing whitespace from the given string. Returns the string unchanged if neither exists.
func trimFunc(input string) string {
return strings.TrimSpace(input)
}
// Doc: `eqFold` compares two strings disregarding their casing.
func eqFoldFunc(a, b string) bool {
return strings.EqualFold(a, b)
}
// Doc: `eqIgnoreCase` is an alias for `eqFold`.
func eqIgnoreCaseFunc(a, b string) bool {
return eqFoldFunc(a, b)
}
// Doc: `stringContains` checks if one string is contained in another.
func stringContainsFunc(needle, haystack string) bool {
return strings.Contains(haystack, needle)
}
// Doc: `stringHasPrefix` determines if a string starts with a given other string.
func stringHasPrefixFunc(prefix, testString string) bool {
return strings.HasPrefix(testString, prefix)
}
// Doc: `stringHasSuffix` determines if a string ends with a given other string.
func stringHasSuffixFunc(suffix, testString string) bool {
return strings.HasSuffix(testString, suffix)
}
// Doc: `toUpperCase` returns the given string converted to all uppercase letters.
func toUpperCaseFunc(input string) string {
return strings.ToUpper(input)
}
// Doc: `toLowerCase` returns the given string converted to all lowercase letters.
func toLowerCaseFunc(input string) string {
return strings.ToLower(input)
}
// Doc: `toCamelCase` returns the given string converted to camel case (https://en.wikipedia.org/wiki/Camel_case), first letter uppercase.
func toCamelCaseFunc(input string) string {
return strcase.ToCamel(input)
}
// Doc: `toLowerCamelCase` returns the given string converted to lower camel case (https://en.wikipedia.org/wiki/Camel_case), first letter lowercase.
func toLowerCamelCaseFunc(input string) string {
return strcase.ToLowerCamel(input)
}
// Doc: `toSnakeCase` returns the given string converted to snake case (https://en.wikipedia.org/wiki/Snake_case).
func toSnakeCaseFunc(input string) string {
return strcase.ToSnake(input)
}
// Doc: `toKebabCase` returns the given string converted to kebab case (https://en.wikipedia.org/wiki/Kebab_case).
func toKebabCaseFunc(input string) string {
return strcase.ToKebab(input)
}
// Doc: `trimPrefix` returns the given string without the given prefix if there is one, otherwise the string is returned unchanged.
func trimPrefixFunc(prefix, input string) string {
return strings.TrimPrefix(input, prefix)
}
// Doc: `trimSuffix` returns the given string without the given suffix if there is one, otherwise the string is returned unchanged.
func trimSuffixFunc(suffix, input string) string {
return strings.TrimSuffix(input, suffix)
}
func stringCleanFunc(replacement rune, input string) string {
repl := regexp.MustCompile(`[^A-Za-z0-9]+`)
replacedString := repl.ReplaceAllString(input, string(replacement))
// remove leading, doubled and trailing replacement runes
var (
r rune
result = ""
activeReplacement = false
)
for _, r = range replacedString {
if r == replacement {
// skip doubled
if activeReplacement {
continue
} else {
// skip leading
if len(result) == 0 {
continue
} else {
activeReplacement = true
}
continue
}
}
// r != replacement
if activeReplacement {
result += string(replacement)
activeReplacement = false
}
result += string(r)
}
return result
}
// Doc: 'stringToFilename' returns the given string suitable for a filename.
func stringToFilenameFunc(input string) string {
return strcase.ToSnake(stringCleanFunc('_', input))
}
// Doc: 'stringToURL' returns the given string suitable for a URL.
func stringToURLFunc(input string) string {
return strcase.ToKebab(stringCleanFunc('-', input))
}
// Doc: `diffFunc` returns the diff between two strings with their associated names.
func diffFunc(nameA, contentA, nameB, contentB string, numContextLines int) string {
edits := myers.ComputeEdits(span.URIFromPath(nameA), contentA, contentB)
diff := fmt.Sprint(gotextdiff.ToUnified(nameA, nameB, contentA, edits))
return diff
}
// Doc: `deHTML` returns the raw string contained in a template.HTML.
func deHTMLFunc(input htmlTemplate.HTML) string {
return string(input)
}
// Doc: `replace` returns a given string with all occurrences of the given substring replaced by the replacement string.
func replaceFunc(search, replacement, input string) string {
return strings.ReplaceAll(input, search, replacement)
}
// Doc: `regexpReplace` returns a given string with all occurrences of the given regexp replaced by the replacement string.
func regexpReplaceFunc(regexpValue, replacement, input string) string {
r := regexp.MustCompile(regexpValue)
return r.ReplaceAllString(input, replacement)
}