...
1
2
3
4
5
6 package color
7
8 import (
9 "fmt"
10 "strconv"
11 "strings"
12 )
13
14
15 type Attribute int
16
17
18 const (
19 Reset Attribute = iota
20 Bold
21 Faint
22 Italic
23 Underline
24 BlinkSlow
25 BlinkRapid
26 ReverseVideo
27 Concealed
28 CrossedOut
29 )
30
31
32 const (
33 FgBlack Attribute = iota + 30
34 FgRed
35 FgGreen
36 FgYellow
37 FgBlue
38 FgMagenta
39 FgCyan
40 FgWhite
41 )
42
43
44 const (
45 FgHiBlack Attribute = iota + 90
46 FgHiRed
47 FgHiGreen
48 FgHiYellow
49 FgHiBlue
50 FgHiMagenta
51 FgHiCyan
52 FgHiWhite
53 )
54
55
56 const (
57 BgBlack Attribute = iota + 40
58 BgRed
59 BgGreen
60 BgYellow
61 BgBlue
62 BgMagenta
63 BgCyan
64 BgWhite
65 )
66
67
68 const (
69 BgHiBlack Attribute = iota + 100
70 BgHiRed
71 BgHiGreen
72 BgHiYellow
73 BgHiBlue
74 BgHiMagenta
75 BgHiCyan
76 BgHiWhite
77 )
78
79 const (
80 escape = "\x1b"
81 unescape = "\\x1b"
82 )
83
84
85
86
87 func Format(s ...interface{}) string {
88 if len(s) == 0 {
89 return ""
90 }
91
92 params := []Attribute{}
93 in := -1
94
95 for i, v := range s {
96 switch vt := v.(type) {
97 case []Attribute:
98 if in == -1 {
99 params = append(params, vt...)
100 } else {
101 s[i] = printExtraColorAttribute(v)
102 }
103 case Attribute:
104 if in == -1 {
105 params = append(params, vt)
106 } else {
107 s[i] = printExtraColorAttribute(v)
108 }
109 default:
110 if in == -1 {
111 in = i
112 }
113 }
114 }
115
116 if in == -1 || len(s[in:]) == 0 {
117 return ""
118 }
119 return wrap(params, fmt.Sprint(s[in:]...))
120 }
121
122 func printExtraColorAttribute(v interface{}) string {
123 return fmt.Sprintf("(EXTRA color.Attribute=%v)", v)
124 }
125
126
127 func StripAttributes(s ...interface{}) (raw string) {
128 in := -1
129 for i, v := range s {
130 switch v.(type) {
131 case []Attribute, Attribute:
132 if in != -1 {
133 s[i] = printExtraColorAttribute(v)
134 }
135 default:
136 if in == -1 {
137 in = i
138 }
139 }
140 }
141 if in == -1 {
142 in = 0
143 }
144 return fmt.Sprint(s[in:]...)
145 }
146
147
148 func Escape(s string) string {
149 return strings.Replace(s, escape, unescape, -1)
150 }
151
152
153
154 func sequence(params []Attribute) string {
155 format := make([]string, len(params))
156 for i, v := range params {
157 format[i] = strconv.Itoa(int(v))
158 }
159
160 return strings.Join(format, ";")
161 }
162
163
164 func wrap(params []Attribute, s string) string {
165 return fmt.Sprintf("%s[%sm%s%s[%dm", escape, sequence(params), s, escape, Reset)
166 }
167
View as plain text