Open
Description
Example usage:
try writer.print(
comptime Output.prettyFmt("<r><d>{d} | <r>{s}\n", true),
.{
source.line,
source.text,
},
);
<r>
means reset
<d>
means dim
I wrote this as a wrapper, but is there a version of this that would be useful to move to std.fmt.format
? If you pass false
to is_enabled
, it strips away the color codes so writers that don't support colors don't receive the escape sequences
// Valid colors:
// <black>
// <blue>
// <cyan>
// <green>
// <magenta>
// <red>
// <white>
// <yellow>
// <b> - bold
// <d> - dim
// </r> - reset
// <r> - reset
pub fn prettyFmt(comptime fmt: string, comptime is_enabled: bool) string {
comptime var new_fmt: [fmt.len * 4]u8 = undefined;
comptime var new_fmt_i: usize = 0;
const ED = comptime "\x1b[";
@setEvalBranchQuota(9999);
comptime var i: usize = 0;
comptime while (i < fmt.len) {
const c = fmt[i];
switch (c) {
'\\' => {
i += 1;
if (fmt.len < i) {
switch (fmt[i]) {
'<', '>' => {
i += 1;
},
else => {
new_fmt[new_fmt_i] = '\\';
new_fmt_i += 1;
new_fmt[new_fmt_i] = fmt[i];
new_fmt_i += 1;
},
}
}
},
'>' => {
i += 1;
},
'{' => {
while (fmt.len > i and fmt[i] != '}') {
new_fmt[new_fmt_i] = fmt[i];
new_fmt_i += 1;
i += 1;
}
},
'<' => {
i += 1;
var is_reset = fmt[i] == '/';
if (is_reset) i += 1;
var start: usize = i;
while (i < fmt.len and fmt[i] != '>') {
i += 1;
}
const color_name = fmt[start..i];
const color_str = color_picker: {
if (std.mem.eql(u8, color_name, "black")) {
break :color_picker ED ++ "30m";
} else if (std.mem.eql(u8, color_name, "blue")) {
break :color_picker ED ++ "34m";
} else if (std.mem.eql(u8, color_name, "b")) {
break :color_picker ED ++ "1m";
} else if (std.mem.eql(u8, color_name, "d")) {
break :color_picker ED ++ "2m";
} else if (std.mem.eql(u8, color_name, "cyan")) {
break :color_picker ED ++ "36m";
} else if (std.mem.eql(u8, color_name, "green")) {
break :color_picker ED ++ "32m";
} else if (std.mem.eql(u8, color_name, "magenta")) {
break :color_picker ED ++ "35m";
} else if (std.mem.eql(u8, color_name, "red")) {
break :color_picker ED ++ "31m";
} else if (std.mem.eql(u8, color_name, "white")) {
break :color_picker ED ++ "37m";
} else if (std.mem.eql(u8, color_name, "yellow")) {
break :color_picker ED ++ "33m";
} else if (std.mem.eql(u8, color_name, "r")) {
is_reset = true;
break :color_picker "";
} else {
@compileError("Invalid color name passed: " ++ color_name);
}
};
var orig = new_fmt_i;
if (is_enabled) {
if (!is_reset) {
orig = new_fmt_i;
new_fmt_i += color_str.len;
std.mem.copy(u8, new_fmt[orig..new_fmt_i], color_str);
}
if (is_reset) {
const reset_sequence = "\x1b[0m";
orig = new_fmt_i;
new_fmt_i += reset_sequence.len;
std.mem.copy(u8, new_fmt[orig..new_fmt_i], reset_sequence);
}
}
},
else => {
new_fmt[new_fmt_i] = fmt[i];
new_fmt_i += 1;
i += 1;
},
}
};
return comptime new_fmt[0..new_fmt_i];
}
No worries if the answer to this is "no" or "not in this form"