123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- package ansi
- import (
- "regexp"
- "strings"
- "unicode"
- )
- func expand(text string) [][]string {
- r := regexp.MustCompile(`(?s)((?:\x1b\[.*?m)*)(.)(?:\x1b\[0m)?`)
- return r.FindAllStringSubmatch(text, -1)
- }
- func Apply(text string, style string) string {
- expanded := expand(text)
- result := ""
- for _, match := range expanded {
- prefix := match[1]
- letter := match[2]
- if letter == "\n" {
- result += "\n"
- continue
- }
- result += "\x1b[" + style + "m" + prefix + letter + "\x1b[0m"
- }
- return result
- }
- func Indent(text string, prefix string, includeFirst bool) string {
- expanded := expand(text)
- result := ""
- if includeFirst {
- result = prefix
- }
- for _, match := range expanded {
- full := match[0]
- letter := match[2]
- if letter == "\n" {
- result += "\n" + prefix
- continue
- }
- result += full
- }
- return result
- }
- const suffix = " "
- func Pad(text string, length int) string {
- expanded := expand(text)
- result := ""
- lineLength := 0
- for _, match := range expanded {
- full := match[0]
- letter := match[2]
- if letter == "\n" {
- amount := length - lineLength
- if amount <= 0 {
- result += "\n"
- lineLength = 0
- continue
- }
- result += strings.Repeat(suffix, amount) + "\n"
- lineLength = 0
- continue
- }
- lineLength += 1
- result += full
- }
-
- amount := length - lineLength
- if amount > 0 {
- result += strings.Repeat(suffix, amount)
- }
- return result
- }
- func Wrap(text string, length int) string {
- expanded := expand(text)
- result := []string{}
- var line, space, word string
- var lineLength, spaceLength, wordLength int
- for _, match := range expanded {
- full := match[0]
- letter := match[2]
-
- if !unicode.IsSpace([]rune(letter)[0]) {
- if wordLength == length {
-
- result = append(result, word)
- line = ""; lineLength = 0
- space = ""; spaceLength = 0
- word = ""; wordLength = 0
- }
-
- if lineLength + spaceLength + wordLength >= length {
-
- result = append(result, line)
- line = ""; lineLength = 0
- space = ""; spaceLength = 0
- }
- word += full; wordLength += 1
- continue
- }
-
- if wordLength > 0 {
- line += space + word; lineLength += spaceLength + wordLength
- space = ""; spaceLength = 0
- word = ""; wordLength = 0
- }
- if letter == "\n" {
-
- if lineLength + spaceLength <= length {
- line += space; lineLength += spaceLength
- }
-
- result = append(result, line)
- line = ""; lineLength = 0
- space = ""; spaceLength = 0
- word = ""; wordLength = 0
- } else {
- space += full; spaceLength += 1
- }
- }
-
- if wordLength > 0 {
- line += space + word; lineLength += spaceLength + wordLength
- }
- finalLetter := ""
- if len(expanded) > 0 {
- finalLetter = expanded[len(expanded)-1][2]
- }
- if lineLength > 0 || finalLetter == "\n" {
- result = append(result, line)
- }
- return strings.Join(result, "\n")
- }
- func DumbWrap(text string, width int) string {
- expanded := expand(text)
- result := ""
- currentLineLength := 0
- for _, match := range expanded {
- full := match[0]
- letter := match[2]
- if letter == "\n" {
- currentLineLength = 0
- result += "\n"
- continue
- }
- if currentLineLength == width {
- currentLineLength = 0
- result += "\n"
- }
- result += full
- currentLineLength += 1
- }
- return result
- }
|