package color import ( "fmt" "io" "os" "strconv" "strings" ) // Color defines a custom color object which is defined by SGR parameters. type Color struct { params []Attribute } // Attribute defines a single SGR Code type Attribute int const escape = "\x1b" // Base attributes const ( Reset Attribute = iota Bold Faint Italic Underline BlinkSlow BlinkRapid ReverseVideo Concealed CrossedOut ) // Foreground text colors const ( FgBlack Attribute = iota + 30 FgRed FgGreen FgYellow FgBlue FgMagenta FgCyan FgWhite ) // Background text colors const ( BgBlack Attribute = iota + 40 BgRed BgGreen BgYellow BgBlue BgMagenta BgCyan BgWhite ) // New returns a newly created color object. func New(value ...Attribute) *Color { c := &Color{params: make([]Attribute, 0)} c.Add(value...) return c } // Set sets the given parameters immediately. It will change the color of // output with the given SGR parameters until color.Unset() is called. func Set(p ...Attribute) *Color { c := New(p...) c.Set() return c } // Unset resets all escape attributes and clears the output. Usually should // be called after Set(). func Unset() { fmt.Fprintf(Output, "%s[%dm", escape, Reset) } // Add is used to chain SGR parameters. Use as many as parameters to combine // and create custom color objects. Example: Add(color.FgRed, color.Underline). func (c *Color) Add(value ...Attribute) *Color { c.params = append(c.params, value...) return c } func (c *Color) prepend(value Attribute) { c.params = append(c.params, 0) copy(c.params[1:], c.params[0:]) c.params[0] = value } // Output defines the standard output of the print functions. By default // os.Stdout is used. var Output io.Writer = os.Stdout // Print formats using the default formats for its operands and writes to // standard output. Spaces are added between operands when neither is a // string. It returns the number of bytes written and any write error // encountered. This is the standard fmt.Print() method wrapped with the given // color. func (c *Color) Print(a ...interface{}) (n int, err error) { c.Set() defer Unset() return fmt.Fprint(Output, a...) } // Printf formats according to a format specifier and writes to standard output. // It returns the number of bytes written and any write error encountered. // This is the standard fmt.Printf() method wrapped with the given color. func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { c.Set() defer Unset() return fmt.Fprintf(Output, format, a...) } // Println formats using the default formats for its operands and writes to // standard output. Spaces are always added between operands and a newline is // appended. It returns the number of bytes written and any write error // encountered. This is the standard fmt.Print() method wrapped with the given // color. func (c *Color) Println(a ...interface{}) (n int, err error) { c.Set() defer Unset() return fmt.Fprintln(Output, a...) } // PrintFunc returns a new function that prints the passed arguments as // colorized with color.Print(). func (c *Color) PrintFunc() func(a ...interface{}) { return func(a ...interface{}) { c.Print(a...) } } // PrintfFunc returns a new function that prints the passed arguments as // colorized with color.Printf(). func (c *Color) PrintfFunc() func(format string, a ...interface{}) { return func(format string, a ...interface{}) { c.Printf(format, a...) } } // PrintlnFunc returns a new function that prints the passed arguments as // colorized with color.Println(). func (c *Color) PrintlnFunc() func(a ...interface{}) { return func(a ...interface{}) { c.Println(a...) } } // SprintFunc returns a new function that returns colorized strings for the // given arguments with fmt.Sprint(). Useful to put into or mix into other // string. func (c *Color) SprintFunc() func(a ...interface{}) string { return func(a ...interface{}) string { return c.wrap(fmt.Sprint(a...)) } } // SprintfFunc returns a new function that returns colorized strings for the // given arguments with fmt.Sprintf(). Useful to put into or mix into other // string. func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { return func(format string, a ...interface{}) string { return c.wrap(fmt.Sprintf(format, a...)) } } // SprintlnFunc returns a new function that returns colorized strings for the // given arguments with fmt.Sprintln(). Useful to put into or mix into other // string. func (c *Color) SprintlnFunc() func(a ...interface{}) string { return func(a ...interface{}) string { return c.wrap(fmt.Sprintln(a...)) } } // sequence returns a formated SGR sequence to be plugged into a "\x1b[...m" // an example output might be: "1;36" -> bold cyan func (c *Color) sequence() string { format := make([]string, len(c.params)) for i, v := range c.params { format[i] = strconv.Itoa(int(v)) } return strings.Join(format, ";") } func (c *Color) wrap(s string) string { return c.format() + s + c.unformat() } func (c *Color) format() string { return fmt.Sprintf("%s[%sm", escape, c.sequence()) } func (c *Color) unformat() string { return fmt.Sprintf("%s[%dm", escape, Reset) } // Set sets the SGR sequence. func (c *Color) Set() *Color { fmt.Fprintf(Output, c.format()) return c } // Black is an convenient helper function to print with black foreground. A // newline is appended to format by default. func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) } // Red is an convenient helper function to print with red foreground. A // newline is appended to format by default. func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) } // Green is an convenient helper function to print with green foreground. A // newline is appended to format by default. func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) } // Yellow is an convenient helper function to print with yellow foreground. // A newline is appended to format by default. func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) } // Blue is an convenient helper function to print with blue foreground. A // newline is appended to format by default. func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) } // Magenta is an convenient helper function to print with magenta foreground. // A newline is appended to format by default. func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) } // Cyan is an convenient helper function to print with cyan foreground. A // newline is appended to format by default. func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) } // White is an convenient helper function to print with white foreground. A // newline is appended to format by default. func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) } func printColor(format string, p Attribute, a ...interface{}) { if !strings.HasSuffix(format, "\n") { format += "\n" } c := &Color{params: []Attribute{p}} c.Printf(format, a...) } // BlackString is an convenient helper function to return a string with black // foreground. func BlackString(format string, a ...interface{}) string { return New(FgBlack).SprintfFunc()(format, a...) } // RedString is an convenient helper function to return a string with red // foreground. func RedString(format string, a ...interface{}) string { return New(FgRed).SprintfFunc()(format, a...) } // GreenString is an convenient helper function to return a string with green // foreground. func GreenString(format string, a ...interface{}) string { return New(FgGreen).SprintfFunc()(format, a...) } // YellowString is an convenient helper function to return a string with yellow // foreground. func YellowString(format string, a ...interface{}) string { return New(FgYellow).SprintfFunc()(format, a...) } // BlueString is an convenient helper function to return a string with blue // foreground. func BlueString(format string, a ...interface{}) string { return New(FgBlue).SprintfFunc()(format, a...) } // MagentaString is an convenient helper function to return a string with magenta // foreground. func MagentaString(format string, a ...interface{}) string { return New(FgMagenta).SprintfFunc()(format, a...) } // CyanString is an convenient helper function to return a string with cyan // foreground. func CyanString(format string, a ...interface{}) string { return New(FgCyan).SprintfFunc()(format, a...) } // WhiteString is an convenient helper function to return a string with white // foreground. func WhiteString(format string, a ...interface{}) string { return New(FgWhite).SprintfFunc()(format, a...) }