From 62f7af1443ad7aaf8b9c6e82c9355eeee406bbb8 Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Tue, 10 Aug 2021 16:44:53 +0200 Subject: [PATCH] [plain] document.plain.fixup_tables Option to draw nice-looking tables. Examples: mysql --pager=elinks lxc ls | elinks --- src/config/options.inc | 4 ++ src/document/options.c | 1 + src/document/options.h | 1 + src/document/plain/renderer.c | 99 +++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) diff --git a/src/config/options.inc b/src/config/options.inc index ff370423e..8a27069d0 100644 --- a/src/config/options.inc +++ b/src/config/options.inc @@ -846,6 +846,10 @@ static union option_info config_options_info[] = { N_("Compress successive empty lines to only one in displayed " "text.")), + INIT_OPT_BOOL("document.plain", N_("Fixup frame borders of tables"), + "fixup_tables", 0, 0, + N_("Change ascii border characters to frame borders. Usage example: " + "mysql --pager=elinks")), INIT_OPT_TREE("document", N_("URI passing"), "uri_passing", OPT_SORT | OPT_AUTOCREATE, diff --git a/src/document/options.c b/src/document/options.c index c0ab5e543..6c6dd6323 100644 --- a/src/document/options.c +++ b/src/document/options.c @@ -82,6 +82,7 @@ init_document_options(struct session *ses, struct document_options *doo) doo->plain_display_links = get_opt_bool("document.plain.display_links", ses); doo->plain_compress_empty_lines = get_opt_bool("document.plain.compress_empty_lines", ses); + doo->plain_fixup_tables = get_opt_bool("document.plain.fixup_tables", ses); doo->underline_links = get_opt_bool("document.html.underline_links", ses); doo->wrap_nbsp = get_opt_bool("document.html.wrap_nbsp", ses); doo->use_tabindex = get_opt_bool("document.browse.links.use_tabindex", ses); diff --git a/src/document/options.h b/src/document/options.h index 4f63914bc..78f5f4b04 100644 --- a/src/document/options.h +++ b/src/document/options.h @@ -103,6 +103,7 @@ struct document_options { * @{ */ unsigned int plain_display_links:1; unsigned int plain_compress_empty_lines:1; + unsigned int plain_fixup_tables:1; /** @} */ /** @name Link navigation diff --git a/src/document/plain/renderer.c b/src/document/plain/renderer.c index cc20ca3d8..5819878e4 100644 --- a/src/document/plain/renderer.c +++ b/src/document/plain/renderer.c @@ -845,6 +845,101 @@ add_document_lines(struct plain_renderer *renderer) assert(!length); } +static void +fixup_tables(struct plain_renderer *renderer) +{ + int y; + + for (y = 0; y < renderer->lineno; y++) { + int x; + struct line *prev_line = y > 0 ? &renderer->document->data[y - 1] : NULL; + struct line *line = &renderer->document->data[y]; + struct line *next_line = y < renderer->lineno - 1 ? &renderer->document->data[y + 1] : NULL; + int dir; + + for (x = 0; x < line->length; x++) { +#ifdef CONFIG_UTF8 + unicode_val_T ch = line->chars[x].data; + unicode_val_T prev_char = x > 0 ? line->chars[x - 1].data : ' '; + unicode_val_T next_char = x < line->length - 1 ? line->chars[x + 1].data : ' '; + unicode_val_T up_char = (prev_line && x < prev_line->length) ? prev_line->chars[x].data : ' '; + unicode_val_T down_char = (next_line && x < next_line->length) ? next_line->chars[x].data : ' '; +#else + unsigned char ch = line->chars[x].data; + unsigned char prev_char = x > 0 ? line->chars[x - 1].data : ' '; + unsigned char next_char = x < line->length - 1 ? line->chars[x + 1].data : ' '; + unsigned char up_char = (prev_line && x < prev_line->length) ? prev_line->chars[x].data : ' '; + unsigned char down_char = (next_line && x < next_line->length) ? next_line->chars[x].data : ' '; +#endif + + switch (ch) { + case '+': + dir = 0; + if (up_char == '|' || up_char == BORDER_SVLINE) dir |= 1; + if (next_char == '-' || next_char == BORDER_SHLINE) dir |= 2; + if (down_char == '|' || down_char == BORDER_SVLINE) dir |= 4; + if (prev_char == '-' || prev_char == BORDER_SHLINE) dir |= 8; + + switch (dir) { + case 15: + line->chars[x].data = BORDER_SCROSS; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + case 13: + line->chars[x].data = BORDER_SLTEE; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + case 7: + line->chars[x].data = BORDER_SRTEE; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + case 6: + line->chars[x].data = BORDER_SULCORNER; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + case 12: + line->chars[x].data = BORDER_SURCORNER; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + case 3: + line->chars[x].data = BORDER_SDLCORNER; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + case 9: + line->chars[x].data = BORDER_SDRCORNER; + line->chars[x].attr = SCREEN_ATTR_FRAME; + break; + default: + break; + } + break; + case '-': + if (prev_char == BORDER_SHLINE || prev_char == BORDER_SCROSS || prev_char == '+' || prev_char == '|' + || prev_char == BORDER_SULCORNER || prev_char == BORDER_SDLCORNER || prev_char == BORDER_SRTEE) { + line->chars[x].data = BORDER_SHLINE; + line->chars[x].attr = SCREEN_ATTR_FRAME; + } + break; + case '|': + if (up_char == BORDER_SVLINE || up_char == '+' || up_char == '|' || up_char == BORDER_SULCORNER + || up_char == BORDER_SURCORNER || up_char == BORDER_SCROSS || up_char == BORDER_SRTEE || up_char == BORDER_SLTEE) { + if (next_char == '-') { + line->chars[x].data = BORDER_SRTEE; + } else if (prev_char == BORDER_SHLINE || prev_char == '-') { + line->chars[x].data = BORDER_SLTEE; + } else { + line->chars[x].data = BORDER_SVLINE; + } + line->chars[x].attr = SCREEN_ATTR_FRAME; + } + break; + default: + continue; + } + } + } +} + void render_plain_document(struct cache_entry *cached, struct document *document, struct string *buffer) @@ -879,4 +974,8 @@ render_plain_document(struct cache_entry *cached, struct document *document, init_template(&renderer.template_, &document->options); add_document_lines(&renderer); + + if (document->options.plain_fixup_tables) { + fixup_tables(&renderer); + } }