hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };