diff options
Diffstat (limited to 'internal/render/color.go')
| -rw-r--r-- | internal/render/color.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/render/color.go b/internal/render/color.go new file mode 100644 index 0000000..cf2af89 --- /dev/null +++ b/internal/render/color.go @@ -0,0 +1,62 @@ +package render + +import "strings" + +// Colour uses ANSI slots 0-15 only -- codes 30-37 and 90-97, plus the +// attributes 1 (bold), 2 (dim) and 4 (underline). Never 256-colour indices: +// this runs on terminals whose palette remaps the low slots (the phone's is +// entirely green), where a hardcoded 38;5;196 would be the one off-palette +// thing on screen. +const ( + Reset = "0" + Bold = "1" + Dim = "2" + Underline = "4" + + Blue = "34" + Cyan = "36" + Green = "32" + Yellow = "33" + Red = "31" + BrightBlue = "94" + BrightRed = "91" + BrightWhite = "97" +) + +// Styler returns a function that wraps text in an ANSI code, or returns it +// unchanged when colour is off. +func Styler(colour bool) func(code, text string) string { + if !colour { + return func(_, text string) string { return text } + } + return func(code, text string) string { + if code == "" { + return text + } + return "\033[" + code + "m" + text + "\033[0m" + } +} + +// Cell is one character of chart output with the style it should carry. +type Cell struct { + Style string + Text string +} + +// Paint joins cells, emitting one escape sequence per run of identical style +// rather than one per character. A per-character version makes the chart around +// ten times larger for output that looks exactly the same. +func Paint(cells []Cell, c func(string, string) string) string { + var b strings.Builder + for i := 0; i < len(cells); { + j := i + var run strings.Builder + for j < len(cells) && cells[j].Style == cells[i].Style { + run.WriteString(cells[j].Text) + j++ + } + b.WriteString(c(cells[i].Style, run.String())) + i = j + } + return b.String() +} |
