color.ha (1976B)
1 // License: GPL-3.0 2 // (c) 2022 Byron Torres <b@torresjrjr.com> 3 use ascii; 4 use fmt; 5 use io; 6 use os; 7 use regex; 8 use strings; 9 10 // Syntax type 11 type syn = enum uint { 12 NORMAL, 13 COMMENT, 14 PRIMARY, 15 CONSTANT, 16 FUNCTION, 17 GLOBAL, 18 TYPEDEF, 19 SECONDARY, 20 KEYWORD, 21 TYPE, 22 ATTRIBUTE, 23 OPERATOR, 24 PUNCTUATION, 25 STRING, 26 NUMBER, 27 }; 28 29 // Colors/Renditions with defaults; SGR parameters for ANSI escape sequences. 30 let COLORS: [_](str, str) = [ 31 ("normal" , "0"), 32 ("comment" , "1"), 33 ("primary" , "0"), 34 ("constant" , "0"), 35 ("function" , "0"), 36 ("global" , "0"), 37 ("typedef" , "0"), 38 ("secondary" , "0"), 39 ("keyword" , "94"), 40 ("type" , "96"), 41 ("attribute" , "33"), 42 ("operator" , "1"), 43 ("punctuation" , "0"), 44 ("string" , "91"), 45 ("number" , "95"), 46 ]; 47 48 fn init_colors() void = { 49 const env_colors = os::tryenv("HAREDOC_COLORS", ""); 50 51 const expr = regex::compile(`([a-z][a-z]*)=(_|[0-9;]*)`)!; 52 defer regex::finish(&expr); 53 54 const matches = regex::findall(&expr, env_colors); 55 defer regex::result_freeall(matches); 56 57 for (let i = 0z; i < len(matches); i += 1) :colors { 58 const (k, v) = (matches[i][1].content, matches[i][2].content); 59 60 let idx = 0z; 61 for (let j = 0z; j < len(COLORS); j += 1) { 62 if (k == COLORS[j].0) { 63 idx = j; 64 break; 65 } else if (j == len(COLORS) - 1) { 66 fmt::fatalf( 67 "Error parsing HAREDOC_COLORS, " 68 "invalid key '{}'", k, 69 ); 70 }; 71 }; 72 73 if (v == "_") { 74 COLORS[idx] = if (k == "normal") (k, "0") else (k, v); 75 continue; 76 }; 77 if (v == "") { 78 continue; 79 }; 80 81 COLORS[idx] = (k, v); 82 }; 83 }; 84 85 fn render(h: io::handle, syntax: syn) (size | io::error) = { 86 if (COLORS[syntax].1 == "_") { 87 syntax = switch (syntax) { 88 case syn::CONSTANT, syn::FUNCTION, syn::GLOBAL, syn::TYPEDEF => 89 yield if (COLORS[syn::PRIMARY].1 == "_") syn::NORMAL 90 else syn::PRIMARY; 91 case => 92 yield syn::NORMAL; 93 }; 94 }; 95 return fmt::fprintf(h, "\x1b[0;{}m", COLORS[syntax].1)?; 96 };