1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// Package color can be used to add color to your terminal using ANSI escape code (or sequences).
//
// See https://en.wikipedia.org/wiki/ANSI_escape_code
// Copy modified from https://github.com/fatih/color
// Copyright 2013 Fatih Arslan
package color
import (
"fmt"
"strconv"
"strings"
)
// Attribute defines a single SGR (Select Graphic Rendition) code.
type Attribute int
// 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
)
// Foreground Hi-Intensity text colors
const (
FgHiBlack Attribute = iota + 90
FgHiRed
FgHiGreen
FgHiYellow
FgHiBlue
FgHiMagenta
FgHiCyan
FgHiWhite
)
// Background text colors
const (
BgBlack Attribute = iota + 40
BgRed
BgGreen
BgYellow
BgBlue
BgMagenta
BgCyan
BgWhite
)
// Background Hi-Intensity text colors
const (
BgHiBlack Attribute = iota + 100
BgHiRed
BgHiGreen
BgHiYellow
BgHiBlue
BgHiMagenta
BgHiCyan
BgHiWhite
)
const (
escape = "\x1b"
unescape = "\\x1b"
)
// Format text for terminal.
// You can pass an arbitrary number of Attribute or []Attribute followed by any other values,
// that can either be a string or something else (that is converted to string using fmt.Sprint).
func Format(s ...interface{}) string {
if len(s) == 0 {
return ""
}
params := []Attribute{}
in := -1
for i, v := range s {
switch vt := v.(type) {
case []Attribute:
if in == -1 {
params = append(params, vt...)
} else {
s[i] = printExtraColorAttribute(v)
}
case Attribute:
if in == -1 {
params = append(params, vt)
} else {
s[i] = printExtraColorAttribute(v)
}
default:
if in == -1 {
in = i
}
}
}
if in == -1 || len(s[in:]) == 0 {
return ""
}
return wrap(params, fmt.Sprint(s[in:]...))
}
func printExtraColorAttribute(v interface{}) string {
return fmt.Sprintf("(EXTRA color.Attribute=%v)", v)
}
// StripAttributes from input arguments and return unformatted text.
func StripAttributes(s ...interface{}) (raw string) {
in := -1
for i, v := range s {
switch v.(type) {
case []Attribute, Attribute:
if in != -1 {
s[i] = printExtraColorAttribute(v)
}
default:
if in == -1 {
in = i
}
}
}
if in == -1 {
in = 0
}
return fmt.Sprint(s[in:]...)
}
// Escape text for terminal.
func Escape(s string) string {
return strings.Replace(s, escape, unescape, -1)
}
// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
// an example output might be: "1;36" -> bold cyan.
func sequence(params []Attribute) string {
format := make([]string, len(params))
for i, v := range params {
format[i] = strconv.Itoa(int(v))
}
return strings.Join(format, ";")
}
// wrap the s string with the colors attributes.
func wrap(params []Attribute, s string) string {
return fmt.Sprintf("%s[%sm%s%s[%dm", escape, sequence(params), s, escape, Reset)
}
|