-
Notifications
You must be signed in to change notification settings - Fork 0
/
pintor.go
155 lines (135 loc) · 2.89 KB
/
pintor.go
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
// Package pintor colorizes text printed to a terminal.
// It applies format to the output using ANSI escape sequences.
package pintor
import (
"fmt"
"strconv"
)
const csi = "\x1b["
type color int
const (
reset color = 0
bold = 1
italic = 3
underline = 4
)
const (
fgBlack color = iota + 30
fgRed
fgGreen
fgYellow
fgBlue
fgMagenta
fgCyan
fgWhite
)
const (
bgBlack color = iota + 40
bgRed
bgGreen
bgYellow
bgBlue
bgMagenta
bgCyan
bgWhite
)
// Values that can be used to create a Formatter object.
//
// Default leaves the current format as it is.
// Eight colors supported: Black, Red, Green, Yellow, Blue, Magenta, Cyan and White.
// Colors apply for foreground and background color.
// Modifiers supported: Bold, Italic and Underline.
const (
Default = 0
Black = 1 << iota
Red
Green
Yellow
Blue
Magenta
Cyan
White
Bold
Italic
Underline
)
var fgUMap = map[uint]color{
Black: fgBlack,
Red: fgRed,
Green: fgGreen,
Yellow: fgYellow,
Blue: fgBlue,
Magenta: fgMagenta,
Cyan: fgCyan,
White: fgWhite,
}
var bgUMap = map[uint]color{
Black: bgBlack,
Red: bgRed,
Green: bgGreen,
Yellow: bgYellow,
Blue: bgBlue,
Magenta: bgMagenta,
Cyan: bgCyan,
White: bgWhite,
}
// Formatter formats the text output.
type Formatter struct {
foreground uint
background uint
modifiers uint
}
// NewFormatter returns a new Formatter that can apply the colors and modifiers specified as parameters.
// Predefined bits control the colors and modifiers.
// Look at the package constant to get the colors and modifiers names.
// Only accepts one color for foreground and one color for background.
// To apply multiple modifiers at once set the modifiers parameter to:
//
// Bold|Italic
//
// This for example will apply both Bold and Italic to the text.
func NewFormatter(foreground, background, modifiers uint) *Formatter {
return &Formatter{
foreground: foreground,
background: background,
modifiers: modifiers,
}
}
// Format applies the format defined by the Formatter.
// It receives the target string and returns the string with the formatting applied.
// Formatting is performed using ANSI escape sequences.
func (f *Formatter) Format(target string) string {
sequence := f.compile()
end := buildEscape([]color{reset})
return fmt.Sprintf("%s%s%s", sequence, target, end)
}
func (f *Formatter) compile() string {
var p []color
if g, ok := fgUMap[f.foreground]; ok {
p = append(p, g)
}
if b, ok := bgUMap[f.background]; ok {
p = append(p, b)
}
if f.modifiers&Bold != 0 {
p = append(p, bold)
}
if f.modifiers&Italic != 0 {
p = append(p, italic)
}
if f.modifiers&Underline != 0 {
p = append(p, underline)
}
return buildEscape(p)
}
func buildEscape(colors []color) string {
escape := csi
for i, c := range colors {
if i > 0 {
escape += ";"
}
escape += strconv.Itoa(int(c))
}
escape += "m"
return escape
}