[textview] cleanup the ansi scrubber

This commit is contained in:
Timothy Stack 2013-06-08 07:57:40 -07:00
parent 5d478fc17a
commit 8754b45699
7 changed files with 144 additions and 107 deletions

View File

@ -191,6 +191,22 @@ public:
iter->length());
};
void reset(const char *str, size_t off = 0, size_t len = -1) {
this->pi_string = str;
this->pi_offset = off;
this->pi_next_offset = off;
if (this->pi_length == (size_t)-1) {
this->pi_length = strlen(str);
}
else {
this->pi_length = len;
}
}
void reset(const std::string &str, size_t off = 0) {
this->reset(str.c_str(), off, str.length());
}
size_t pi_offset;
size_t pi_next_offset;
size_t pi_length;

View File

@ -32,6 +32,7 @@
#include <vector>
#include <algorithm>
#include "pcrepp.hh"
#include "lnav_util.hh"
#include "data_parser.hh"
#include "textview_curses.hh"
@ -55,111 +56,92 @@ public:
void scrub_value(string &str, string_attrs_t &sa)
{
vector<line_range> range_queue;
view_colors &vc = view_colors::singleton();
vector<pair<string, string_attr_t> > attr_queue;
int rc, matches[60];
pcre_context_static<60> context;
vector<line_range> range_queue;
pcre_input pi(str);
do {
rc = pcre_exec(this->as_pcre,
NULL,
str.c_str(),
str.size(),
0,
0,
matches,
60);
if (rc > 0) {
int c_start = matches[0];
int c_end = matches[1];
struct line_range lr;
bool has_attrs = false;
int attrs = 0;
int lpc;
while (this->as_regex.match(context, pi)) {
pcre_context::capture_t *caps = context.all();
struct line_range lr;
bool has_attrs = false;
int attrs = 0;
int bg = 0;
int fg = 0;
int lpc;
switch (str[matches[4]]) {
case 'm':
for (lpc = matches[2];
lpc != (int)string::npos && lpc < matches[3]; ) {
int ansi_code = 0;
switch (pi.get_substr_start(&caps[2])[0]) {
case 'm':
for (lpc = caps[1].c_begin;
lpc != (int)string::npos && lpc < caps[1].c_end; ) {
int ansi_code = 0;
if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) {
switch (ansi_code) {
case 1:
attrs |= A_BOLD;
break;
case 2:
attrs |= A_DIM;
break;
case 4:
attrs |= A_UNDERLINE;
break;
case 7:
attrs |= A_REVERSE;
break;
case 31:
attrs |= COLOR_PAIR(view_colors::VC_RED);
break;
case 32:
attrs |= COLOR_PAIR(view_colors::VC_GREEN);
break;
case 33:
attrs |= COLOR_PAIR(view_colors::VC_YELLOW);
break;
case 34:
attrs |= COLOR_PAIR(view_colors::VC_BLUE);
break;
case 35:
attrs |= COLOR_PAIR(view_colors::VC_MAGENTA);
break;
case 36:
attrs |= COLOR_PAIR(view_colors::VC_CYAN);
break;
case 37:
attrs |= COLOR_PAIR(view_colors::VC_WHITE);
break;
}
if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) {
if (90 <= ansi_code && ansi_code <= 97) {
ansi_code -= 60;
attrs |= A_STANDOUT;
}
lpc = str.find(";", lpc);
if (lpc != (int)string::npos) {
lpc += 1;
if (30 <= ansi_code && ansi_code <= 37) {
fg = ansi_code - 30;
}
if (40 <= ansi_code && ansi_code <= 47) {
bg = ansi_code - 40;
}
switch (ansi_code) {
case 1:
attrs |= A_BOLD;
break;
case 2:
attrs |= A_DIM;
break;
case 4:
attrs |= A_UNDERLINE;
break;
case 7:
attrs |= A_REVERSE;
break;
}
}
has_attrs = true;
break;
lpc = str.find(";", lpc);
if (lpc != (int)string::npos) {
lpc += 1;
}
}
if (fg != 0 || bg != 0) {
attrs |= vc.ansi_color_pair(fg, bg);
}
has_attrs = true;
break;
case 'C':
case 'C':
{
int spaces = 0;
if (sscanf(&(str[matches[2]]), "%d", &spaces) == 1) {
str.insert(c_end, spaces, ' ');
if (sscanf(&(str[caps[1].c_begin]), "%d", &spaces) == 1) {
str.insert(caps[0].c_end, spaces, ' ');
}
}
break;
}
str.erase(str.begin() + c_start, str.begin() + c_end);
if (has_attrs) {
if (!range_queue.empty()) {
range_queue.back().lr_end = c_start;
}
lr.lr_start = c_start;
lr.lr_end = -1;
range_queue.push_back(lr);
attr_queue.push_back(make_string_attr("style", attrs));
}
}
} while (rc > 0);
str.erase(str.begin() + caps[0].c_begin,
str.begin() + caps[0].c_end);
if (has_attrs) {
if (!range_queue.empty()) {
range_queue.back().lr_end = caps[0].c_begin;
}
lr.lr_start = caps[0].c_begin;
lr.lr_end = -1;
range_queue.push_back(lr);
attr_queue.push_back(make_string_attr("style", attrs));
}
pi.reset(str);
}
for (size_t lpc = 0; lpc < range_queue.size(); lpc++) {
sa[range_queue[lpc]].insert(attr_queue[lpc]);
@ -167,26 +149,11 @@ public:
};
private:
pcre *build_pcre(const char *pattern) /* XXX refactor me */
{
const char *errptr;
pcre * retval;
int eoff;
retval = pcre_compile(pattern, 0, &errptr, &eoff, NULL);
if (retval == NULL) {
throw errptr;
}
return retval;
};
ansi_scrubber()
{
this->as_pcre = this->build_pcre("\x1b\\[([\\d=;]*)([a-zA-Z])");
: as_regex("\x1b\\[([\\d=;]*)([a-zA-Z])") {
};
pcre *as_pcre;
pcrepp as_regex;
};
textview_curses::textview_curses()

View File

@ -237,6 +237,17 @@ view_colors::view_colors()
void view_colors::init(void)
{
if (has_colors()) {
static int ansi_colors_to_curses[] = {
COLOR_BLACK,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW,
COLOR_BLUE,
COLOR_MAGENTA,
COLOR_CYAN,
COLOR_WHITE,
};
start_color();
/* use_default_colors(); */
@ -262,6 +273,14 @@ void view_colors::init(void)
init_pair(VC_GRAY, COLOR_BLACK, COLOR_BLACK);
for (int fg = 0; fg < 8; fg++) {
for (int bg = 0; bg < 8; bg++) {
init_pair(ansi_color_pair_index(fg, bg),
ansi_colors_to_curses[fg],
ansi_colors_to_curses[bg]);
}
}
for (int lpc = 0; lpc < 8; lpc++) {
short gradient_value = (1000 / 8) * lpc;

View File

@ -414,9 +414,20 @@ public:
VC_GRAY,
VC_ANSI_START,
VC_ANSI_END = VC_ANSI_START + (8 * 8),
VC_GRADIENT_START,
};
static inline int ansi_color_pair_index(int fg, int bg) {
return VC_ANSI_START + ((fg * 8) + bg);
};
int ansi_color_pair(int fg, int bg) {
return COLOR_PAIR(ansi_color_pair_index(fg, bg));
};
private:
/** The number of colors used for highlighting. */

View File

@ -156,6 +156,7 @@ dist_noinst_SCRIPTS = \
test_vt52_curses.sh
dist_noinst_DATA = \
ansi-colors.0.in \
datafile_simple.0 \
datafile_simple.1 \
datafile_simple.2 \

View File

@ -721,6 +721,7 @@ dist_noinst_SCRIPTS = \
test_vt52_curses.sh
dist_noinst_DATA = \
ansi-colors.0.in \
datafile_simple.0 \
datafile_simple.1 \
datafile_simple.2 \

22
test/ansi-colors.0.in Normal file
View File

@ -0,0 +1,22 @@
Basic ANSI colors (eight-color, or dim)
black  black  red  green  yellow  blue  magenta cyan  white 
bold black  black  red  green  yellow  blue  magenta cyan  white 
red  black  red  green  yellow  blue  magenta cyan  white 
bold red  black  red  green  yellow  blue  magenta cyan  white 
green  black  red  green  yellow  blue  magenta cyan  white 
bold green  black  red  green  yellow  blue  magenta cyan  white 
yellow  black  red  green  yellow  blue  magenta cyan  white 
bold yellow  black  red  green  yellow  blue  magenta cyan  white 
blue  black  red  green  yellow  blue  magenta cyan  white 
bold blue  black  red  green  yellow  blue  magenta cyan  white 
magenta  black  red  green  yellow  blue  magenta cyan  white 
bold magenta  black  red  green  yellow  blue  magenta cyan  white 
cyan  black  red  green  yellow  blue  magenta cyan  white 
bold cyan  black  red  green  yellow  blue  magenta cyan  white 
white  black  red  green  yellow  blue  magenta cyan  white 
bold white  black  red  green  yellow  blue  magenta cyan  white 
Attributes: bold dark italic underline blink concealed
 testing  testing  testing  testing  testing  testing