aboutsummaryrefslogtreecommitdiff
path: root/internal/render/color.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/render/color.go')
-rw-r--r--internal/render/color.go62
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()
+}