Documentation ¶
Overview ¶
Package brimtext contains tools for working with text. Probably the most complex of these tools is Align, which allows for formatting "pretty tables".
Index ¶
- Variables
- func Align(data [][]string, opts *AlignOptions) string
- func AllEqual(values ...string) bool
- func ClosestANSIForeground(red int, green int, blue int) []byte
- func ClosestANSIForegroundString(value string) []byte
- func FalseString(value string) bool
- func GetTTYWidth() int
- func HumanSize(v float64, u float64, s []string) string
- func HumanSize1000(v float64) string
- func HumanSize1024(v float64) string
- func OrdinalSuffix(number int) string
- func RuneLenStripANSIEscapes(v string) int
- func Sentence(value string) string
- func StripANSIEscapes(v string) string
- func ThousandsSep(v int64, sep string) string
- func ThousandsSepU(v uint64, sep string) string
- func TrueString(value string) bool
- func Wrap(text string, width int, indent1 string, indent2 string) string
- type ANSIEscapeCodes
- type AlignOptions
- type Alignment
- type StringSliceToLowerSort
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ANSIEscape = ANSIEscapeCodes{ Reset: []byte{27, '[', '0', 'm'}, Bold: []byte{27, '[', '1', 'm'}, BBlack: []byte{27, '[', '4', '0', 'm'}, BRed: []byte{27, '[', '4', '1', 'm'}, BGreen: []byte{27, '[', '4', '2', 'm'}, BYellow: []byte{27, '[', '4', '3', 'm'}, BBlue: []byte{27, '[', '4', '4', 'm'}, BMagenta: []byte{27, '[', '4', '5', 'm'}, BCyan: []byte{27, '[', '4', '6', 'm'}, BWhite: []byte{27, '[', '4', '7', 'm'}, FBlack: []byte{27, '[', '3', '0', 'm'}, FRed: []byte{27, '[', '3', '1', 'm'}, FGreen: []byte{27, '[', '3', '2', 'm'}, FYellow: []byte{27, '[', '3', '3', 'm'}, FBlue: []byte{27, '[', '3', '4', 'm'}, FMagenta: []byte{27, '[', '3', '5', 'm'}, FCyan: []byte{27, '[', '3', '6', 'm'}, FWhite: []byte{27, '[', '3', '7', 'm'}, }
ANSIEscape provides ease of access to common ANSI Escape Codes.
Functions ¶
func Align ¶
func Align(data [][]string, opts *AlignOptions) string
Align will format a table according to options. If opts is nil, NewDefaultAlignOptions is used.
Example (Default) ¶
package main import ( "fmt" "github.com/gholt/brimtext" ) func main() { fmt.Println(brimtext.Align([][]string{ {"", "Bob", "Sue", "John"}, {"Hometown", "San Antonio", "Austin", "New York"}, {"Mother", "Bessie", "Mary", "Sarah"}, {"Father", "Rick", "Dan", "Mike"}, }, nil)) }
Output: Bob Sue John Hometown San Antonio Austin New York Mother Bessie Mary Sarah Father Rick Dan Mike
Example (Simple) ¶
package main import ( "fmt" "github.com/gholt/brimtext" ) func main() { fmt.Println(brimtext.Align([][]string{ {"", "Bob", "Sue", "John"}, nil, {"Hometown", "San Antonio", "Austin", "New York"}, {"Mother", "Bessie", "Mary", "Sarah"}, {"Father", "Rick", "Dan", "Mike"}, }, brimtext.NewSimpleAlignOptions())) }
Output: +----------+-------------+--------+----------+ | | Bob | Sue | John | +----------+-------------+--------+----------+ | Hometown | San Antonio | Austin | New York | | Mother | Bessie | Mary | Sarah | | Father | Rick | Dan | Mike | +----------+-------------+--------+----------+
Example (UnicodeBoxed) ¶
package main import ( "fmt" "github.com/gholt/brimtext" ) func main() { data := [][]int{ {8, 20, 11}, {5, 11, 10}, {3, 9, 1}, {1200000, 2400000, 1700000}, } table := [][]string{{"", "Bob", "Sue", "John"}} for rowNum, values := range data { row := []string{""} prefix := "" switch rowNum { case 0: row[0] = "Shot Attempts" case 1: row[0] = "Shots Made" case 2: row[0] = "Shots Missed" case 3: row[0] = "Salary" prefix = "$" } for _, v := range values { row = append(row, prefix+brimtext.ThousandsSep(int64(v), ",")) } table = append(table, row) } opts := brimtext.NewUnicodeBoxedAlignOptions() opts.Alignments = []brimtext.Alignment{ brimtext.Right, brimtext.Right, brimtext.Right, brimtext.Right, } fmt.Println(brimtext.Align(table, opts)) }
Output: ╔═══════════════╦════════════╤════════════╤════════════╗ ║ ║ Bob │ Sue │ John ║ ╠═══════════════╬════════════╪════════════╪════════════╣ ║ Shot Attempts ║ 8 │ 20 │ 11 ║ ╟───────────────╫────────────┼────────────┼────────────╢ ║ Shots Made ║ 5 │ 11 │ 10 ║ ╟───────────────╫────────────┼────────────┼────────────╢ ║ Shots Missed ║ 3 │ 9 │ 1 ║ ╟───────────────╫────────────┼────────────┼────────────╢ ║ Salary ║ $1,200,000 │ $2,400,000 │ $1,700,000 ║ ╚═══════════════╩════════════╧════════════╧════════════╝
Example (UnicodeCustom) ¶
package main import ( "fmt" "github.com/gholt/brimtext" ) func main() { opts := brimtext.NewUnicodeBoxedAlignOptions() opts.FirstFirstDLR = opts.FirstDLR opts.RowSecondUD = opts.RowUD opts.NilFirstUDLR = opts.NilUDLR opts.FirstNilFirstUDR = opts.NilFirstUDR opts.FirstNilLR = opts.NilLR opts.FirstNilFirstUDLR = opts.NilFirstUDLR opts.FirstNilUDLR = opts.NilUDLR opts.FirstNilLastUDL = opts.NilLastUDL opts.LastFirstULR = opts.LastULR opts.NilBetweenEveryRow = false opts.Alignments = []brimtext.Alignment{ brimtext.Left, brimtext.Right, brimtext.Right, } fmt.Println(brimtext.Align([][]string{ {"Name", "Points", "Assists"}, nil, {"Bob", "10", "1"}, {"Sue", "7", "5"}, {"John", "2", "1"}, nil, {"Shooting Stars", "19", "7"}, }, opts)) }
Output: ╔════════════════╤════════╤═════════╗ ║ Name │ Points │ Assists ║ ╟────────────────┼────────┼─────────╢ ║ Bob │ 10 │ 1 ║ ║ Sue │ 7 │ 5 ║ ║ John │ 2 │ 1 ║ ╟────────────────┼────────┼─────────╢ ║ Shooting Stars │ 19 │ 7 ║ ╚════════════════╧════════╧═════════╝
func AllEqual ¶
AllEqual returns true if all the values are equal strings; no strings, AllEqual() or AllEqual([]string{}...), are considered AllEqual.
func ClosestANSIForeground ¶
ClosestANSIForeground translates the RGB values to the closest ANSIEscape sequence for that foreground color.
func ClosestANSIForegroundString ¶
ClosestANSIForegroundString translates the CSS-style color (e.g. "#ac8" "#ffee66") string to the closest ANSIEscape sequence for that foreground color.
func FalseString ¶
FalseString returns true if the string contains a recognized false value, such as "false", "False", "FALSE", "no", "off", etc. Yes, there is already strconv.ParseBool, but this function is often easier to work with since it just returns true or false instead of (bool, error) like ParseBool does. If you need to differentiate between true, false, and unknown, ParseBool should be your choice. Although I suppose you could use TrueString(s), FalseString(s), and !TrueString(s) && !FalseString(s).
func GetTTYWidth ¶
func GetTTYWidth() int
GetTTYWidth returns the width of the controlling TTY if it can or 80.
func HumanSize ¶
HumanSize returns a more readable size format. Quick, "standard" implementations are HumanSize1000 and HumanSize1024, but this more generic function is provided so you can tweak the output a bit more.
Here are the implementations of the two standard functions, to get an idea of how you might wish to use HumanSize directly.
// HumanSize1000 returns a more readable size format, such as // HumanSize1000(1234567) giving "1.23m". // These are 1,000 unit based: 1k = 1000, 1m = 1000000, etc. func HumanSize1000(v float64) string { return HumanSize(v, 1000, []string{"", "k", "m", "g", "t", "p", "e", "z", "y"}) } // HumanSize1024 returns a more readable size format, such as // HumanSize1024(1234567) giving "1.18M". // These are 1,024 unit based: 1K = 1024, 1M = 1048576, etc. func HumanSize1024(v float64) string { return HumanSize(v, 1024, []string{"", "K", "M", "G", "T", "P", "E", "Z", "Y"}) }
func HumanSize1000 ¶
HumanSize1000 returns a more readable size format, such as HumanSize1000(1234567) giving "1.23m". These are 1,000 unit based: 1k = 1000, 1m = 1000000, etc.
func HumanSize1024 ¶
HumanSize1024 returns a more readable size format, such as HumanSize1024(1234567) giving "1.18M". These are 1,024 unit based: 1K = 1024, 1M = 1048576, etc.
func OrdinalSuffix ¶
OrdinalSuffix returns "st", "nd", "rd", etc. for the number given (1st, 2nd, 3rd, etc.).
func RuneLenStripANSIEscapes ¶
func Sentence ¶
Sentence converts the value into a sentence, uppercasing the first character and ensuring the string ends with a period. Useful to output better looking error.Error() messages, which are all lower case with no trailing period by convention.
func StripANSIEscapes ¶
func ThousandsSep ¶
ThousandsSep returns the number formatted using the separator at each thousands position, such as ThousandsSep(1234567, ",") giving 1,234,567.
func ThousandsSepU ¶
ThousandsSepU returns the number formatted using the separator at each thousands position, such as ThousandsSepU(1234567, ",") giving 1,234,567.
func TrueString ¶
TrueString returns true if the string contains a recognized true value, such as "true", "True", "TRUE", "yes", "on", etc. Yes, there is already strconv.ParseBool, but this function is often easier to work with since it just returns true or false instead of (bool, error) like ParseBool does. If you need to differentiate between true, false, and unknown, ParseBool should be your choice. Although I suppose you could use TrueString(s), FalseString(s), and !TrueString(s) && !FalseString(s).
func Wrap ¶
Wrap wraps text for more readable output.
The width can be a positive int for a specific width, 0 for the default width (attempted to get from terminal, 79 otherwise), or a negative number for a width relative to the default.
The indent1 is the prefix for the first line.
The indent2 is the prefix for any second or subsequent lines.
Types ¶
type ANSIEscapeCodes ¶
type ANSIEscapeCodes struct { Reset []byte Bold []byte BBlack, BRed, BGreen, BYellow, BBlue, BMagenta, BCyan, BWhite []byte FBlack, FRed, FGreen, FYellow, FBlue, FMagenta, FCyan, FWhite []byte }
ANSIEscapeCodes is the defining structure for the more commonly used ANSIEscape global variable.
type AlignOptions ¶
type AlignOptions struct { // Widths indicate the desired widths of each column. If nil or if a value // is 0, no rewrapping will be done. Widths []int Alignments []Alignment // FirstDR etc. control what is output for situations with a prepended // display row, First row output with Down and Right connections, etc. FirstDR string FirstLR string FirstFirstDLR string FirstDLR string FirstDL string // RowFirstUD etc. control situations for each data row output. RowFirstUD string RowSecondUD string RowUD string RowLastUD string // LeaveTrailingWhitespace should be set true if the last cell of data row // needs spaces to fill to the end (usually needed when setting RowLastUD). LeaveTrailingWhitespace bool // FirstNilFirstUDR etc. control situations when the first nil data row is // encountered. Can be used to separate the header from the rest of the // rows. FirstNilFirstUDR string FirstNilLR string FirstNilFirstUDLR string FirstNilUDLR string FirstNilLastUDL string // NilFirstUDR etc. control situations when the second and subsequent nil // data rows are encountered. Can be used to separate rows from each other. NilFirstUDR string NilLR string NilFirstUDLR string NilUDLR string NilLastUDL string // LastUR etc. control what is output for situations with an appended // display row. LastUR string LastLR string LastFirstULR string LastULR string LastUL string // NilBetweenEveryRow will add a nil data row between all rows; use to emit // FirstNil* and Nil* row separators. NilBetweenEveryRow bool }
func NewBoxedAlignOptions ¶
func NewBoxedAlignOptions() *AlignOptions
NewBoxedAlignOptions gives:
&AlignOptions{ FirstDR: "+=", FirstLR: "=", FirstFirstDLR: "=+=", FirstDLR: "=+=", FirstDL: "=+", RowFirstUD: "| ", RowSecondUD: " | ", RowUD: " | ", RowLastUD: " |", LeaveTrailingWhitespace: true, FirstNilFirstUDR: "+=", FirstNilLR: "=", FirstNilFirstUDLR: "=+=", FirstNilUDLR: "=+=", FirstNilLastUDL: "=+", NilFirstUDR: "+-", NilLR: "-", NilFirstUDLR: "-+-", NilUDLR: "-+-", NilLastUDL: "-+", LastUR: "+=", LastLR: "=", LastFirstULR: "=+=", LastULR: "=+=", LastUL: "=+", NilBetweenEveryRow: true, }
Which will format tables like:
+==========+=============+========+==========+ | | Bob | Sue | John | +==========+=============+========+==========+ | Hometown | San Antonio | Austin | New York | +----------+-------------+--------+----------+ | Mother | Bessie | Mary | Sarah | +----------+-------------+--------+----------+ | Father | Rick | Dan | Mike | +==========+=============+========+==========+
func NewDefaultAlignOptions ¶
func NewDefaultAlignOptions() *AlignOptions
NewDefaultAlignOptions gives:
&AlignOptions{RowSecondUD: " ", RowUD: " "}
Which will format tables like:
Bob Sue John Hometown San Antonio Austin New York Mother Bessie Mary Sarah Father Rick Dan Mike
func NewSimpleAlignOptions ¶
func NewSimpleAlignOptions() *AlignOptions
NewSimpleAlignOptions gives:
return &AlignOptions{ FirstDR: "+-", FirstLR: "-", FirstFirstDLR: "-+-", FirstDLR: "-+-", FirstDL: "-+", RowFirstUD: "| ", RowSecondUD: " | ", RowUD: " | ", RowLastUD: " |", LeaveTrailingWhitespace: true, FirstNilFirstUDR: "+-", FirstNilLR: "-", FirstNilFirstUDLR: "-+-", FirstNilUDLR: "-+-", FirstNilLastUDL: "-+", LastUR: "+-", LastLR: "-", LastFirstULR: "-+-", LastULR: "-+-", LastUL: "-+", }
Which will format tables like:
+----------+-------------+--------+----------+ | | Bob | Sue | John | +----------+-------------+--------+----------+ | Hometown | San Antonio | Austin | New York | | Mother | Bessie | Mary | Sarah | | Father | Rick | Dan | Mike | +----------+-------------+--------+----------+
func NewUnicodeBoxedAlignOptions ¶
func NewUnicodeBoxedAlignOptions() *AlignOptions
NewUnicodeBoxedAlignOptions gives:
&AlignOptions{ FirstDR: "\u2554\u2550", FirstLR: "\u2550", FirstFirstDLR: "\u2550\u2566\u2550", FirstDLR: "\u2550\u2564\u2550", FirstDL: "\u2550\u2557", RowFirstUD: "\u2551 ", RowSecondUD: " \u2551 ", RowUD: " \u2502 ", RowLastUD: " \u2551", LeaveTrailingWhitespace: true, FirstNilFirstUDR: "\u2560\u2550", FirstNilLR: "\u2550", FirstNilFirstUDLR: "\u2550\u256c\u2550", FirstNilUDLR: "\u2550\u256a\u2550", FirstNilLastUDL: "\u2550\u2563", NilFirstUDR: "\u255f\u2500", NilLR: "\u2500", NilFirstUDLR: "\u2500\u256b\u2500", NilUDLR: "\u2500\u253c\u2500", NilLastUDL: "\u2500\u2562", LastUR: "\u255a\u2550", LastLR: "\u2550", LastFirstULR: "\u2550\u2569\u2550", LastULR: "\u2550\u2567\u2550", LastUL: "\u2550\u255d", NilBetweenEveryRow: true, }
Which will format tables like:
╔══════════╦═════════════╤════════╤══════════╗ ║ ║ Bob │ Sue │ John ║ ╠══════════╬═════════════╪════════╪══════════╣ ║ Hometown ║ San Antonio │ Austin │ New York ║ ╟──────────╫─────────────┼────────┼──────────╢ ║ Mother ║ Bessie │ Mary │ Sarah ║ ╟──────────╫─────────────┼────────┼──────────╢ ║ Father ║ Rick │ Dan │ Mike ║ ╚══════════╩═════════════╧════════╧══════════╝
type StringSliceToLowerSort ¶
type StringSliceToLowerSort []string
StringSliceToLowerSort provides a sort.Interface that will sort a []string by their strings.ToLower values. This isn't exactly a case insensitive sort due to Unicode situations, but is usually good enough.
func (StringSliceToLowerSort) Len ¶
func (s StringSliceToLowerSort) Len() int
func (StringSliceToLowerSort) Swap ¶
func (s StringSliceToLowerSort) Swap(x int, y int)