commit 888f8043c0903eed3d01da9411d872aab90edd8f
parent 10d78afae2c706b3c9b3bca31d8b463e9738a3f2
Author: Byron Torres <b@torresjrjr.com>
Date: Tue, 21 Jun 2022 22:10:04 +0100
haredoc: tty: add color.ha, rendering functions
Signed-off-by: Byron Torres <b@torresjrjr.com>
Diffstat:
A | cmd/haredoc/color.ha | | | 91 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 91 insertions(+), 0 deletions(-)
diff --git a/cmd/haredoc/color.ha b/cmd/haredoc/color.ha
@@ -0,0 +1,91 @@
+// License: GPL-3.0
+// (c) 2022 Byron Torres <b@torresjrjr.com>
+use ascii;
+use fmt;
+use io;
+use os;
+use regex;
+use strings;
+
+// Syntax type
+type syn = enum uint {
+ NORMAL,
+ COMMENT,
+ PRIMARY,
+ SECONDARY,
+ KEYWORD,
+ TYPE,
+ ATTRIBUTE,
+ OPERATOR,
+ PUNCTUATION,
+ CONSTANT,
+ STRING,
+ NUMBER,
+};
+
+// Colors/Renditions with defaults; SGR parameters for ANSI escape sequences.
+let COLORS: [_](str, str) = [
+ ("normal" , "0"),
+ ("comment" , "0"),
+ ("primary" , "1"),
+ ("secondary" , "0"),
+ ("keyword" , "94"),
+ ("type" , "96"),
+ ("attribute" , "33"),
+ ("operator" , "1"),
+ ("punctuation" , "0"),
+ ("constant" , "91"),
+ ("string" , "91"),
+ ("number" , "95"),
+];
+
+fn init_colors() void = {
+ const env_colors = os::tryenv("HAREDOC_COLORS", "");
+
+ const expr = regex::compile(`([a-z][a-z]*)=(_|[0-9;]*)`)!;
+ defer regex::finish(&expr);
+
+ const matches = match (regex::findall(&expr, env_colors)) {
+ case void =>
+ return;
+ case let matches: [][]regex::capture =>
+ yield matches;
+ };
+ defer regex::free_matches(matches);
+
+ for (let i = 0z; i < len(matches); i += 1) :colors {
+ const (k, v) = (matches[i][1].content, matches[i][2].content);
+
+ let idx = 0z;
+ for (let j = 0z; j < len(COLORS); j += 1) {
+ if (k == COLORS[j].0) {
+ idx = j;
+ break;
+ } else if (j == len(COLORS) - 1) {
+ fmt::fatalf(
+ "Error parsing HAREDOC_COLORS, "
+ "invalid key '{}'", k,
+ );
+ };
+ };
+
+ if (v == "_") {
+ COLORS[idx] = if (k == "normal") (k, "0") else (k, v);
+ continue;
+ };
+ if (v == "") {
+ continue;
+ };
+
+ COLORS[idx] = (k, v);
+ };
+};
+
+fn render(h: io::handle, syntax: syn) (size | io::error) = {
+ switch (COLORS[syntax].1) {
+ case "_" =>
+ return fmt::fprintf(h, "\x1b[0;{}m", COLORS[syn::NORMAL].1)?;
+ case =>
+ return fmt::fprintf(h, "\x1b[0;{}m", COLORS[syntax].1)?;
+ };
+};