You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.8 KiB
117 lines
2.8 KiB
#include <fmt/core.h>
|
|
#include <string_view>
|
|
#include <charconv>
|
|
#include "dbc.hpp"
|
|
#include <SFML/Graphics.hpp>
|
|
#include "ansi_parser.hpp"
|
|
|
|
using namespace fmt;
|
|
|
|
%%{
|
|
machine foo;
|
|
alphtype int;
|
|
|
|
action tstart {
|
|
start = fpc;
|
|
}
|
|
|
|
action number {
|
|
value = 0;
|
|
size_t len = fpc - start;
|
|
dbc::check(start[0] != '-', "negative numbers not supported");
|
|
|
|
switch(len) {
|
|
case 10: value += (start[len-10] - '0') * 1000000000;
|
|
case 9: value += (start[len- 9] - '0') * 100000000;
|
|
case 8: value += (start[len- 8] - '0') * 10000000;
|
|
case 7: value += (start[len- 7] - '0') * 1000000;
|
|
case 6: value += (start[len- 6] - '0') * 100000;
|
|
case 5: value += (start[len- 5] - '0') * 10000;
|
|
case 4: value += (start[len- 4] - '0') * 1000;
|
|
case 3: value += (start[len- 3] - '0') * 100;
|
|
case 2: value += (start[len- 2] - '0') * 10;
|
|
case 1: value += (start[len- 1] - '0');
|
|
break;
|
|
default:
|
|
dbc::sentinel("can't process > 10 digits");
|
|
}
|
|
}
|
|
|
|
action color24b { }
|
|
action is_fg {
|
|
target = color;
|
|
}
|
|
action is_bg {
|
|
target = bgcolor;
|
|
}
|
|
|
|
action out {
|
|
write(bgcolor, color, fc);
|
|
}
|
|
|
|
action reset_fg { color = $default_fg; }
|
|
action reset_bg { bgcolor = $default_bg; }
|
|
|
|
action red { target.r = value; }
|
|
action blue { target.g = value; }
|
|
action green { target.b = value; }
|
|
action start { value = 0; }
|
|
action end { }
|
|
|
|
ESC = 0x1B;
|
|
start = ESC "[";
|
|
fg = "38;" %is_fg;
|
|
bg = "48;" %is_bg;
|
|
reset = ("39" %reset_fg | "49" %reset_bg);
|
|
num = digit+ >tstart %number;
|
|
color256 = "5;";
|
|
color24b = "2;";
|
|
|
|
ansi = (
|
|
start %start
|
|
(
|
|
reset |
|
|
(fg|bg) color24b num %red ";" num %blue ";" num %green %color24b
|
|
) "m" %end
|
|
);
|
|
|
|
other = (any+ @out -- ESC)*;
|
|
|
|
main := (other :> ansi)**;
|
|
}%%
|
|
|
|
%% write data;
|
|
|
|
#include <ftxui/screen/terminal.hpp>
|
|
|
|
ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) :
|
|
$default_fg(default_fg),
|
|
$default_bg(default_bg)
|
|
{
|
|
// the parser only handles full color so force it
|
|
if(ftxui::Terminal::ColorSupport() != ftxui::Terminal::Color::TrueColor) {
|
|
ftxui::Terminal::SetColorSupport(ftxui::Terminal::Color::TrueColor);
|
|
}
|
|
}
|
|
|
|
bool ANSIParser::parse(const std::string &screen, WriteCB write) {
|
|
std::wstring screen_utf8 = $converter.from_bytes(screen);
|
|
return parse(screen_utf8, write);
|
|
}
|
|
|
|
bool ANSIParser::parse(std::wstring_view codes, WriteCB write) {
|
|
const wchar_t *start = NULL;
|
|
int cs = 0;
|
|
unsigned int value = 0;
|
|
const wchar_t *p = codes.data();
|
|
const wchar_t *pe = p + codes.size();
|
|
const wchar_t *eof = pe;
|
|
sf::Color bgcolor($default_bg);
|
|
sf::Color color($default_fg);
|
|
sf::Color &target = color;
|
|
|
|
%% write init;
|
|
%% write exec;
|
|
|
|
return p - pe == 0;
|
|
}
|
|
|