...
1
2
3
4
5 package precis
6
7 import (
8 "golang.org/x/text/cases"
9 "golang.org/x/text/language"
10 "golang.org/x/text/runes"
11 "golang.org/x/text/transform"
12 "golang.org/x/text/unicode/norm"
13 )
14
15
16 type Option func(*options)
17
18 type options struct {
19
20 foldWidth bool
21
22
23 asciiLower bool
24 cases transform.SpanningTransformer
25 disallow runes.Set
26 norm transform.SpanningTransformer
27 additional []func() transform.SpanningTransformer
28 width transform.SpanningTransformer
29 disallowEmpty bool
30 bidiRule bool
31 repeat bool
32
33
34 ignorecase bool
35 }
36
37 func getOpts(o ...Option) (res options) {
38 for _, f := range o {
39 f(&res)
40 }
41
42
43 if res.norm == nil {
44 res.norm = norm.NFC
45 }
46 return
47 }
48
49 var (
50
51
52 IgnoreCase Option = ignoreCase
53
54
55
56
57
58 FoldWidth Option = foldWidth
59
60
61
62 DisallowEmpty Option = disallowEmpty
63
64
65
66 BidiRule Option = bidiRule
67 )
68
69 var (
70 ignoreCase = func(o *options) {
71 o.ignorecase = true
72 }
73 foldWidth = func(o *options) {
74 o.foldWidth = true
75 }
76 disallowEmpty = func(o *options) {
77 o.disallowEmpty = true
78 }
79 bidiRule = func(o *options) {
80 o.bidiRule = true
81 }
82 repeat = func(o *options) {
83 o.repeat = true
84 }
85 )
86
87
88
89 type spanWrap struct{ transform.Transformer }
90
91 func (s spanWrap) Span(src []byte, atEOF bool) (n int, err error) {
92 return 0, transform.ErrEndOfSpan
93 }
94
95
96
97
98
99
100
101
102
103
104 func AdditionalMapping(t ...func() transform.Transformer) Option {
105 return func(o *options) {
106 for _, f := range t {
107 sf := func() transform.SpanningTransformer {
108 return f().(transform.SpanningTransformer)
109 }
110 if _, ok := f().(transform.SpanningTransformer); !ok {
111 sf = func() transform.SpanningTransformer {
112 return spanWrap{f()}
113 }
114 }
115 o.additional = append(o.additional, sf)
116 }
117 }
118 }
119
120
121 func Norm(f norm.Form) Option {
122 return func(o *options) {
123 o.norm = f
124 }
125 }
126
127
128
129 func FoldCase(opts ...cases.Option) Option {
130 return func(o *options) {
131 o.asciiLower = true
132 o.cases = cases.Fold(opts...)
133 }
134 }
135
136
137
138 func LowerCase(opts ...cases.Option) Option {
139 return func(o *options) {
140 o.asciiLower = true
141 if len(opts) == 0 {
142 o.cases = cases.Lower(language.Und, cases.HandleFinalSigma(false))
143 return
144 }
145
146 opts = append([]cases.Option{cases.HandleFinalSigma(false)}, opts...)
147 o.cases = cases.Lower(language.Und, opts...)
148 }
149 }
150
151
152
153 func Disallow(set runes.Set) Option {
154 return func(o *options) {
155 o.disallow = set
156 }
157 }
158
View as plain text