Add support for 24-bit color escape sequences, simplify print_rich
BBCode parsing.
This commit is contained in:
parent
92e51fca72
commit
0d7027ea4c
2 changed files with 167 additions and 70 deletions
|
@ -93,80 +93,178 @@ void __print_line_rich(const String &p_string) {
|
|||
// Convert a subset of BBCode tags to ANSI escape codes for correct display in the terminal.
|
||||
// Support of those ANSI escape codes varies across terminal emulators,
|
||||
// especially for italic and strikethrough.
|
||||
String p_string_ansi = p_string;
|
||||
|
||||
p_string_ansi = p_string_ansi.replace("[b]", "\u001b[1m");
|
||||
p_string_ansi = p_string_ansi.replace("[/b]", "\u001b[22m");
|
||||
p_string_ansi = p_string_ansi.replace("[i]", "\u001b[3m");
|
||||
p_string_ansi = p_string_ansi.replace("[/i]", "\u001b[23m");
|
||||
p_string_ansi = p_string_ansi.replace("[u]", "\u001b[4m");
|
||||
p_string_ansi = p_string_ansi.replace("[/u]", "\u001b[24m");
|
||||
p_string_ansi = p_string_ansi.replace("[s]", "\u001b[9m");
|
||||
p_string_ansi = p_string_ansi.replace("[/s]", "\u001b[29m");
|
||||
String output;
|
||||
int pos = 0;
|
||||
while (pos <= p_string.length()) {
|
||||
int brk_pos = p_string.find_char('[', pos);
|
||||
|
||||
p_string_ansi = p_string_ansi.replace("[indent]", " ");
|
||||
p_string_ansi = p_string_ansi.replace("[/indent]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[code]", "\u001b[2m");
|
||||
p_string_ansi = p_string_ansi.replace("[/code]", "\u001b[22m");
|
||||
p_string_ansi = p_string_ansi.replace("[url]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[/url]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[center]", "\n\t\t\t");
|
||||
p_string_ansi = p_string_ansi.replace("[/center]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[right]", "\n\t\t\t\t\t\t");
|
||||
p_string_ansi = p_string_ansi.replace("[/right]", "");
|
||||
if (brk_pos < 0) {
|
||||
brk_pos = p_string.length();
|
||||
}
|
||||
|
||||
if (p_string_ansi.contains("[color")) {
|
||||
p_string_ansi = p_string_ansi.replace("[color=black]", "\u001b[30m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=red]", "\u001b[91m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=green]", "\u001b[92m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=lime]", "\u001b[92m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=yellow]", "\u001b[93m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=blue]", "\u001b[94m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=magenta]", "\u001b[95m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=pink]", "\u001b[38;5;218m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=purple]", "\u001b[38;5;98m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=cyan]", "\u001b[96m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=white]", "\u001b[97m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=orange]", "\u001b[38;5;208m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=gray]", "\u001b[90m");
|
||||
p_string_ansi = p_string_ansi.replace("[/color]", "\u001b[39m");
|
||||
}
|
||||
if (p_string_ansi.contains("[bgcolor")) {
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=black]", "\u001b[40m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=red]", "\u001b[101m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=green]", "\u001b[102m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=lime]", "\u001b[102m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=yellow]", "\u001b[103m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=blue]", "\u001b[104m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=magenta]", "\u001b[105m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=pink]", "\u001b[48;5;218m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=purple]", "\u001b[48;5;98m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=cyan]", "\u001b[106m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=white]", "\u001b[107m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=orange]", "\u001b[48;5;208m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=gray]", "\u001b[100m");
|
||||
p_string_ansi = p_string_ansi.replace("[/bgcolor]", "\u001b[49m");
|
||||
}
|
||||
if (p_string_ansi.contains("[fgcolor")) {
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=black]", "\u001b[30;40m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=red]", "\u001b[91;101m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=green]", "\u001b[92;102m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=lime]", "\u001b[92;102m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=yellow]", "\u001b[93;103m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=blue]", "\u001b[94;104m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=magenta]", "\u001b[95;105m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=pink]", "\u001b[38;5;218;48;5;218m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=purple]", "\u001b[38;5;98;48;5;98m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=cyan]", "\u001b[96;106m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=white]", "\u001b[97;107m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=orange]", "\u001b[38;5;208;48;5;208m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=gray]", "\u001b[90;100m");
|
||||
p_string_ansi = p_string_ansi.replace("[/fgcolor]", "\u001b[39;49m");
|
||||
String txt = brk_pos > pos ? p_string.substr(pos, brk_pos - pos) : "";
|
||||
if (brk_pos == p_string.length()) {
|
||||
output += txt;
|
||||
break;
|
||||
}
|
||||
|
||||
int brk_end = p_string.find_char(']', brk_pos + 1);
|
||||
|
||||
if (brk_end == -1) {
|
||||
txt += p_string.substr(brk_pos, p_string.length() - brk_pos);
|
||||
output += txt;
|
||||
break;
|
||||
}
|
||||
pos = brk_end + 1;
|
||||
output += txt;
|
||||
|
||||
String tag = p_string.substr(brk_pos + 1, brk_end - brk_pos - 1);
|
||||
if (tag == "b") {
|
||||
output += "\u001b[1m";
|
||||
} else if (tag == "/b") {
|
||||
output += "\u001b[22m";
|
||||
} else if (tag == "i") {
|
||||
output += "\u001b[3m";
|
||||
} else if (tag == "/i") {
|
||||
output += "\u001b[23m";
|
||||
} else if (tag == "u") {
|
||||
output += "\u001b[4m";
|
||||
} else if (tag == "/u") {
|
||||
output += "\u001b[24m";
|
||||
} else if (tag == "s") {
|
||||
output += "\u001b[9m";
|
||||
} else if (tag == "/s") {
|
||||
output += "\u001b[29m";
|
||||
} else if (tag == "indent") {
|
||||
output += " ";
|
||||
} else if (tag == "/indent") {
|
||||
output += "";
|
||||
} else if (tag == "code") {
|
||||
output += "\u001b[2m";
|
||||
} else if (tag == "/code") {
|
||||
output += "\u001b[22m";
|
||||
} else if (tag == "url") {
|
||||
output += "";
|
||||
} else if (tag == "/url") {
|
||||
output += "";
|
||||
} else if (tag == "center") {
|
||||
output += "\n\t\t\t";
|
||||
} else if (tag == "center") {
|
||||
output += "";
|
||||
} else if (tag == "right") {
|
||||
output += "\n\t\t\t\t\t\t";
|
||||
} else if (tag == "/right") {
|
||||
output += "";
|
||||
} else if (tag.begins_with("color=")) {
|
||||
String color_name = tag.trim_prefix("color=");
|
||||
if (color_name == "black") {
|
||||
output += "\u001b[30m";
|
||||
} else if (color_name == "red") {
|
||||
output += "\u001b[91m";
|
||||
} else if (color_name == "green") {
|
||||
output += "\u001b[92m";
|
||||
} else if (color_name == "lime") {
|
||||
output += "\u001b[92m";
|
||||
} else if (color_name == "yellow") {
|
||||
output += "\u001b[93m";
|
||||
} else if (color_name == "blue") {
|
||||
output += "\u001b[94m";
|
||||
} else if (color_name == "magenta") {
|
||||
output += "\u001b[95m";
|
||||
} else if (color_name == "pink") {
|
||||
output += "\u001b[38;5;218m";
|
||||
} else if (color_name == "purple") {
|
||||
output += "\u001b[38;5;98m";
|
||||
} else if (color_name == "cyan") {
|
||||
output += "\u001b[96m";
|
||||
} else if (color_name == "white") {
|
||||
output += "\u001b[97m";
|
||||
} else if (color_name == "orange") {
|
||||
output += "\u001b[38;5;208m";
|
||||
} else if (color_name == "gray") {
|
||||
output += "\u001b[90m";
|
||||
} else {
|
||||
Color c = Color::from_string(color_name, Color());
|
||||
output += vformat("\u001b[38;2;%d;%d;%dm", c.r * 255, c.g * 255, c.b * 255);
|
||||
}
|
||||
} else if (tag == "/color") {
|
||||
output += "\u001b[39m";
|
||||
} else if (tag.begins_with("bgcolor=")) {
|
||||
String color_name = tag.trim_prefix("bgcolor=");
|
||||
if (color_name == "black") {
|
||||
output += "\u001b[40m";
|
||||
} else if (color_name == "red") {
|
||||
output += "\u001b[101m";
|
||||
} else if (color_name == "green") {
|
||||
output += "\u001b[102m";
|
||||
} else if (color_name == "lime") {
|
||||
output += "\u001b[102m";
|
||||
} else if (color_name == "yellow") {
|
||||
output += "\u001b[103m";
|
||||
} else if (color_name == "blue") {
|
||||
output += "\u001b[104m";
|
||||
} else if (color_name == "magenta") {
|
||||
output += "\u001b[105m";
|
||||
} else if (color_name == "pink") {
|
||||
output += "\u001b[48;5;218m";
|
||||
} else if (color_name == "purple") {
|
||||
output += "\u001b[48;5;98m";
|
||||
} else if (color_name == "cyan") {
|
||||
output += "\u001b[106m";
|
||||
} else if (color_name == "white") {
|
||||
output += "\u001b[107m";
|
||||
} else if (color_name == "orange") {
|
||||
output += "\u001b[48;5;208m";
|
||||
} else if (color_name == "gray") {
|
||||
output += "\u001b[100m";
|
||||
} else {
|
||||
Color c = Color::from_string(color_name, Color());
|
||||
output += vformat("\u001b[48;2;%d;%d;%dm", c.r * 255, c.g * 255, c.b * 255);
|
||||
}
|
||||
} else if (tag == "/bgcolor") {
|
||||
output += "\u001b[49m";
|
||||
} else if (tag.begins_with("fgcolor=")) {
|
||||
String color_name = tag.trim_prefix("fgcolor=");
|
||||
if (color_name == "black") {
|
||||
output += "\u001b[30;40m";
|
||||
} else if (color_name == "red") {
|
||||
output += "\u001b[91;101m";
|
||||
} else if (color_name == "green") {
|
||||
output += "\u001b[92;102m";
|
||||
} else if (color_name == "lime") {
|
||||
output += "\u001b[92;102m";
|
||||
} else if (color_name == "yellow") {
|
||||
output += "\u001b[93;103m";
|
||||
} else if (color_name == "blue") {
|
||||
output += "\u001b[94;104m";
|
||||
} else if (color_name == "magenta") {
|
||||
output += "\u001b[95;105m";
|
||||
} else if (color_name == "pink") {
|
||||
output += "\u001b[38;5;218;48;5;218m";
|
||||
} else if (color_name == "purple") {
|
||||
output += "\u001b[38;5;98;48;5;98m";
|
||||
} else if (color_name == "cyan") {
|
||||
output += "\u001b[96;106m";
|
||||
} else if (color_name == "white") {
|
||||
output += "\u001b[97;107m";
|
||||
} else if (color_name == "orange") {
|
||||
output += "\u001b[38;5;208;48;5;208m";
|
||||
} else if (color_name == "gray") {
|
||||
output += "\u001b[90;100m";
|
||||
} else {
|
||||
Color c = Color::from_string(color_name, Color());
|
||||
output += vformat("\u001b[38;2;%d;%d;%d;48;2;%d;%d;%dm", c.r * 255, c.g * 255, c.b * 255, c.r * 255, c.g * 255, c.b * 255);
|
||||
}
|
||||
} else if (tag == "/fgcolor") {
|
||||
output += "\u001b[39;49m";
|
||||
} else {
|
||||
output += vformat("[%s]", tag);
|
||||
}
|
||||
}
|
||||
output += "\u001b[0m"; // Reset.
|
||||
|
||||
p_string_ansi += "\u001b[0m"; // Reset.
|
||||
|
||||
OS::get_singleton()->print_rich("%s\n", p_string_ansi.utf8().get_data());
|
||||
OS::get_singleton()->print_rich("%s\n", output.utf8().get_data());
|
||||
|
||||
_global_lock();
|
||||
PrintHandlerList *l = print_handler_list;
|
||||
|
|
|
@ -863,7 +863,6 @@
|
|||
<description>
|
||||
Converts one or more arguments of any type to string in the best way possible and prints them to the console.
|
||||
The following BBCode tags are supported: [code]b[/code], [code]i[/code], [code]u[/code], [code]s[/code], [code]indent[/code], [code]code[/code], [code]url[/code], [code]center[/code], [code]right[/code], [code]color[/code], [code]bgcolor[/code], [code]fgcolor[/code].
|
||||
Color tags only support the following named colors: [code]black[/code], [code]red[/code], [code]green[/code], [code]yellow[/code], [code]blue[/code], [code]magenta[/code], [code]pink[/code], [code]purple[/code], [code]cyan[/code], [code]white[/code], [code]orange[/code], [code]gray[/code]. Hexadecimal color codes are not supported.
|
||||
URL tags only support URLs wrapped by a URL tag, not URLs with a different title.
|
||||
When printing to standard output, the supported subset of BBCode is converted to ANSI escape codes for the terminal emulator to display. Support for ANSI escape codes varies across terminal emulators, especially for italic and strikethrough. In standard output, [code]code[/code] is represented with faint text but without any font change. Unsupported tags are left as-is in standard output.
|
||||
[codeblocks]
|
||||
|
|
Loading…
Reference in a new issue