podman

Форк
0
169 строк · 4.0 Кб
1
// Copyright 2015 Huan Du. All rights reserved.
2
// Licensed under the MIT license that can be found in the LICENSE file.
3

4
package xstrings
5

6
import (
7
	"unicode/utf8"
8
)
9

10
// ExpandTabs can expand tabs ('\t') rune in str to one or more spaces dpending on
11
// current column and tabSize.
12
// The column number is reset to zero after each newline ('\n') occurring in the str.
13
//
14
// ExpandTabs uses RuneWidth to decide rune's width.
15
// For example, CJK characters will be treated as two characters.
16
//
17
// If tabSize <= 0, ExpandTabs panics with error.
18
//
19
// Samples:
20
//     ExpandTabs("a\tbc\tdef\tghij\tk", 4) => "a   bc  def ghij    k"
21
//     ExpandTabs("abcdefg\thij\nk\tl", 4)  => "abcdefg hij\nk   l"
22
//     ExpandTabs("z中\t文\tw", 4)           => "z中 文  w"
23
func ExpandTabs(str string, tabSize int) string {
24
	if tabSize <= 0 {
25
		panic("tab size must be positive")
26
	}
27

28
	var r rune
29
	var i, size, column, expand int
30
	var output *stringBuilder
31

32
	orig := str
33

34
	for len(str) > 0 {
35
		r, size = utf8.DecodeRuneInString(str)
36

37
		if r == '\t' {
38
			expand = tabSize - column%tabSize
39

40
			if output == nil {
41
				output = allocBuffer(orig, str)
42
			}
43

44
			for i = 0; i < expand; i++ {
45
				output.WriteRune(' ')
46
			}
47

48
			column += expand
49
		} else {
50
			if r == '\n' {
51
				column = 0
52
			} else {
53
				column += RuneWidth(r)
54
			}
55

56
			if output != nil {
57
				output.WriteRune(r)
58
			}
59
		}
60

61
		str = str[size:]
62
	}
63

64
	if output == nil {
65
		return orig
66
	}
67

68
	return output.String()
69
}
70

71
// LeftJustify returns a string with pad string at right side if str's rune length is smaller than length.
72
// If str's rune length is larger than length, str itself will be returned.
73
//
74
// If pad is an empty string, str will be returned.
75
//
76
// Samples:
77
//     LeftJustify("hello", 4, " ")    => "hello"
78
//     LeftJustify("hello", 10, " ")   => "hello     "
79
//     LeftJustify("hello", 10, "123") => "hello12312"
80
func LeftJustify(str string, length int, pad string) string {
81
	l := Len(str)
82

83
	if l >= length || pad == "" {
84
		return str
85
	}
86

87
	remains := length - l
88
	padLen := Len(pad)
89

90
	output := &stringBuilder{}
91
	output.Grow(len(str) + (remains/padLen+1)*len(pad))
92
	output.WriteString(str)
93
	writePadString(output, pad, padLen, remains)
94
	return output.String()
95
}
96

97
// RightJustify returns a string with pad string at left side if str's rune length is smaller than length.
98
// If str's rune length is larger than length, str itself will be returned.
99
//
100
// If pad is an empty string, str will be returned.
101
//
102
// Samples:
103
//     RightJustify("hello", 4, " ")    => "hello"
104
//     RightJustify("hello", 10, " ")   => "     hello"
105
//     RightJustify("hello", 10, "123") => "12312hello"
106
func RightJustify(str string, length int, pad string) string {
107
	l := Len(str)
108

109
	if l >= length || pad == "" {
110
		return str
111
	}
112

113
	remains := length - l
114
	padLen := Len(pad)
115

116
	output := &stringBuilder{}
117
	output.Grow(len(str) + (remains/padLen+1)*len(pad))
118
	writePadString(output, pad, padLen, remains)
119
	output.WriteString(str)
120
	return output.String()
121
}
122

123
// Center returns a string with pad string at both side if str's rune length is smaller than length.
124
// If str's rune length is larger than length, str itself will be returned.
125
//
126
// If pad is an empty string, str will be returned.
127
//
128
// Samples:
129
//     Center("hello", 4, " ")    => "hello"
130
//     Center("hello", 10, " ")   => "  hello   "
131
//     Center("hello", 10, "123") => "12hello123"
132
func Center(str string, length int, pad string) string {
133
	l := Len(str)
134

135
	if l >= length || pad == "" {
136
		return str
137
	}
138

139
	remains := length - l
140
	padLen := Len(pad)
141

142
	output := &stringBuilder{}
143
	output.Grow(len(str) + (remains/padLen+1)*len(pad))
144
	writePadString(output, pad, padLen, remains/2)
145
	output.WriteString(str)
146
	writePadString(output, pad, padLen, (remains+1)/2)
147
	return output.String()
148
}
149

150
func writePadString(output *stringBuilder, pad string, padLen, remains int) {
151
	var r rune
152
	var size int
153

154
	repeats := remains / padLen
155

156
	for i := 0; i < repeats; i++ {
157
		output.WriteString(pad)
158
	}
159

160
	remains = remains % padLen
161

162
	if remains != 0 {
163
		for i := 0; i < remains; i++ {
164
			r, size = utf8.DecodeRuneInString(pad)
165
			output.WriteRune(r)
166
			pad = pad[size:]
167
		}
168
	}
169
}
170

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.