...
1 package text
2
3 import (
4 "strings"
5 "unicode"
6 )
7
8
9
10 type Format int
11
12
13 const (
14 FormatDefault Format = iota
15 FormatLower
16 FormatTitle
17 FormatUpper
18 )
19
20
21 func (tc Format) Apply(text string) string {
22 switch tc {
23 case FormatLower:
24 return strings.ToLower(text)
25 case FormatTitle:
26 return toTitle(text)
27 case FormatUpper:
28 return toUpper(text)
29 default:
30 return text
31 }
32 }
33
34 func toTitle(text string) string {
35 prev, inEscSeq := ' ', false
36 return strings.Map(
37 func(r rune) rune {
38 if r == EscapeStartRune {
39 inEscSeq = true
40 }
41 if !inEscSeq {
42 if isSeparator(prev) {
43 prev = r
44 r = unicode.ToUpper(r)
45 } else {
46 prev = r
47 }
48 }
49 if inEscSeq && r == EscapeStopRune {
50 inEscSeq = false
51 }
52 return r
53 },
54 text,
55 )
56 }
57
58 func toUpper(text string) string {
59 inEscSeq := false
60 return strings.Map(
61 func(r rune) rune {
62 if r == EscapeStartRune {
63 inEscSeq = true
64 }
65 if !inEscSeq {
66 r = unicode.ToUpper(r)
67 }
68 if inEscSeq && r == EscapeStopRune {
69 inEscSeq = false
70 }
71 return r
72 },
73 text,
74 )
75 }
76
77
78
79 func isSeparator(r rune) bool {
80
81 if r <= 0x7F {
82 switch {
83 case '0' <= r && r <= '9':
84 return false
85 case 'a' <= r && r <= 'z':
86 return false
87 case 'A' <= r && r <= 'Z':
88 return false
89 case r == '_':
90 return false
91 }
92 return true
93 }
94
95 if unicode.IsLetter(r) || unicode.IsDigit(r) {
96 return false
97 }
98
99 return unicode.IsSpace(r)
100 }
101
View as plain text