116 lines
2.3 KiB
Go
116 lines
2.3 KiB
Go
package clifmt
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
var titleIndex = 0
|
||
var alignOffset = 40
|
||
|
||
// Warn returns a red warning ASCII sign. If a string is given
|
||
// as argument, it will print it after the warning sign
|
||
func Warn(s ...string) string {
|
||
if len(s) == 0 {
|
||
return Color(31, "/!\\")
|
||
}
|
||
|
||
return fmt.Sprintf("%s %s", Warn(), s[0])
|
||
}
|
||
|
||
// Info returns a blue info ASCII sign. If a string is given
|
||
// as argument, it will print it after the info sign
|
||
func Info(s ...string) string {
|
||
if len(s) == 0 {
|
||
return Color(34, "(!)")
|
||
}
|
||
|
||
return fmt.Sprintf("%s %s", Info(), s[0])
|
||
}
|
||
|
||
// Title prints a formatted title (auto-indexed from local counted)
|
||
func Title(s string) {
|
||
titleIndex++
|
||
fmt.Printf("\n%s |%d| %s %s\n", Color(33, ">>", false), titleIndex, s, Color(33, "<<", false))
|
||
|
||
}
|
||
|
||
// Align prints strings with space padding to align line ends (fixed width)
|
||
// also crops the content to add '...' at the end if too long (must have a space
|
||
// at the end)
|
||
func Align(s string) {
|
||
|
||
// 1. replace tabs with 4 spaces
|
||
tabs := strings.Split(strings.Trim(s, " \t"), "\t")
|
||
s = strings.Join(tabs, " ")
|
||
|
||
// 2. get real size
|
||
size := displaySize(s)
|
||
|
||
offset := alignOffset
|
||
|
||
if size > alignOffset-6 {
|
||
|
||
for i, l := 0, len(s); i < l; i++ { // find when real size is right under
|
||
next := fmt.Sprintf("%s\033[0m… ", s[0:i+1])
|
||
if displaySize(next) >= alignOffset-5 {
|
||
s = next
|
||
break
|
||
}
|
||
|
||
}
|
||
size = displaySize(s)
|
||
|
||
} else {
|
||
// fix
|
||
offset -= 2
|
||
}
|
||
|
||
// 3. print string
|
||
fmt.Printf("%s", s)
|
||
|
||
// 4. print trailing spaces
|
||
for i := size; i < offset; i++ {
|
||
fmt.Printf(" ")
|
||
}
|
||
}
|
||
|
||
var re = regexp.MustCompile(`(?m)\[(?:\d+;)*\d+m`)
|
||
|
||
// displaySize returns the real size escaping special characters
|
||
func displaySize(s string) int {
|
||
|
||
// 1. get actual size
|
||
size := len(s)
|
||
|
||
// 2. get all terminal coloring matches
|
||
matches := re.FindAllString(s, -1)
|
||
for _, m := range matches {
|
||
size -= len(m)
|
||
}
|
||
|
||
return size
|
||
}
|
||
|
||
func escape(in string) string {
|
||
|
||
out := make([]rune, 0)
|
||
|
||
for _, char := range in {
|
||
if char == '\n' {
|
||
out = append(out, []rune("\\n")...)
|
||
} else if char == '\r' {
|
||
out = append(out, []rune("\\r")...)
|
||
} else if char == '\t' {
|
||
out = append(out, []rune("\\t")...)
|
||
} else if char == '\033' {
|
||
out = append(out, []rune("\\033")...)
|
||
} else {
|
||
out = append(out, char)
|
||
}
|
||
}
|
||
|
||
return string(out)
|
||
}
|