...
1
2
3
4 package xstrings
5
6 import (
7 "unicode/utf8"
8 )
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 func ExpandTabs(str string, tabSize int) string {
25 if tabSize <= 0 {
26 panic("tab size must be positive")
27 }
28
29 var r rune
30 var i, size, column, expand int
31 var output *stringBuilder
32
33 orig := str
34
35 for len(str) > 0 {
36 r, size = utf8.DecodeRuneInString(str)
37
38 if r == '\t' {
39 expand = tabSize - column%tabSize
40
41 if output == nil {
42 output = allocBuffer(orig, str)
43 }
44
45 for i = 0; i < expand; i++ {
46 output.WriteRune(' ')
47 }
48
49 column += expand
50 } else {
51 if r == '\n' {
52 column = 0
53 } else {
54 column += RuneWidth(r)
55 }
56
57 if output != nil {
58 output.WriteRune(r)
59 }
60 }
61
62 str = str[size:]
63 }
64
65 if output == nil {
66 return orig
67 }
68
69 return output.String()
70 }
71
72
73
74
75
76
77
78
79
80
81
82 func LeftJustify(str string, length int, pad string) string {
83 l := Len(str)
84
85 if l >= length || pad == "" {
86 return str
87 }
88
89 remains := length - l
90 padLen := Len(pad)
91
92 output := &stringBuilder{}
93 output.Grow(len(str) + (remains/padLen+1)*len(pad))
94 output.WriteString(str)
95 writePadString(output, pad, padLen, remains)
96 return output.String()
97 }
98
99
100
101
102
103
104
105
106
107
108
109 func RightJustify(str string, length int, pad string) string {
110 l := Len(str)
111
112 if l >= length || pad == "" {
113 return str
114 }
115
116 remains := length - l
117 padLen := Len(pad)
118
119 output := &stringBuilder{}
120 output.Grow(len(str) + (remains/padLen+1)*len(pad))
121 writePadString(output, pad, padLen, remains)
122 output.WriteString(str)
123 return output.String()
124 }
125
126
127
128
129
130
131
132
133
134
135
136 func Center(str string, length int, pad string) string {
137 l := Len(str)
138
139 if l >= length || pad == "" {
140 return str
141 }
142
143 remains := length - l
144 padLen := Len(pad)
145
146 output := &stringBuilder{}
147 output.Grow(len(str) + (remains/padLen+1)*len(pad))
148 writePadString(output, pad, padLen, remains/2)
149 output.WriteString(str)
150 writePadString(output, pad, padLen, (remains+1)/2)
151 return output.String()
152 }
153
154 func writePadString(output *stringBuilder, pad string, padLen, remains int) {
155 var r rune
156 var size int
157
158 repeats := remains / padLen
159
160 for i := 0; i < repeats; i++ {
161 output.WriteString(pad)
162 }
163
164 remains = remains % padLen
165
166 if remains != 0 {
167 for i := 0; i < remains; i++ {
168 r, size = utf8.DecodeRuneInString(pad)
169 output.WriteRune(r)
170 pad = pad[size:]
171 }
172 }
173 }
174
View as plain text