diff --git a/src/config/options.c b/src/config/options.c index 311d83666..0f25cb96d 100644 --- a/src/config/options.c +++ b/src/config/options.c @@ -785,13 +785,16 @@ register_autocreated_options(void) get_opt_int("terminal.vt110.type", NULL) = TERM_VT100; get_opt_int("terminal.xterm.type", NULL) = TERM_VT100; get_opt_bool("terminal.xterm.underline", NULL) = 1; + get_opt_bool("terminal.xterm.strike", NULL) = 1; get_opt_int("terminal.xterm-color.type", NULL) = TERM_VT100; get_opt_int("terminal.xterm-color.colors", NULL) = COLOR_MODE_16; get_opt_bool("terminal.xterm-color.underline", NULL) = 1; + get_opt_bool("terminal.xterm-color.strike", NULL) = 1; #ifdef CONFIG_88_COLORS get_opt_int("terminal.xterm-88color.type", NULL) = TERM_VT100; get_opt_int("terminal.xterm-88color.colors", NULL) = COLOR_MODE_88; get_opt_bool("terminal.xterm-88color.underline", NULL) = 1; + get_opt_bool("terminal.xterm-88color.strike", NULL) = 1; #endif get_opt_int("terminal.rxvt-unicode.type", NULL) = 1; #ifdef CONFIG_88_COLORS @@ -801,6 +804,7 @@ register_autocreated_options(void) #endif get_opt_bool("terminal.rxvt-unicode.italic", NULL) = 1; get_opt_bool("terminal.rxvt-unicode.underline", NULL) = 1; + get_opt_bool("terminal.rxvt-unicode.strike", NULL) = 0; #ifdef CONFIG_256_COLORS get_opt_int("terminal.xterm-256color.type", NULL) = TERM_VT100; get_opt_int("terminal.xterm-256color.colors", NULL) = COLOR_MODE_256; @@ -808,6 +812,7 @@ register_autocreated_options(void) get_opt_int("terminal.fbterm.type", NULL) = TERM_FBTERM; get_opt_int("terminal.fbterm.colors", NULL) = COLOR_MODE_256; get_opt_bool("terminal.fbterm.underline", NULL) = 0; + get_opt_bool("terminal.fbterm.strike", NULL) = 0; #endif get_opt_int("terminal.st-256color.type", NULL) = TERM_VT100; get_opt_bool("terminal.st-256color.latin1_title", NULL) = 0; @@ -822,6 +827,7 @@ register_autocreated_options(void) #endif get_opt_bool("terminal.st-256color.italic", NULL) = 1; get_opt_bool("terminal.st-256color.underline", NULL) = 1; + get_opt_bool("terminal.st-256color.strike", NULL) = 1; } extern union option_info cmdline_options_info[]; diff --git a/src/config/options.inc b/src/config/options.inc index 8b4487024..46819a7ac 100644 --- a/src/config/options.inc +++ b/src/config/options.inc @@ -1130,15 +1130,19 @@ static union option_info config_options_info[] = { "italic", OPT_ZERO, 0, N_("If we should use italics.")), - INIT_OPT_BOOL("terminal._template_", N_("Underline"), - "underline", OPT_ZERO, 0, - N_("If we should use underline or enhance the color " - "instead.")), #ifdef CONFIG_LIBSIXEL INIT_OPT_BOOL("terminal._template_", N_("Sixel"), "sixel", OPT_ZERO, 0, N_("Whether terminal supports sixel graphics.")), #endif + INIT_OPT_BOOL("terminal._template_", N_("Strikethrough"), + "strike", OPT_ZERO, 0, + N_("If we should use strikethrough.")), + + INIT_OPT_BOOL("terminal._template_", N_("Underline"), + "underline", OPT_ZERO, 0, + N_("If we should use underline or enhance the color " + "instead.")), INIT_OPT_CODEPAGE("terminal._template_", N_("Codepage"), "charset", OPT_ZERO, "System", N_("Codepage of charset used for displaying content on " diff --git a/src/dialogs/options.c b/src/dialogs/options.c index b1f138bbf..5ee04b5f4 100644 --- a/src/dialogs/options.c +++ b/src/dialogs/options.c @@ -96,6 +96,7 @@ enum termopt { TERM_OPT_TRANSPARENCY, TERM_OPT_UNDERLINE, TERM_OPT_ITALIC, + TERM_OPT_STRIKE, #ifdef CONFIG_COMBINE TERM_OPT_COMBINE, #endif @@ -115,6 +116,7 @@ static struct option_resolver resolvers[] = { { TERM_OPT_UTF_8_IO, "utf_8_io" }, { TERM_OPT_UNDERLINE, "underline" }, { TERM_OPT_ITALIC, "italic" }, + { TERM_OPT_STRIKE, "strike" }, #ifdef CONFIG_COMBINE { TERM_OPT_COMBINE, "combine" }, #endif @@ -242,6 +244,7 @@ terminal_options(struct terminal *term, void *xxx, struct session *ses) add_dlg_checkbox(dlg, _("Italic", term), &values[TERM_OPT_ITALIC].number); add_dlg_checkbox(dlg, _("Transparency", term), &values[TERM_OPT_TRANSPARENCY].number); add_dlg_checkbox(dlg, _("Underline", term), &values[TERM_OPT_UNDERLINE].number); + add_dlg_checkbox(dlg, _("Strikethrough", term), &values[TERM_OPT_STRIKE].number); add_dlg_checkbox(dlg, _("UTF-8 I/O", term), &values[TERM_OPT_UTF_8_IO].number); #ifdef CONFIG_COMBINE add_dlg_checkbox(dlg, _("Combining characters", term), &values[TERM_OPT_COMBINE].number); diff --git a/src/document/format.c b/src/document/format.c index f28cf2849..87482eebd 100644 --- a/src/document/format.c +++ b/src/document/format.c @@ -37,6 +37,10 @@ get_screen_char_template(struct screen_char *template_, if (style.attr & AT_GRAPHICS) { template_->attr |= SCREEN_ATTR_FRAME; } + + if (style.attr & AT_STRIKE) { + template_->attr |= SCREEN_ATTR_STRIKE; + } } { diff --git a/src/document/format.h b/src/document/format.h index b6b15b23b..321a30518 100644 --- a/src/document/format.h +++ b/src/document/format.h @@ -23,6 +23,7 @@ enum text_style_format { * entities and numeric character references, so the put_chars * function of the renderer must not do that again. */ AT_NO_ENTITIES = 64, + AT_STRIKE = 128 }; typedef signed short text_style_format_T; diff --git a/src/document/html/parser/general.c b/src/document/html/parser/general.c index c75efddb0..c38806afe 100644 --- a/src/document/html/parser/general.c +++ b/src/document/html/parser/general.c @@ -67,6 +67,13 @@ html_italic(struct html_context *html_context, char *a, elformat.style.attr |= AT_ITALIC; } +void +html_strike(struct html_context *html_context, char *a, + char *xxx3, char *xxx4, char **xxx5) +{ + elformat.style.attr |= AT_STRIKE; +} + void html_underline(struct html_context *html_context, char *a, char *xxx3, char *xxx4, char **xxx5) @@ -74,6 +81,7 @@ html_underline(struct html_context *html_context, char *a, elformat.style.attr |= AT_UNDERLINE; } + void html_fixed(struct html_context *html_context, char *a, char *xxx3, char *xxx4, char **xxx5) diff --git a/src/document/html/parser/general.h b/src/document/html/parser/general.h index 5d746bcc8..2db2098f2 100644 --- a/src/document/html/parser/general.h +++ b/src/document/html/parser/general.h @@ -47,6 +47,7 @@ element_handler_T html_quote_close; element_handler_T html_script; element_handler_T html_section; element_handler_T html_span; +element_handler_T html_strike; element_handler_T html_style; element_handler_T html_style_close; element_handler_T html_subscript; diff --git a/src/document/html/parser/parse.c b/src/document/html/parser/parse.c index 3c2394b96..c04082d91 100644 --- a/src/document/html/parser/parse.c +++ b/src/document/html/parser/parse.c @@ -508,13 +508,13 @@ static struct element_info elements[] = { {"P", html_p, NULL, 2, ET_NON_NESTABLE}, {"PRE", html_pre, NULL, 2, ET_NESTABLE }, {"Q", html_quote, html_quote_close, 0, ET_NESTABLE }, - {"S", html_underline, NULL, 0, ET_NESTABLE }, + {"S", html_strike, NULL, 0, ET_NESTABLE }, {"SCRIPT", html_script, NULL, 0, ET_NESTABLE }, {"SECTION", html_section, NULL, 0, ET_NESTABLE }, {"SELECT", html_select, NULL, 0, ET_NESTABLE }, {"SOURCE", html_source, NULL, 1, ET_NON_PAIRABLE}, {"SPAN", html_span, NULL, 0, ET_NESTABLE }, - {"STRIKE", html_underline, NULL, 0, ET_NESTABLE }, + {"STRIKE", html_strike, NULL, 0, ET_NESTABLE }, {"STRONG", html_bold, NULL, 0, ET_NESTABLE }, {"STYLE", html_style, html_style_close, 0, ET_NESTABLE }, {"SUB", html_subscript, html_subscript_close, 0, ET_NESTABLE }, diff --git a/src/terminal/draw.h b/src/terminal/draw.h index 59944a86f..a05443079 100644 --- a/src/terminal/draw.h +++ b/src/terminal/draw.h @@ -30,7 +30,7 @@ struct terminal; enum screen_char_attr { SCREEN_ATTR_NONE = 0, SCREEN_ATTR_UNSEARCHABLE = 0x01, - SCREEN_ATTR_NODE_NUMBER = 0x02, + SCREEN_ATTR_STRIKE = 0x02, SCREEN_ATTR_BOLD = 0x08, SCREEN_ATTR_ITALIC = 0x10, SCREEN_ATTR_UNDERLINE = 0x20, diff --git a/src/terminal/screen.c b/src/terminal/screen.c index 46fa3bcca..c484ed563 100644 --- a/src/terminal/screen.c +++ b/src/terminal/screen.c @@ -215,6 +215,11 @@ static const struct string underline_seqs[] = { /* begin underline: */ TERM_STRING("\033[4m"), }; +static const struct string strike_seqs[] = { + /* end underline: */ TERM_STRING("\033[29m"), + /* begin underline: */ TERM_STRING("\033[9m"), +}; + /* elinks --dump has a separate implementation of color-changing * sequences and does not use these. */ #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) @@ -247,6 +252,9 @@ struct screen_driver_opt { /** The underline mode setup and teardown sequences. May be NULL. */ const struct string *underline; + /** The strike mode setup and teardown sequences. May be NULL. */ + const struct string *strike; + /** The color mode */ color_mode_T color_mode; @@ -304,6 +312,7 @@ static const struct screen_driver_opt dumb_screen_driver_opt = { /* frame_seqs: */ NULL, /* italic: */ italic_seqs, /* underline: */ underline_seqs, + /* strike */ strike_seqs, /* color_mode: */ COLOR_MODE_16, #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) /* color256_seqs: */ color256_seqs, @@ -330,6 +339,7 @@ static const struct screen_driver_opt vt100_screen_driver_opt = { /* frame_seqs: */ vt100_frame_seqs, /* italic: */ italic_seqs, /* underline: */ underline_seqs, + /* strike */ strike_seqs, /* color_mode: */ COLOR_MODE_16, #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) /* color256_seqs: */ color256_seqs, @@ -356,6 +366,7 @@ static const struct screen_driver_opt linux_screen_driver_opt = { /* frame_seqs: */ NULL, /* No m11_hack */ /* italic: */ italic_seqs, /* underline: */ underline_seqs, + /* strike */ strike_seqs, /* color_mode: */ COLOR_MODE_16, #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) /* color256_seqs: */ color256_seqs, @@ -382,6 +393,7 @@ static const struct screen_driver_opt koi8_screen_driver_opt = { /* frame_seqs: */ NULL, /* italic: */ italic_seqs, /* underline: */ underline_seqs, + /* strike */ strike_seqs, /* color_mode: */ COLOR_MODE_16, #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) /* color256_seqs: */ color256_seqs, @@ -408,6 +420,7 @@ static const struct screen_driver_opt freebsd_screen_driver_opt = { /* frame_seqs: */ NULL, /* No m11_hack */ /* italic: */ italic_seqs, /* underline: */ underline_seqs, + /* strike */ NULL, /* color_mode: */ COLOR_MODE_16, #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) /* color256_seqs: */ color256_seqs, @@ -434,6 +447,7 @@ static const struct screen_driver_opt fbterm_screen_driver_opt = { /* frame_seqs: */ NULL, /* No m11_hack */ /* italic: */ italic_seqs, /* underline: */ underline_seqs, + /* strike */ strike_seqs, /* color_mode: */ COLOR_MODE_16, #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) /* color256_seqs: */ fbterm_color256_seqs, @@ -533,6 +547,12 @@ set_screen_driver_opt(struct screen_driver *driver, struct option *term_spec) driver->opt.underline = NULL; } + if (get_opt_bool_tree(term_spec, "strike", NULL)) { + driver->opt.strike = strike_seqs; + } else { + driver->opt.strike = driver->opt.underline; + } + if (utf8_io) { driver->opt.charsets[0] = cp; @@ -706,16 +726,17 @@ struct screen_state { unsigned char underline; unsigned char bold; unsigned char attr; + unsigned char strike; /** Following should match the screen_char.color field. */ unsigned char color[SCREEN_COLOR_SIZE]; }; #if defined(CONFIG_TRUE_COLOR) -#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} } +#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} } #elif defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) -#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF } } +#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, { 0xFF, 0xFF } } #else -#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, { 0xFF } } +#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, { 0xFF } } #endif #ifdef CONFIG_TRUE_COLOR @@ -883,6 +904,7 @@ add_char16(struct string *screen, struct screen_driver *driver, unsigned char italic = (ch->attr & SCREEN_ATTR_ITALIC); unsigned char underline = (ch->attr & SCREEN_ATTR_UNDERLINE); unsigned char bold = (ch->attr & SCREEN_ATTR_BOLD); + unsigned char strike = (ch->attr & SCREEN_ATTR_STRIKE); if ( #ifdef CONFIG_UTF8 @@ -928,6 +950,24 @@ add_char16(struct string *screen, struct screen_driver *driver, } } + if ( +#ifdef CONFIG_UTF8 + !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) && +#endif /* CONFIG_UTF8 */ + strike != state->strike && driver->opt.strike + ) { + state->strike = strike; +#ifdef CONFIG_TERMINFO + if (driver->opt.terminfo) { + add_to_string(screen, terminfo_set_strike(strike)); + } else +#endif + { + add_term_string(screen, driver->opt.strike[!!strike]); + } + } + + if ( #ifdef CONFIG_UTF8 !(driver->opt.utf8_cp && ch->data == UCS_NO_CHAR) && @@ -975,6 +1015,9 @@ add_char16(struct string *screen, struct screen_driver *driver, if (underline) add_to_string(screen, terminfo_set_underline(underline)); + if (strike) + add_to_string(screen, terminfo_set_strike(strike)); + } else #endif { @@ -1015,6 +1058,11 @@ add_char16(struct string *screen, struct screen_driver *driver, add_bytes_to_string(screen, ";4", 2); } + if (strike && driver->opt.strike) { + add_bytes_to_string(screen, ";9", 2); + } + + /* Check if the char should be rendered bold. */ if (bold) { add_bytes_to_string(screen, ";1", 2); @@ -1120,6 +1168,18 @@ add_char256(struct string *screen, struct screen_driver *driver, } } + if ((attr_delta & SCREEN_ATTR_STRIKE) && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); +#ifdef CONFIG_TERMINFO + if (driver->opt.terminfo) { + add_to_string(screen, terminfo_set_strike(state->strike)); + } else +#endif + { + add_term_string(screen, driver->opt.strike[state->strike]); + } + } + if (attr_delta & SCREEN_ATTR_BOLD) { if (ch->attr & SCREEN_ATTR_BOLD) { #ifdef CONFIG_TERMINFO @@ -1161,6 +1221,11 @@ add_char256(struct string *screen, struct screen_driver *driver, state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); add_to_string(screen, terminfo_set_underline(state->underline)); } + + if (ch->attr & SCREEN_ATTR_STRIKE && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); + add_to_string(screen, terminfo_set_strike(state->strike)); + } } else #endif { @@ -1181,6 +1246,12 @@ add_char256(struct string *screen, struct screen_driver *driver, state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); add_term_string(screen, driver->opt.underline[state->underline]); } + + if (ch->attr & SCREEN_ATTR_STRIKE && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); + add_term_string(screen, driver->opt.strike[state->strike]); + } + } } @@ -1271,6 +1342,11 @@ add_char_true(struct string *screen, struct screen_driver *driver, add_to_string(screen, terminfo_set_underline(state->underline)); } + if ((attr_delta & SCREEN_ATTR_STRIKE) && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); + add_to_string(screen, terminfo_set_strike(state->strike)); + } + if (attr_delta & SCREEN_ATTR_BOLD) { if (ch->attr & SCREEN_ATTR_BOLD) { add_to_string(screen, terminfo_set_bold(ch->attr & SCREEN_ATTR_BOLD)); @@ -1292,6 +1368,11 @@ add_char_true(struct string *screen, struct screen_driver *driver, add_term_string(screen, driver->opt.underline[state->underline]); } + if ((attr_delta & SCREEN_ATTR_STRIKE) && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); + add_term_string(screen, driver->opt.strike[state->strike]); + } + if (attr_delta & SCREEN_ATTR_BOLD) { if (ch->attr & SCREEN_ATTR_BOLD) { add_bytes_to_string(screen, "\033[1m", 4); @@ -1328,6 +1409,11 @@ add_char_true(struct string *screen, struct screen_driver *driver, state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); add_to_string(screen, terminfo_set_underline(state->underline)); } + + if (ch->attr & SCREEN_ATTR_STRIKE && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); + add_to_string(screen, terminfo_set_strike(state->strike)); + } } else #endif { @@ -1348,6 +1434,12 @@ add_char_true(struct string *screen, struct screen_driver *driver, state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); add_term_string(screen, driver->opt.underline[state->underline]); } + + if (ch->attr & SCREEN_ATTR_STRIKE && driver->opt.strike) { + state->strike = !!(ch->attr & SCREEN_ATTR_STRIKE); + add_term_string(screen, driver->opt.strike[state->strike]); + } + } } diff --git a/src/terminal/terminfo.c b/src/terminal/terminfo.c index 896a7d513..65f0b32a1 100644 --- a/src/terminal/terminfo.c +++ b/src/terminal/terminfo.c @@ -58,6 +58,14 @@ terminfo_set_underline(int arg) return res ?: ""; } +const char * +terminfo_set_strike(int arg) +{ + char *res = tiparm(arg ? enter_underline_mode : exit_underline_mode); + + return res ?: ""; +} + const char * terminfo_set_background(int arg) { diff --git a/src/terminal/terminfo.h b/src/terminal/terminfo.h index ec53422c2..681b87da1 100644 --- a/src/terminal/terminfo.h +++ b/src/terminal/terminfo.h @@ -13,6 +13,7 @@ const char *terminfo_set_underline(int arg); const char *terminfo_set_foreground(int arg); const char *terminfo_set_background(int arg); const char *terminfo_set_standout(int arg); +const char *terminfo_set_strike(int arg); int terminfo_max_colors(void); const char *terminfo_cursor_address(int y, int x); diff --git a/test/strike.html b/test/strike.html new file mode 100644 index 000000000..18e653ecd --- /dev/null +++ b/test/strike.html @@ -0,0 +1 @@ +striketrough