podman
357 строк · 9.6 Кб
1/*
2Copyright 2014 Alexander Okoli
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17/*
18Package goutils provides utility functions to manipulate strings in various ways.
19The code snippets below show examples of how to use goutils. Some functions return
20errors while others do not, so usage would vary as a result.
21
22Example:
23
24package main
25
26import (
27"fmt"
28"github.com/aokoli/goutils"
29)
30
31func main() {
32
33// EXAMPLE 1: A goutils function which returns no errors
34fmt.Println (goutils.Initials("John Doe Foo")) // Prints out "JDF"
35
36
37
38// EXAMPLE 2: A goutils function which returns an error
39rand1, err1 := goutils.Random (-1, 0, 0, true, true)
40
41if err1 != nil {
42fmt.Println(err1) // Prints out error message because -1 was entered as the first parameter in goutils.Random(...)
43} else {
44fmt.Println(rand1)
45}
46}
47*/
48package goutils49
50import (51"bytes"52"strings"53"unicode"54)
55
56// VERSION indicates the current version of goutils
57const VERSION = "1.0.0"58
59/*
60Wrap wraps a single line of text, identifying words by ' '.
61New lines will be separated by '\n'. Very long words, such as URLs will not be wrapped.
62Leading spaces on a new line are stripped. Trailing spaces are not stripped.
63
64Parameters:
65str - the string to be word wrapped
66wrapLength - the column (a column can fit only one character) to wrap the words at, less than 1 is treated as 1
67
68Returns:
69a line with newlines inserted
70*/
71func Wrap(str string, wrapLength int) string {72return WrapCustom(str, wrapLength, "", false)73}
74
75/*
76WrapCustom wraps a single line of text, identifying words by ' '.
77Leading spaces on a new line are stripped. Trailing spaces are not stripped.
78
79Parameters:
80str - the string to be word wrapped
81wrapLength - the column number (a column can fit only one character) to wrap the words at, less than 1 is treated as 1
82newLineStr - the string to insert for a new line, "" uses '\n'
83wrapLongWords - true if long words (such as URLs) should be wrapped
84
85Returns:
86a line with newlines inserted
87*/
88func WrapCustom(str string, wrapLength int, newLineStr string, wrapLongWords bool) string {89
90if str == "" {91return ""92}93if newLineStr == "" {94newLineStr = "\n" // TODO Assumes "\n" is seperator. Explore SystemUtils.LINE_SEPARATOR from Apache Commons95}96if wrapLength < 1 {97wrapLength = 198}99
100inputLineLength := len(str)101offset := 0102
103var wrappedLine bytes.Buffer104
105for inputLineLength-offset > wrapLength {106
107if rune(str[offset]) == ' ' {108offset++109continue110}111
112end := wrapLength + offset + 1113spaceToWrapAt := strings.LastIndex(str[offset:end], " ") + offset114
115if spaceToWrapAt >= offset {116// normal word (not longer than wrapLength)117wrappedLine.WriteString(str[offset:spaceToWrapAt])118wrappedLine.WriteString(newLineStr)119offset = spaceToWrapAt + 1120
121} else {122// long word or URL123if wrapLongWords {124end := wrapLength + offset125// long words are wrapped one line at a time126wrappedLine.WriteString(str[offset:end])127wrappedLine.WriteString(newLineStr)128offset += wrapLength129} else {130// long words aren't wrapped, just extended beyond limit131end := wrapLength + offset132index := strings.IndexRune(str[end:len(str)], ' ')133if index == -1 {134wrappedLine.WriteString(str[offset:len(str)])135offset = inputLineLength136} else {137spaceToWrapAt = index + end138wrappedLine.WriteString(str[offset:spaceToWrapAt])139wrappedLine.WriteString(newLineStr)140offset = spaceToWrapAt + 1141}142}143}144}145
146wrappedLine.WriteString(str[offset:len(str)])147
148return wrappedLine.String()149
150}
151
152/*
153Capitalize capitalizes all the delimiter separated words in a string. Only the first letter of each word is changed.
154To convert the rest of each word to lowercase at the same time, use CapitalizeFully(str string, delimiters ...rune).
155The delimiters represent a set of characters understood to separate words. The first string character
156and the first non-delimiter character after a delimiter will be capitalized. A "" input string returns "".
157Capitalization uses the Unicode title case, normally equivalent to upper case.
158
159Parameters:
160str - the string to capitalize
161delimiters - set of characters to determine capitalization, exclusion of this parameter means whitespace would be delimeter
162
163Returns:
164capitalized string
165*/
166func Capitalize(str string, delimiters ...rune) string {167
168var delimLen int169
170if delimiters == nil {171delimLen = -1172} else {173delimLen = len(delimiters)174}175
176if str == "" || delimLen == 0 {177return str178}179
180buffer := []rune(str)181capitalizeNext := true182for i := 0; i < len(buffer); i++ {183ch := buffer[i]184if isDelimiter(ch, delimiters...) {185capitalizeNext = true186} else if capitalizeNext {187buffer[i] = unicode.ToTitle(ch)188capitalizeNext = false189}190}191return string(buffer)192
193}
194
195/*
196CapitalizeFully converts all the delimiter separated words in a string into capitalized words, that is each word is made up of a
197titlecase character and then a series of lowercase characters. The delimiters represent a set of characters understood
198to separate words. The first string character and the first non-delimiter character after a delimiter will be capitalized.
199Capitalization uses the Unicode title case, normally equivalent to upper case.
200
201Parameters:
202str - the string to capitalize fully
203delimiters - set of characters to determine capitalization, exclusion of this parameter means whitespace would be delimeter
204
205Returns:
206capitalized string
207*/
208func CapitalizeFully(str string, delimiters ...rune) string {209
210var delimLen int211
212if delimiters == nil {213delimLen = -1214} else {215delimLen = len(delimiters)216}217
218if str == "" || delimLen == 0 {219return str220}221str = strings.ToLower(str)222return Capitalize(str, delimiters...)223}
224
225/*
226Uncapitalize uncapitalizes all the whitespace separated words in a string. Only the first letter of each word is changed.
227The delimiters represent a set of characters understood to separate words. The first string character and the first non-delimiter
228character after a delimiter will be uncapitalized. Whitespace is defined by unicode.IsSpace(char).
229
230Parameters:
231str - the string to uncapitalize fully
232delimiters - set of characters to determine capitalization, exclusion of this parameter means whitespace would be delimeter
233
234Returns:
235uncapitalized string
236*/
237func Uncapitalize(str string, delimiters ...rune) string {238
239var delimLen int240
241if delimiters == nil {242delimLen = -1243} else {244delimLen = len(delimiters)245}246
247if str == "" || delimLen == 0 {248return str249}250
251buffer := []rune(str)252uncapitalizeNext := true // TODO Always makes capitalize/un apply to first char.253for i := 0; i < len(buffer); i++ {254ch := buffer[i]255if isDelimiter(ch, delimiters...) {256uncapitalizeNext = true257} else if uncapitalizeNext {258buffer[i] = unicode.ToLower(ch)259uncapitalizeNext = false260}261}262return string(buffer)263}
264
265/*
266SwapCase swaps the case of a string using a word based algorithm.
267
268Conversion algorithm:
269
270Upper case character converts to Lower case
271Title case character converts to Lower case
272Lower case character after Whitespace or at start converts to Title case
273Other Lower case character converts to Upper case
274Whitespace is defined by unicode.IsSpace(char).
275
276Parameters:
277str - the string to swap case
278
279Returns:
280the changed string
281*/
282func SwapCase(str string) string {283if str == "" {284return str285}286buffer := []rune(str)287
288whitespace := true289
290for i := 0; i < len(buffer); i++ {291ch := buffer[i]292if unicode.IsUpper(ch) {293buffer[i] = unicode.ToLower(ch)294whitespace = false295} else if unicode.IsTitle(ch) {296buffer[i] = unicode.ToLower(ch)297whitespace = false298} else if unicode.IsLower(ch) {299if whitespace {300buffer[i] = unicode.ToTitle(ch)301whitespace = false302} else {303buffer[i] = unicode.ToUpper(ch)304}305} else {306whitespace = unicode.IsSpace(ch)307}308}309return string(buffer)310}
311
312/*
313Initials extracts the initial letters from each word in the string. The first letter of the string and all first
314letters after the defined delimiters are returned as a new string. Their case is not changed. If the delimiters
315parameter is excluded, then Whitespace is used. Whitespace is defined by unicode.IsSpacea(char). An empty delimiter array returns an empty string.
316
317Parameters:
318str - the string to get initials from
319delimiters - set of characters to determine words, exclusion of this parameter means whitespace would be delimeter
320Returns:
321string of initial letters
322*/
323func Initials(str string, delimiters ...rune) string {324if str == "" {325return str326}327if delimiters != nil && len(delimiters) == 0 {328return ""329}330strLen := len(str)331var buf bytes.Buffer332lastWasGap := true333for i := 0; i < strLen; i++ {334ch := rune(str[i])335
336if isDelimiter(ch, delimiters...) {337lastWasGap = true338} else if lastWasGap {339buf.WriteRune(ch)340lastWasGap = false341}342}343return buf.String()344}
345
346// private function (lower case func name)
347func isDelimiter(ch rune, delimiters ...rune) bool {348if delimiters == nil {349return unicode.IsSpace(ch)350}351for _, delimiter := range delimiters {352if ch == delimiter {353return true354}355}356return false357}
358