-
Notifications
You must be signed in to change notification settings - Fork 120
/
format.go
100 lines (93 loc) · 1.94 KB
/
format.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
package text
import (
"strings"
"unicode"
)
// Format lets you transform the text in supported methods while keeping escape
// sequences in the string intact and untouched.
type Format int
// Format enumerations
const (
FormatDefault Format = iota // default_Case
FormatLower // lower
FormatTitle // Title
FormatUpper // UPPER
)
// Apply converts the text as directed.
func (tc Format) Apply(text string) string {
switch tc {
case FormatLower:
return strings.ToLower(text)
case FormatTitle:
return toTitle(text)
case FormatUpper:
return toUpper(text)
default:
return text
}
}
func toTitle(text string) string {
prev, inEscSeq := ' ', false
return strings.Map(
func(r rune) rune {
if r == EscapeStartRune {
inEscSeq = true
}
if !inEscSeq {
if isSeparator(prev) {
prev = r
r = unicode.ToUpper(r)
} else {
prev = r
}
}
if inEscSeq && r == EscapeStopRune {
inEscSeq = false
}
return r
},
text,
)
}
func toUpper(text string) string {
inEscSeq := false
return strings.Map(
func(r rune) rune {
if r == EscapeStartRune {
inEscSeq = true
}
if !inEscSeq {
r = unicode.ToUpper(r)
}
if inEscSeq && r == EscapeStopRune {
inEscSeq = false
}
return r
},
text,
)
}
// isSeparator returns true if the given rune is a separator. This function is
// lifted straight out of the standard library @ strings/strings.go.
func isSeparator(r rune) bool {
// ASCII alphanumerics and underscore are not separators
if r <= 0x7F {
switch {
case '0' <= r && r <= '9':
return false
case 'a' <= r && r <= 'z':
return false
case 'A' <= r && r <= 'Z':
return false
case r == '_':
return false
}
return true
}
// Letters and digits are not separators
if unicode.IsLetter(r) || unicode.IsDigit(r) {
return false
}
// Otherwise, all we can do for now is treat spaces as separators.
return unicode.IsSpace(r)
}