Update vendor

This commit is contained in:
Ettore Di Giacinto
2020-11-23 19:14:07 +01:00
parent 7a10ff2742
commit 5b54aeb822
147 changed files with 28614 additions and 0 deletions

137
vendor/github.com/jedib0t/go-pretty/text/align.go generated vendored Normal file
View File

@@ -0,0 +1,137 @@
package text
import (
"fmt"
"strconv"
"strings"
"unicode/utf8"
)
// Align denotes how text is to be aligned horizontally.
type Align int
// Align enumerations
const (
AlignDefault Align = iota // same as AlignLeft
AlignLeft // "left "
AlignCenter // " center "
AlignJustify // "justify it"
AlignRight // " right"
)
// Apply aligns the text as directed. For ex.:
// * AlignDefault.Apply("Jon Snow", 12) returns "Jon Snow "
// * AlignLeft.Apply("Jon Snow", 12) returns "Jon Snow "
// * AlignCenter.Apply("Jon Snow", 12) returns " Jon Snow "
// * AlignJustify.Apply("Jon Snow", 12) returns "Jon Snow"
// * AlignRight.Apply("Jon Snow", 12) returns " Jon Snow"
func (a Align) Apply(text string, maxLength int) string {
text = a.trimString(text)
sLen := utf8.RuneCountInString(text)
sLenWoE := RuneCount(text)
numEscChars := sLen - sLenWoE
// now, align the text
switch a {
case AlignDefault, AlignLeft:
return fmt.Sprintf("%-"+strconv.Itoa(maxLength+numEscChars)+"s", text)
case AlignCenter:
if sLenWoE < maxLength {
// left pad with half the number of spaces needed before using %text
return fmt.Sprintf("%"+strconv.Itoa(maxLength+numEscChars)+"s",
text+strings.Repeat(" ", int((maxLength-sLenWoE)/2)))
}
case AlignJustify:
return a.justifyText(text, sLenWoE, maxLength)
}
return fmt.Sprintf("%"+strconv.Itoa(maxLength+numEscChars)+"s", text)
}
// HTMLProperty returns the equivalent HTML horizontal-align tag property.
func (a Align) HTMLProperty() string {
switch a {
case AlignLeft:
return "align=\"left\""
case AlignCenter:
return "align=\"center\""
case AlignJustify:
return "align=\"justify\""
case AlignRight:
return "align=\"right\""
default:
return ""
}
}
// MarkdownProperty returns the equivalent Markdown horizontal-align separator.
func (a Align) MarkdownProperty() string {
switch a {
case AlignLeft:
return ":--- "
case AlignCenter:
return ":---:"
case AlignRight:
return " ---:"
default:
return " --- "
}
}
func (a Align) justifyText(text string, textLength int, maxLength int) string {
// split the text into individual words
wordsUnfiltered := strings.Split(text, " ")
words := Filter(wordsUnfiltered, func(item string) bool {
return item != ""
})
// empty string implies spaces for maxLength
if len(words) == 0 {
return strings.Repeat(" ", maxLength)
}
// get the number of spaces to insert into the text
numSpacesNeeded := maxLength - textLength + strings.Count(text, " ")
numSpacesNeededBetweenWords := 0
if len(words) > 1 {
numSpacesNeededBetweenWords = numSpacesNeeded / (len(words) - 1)
}
// create the output string word by word with spaces in between
var outText strings.Builder
outText.Grow(maxLength)
for idx, word := range words {
if idx > 0 {
// insert spaces only after the first word
if idx == len(words)-1 {
// insert all the remaining space before the last word
outText.WriteString(strings.Repeat(" ", numSpacesNeeded))
numSpacesNeeded = 0
} else {
// insert the determined number of spaces between each word
outText.WriteString(strings.Repeat(" ", numSpacesNeededBetweenWords))
// and reduce the number of spaces needed after this
numSpacesNeeded -= numSpacesNeededBetweenWords
}
}
outText.WriteString(word)
if idx == len(words)-1 && numSpacesNeeded > 0 {
outText.WriteString(strings.Repeat(" ", numSpacesNeeded))
}
}
return outText.String()
}
func (a Align) trimString(text string) string {
switch a {
case AlignDefault, AlignLeft:
if strings.HasSuffix(text, " ") {
return strings.TrimRight(text, " ")
}
case AlignRight:
if strings.HasPrefix(text, " ") {
return strings.TrimLeft(text, " ")
}
default:
if strings.HasPrefix(text, " ") || strings.HasSuffix(text, " ") {
return strings.Trim(text, " ")
}
}
return text
}

55
vendor/github.com/jedib0t/go-pretty/text/ansi.go generated vendored Normal file
View File

@@ -0,0 +1,55 @@
package text
import "strings"
// ANSICodesSupported will be true on consoles where ANSI Escape Codes/Sequences
// are supported.
var ANSICodesSupported = areANSICodesSupported()
// Escape encodes the string with the ANSI Escape Sequence.
// For ex.:
// Escape("Ghost", "") == "Ghost"
// Escape("Ghost", "\x1b[91m") == "\x1b[91mGhost\x1b[0m"
// Escape("\x1b[94mGhost\x1b[0mLady", "\x1b[91m") == "\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m"
// Escape("Nymeria\x1b[94mGhost\x1b[0mLady", "\x1b[91m") == "\x1b[91mNymeria\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m"
// Escape("Nymeria \x1b[94mGhost\x1b[0m Lady", "\x1b[91m") == "\x1b[91mNymeria \x1b[94mGhost\x1b[0m\x1b[91m Lady\x1b[0m"
func Escape(str string, escapeSeq string) string {
out := ""
if !strings.HasPrefix(str, EscapeStart) {
out += escapeSeq
}
out += strings.Replace(str, EscapeReset, EscapeReset+escapeSeq, -1)
if !strings.HasSuffix(out, EscapeReset) {
out += EscapeReset
}
if strings.Contains(out, escapeSeq+EscapeReset) {
out = strings.Replace(out, escapeSeq+EscapeReset, "", -1)
}
return out
}
// StripEscape strips all ANSI Escape Sequence from the string.
// For ex.:
// StripEscape("Ghost") == "Ghost"
// StripEscape("\x1b[91mGhost\x1b[0m") == "Ghost"
// StripEscape("\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m") == "GhostLady"
// StripEscape("\x1b[91mNymeria\x1b[94mGhost\x1b[0m\x1b[91mLady\x1b[0m") == "NymeriaGhostLady"
// StripEscape("\x1b[91mNymeria \x1b[94mGhost\x1b[0m\x1b[91m Lady\x1b[0m") == "Nymeria Ghost Lady"
func StripEscape(str string) string {
var out strings.Builder
out.Grow(RuneCount(str))
isEscSeq := false
for _, sChr := range str {
if sChr == EscapeStartRune {
isEscSeq = true
}
if !isEscSeq {
out.WriteRune(sChr)
}
if isEscSeq && sChr == EscapeStopRune {
isEscSeq = false
}
}
return out.String()
}

View File

@@ -0,0 +1,7 @@
// +build !windows
package text
func areANSICodesSupported() bool {
return true
}

View File

@@ -0,0 +1,31 @@
// +build windows
package text
import (
"os"
"sync"
"golang.org/x/sys/windows"
)
var (
enableVTPMutex = sync.Mutex{}
)
func areANSICodesSupported() bool {
enableVTPMutex.Lock()
defer enableVTPMutex.Unlock()
outHandle := windows.Handle(os.Stdout.Fd())
var outMode uint32
if err := windows.GetConsoleMode(outHandle, &outMode); err == nil {
if outMode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 {
return true
}
if err := windows.SetConsoleMode(outHandle, outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
return true
}
}
return false
}

183
vendor/github.com/jedib0t/go-pretty/text/color.go generated vendored Normal file
View File

@@ -0,0 +1,183 @@
package text
import (
"fmt"
"sort"
"strconv"
"strings"
"sync"
)
var (
colorsEnabled = areANSICodesSupported()
)
// DisableColors (forcefully) disables color coding globally.
func DisableColors() {
colorsEnabled = false
}
// EnableColors (forcefully) enables color coding globally.
func EnableColors() {
colorsEnabled = true
}
// The logic here is inspired from github.com/fatih/color; the following is
// the the bare minimum logic required to print Colored to the console.
// The differences:
// * This one caches the escape sequences for cases with multiple colors
// * This one handles cases where the incoming already has colors in the
// form of escape sequences; in which case, text that does not have any
// escape sequences are colored/escaped
// Color represents a single color to render with.
type Color int
// Base colors -- attributes in reality
const (
Reset Color = iota
Bold
Faint
Italic
Underline
BlinkSlow
BlinkRapid
ReverseVideo
Concealed
CrossedOut
)
// Foreground colors
const (
FgBlack Color = iota + 30
FgRed
FgGreen
FgYellow
FgBlue
FgMagenta
FgCyan
FgWhite
)
// Foreground Hi-Intensity colors
const (
FgHiBlack Color = iota + 90
FgHiRed
FgHiGreen
FgHiYellow
FgHiBlue
FgHiMagenta
FgHiCyan
FgHiWhite
)
// Background colors
const (
BgBlack Color = iota + 40
BgRed
BgGreen
BgYellow
BgBlue
BgMagenta
BgCyan
BgWhite
)
// Background Hi-Intensity colors
const (
BgHiBlack Color = iota + 100
BgHiRed
BgHiGreen
BgHiYellow
BgHiBlue
BgHiMagenta
BgHiCyan
BgHiWhite
)
// EscapeSeq returns the ANSI escape sequence for the color.
func (c Color) EscapeSeq() string {
return EscapeStart + strconv.Itoa(int(c)) + EscapeStop
}
// HTMLProperty returns the "class" attribute for the color.
func (c Color) HTMLProperty() string {
out := ""
if class, ok := colorCSSClassMap[c]; ok {
out = fmt.Sprintf("class=\"%s\"", class)
}
return out
}
// Sprint colorizes and prints the given string(s).
func (c Color) Sprint(a ...interface{}) string {
return colorize(fmt.Sprint(a...), c.EscapeSeq())
}
// Sprintf formats and colorizes and prints the given string(s).
func (c Color) Sprintf(format string, a ...interface{}) string {
return colorize(fmt.Sprintf(format, a...), c.EscapeSeq())
}
// Colors represents an array of Color objects to render with.
// Example: Colors{FgCyan, BgBlack}
type Colors []Color
var (
// colorsSeqMap caches the escape sequence for a set of colors
colorsSeqMap = sync.Map{}
)
// EscapeSeq returns the ANSI escape sequence for the colors set.
func (c Colors) EscapeSeq() string {
if len(c) == 0 {
return ""
}
colorsKey := fmt.Sprintf("%#v", c)
escapeSeq, ok := colorsSeqMap.Load(colorsKey)
if !ok || escapeSeq == "" {
colorNums := make([]string, len(c))
for idx, color := range c {
colorNums[idx] = strconv.Itoa(int(color))
}
escapeSeq = EscapeStart + strings.Join(colorNums, ";") + EscapeStop
colorsSeqMap.Store(colorsKey, escapeSeq)
}
return escapeSeq.(string)
}
// HTMLProperty returns the "class" attribute for the colors.
func (c Colors) HTMLProperty() string {
if len(c) == 0 {
return ""
}
var classes []string
for _, color := range c {
if class, ok := colorCSSClassMap[color]; ok {
classes = append(classes, class)
}
}
if len(classes) > 1 {
sort.Strings(classes)
}
return fmt.Sprintf("class=\"%s\"", strings.Join(classes, " "))
}
// Sprint colorizes and prints the given string(s).
func (c Colors) Sprint(a ...interface{}) string {
return colorize(fmt.Sprint(a...), c.EscapeSeq())
}
// Sprintf formats and colorizes and prints the given string(s).
func (c Colors) Sprintf(format string, a ...interface{}) string {
return colorize(fmt.Sprintf(format, a...), c.EscapeSeq())
}
func colorize(s string, escapeSeq string) string {
if !colorsEnabled || escapeSeq == "" {
return s
}
return Escape(s, escapeSeq)
}

48
vendor/github.com/jedib0t/go-pretty/text/color_html.go generated vendored Normal file
View File

@@ -0,0 +1,48 @@
package text
var (
// colorCSSClassMap contains the equivalent CSS-class for all colors
colorCSSClassMap = map[Color]string{
Bold: "bold",
Faint: "faint",
Italic: "italic",
Underline: "underline",
BlinkSlow: "blink-slow",
BlinkRapid: "blink-rapid",
ReverseVideo: "reverse-video",
Concealed: "concealed",
CrossedOut: "crossed-out",
FgBlack: "fg-black",
FgRed: "fg-red",
FgGreen: "fg-green",
FgYellow: "fg-yellow",
FgBlue: "fg-blue",
FgMagenta: "fg-magenta",
FgCyan: "fg-cyan",
FgWhite: "fg-white",
FgHiBlack: "fg-hi-black",
FgHiRed: "fg-hi-red",
FgHiGreen: "fg-hi-green",
FgHiYellow: "fg-hi-yellow",
FgHiBlue: "fg-hi-blue",
FgHiMagenta: "fg-hi-magenta",
FgHiCyan: "fg-hi-cyan",
FgHiWhite: "fg-hi-white",
BgBlack: "bg-black",
BgRed: "bg-red",
BgGreen: "bg-green",
BgYellow: "bg-yellow",
BgBlue: "bg-blue",
BgMagenta: "bg-magenta",
BgCyan: "bg-cyan",
BgWhite: "bg-white",
BgHiBlack: "bg-hi-black",
BgHiRed: "bg-hi-red",
BgHiGreen: "bg-hi-green",
BgHiYellow: "bg-hi-yellow",
BgHiBlue: "bg-hi-blue",
BgHiMagenta: "bg-hi-magenta",
BgHiCyan: "bg-hi-cyan",
BgHiWhite: "bg-hi-white",
}
)

39
vendor/github.com/jedib0t/go-pretty/text/cursor.go generated vendored Normal file
View File

@@ -0,0 +1,39 @@
package text
import (
"fmt"
)
// Cursor helps move the cursor on the console in multiple directions.
type Cursor rune
const (
// CursorDown helps move the Cursor Down X lines
CursorDown Cursor = 'B'
// CursorLeft helps move the Cursor Left X characters
CursorLeft Cursor = 'D'
// CursorRight helps move the Cursor Right X characters
CursorRight Cursor = 'C'
// CursorUp helps move the Cursor Up X lines
CursorUp Cursor = 'A'
// EraseLine helps erase all characters to the Right of the Cursor in the
// current line
EraseLine Cursor = 'K'
)
// Sprint prints the Escape Sequence to move the Cursor once.
func (c Cursor) Sprint() string {
return fmt.Sprintf("%s%c", EscapeStart, c)
}
// Sprintn prints the Escape Sequence to move the Cursor "n" times.
func (c Cursor) Sprintn(n int) string {
if c == EraseLine {
return c.Sprint()
}
return fmt.Sprintf("%s%d%c", EscapeStart, n, c)
}

12
vendor/github.com/jedib0t/go-pretty/text/filter.go generated vendored Normal file
View File

@@ -0,0 +1,12 @@
package text
// Filter filters the slice 's' to items which return truth when passed to 'f'.
func Filter(s []string, f func(string) bool) []string {
var out []string
for _, item := range s {
if f(item) {
out = append(out, item)
}
}
return out
}

28
vendor/github.com/jedib0t/go-pretty/text/format.go generated vendored Normal file
View File

@@ -0,0 +1,28 @@
package text
import "strings"
// Format denotes the "case" to use for text.
type Format int
// Format enumerations
const (
FormatDefault Format = iota // default_Case
FormatLower // lower
FormatTitle // Title
FormatUpper // UPPER
)
// Apply converts the text as directed.
func (tc Format) Apply(text string) string {
switch tc {
case FormatLower:
return strings.ToLower(text)
case FormatTitle:
return strings.Title(text)
case FormatUpper:
return strings.ToUpper(text)
default:
return text
}
}

203
vendor/github.com/jedib0t/go-pretty/text/string.go generated vendored Normal file
View File

@@ -0,0 +1,203 @@
package text
import (
"strings"
"unicode/utf8"
"github.com/mattn/go-runewidth"
)
// Constants
const (
EscapeReset = EscapeStart + "0" + EscapeStop
EscapeStart = "\x1b["
EscapeStartRune = rune(27) // \x1b
EscapeStop = "m"
EscapeStopRune = 'm'
)
// InsertEveryN inserts the rune every N characters in the string. For ex.:
// InsertEveryN("Ghost", '-', 1) == "G-h-o-s-t"
// InsertEveryN("Ghost", '-', 2) == "Gh-os-t"
// InsertEveryN("Ghost", '-', 3) == "Gho-st"
// InsertEveryN("Ghost", '-', 4) == "Ghos-t"
// InsertEveryN("Ghost", '-', 5) == "Ghost"
func InsertEveryN(str string, runeToInsert rune, n int) string {
if n <= 0 {
return str
}
sLen := RuneCount(str)
var out strings.Builder
out.Grow(sLen + (sLen / n))
outLen, isEscSeq := 0, false
for idx, c := range str {
if c == EscapeStartRune {
isEscSeq = true
}
if !isEscSeq && outLen > 0 && (outLen%n) == 0 && idx != sLen {
out.WriteRune(runeToInsert)
}
out.WriteRune(c)
if !isEscSeq {
outLen += RuneWidth(c)
}
if isEscSeq && c == EscapeStopRune {
isEscSeq = false
}
}
return out.String()
}
// LongestLineLen returns the length of the longest "line" within the
// argument string. For ex.:
// LongestLineLen("Ghost!\nCome back here!\nRight now!") == 15
func LongestLineLen(str string) int {
maxLength, currLength, isEscSeq := 0, 0, false
for _, c := range str {
if c == EscapeStartRune {
isEscSeq = true
} else if isEscSeq && c == EscapeStopRune {
isEscSeq = false
continue
}
if c == '\n' {
if currLength > maxLength {
maxLength = currLength
}
currLength = 0
} else if !isEscSeq {
currLength += RuneWidth(c)
}
}
if currLength > maxLength {
maxLength = currLength
}
return maxLength
}
// Pad pads the given string with as many characters as needed to make it as
// long as specified (maxLen). This function does not count escape sequences
// while calculating length of the string. Ex.:
// Pad("Ghost", 0, ' ') == "Ghost"
// Pad("Ghost", 3, ' ') == "Ghost"
// Pad("Ghost", 5, ' ') == "Ghost"
// Pad("Ghost", 7, ' ') == "Ghost "
// Pad("Ghost", 10, '.') == "Ghost....."
func Pad(str string, maxLen int, paddingChar rune) string {
strLen := RuneCount(str)
if strLen < maxLen {
str += strings.Repeat(string(paddingChar), maxLen-strLen)
}
return str
}
// RepeatAndTrim repeats the given string until it is as long as maxRunes.
// For ex.:
// RepeatAndTrim("Ghost", 0) == ""
// RepeatAndTrim("Ghost", 5) == "Ghost"
// RepeatAndTrim("Ghost", 7) == "GhostGh"
// RepeatAndTrim("Ghost", 10) == "GhostGhost"
func RepeatAndTrim(str string, maxRunes int) string {
if maxRunes == 0 {
return ""
} else if maxRunes == utf8.RuneCountInString(str) {
return str
}
repeatedS := strings.Repeat(str, int(maxRunes/utf8.RuneCountInString(str))+1)
return Trim(repeatedS, maxRunes)
}
// RuneCount is similar to utf8.RuneCountInString, except for the fact that it
// ignores escape sequences while counting. For ex.:
// RuneCount("") == 0
// RuneCount("Ghost") == 5
// RuneCount("\x1b[33mGhost\x1b[0m") == 5
// RuneCount("\x1b[33mGhost\x1b[0") == 5
func RuneCount(str string) int {
count, isEscSeq := 0, false
for _, c := range str {
if c == EscapeStartRune {
isEscSeq = true
} else if isEscSeq {
if c == EscapeStopRune {
isEscSeq = false
}
} else {
count += RuneWidth(c)
}
}
return count
}
// RuneWidth returns the mostly accurate character-width of the rune. This is
// not 100% accurate as the character width is usually dependant on the
// typeface (font) used in the console/terminal. For ex.:
// RuneWidth('A') == 1
// RuneWidth('ツ') == 2
// RuneWidth('⊙') == 1
// RuneWidth('︿') == 2
// RuneWidth(0x27) == 0
func RuneWidth(r rune) int {
return runewidth.RuneWidth(r)
}
// Snip returns the given string with a fixed length. For ex.:
// Snip("Ghost", 0, "~") == "Ghost"
// Snip("Ghost", 1, "~") == "~"
// Snip("Ghost", 3, "~") == "Gh~"
// Snip("Ghost", 5, "~") == "Ghost"
// Snip("Ghost", 7, "~") == "Ghost "
// Snip("\x1b[33mGhost\x1b[0m", 7, "~") == "\x1b[33mGhost\x1b[0m "
func Snip(str string, length int, snipIndicator string) string {
if length > 0 {
lenStr := RuneCount(str)
if lenStr > length {
lenStrFinal := length - RuneCount(snipIndicator)
return Trim(str, lenStrFinal) + snipIndicator
}
}
return str
}
// Trim trims a string to the given length while ignoring escape sequences. For
// ex.:
// Trim("Ghost", 3) == "Gho"
// Trim("Ghost", 6) == "Ghost"
// Trim("\x1b[33mGhost\x1b[0m", 3) == "\x1b[33mGho\x1b[0m"
// Trim("\x1b[33mGhost\x1b[0m", 6) == "\x1b[33mGhost\x1b[0m"
func Trim(str string, maxLen int) string {
if maxLen <= 0 {
return ""
}
var out strings.Builder
out.Grow(maxLen)
outLen, isEscSeq, lastEscSeq := 0, false, strings.Builder{}
for _, sChr := range str {
out.WriteRune(sChr)
if sChr == EscapeStartRune {
isEscSeq = true
lastEscSeq.Reset()
lastEscSeq.WriteRune(sChr)
} else if isEscSeq {
lastEscSeq.WriteRune(sChr)
if sChr == EscapeStopRune {
isEscSeq = false
}
} else {
outLen++
if outLen == maxLen {
break
}
}
}
if lastEscSeq.Len() > 0 && lastEscSeq.String() != EscapeReset {
out.WriteString(EscapeReset)
}
return out.String()
}

191
vendor/github.com/jedib0t/go-pretty/text/transformer.go generated vendored Normal file
View File

@@ -0,0 +1,191 @@
package text
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/go-openapi/strfmt"
)
// Transformer related constants
const (
unixTimeMinMilliseconds = int64(10000000000)
unixTimeMinMicroseconds = unixTimeMinMilliseconds * 1000
unixTimeMinNanoSeconds = unixTimeMinMicroseconds * 1000
)
// Transformer related variables
var (
colorsNumberPositive = Colors{FgHiGreen}
colorsNumberNegative = Colors{FgHiRed}
colorsNumberZero = Colors{}
colorsURL = Colors{Underline, FgBlue}
)
// Transformer helps format the contents of an object to the user's liking.
type Transformer func(val interface{}) string
// NewNumberTransformer returns a number Transformer that:
// * transforms the number as directed by 'format' (ex.: %.2f)
// * colors negative values Red
// * colors positive values Green
func NewNumberTransformer(format string) Transformer {
return func(val interface{}) string {
if number, ok := val.(int); ok {
return transformInt(format, int64(number))
}
if number, ok := val.(int8); ok {
return transformInt(format, int64(number))
}
if number, ok := val.(int16); ok {
return transformInt(format, int64(number))
}
if number, ok := val.(int32); ok {
return transformInt(format, int64(number))
}
if number, ok := val.(int64); ok {
return transformInt(format, int64(number))
}
if number, ok := val.(uint); ok {
return transformUint(format, uint64(number))
}
if number, ok := val.(uint8); ok {
return transformUint(format, uint64(number))
}
if number, ok := val.(uint16); ok {
return transformUint(format, uint64(number))
}
if number, ok := val.(uint32); ok {
return transformUint(format, uint64(number))
}
if number, ok := val.(uint64); ok {
return transformUint(format, uint64(number))
}
if number, ok := val.(float32); ok {
return transformFloat(format, float64(number))
}
if number, ok := val.(float64); ok {
return transformFloat(format, float64(number))
}
return fmt.Sprint(val)
}
}
func transformInt(format string, val int64) string {
if val < 0 {
return colorsNumberNegative.Sprintf("-"+format, -val)
}
if val > 0 {
return colorsNumberPositive.Sprintf(format, val)
}
return colorsNumberZero.Sprintf(format, val)
}
func transformUint(format string, val uint64) string {
if val > 0 {
return colorsNumberPositive.Sprintf(format, val)
}
return colorsNumberZero.Sprintf(format, val)
}
func transformFloat(format string, val float64) string {
if val < 0 {
return colorsNumberNegative.Sprintf("-"+format, -val)
}
if val > 0 {
return colorsNumberPositive.Sprintf(format, val)
}
return colorsNumberZero.Sprintf(format, val)
}
// NewJSONTransformer returns a Transformer that can format a JSON string or an
// object into pretty-indented JSON-strings.
func NewJSONTransformer(prefix string, indent string) Transformer {
return func(val interface{}) string {
if valStr, ok := val.(string); ok {
var b bytes.Buffer
if err := json.Indent(&b, []byte(strings.TrimSpace(valStr)), prefix, indent); err == nil {
return string(b.Bytes())
}
} else if b, err := json.MarshalIndent(val, prefix, indent); err == nil {
return string(b)
}
return fmt.Sprintf("%#v", val)
}
}
// NewTimeTransformer returns a Transformer that can format a timestamp (a
// time.Time or strfmt.DateTime object) into a well-defined time format defined
// using the provided layout (ex.: time.RFC3339).
//
// If a non-nil location value is provided, the time will be localized to that
// location (use time.Local to get localized timestamps).
func NewTimeTransformer(layout string, location *time.Location) Transformer {
return func(val interface{}) string {
formatTime := func(t time.Time) string {
rsp := ""
if t.Unix() > 0 {
if location != nil {
t = t.In(location)
}
rsp = t.Format(layout)
}
return rsp
}
rsp := fmt.Sprint(val)
if valDate, ok := val.(strfmt.DateTime); ok {
rsp = formatTime(time.Time(valDate))
} else if valTime, ok := val.(time.Time); ok {
rsp = formatTime(valTime)
} else if valStr, ok := val.(string); ok {
if valTime, err := time.Parse(time.RFC3339, valStr); err == nil {
rsp = formatTime(valTime)
}
}
return rsp
}
}
// NewUnixTimeTransformer returns a Transformer that can format a unix-timestamp
// into a well-defined time format as defined by 'layout'. This can handle
// unix-time in Seconds, MilliSeconds, Microseconds and Nanoseconds.
//
// If a non-nil location value is provided, the time will be localized to that
// location (use time.Local to get localized timestamps).
func NewUnixTimeTransformer(layout string, location *time.Location) Transformer {
timeTransformer := NewTimeTransformer(layout, location)
formatUnixTime := func(unixTime int64) string {
if unixTime >= unixTimeMinNanoSeconds {
unixTime = unixTime / time.Second.Nanoseconds()
} else if unixTime >= unixTimeMinMicroseconds {
unixTime = unixTime / (time.Second.Nanoseconds() / 1000)
} else if unixTime >= unixTimeMinMilliseconds {
unixTime = unixTime / (time.Second.Nanoseconds() / 1000000)
}
return timeTransformer(time.Unix(unixTime, 0))
}
return func(val interface{}) string {
if unixTime, ok := val.(int64); ok {
return formatUnixTime(unixTime)
} else if unixTimeStr, ok := val.(string); ok {
if unixTime, err := strconv.ParseInt(unixTimeStr, 10, 64); err == nil {
return formatUnixTime(unixTime)
}
}
return fmt.Sprint(val)
}
}
// NewURLTransformer returns a Transformer that can format and pretty print a string
// that contains an URL (the text is underlined and colored Blue).
func NewURLTransformer() Transformer {
return func(val interface{}) string {
return colorsURL.Sprint(val)
}
}

67
vendor/github.com/jedib0t/go-pretty/text/valign.go generated vendored Normal file
View File

@@ -0,0 +1,67 @@
package text
import "strings"
// VAlign denotes how text is to be aligned vertically.
type VAlign int
// VAlign enumerations
const (
VAlignDefault VAlign = iota // same as VAlignTop
VAlignTop // "top\n\n"
VAlignMiddle // "\nmiddle\n"
VAlignBottom // "\n\nbottom"
)
// Apply aligns the lines vertically. For ex.:
// * VAlignTop.Apply({"Game", "Of", "Thrones"}, 5)
// returns {"Game", "Of", "Thrones", "", ""}
// * VAlignMiddle.Apply({"Game", "Of", "Thrones"}, 5)
// returns {"", "Game", "Of", "Thrones", ""}
// * VAlignBottom.Apply({"Game", "Of", "Thrones"}, 5)
// returns {"", "", "Game", "Of", "Thrones"}
func (va VAlign) Apply(lines []string, maxLines int) []string {
if len(lines) == maxLines {
return lines
} else if len(lines) > maxLines {
maxLines = len(lines)
}
insertIdx := 0
if va == VAlignMiddle {
insertIdx = int(maxLines-len(lines)) / 2
} else if va == VAlignBottom {
insertIdx = maxLines - len(lines)
}
linesOut := strings.Split(strings.Repeat("\n", maxLines-1), "\n")
for idx, line := range lines {
linesOut[idx+insertIdx] = line
}
return linesOut
}
// ApplyStr aligns the string (of 1 or more lines) vertically. For ex.:
// * VAlignTop.ApplyStr("Game\nOf\nThrones", 5)
// returns {"Game", "Of", "Thrones", "", ""}
// * VAlignMiddle.ApplyStr("Game\nOf\nThrones", 5)
// returns {"", "Game", "Of", "Thrones", ""}
// * VAlignBottom.ApplyStr("Game\nOf\nThrones", 5)
// returns {"", "", "Game", "Of", "Thrones"}
func (va VAlign) ApplyStr(text string, maxLines int) []string {
return va.Apply(strings.Split(text, "\n"), maxLines)
}
// HTMLProperty returns the equivalent HTML vertical-align tag property.
func (va VAlign) HTMLProperty() string {
switch va {
case VAlignTop:
return "valign=\"top\""
case VAlignMiddle:
return "valign=\"middle\""
case VAlignBottom:
return "valign=\"bottom\""
default:
return ""
}
}

256
vendor/github.com/jedib0t/go-pretty/text/wrap.go generated vendored Normal file
View File

@@ -0,0 +1,256 @@
package text
import (
"strings"
"unicode/utf8"
)
// WrapHard wraps a string to the given length using a newline. Handles strings
// with ANSI escape sequences (such as text color) without breaking the text
// formatting. Breaks all words that go beyond the line boundary.
//
// For examples, refer to the unit-tests or GoDoc examples.
func WrapHard(str string, wrapLen int) string {
if wrapLen <= 0 {
return ""
}
str = strings.Replace(str, "\t", " ", -1)
sLen := utf8.RuneCountInString(str)
if sLen <= wrapLen {
return str
}
out := &strings.Builder{}
out.Grow(sLen + (sLen / wrapLen))
for idx, paragraph := range strings.Split(str, "\n\n") {
if idx > 0 {
out.WriteString("\n\n")
}
wrapHard(paragraph, wrapLen, out)
}
return out.String()
}
// WrapSoft wraps a string to the given length using a newline. Handles strings
// with ANSI escape sequences (such as text color) without breaking the text
// formatting. Tries to move words that go beyond the line boundary to the next
// line.
//
// For examples, refer to the unit-tests or GoDoc examples.
func WrapSoft(str string, wrapLen int) string {
if wrapLen <= 0 {
return ""
}
str = strings.Replace(str, "\t", " ", -1)
sLen := utf8.RuneCountInString(str)
if sLen <= wrapLen {
return str
}
out := &strings.Builder{}
out.Grow(sLen + (sLen / wrapLen))
for idx, paragraph := range strings.Split(str, "\n\n") {
if idx > 0 {
out.WriteString("\n\n")
}
wrapSoft(paragraph, wrapLen, out)
}
return out.String()
}
// WrapText is very similar to WrapHard except for one minor difference. Unlike
// WrapHard which discards line-breaks and respects only paragraph-breaks, this
// function respects line-breaks too.
//
// For examples, refer to the unit-tests or GoDoc examples.
func WrapText(str string, wrapLen int) string {
if wrapLen <= 0 {
return ""
}
var out strings.Builder
sLen := utf8.RuneCountInString(str)
out.Grow(sLen + (sLen / wrapLen))
lineIdx, isEscSeq, lastEscSeq := 0, false, ""
for _, char := range str {
if char == EscapeStartRune {
isEscSeq = true
lastEscSeq = ""
}
if isEscSeq {
lastEscSeq += string(char)
}
appendChar(char, wrapLen, &lineIdx, isEscSeq, lastEscSeq, &out)
if isEscSeq && char == EscapeStopRune {
isEscSeq = false
}
if lastEscSeq == EscapeReset {
lastEscSeq = ""
}
}
if lastEscSeq != "" && lastEscSeq != EscapeReset {
out.WriteString(EscapeReset)
}
return out.String()
}
func appendChar(char rune, wrapLen int, lineLen *int, inEscSeq bool, lastSeenEscSeq string, out *strings.Builder) {
// handle reaching the end of the line as dictated by wrapLen or by finding
// a newline character
if (*lineLen == wrapLen && !inEscSeq && char != '\n') || (char == '\n') {
if lastSeenEscSeq != "" {
// terminate escape sequence and the line; and restart the escape
// sequence in the next line
out.WriteString(EscapeReset)
out.WriteRune('\n')
out.WriteString(lastSeenEscSeq)
} else {
// just start a new line
out.WriteRune('\n')
}
// reset line index to 0th character
*lineLen = 0
}
// if the rune is not a new line, output it
if char != '\n' {
out.WriteRune(char)
// increment the line index if not in the middle of an escape sequence
if !inEscSeq {
*lineLen++
}
}
}
func appendWord(word string, lineIdx *int, lastSeenEscSeq string, wrapLen int, out *strings.Builder) {
inEscSeq := false
for _, char := range word {
if char == EscapeStartRune {
inEscSeq = true
lastSeenEscSeq = ""
}
if inEscSeq {
lastSeenEscSeq += string(char)
}
appendChar(char, wrapLen, lineIdx, inEscSeq, lastSeenEscSeq, out)
if inEscSeq && char == EscapeStopRune {
inEscSeq = false
}
if lastSeenEscSeq == EscapeReset {
lastSeenEscSeq = ""
}
}
}
func extractOpenEscapeSeq(str string) string {
escapeSeq, inEscSeq := "", false
for _, char := range str {
if char == EscapeStartRune {
inEscSeq = true
escapeSeq = ""
}
if inEscSeq {
escapeSeq += string(char)
}
if char == EscapeStopRune {
inEscSeq = false
}
}
if escapeSeq == EscapeReset {
escapeSeq = ""
}
return escapeSeq
}
func terminateLine(wrapLen int, lineLen *int, lastSeenEscSeq string, out *strings.Builder) {
if *lineLen < wrapLen {
out.WriteString(strings.Repeat(" ", wrapLen-*lineLen))
}
// something is already on the line; terminate it
if lastSeenEscSeq != "" {
out.WriteString(EscapeReset)
}
out.WriteRune('\n')
out.WriteString(lastSeenEscSeq)
*lineLen = 0
}
func terminateOutput(lastSeenEscSeq string, out *strings.Builder) {
if lastSeenEscSeq != "" && lastSeenEscSeq != EscapeReset && !strings.HasSuffix(out.String(), EscapeReset) {
out.WriteString(EscapeReset)
}
}
func wrapHard(paragraph string, wrapLen int, out *strings.Builder) {
lineLen, lastSeenEscSeq := 0, ""
words := strings.Fields(paragraph)
for wordIdx, word := range words {
escSeq := extractOpenEscapeSeq(word)
if escSeq != "" {
lastSeenEscSeq = escSeq
}
if lineLen > 0 {
out.WriteRune(' ')
lineLen++
}
wordLen := RuneCount(word)
if lineLen+wordLen <= wrapLen { // word fits within the line
out.WriteString(word)
lineLen += wordLen
} else { // word doesn't fit within the line; hard-wrap
appendWord(word, &lineLen, lastSeenEscSeq, wrapLen, out)
}
// end of line; but more words incoming
if lineLen == wrapLen && wordIdx < len(words)-1 {
terminateLine(wrapLen, &lineLen, lastSeenEscSeq, out)
}
}
terminateOutput(lastSeenEscSeq, out)
}
func wrapSoft(paragraph string, wrapLen int, out *strings.Builder) {
lineLen, lastSeenEscSeq := 0, ""
words := strings.Fields(paragraph)
for wordIdx, word := range words {
escSeq := extractOpenEscapeSeq(word)
if escSeq != "" {
lastSeenEscSeq = escSeq
}
spacing, spacingLen := "", 0
if lineLen > 0 {
spacing, spacingLen = " ", 1
}
wordLen := RuneCount(word)
if lineLen+spacingLen+wordLen <= wrapLen { // word fits within the line
out.WriteString(spacing)
out.WriteString(word)
lineLen += spacingLen + wordLen
} else { // word doesn't fit within the line
if lineLen > 0 { // something is already on the line; terminate it
terminateLine(wrapLen, &lineLen, lastSeenEscSeq, out)
}
if wordLen <= wrapLen { // word fits within a single line
out.WriteString(word)
lineLen = wordLen
} else { // word doesn't fit within a single line; hard-wrap
appendWord(word, &lineLen, lastSeenEscSeq, wrapLen, out)
}
}
// end of line; but more words incoming
if lineLen == wrapLen && wordIdx < len(words)-1 {
terminateLine(wrapLen, &lineLen, lastSeenEscSeq, out)
}
}
terminateOutput(lastSeenEscSeq, out)
}