new object $ansi_format: $plain_format;
var $ansi_format bcolors = #[["black", "40"], ["red", "41"], ["green", "42"], ["yellow", "43"], ["blue", "44"], ["magenta", "45"], ["cyan", "46"], ["white", "47"]];
var $ansi_format colors = #[["black", "30"], ["red", "31"], ["green", "32"], ["yellow", "33"], ["blue", "34"], ["magenta", "35"], ["cyan", "36"], ["white", "37"]];
var $dmi_data descriptions = #[];
var $root created_on = 863402529;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root inited = 1;
var $root managed = [$ansi_format];
var $root manager = $ansi_format;
public method .do_detail() {
arg vars, flags, args;
return [("\A1;4m" + (flags.getkey("name"))) + "\A0m", vars];
};
public method .do_font() {
arg vars, flags, args;
var color, bcolor, code, nested, current;
// allow other .do_* methods to call this with a specific code
if (dict_contains(vars, 'ansi_code)) {
code = vars['ansi_code];
vars = dict_del(vars, 'ansi_code);
} else {
color = (| flags.getkey("color") |);
bcolor = (| flags.getkey("bcolor") |);
code = (color ? (| ($cml_color.get_color(color))[2] |) : "") || "";
code += (bcolor ? (code ? (| ";" + (($cml_color.get_color(bcolor))[3]) |) : (| ($cml_color.get_color(bcolor))[3] |)) : "") || "";
}
if (code) {
code = ("\A" + code) + "m";
// handle existing nesting
if (dict_contains(vars, 'ansi_color)) {
current = vars['ansi_color];
nested++;
}
vars = dict_add(vars, 'ansi_color, code);
}
[args, vars] = ._eval_ctext(args, vars);
if (code) {
if (nested) {
args = ((("\A0m" + code) + args) + "\A0m") + current;
vars = dict_add(vars, 'ansi_color, current);
} else {
args = (code + args) + "\A0m";
vars = dict_del(vars, 'ansi_color);
}
}
return [args, vars];
};
public method .do_link() {
arg vars, flags, args;
vars = dict_add(vars, 'ansi_code, "1;4");
return .do_font(vars, flags, args);
};
public method .explode_ansi() {
arg line;
var m, out;
out = [];
while (line) {
if ((m = match_regexp(line, "\\\A[^a-z]+[a-z]"))) {
m = m[1];
out += [substr(line, 1, (m[1]) - 1), substr(line, m[1], m[2])];
line = substr(line, (m[1]) + (m[2]));
} else {
out += [line];
break;
}
}
return out;
};
public method .format() {
arg data, vars;
var str, len, line, out;
str = (> (._eval_ctext(data, vars))[1] <);
if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
str += "\n";
// ugly and inneficient--use a client people
out = str_to_buf(str);
out = out.bufsub(`[92, 65], `[27, 91]);
return out;
};
public method .hold_rewrap_lines() {
arg vars, str, prefix;
var s, p, n, firstline;
s = [];
n = (vars['width]) + (prefix.length());
for str in (str.explode("\n", 1))
s += .wrap_lines(str, n, prefix, 1);
return s.join("\n");
};
public method .hold_wrap_lines() {
arg str, len, @stuff;
var prefix, firstline, split_str, ansi_parts, output, plen, hide_len, x, tlen, cutoff, tstr;
// takes string and wraps it by words, compared to length, returns a list.
[(prefix ?= ""), (firstline ?= 0)] = stuff;
split_str = .explode_ansi(str);
str = "";
x = 1;
tlen = 1;
ansi_parts = [];
while (x < (split_str.length())) {
str += split_str[x];
ansi_parts = ansi_parts.add([tlen, split_str[x + 1]]);
tlen += strlen(str);
x += 2;
}
if (firstline)
str = prefix + str;
output = [];
plen = strlen(prefix);
while (strlen(str) > len) {
cutoff = stridx(substr(str, 1, len), " ", -1);
if (cutoff <= plen) {
tstr = substr(str, 1, len);
str = prefix + substr(str, len + 1);
} else {
tstr = substr(str, 1, cutoff - 1);
str = prefix + substr(str, cutoff + 1);
}
output += tstr;
}
return output + [str];
};