diff --git a/crates/anstyle-svg/src/adapter.rs b/crates/anstyle-svg/src/adapter.rs index 4cb6467b..0c124fd7 100644 --- a/crates/anstyle-svg/src/adapter.rs +++ b/crates/anstyle-svg/src/adapter.rs @@ -138,10 +138,6 @@ impl anstyle_parse::Perform for AnsiCapture { style = style.underline(); state = CsiState::Underline; } - (CsiState::Normal, 21) => { - style |= anstyle::Effects::DOUBLE_UNDERLINE; - break; - } (CsiState::Normal, 7) => { style = style.invert(); break; @@ -154,6 +150,48 @@ impl anstyle_parse::Perform for AnsiCapture { style = style.strikethrough(); break; } + (CsiState::Normal, 21) => { + style |= anstyle::Effects::DOUBLE_UNDERLINE; + break; + } + (CsiState::Normal, 22) => { + style = style.effects( + style + .get_effects() + .remove(anstyle::Effects::BOLD) + .remove(anstyle::Effects::DIMMED), + ); + break; + } + (CsiState::Normal, 23) => { + style = style.effects(style.get_effects().remove(anstyle::Effects::ITALIC)); + break; + } + (CsiState::Normal, 24) => { + style = style.effects( + style + .get_effects() + .remove(anstyle::Effects::UNDERLINE) + .remove(anstyle::Effects::DOUBLE_UNDERLINE) + .remove(anstyle::Effects::CURLY_UNDERLINE) + .remove(anstyle::Effects::DOTTED_UNDERLINE) + .remove(anstyle::Effects::DASHED_UNDERLINE), + ); + break; + } + (CsiState::Normal, 27) => { + style = style.effects(style.get_effects().remove(anstyle::Effects::INVERT)); + break; + } + (CsiState::Normal, 28) => { + style = style.effects(style.get_effects().remove(anstyle::Effects::HIDDEN)); + break; + } + (CsiState::Normal, 29) => { + style = style + .effects(style.get_effects().remove(anstyle::Effects::STRIKETHROUGH)); + break; + } (CsiState::Normal, 30..=37) => { let color = to_ansi_color(value - 30).expect("within 4-bit range"); style = style.fg_color(Some(color.into())); @@ -184,6 +222,10 @@ impl anstyle_parse::Perform for AnsiCapture { color_target = ColorTarget::Underline; state = CsiState::PrepareCustomColor; } + (CsiState::Normal, 59) => { + style = style.underline_color(None); + break; + } (CsiState::Normal, 90..=97) => { let color = to_ansi_color(value - 90) .expect("within 4-bit range") @@ -233,8 +275,15 @@ impl anstyle_parse::Perform for AnsiCapture { } }, (CsiState::Underline, 0) => { - style = - style.effects(style.get_effects().remove(anstyle::Effects::UNDERLINE)); + style = style.effects( + style + .get_effects() + .remove(anstyle::Effects::UNDERLINE) + .remove(anstyle::Effects::DOUBLE_UNDERLINE) + .remove(anstyle::Effects::CURLY_UNDERLINE) + .remove(anstyle::Effects::DOTTED_UNDERLINE) + .remove(anstyle::Effects::DASHED_UNDERLINE), + ); } (CsiState::Underline, 1) => { // underline already set diff --git a/crates/anstyle-svg/tests/sgr_off_codes.html b/crates/anstyle-svg/tests/sgr_off_codes.html new file mode 100644 index 00000000..c453d43e --- /dev/null +++ b/crates/anstyle-svg/tests/sgr_off_codes.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+bold normal
+dim normal
+italic normal
+underline normal
+██████
+invert normal
+ normal
+strikethrough normal
+all three no bold no italic plain
+
+
+ + + diff --git a/crates/anstyle-svg/tests/sgr_off_codes.svg b/crates/anstyle-svg/tests/sgr_off_codes.svg new file mode 100644 index 00000000..703f4d97 --- /dev/null +++ b/crates/anstyle-svg/tests/sgr_off_codes.svg @@ -0,0 +1,49 @@ + + + + + + + bold normal + + dim normal + + italic normal + + underline normal + + ██████ + + invert normal + + normal + + strikethrough normal + + all three no bold no italic plain + + + + + + diff --git a/crates/anstyle-svg/tests/sgr_off_codes.vte b/crates/anstyle-svg/tests/sgr_off_codes.vte new file mode 100644 index 00000000..16011406 --- /dev/null +++ b/crates/anstyle-svg/tests/sgr_off_codes.vte @@ -0,0 +1,8 @@ +bold normal +dim normal +italic normal +underline normal +invert normal +hidden normal +strikethrough normal +all three no bold no italic plain diff --git a/crates/anstyle-svg/tests/term.rs b/crates/anstyle-svg/tests/term.rs index df244827..7e934a3c 100644 --- a/crates/anstyle-svg/tests/term.rs +++ b/crates/anstyle-svg/tests/term.rs @@ -73,3 +73,57 @@ fn custom_background_color_html() { snapbox::file!["custom_background_color.html": Text].raw() ); } + +#[test] +fn sgr_off_codes() { + let input = std::fs::read_to_string("tests/sgr_off_codes.vte").unwrap(); + let actual = anstyle_svg::Term::new().render_svg(&input); + snapbox::assert_data_eq!(actual, snapbox::file!["sgr_off_codes.svg": Text].raw()); +} + +#[test] +fn sgr_off_codes_html() { + let input = std::fs::read_to_string("tests/sgr_off_codes.vte").unwrap(); + let actual = anstyle_svg::Term::new().render_html(&input); + snapbox::assert_data_eq!(actual, snapbox::file!["sgr_off_codes.html": Text].raw()); +} + +#[test] +fn underline_subparams() { + let input = std::fs::read_to_string("tests/underline_subparams.vte").unwrap(); + let actual = anstyle_svg::Term::new().render_svg(&input); + snapbox::assert_data_eq!( + actual, + snapbox::file!["underline_subparams.svg": Text].raw() + ); +} + +#[test] +fn underline_subparams_html() { + let input = std::fs::read_to_string("tests/underline_subparams.vte").unwrap(); + let actual = anstyle_svg::Term::new().render_html(&input); + snapbox::assert_data_eq!( + actual, + snapbox::file!["underline_subparams.html": Text].raw() + ); +} + +#[test] +fn underline_color_reset() { + let input = std::fs::read_to_string("tests/underline_color_reset.vte").unwrap(); + let actual = anstyle_svg::Term::new().render_svg(&input); + snapbox::assert_data_eq!( + actual, + snapbox::file!["underline_color_reset.svg": Text].raw() + ); +} + +#[test] +fn underline_color_reset_html() { + let input = std::fs::read_to_string("tests/underline_color_reset.vte").unwrap(); + let actual = anstyle_svg::Term::new().render_html(&input); + snapbox::assert_data_eq!( + actual, + snapbox::file!["underline_color_reset.html": Text].raw() + ); +} diff --git a/crates/anstyle-svg/tests/underline_color_reset.html b/crates/anstyle-svg/tests/underline_color_reset.html new file mode 100644 index 00000000..b4360bf2 --- /dev/null +++ b/crates/anstyle-svg/tests/underline_color_reset.html @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+red underline default color underline normal
+orange underline default color underline normal
+blue underline default color underline normal
+
+
+ + + diff --git a/crates/anstyle-svg/tests/underline_color_reset.svg b/crates/anstyle-svg/tests/underline_color_reset.svg new file mode 100644 index 00000000..5ce70e8c --- /dev/null +++ b/crates/anstyle-svg/tests/underline_color_reset.svg @@ -0,0 +1,33 @@ + + + + + + + red underline default color underline normal + + orange underline default color underline normal + + blue underline default color underline normal + + + + + + diff --git a/crates/anstyle-svg/tests/underline_color_reset.vte b/crates/anstyle-svg/tests/underline_color_reset.vte new file mode 100644 index 00000000..e9d85bdc --- /dev/null +++ b/crates/anstyle-svg/tests/underline_color_reset.vte @@ -0,0 +1,3 @@ +red underline default color underline normal +orange underline default color underline normal +[58:2:0:128:255mblue underline default color underline normal diff --git a/crates/anstyle-svg/tests/underline_subparams.html b/crates/anstyle-svg/tests/underline_subparams.html new file mode 100644 index 00000000..710977cc --- /dev/null +++ b/crates/anstyle-svg/tests/underline_subparams.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+underline normal
+double normal
+curly normal
+dotted normal
+dashed normal
+
+
+ + + diff --git a/crates/anstyle-svg/tests/underline_subparams.svg b/crates/anstyle-svg/tests/underline_subparams.svg new file mode 100644 index 00000000..02d3c87c --- /dev/null +++ b/crates/anstyle-svg/tests/underline_subparams.svg @@ -0,0 +1,38 @@ + + + + + + + underline normal + + double normal + + curly normal + + dotted normal + + dashed normal + + + + + + diff --git a/crates/anstyle-svg/tests/underline_subparams.vte b/crates/anstyle-svg/tests/underline_subparams.vte new file mode 100644 index 00000000..34bf43be --- /dev/null +++ b/crates/anstyle-svg/tests/underline_subparams.vte @@ -0,0 +1,5 @@ +underline[4:0m normal +[4:2mdouble[4:0m normal +[4:3mcurly[4:0m normal +[4:4mdotted[4:0m normal +[4:5mdashed[4:0m normal