summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/huandu/xstrings/format.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/huandu/xstrings/format.go')
-rw-r--r--vendor/github.com/huandu/xstrings/format.go170
1 files changed, 170 insertions, 0 deletions
diff --git a/vendor/github.com/huandu/xstrings/format.go b/vendor/github.com/huandu/xstrings/format.go
new file mode 100644
index 0000000000..2d02df1c04
--- /dev/null
+++ b/vendor/github.com/huandu/xstrings/format.go
@@ -0,0 +1,170 @@
+// Copyright 2015 Huan Du. All rights reserved.
+// Licensed under the MIT license that can be found in the LICENSE file.
+
+package xstrings
+
+import (
+ "bytes"
+ "unicode/utf8"
+)
+
+// ExpandTabs can expand tabs ('\t') rune in str to one or more spaces dpending on
+// current column and tabSize.
+// The column number is reset to zero after each newline ('\n') occurring in the str.
+//
+// ExpandTabs uses RuneWidth to decide rune's width.
+// For example, CJK characters will be treated as two characters.
+//
+// If tabSize <= 0, ExpandTabs panics with error.
+//
+// Samples:
+// ExpandTabs("a\tbc\tdef\tghij\tk", 4) => "a bc def ghij k"
+// ExpandTabs("abcdefg\thij\nk\tl", 4) => "abcdefg hij\nk l"
+// ExpandTabs("z中\t文\tw", 4) => "z中 文 w"
+func ExpandTabs(str string, tabSize int) string {
+ if tabSize <= 0 {
+ panic("tab size must be positive")
+ }
+
+ var r rune
+ var i, size, column, expand int
+ var output *bytes.Buffer
+
+ orig := str
+
+ for len(str) > 0 {
+ r, size = utf8.DecodeRuneInString(str)
+
+ if r == '\t' {
+ expand = tabSize - column%tabSize
+
+ if output == nil {
+ output = allocBuffer(orig, str)
+ }
+
+ for i = 0; i < expand; i++ {
+ output.WriteByte(byte(' '))
+ }
+
+ column += expand
+ } else {
+ if r == '\n' {
+ column = 0
+ } else {
+ column += RuneWidth(r)
+ }
+
+ if output != nil {
+ output.WriteRune(r)
+ }
+ }
+
+ str = str[size:]
+ }
+
+ if output == nil {
+ return orig
+ }
+
+ return output.String()
+}
+
+// LeftJustify returns a string with pad string at right side if str's rune length is smaller than length.
+// If str's rune length is larger than length, str itself will be returned.
+//
+// If pad is an empty string, str will be returned.
+//
+// Samples:
+// LeftJustify("hello", 4, " ") => "hello"
+// LeftJustify("hello", 10, " ") => "hello "
+// LeftJustify("hello", 10, "123") => "hello12312"
+func LeftJustify(str string, length int, pad string) string {
+ l := Len(str)
+
+ if l >= length || pad == "" {
+ return str
+ }
+
+ remains := length - l
+ padLen := Len(pad)
+
+ output := &bytes.Buffer{}
+ output.Grow(len(str) + (remains/padLen+1)*len(pad))
+ output.WriteString(str)
+ writePadString(output, pad, padLen, remains)
+ return output.String()
+}
+
+// RightJustify returns a string with pad string at left side if str's rune length is smaller than length.
+// If str's rune length is larger than length, str itself will be returned.
+//
+// If pad is an empty string, str will be returned.
+//
+// Samples:
+// RightJustify("hello", 4, " ") => "hello"
+// RightJustify("hello", 10, " ") => " hello"
+// RightJustify("hello", 10, "123") => "12312hello"
+func RightJustify(str string, length int, pad string) string {
+ l := Len(str)
+
+ if l >= length || pad == "" {
+ return str
+ }
+
+ remains := length - l
+ padLen := Len(pad)
+
+ output := &bytes.Buffer{}
+ output.Grow(len(str) + (remains/padLen+1)*len(pad))
+ writePadString(output, pad, padLen, remains)
+ output.WriteString(str)
+ return output.String()
+}
+
+// Center returns a string with pad string at both side if str's rune length is smaller than length.
+// If str's rune length is larger than length, str itself will be returned.
+//
+// If pad is an empty string, str will be returned.
+//
+// Samples:
+// Center("hello", 4, " ") => "hello"
+// Center("hello", 10, " ") => " hello "
+// Center("hello", 10, "123") => "12hello123"
+func Center(str string, length int, pad string) string {
+ l := Len(str)
+
+ if l >= length || pad == "" {
+ return str
+ }
+
+ remains := length - l
+ padLen := Len(pad)
+
+ output := &bytes.Buffer{}
+ output.Grow(len(str) + (remains/padLen+1)*len(pad))
+ writePadString(output, pad, padLen, remains/2)
+ output.WriteString(str)
+ writePadString(output, pad, padLen, (remains+1)/2)
+ return output.String()
+}
+
+func writePadString(output *bytes.Buffer, pad string, padLen, remains int) {
+ var r rune
+ var size int
+
+ repeats := remains / padLen
+
+ for i := 0; i < repeats; i++ {
+ output.WriteString(pad)
+ }
+
+ remains = remains % padLen
+
+ if remains != 0 {
+ for i := 0; i < remains; i++ {
+ r, size = utf8.DecodeRuneInString(pad)
+ output.WriteRune(r)
+ pad = pad[size:]
+ }
+ }
+}