Skip to content

Commit

Permalink
ansi: support minify by heap
Browse files Browse the repository at this point in the history
  • Loading branch information
ahaoboy committed Oct 29, 2024
1 parent bb3792b commit 28e3ca1
Show file tree
Hide file tree
Showing 50 changed files with 1,944 additions and 116 deletions.
467 changes: 373 additions & 94 deletions ansi2/src/ans.rs

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion ansi2/src/css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum NodeStyle {
Row,
Text,
Main,
Strike,
}

#[derive(Debug, Clone, Default)]
Expand All @@ -42,6 +43,7 @@ pub struct Style {
pub italic: bool,
pub underline: bool,
pub hide: bool,
pub strike: bool,
}

impl NodeStyle {
Expand All @@ -56,6 +58,7 @@ impl NodeStyle {
NodeStyle::Row => "r",
NodeStyle::Text => "t",
NodeStyle::Main => "m",
NodeStyle::Strike => "s",
}
}
}
Expand Down Expand Up @@ -135,9 +138,15 @@ impl Style {
NodeStyle::Underline.class_name()
));
}
if self.strike {
css.push_str(&format!(
".{}{{text-decoration:line-through}}",
NodeStyle::Strike.class_name()
));
}
if self.blink {
css.push_str(&format!(
".{}{{animation:bk 1s steps(1, end) infinite;}} @keyframes bk{{50% {{opacity: 0}}",
".{}{{animation:bk 1s steps(1, end) infinite;}} @keyframes bk{{50% {{opacity: 0}}}}",
NodeStyle::Blink.class_name()
));
}
Expand Down
5 changes: 4 additions & 1 deletion ansi2/src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ pub fn to_html<S: AsRef<str>>(
text_class.push(NodeStyle::Blink.class_name().to_string());
style.blink = true;
}

if c.strike {
text_class.push(NodeStyle::Strike.class_name().to_string());
style.strike = true;
}
if !c.color.is_default() {
let name = c.color.class_name();
text_class.push(name);
Expand Down
113 changes: 100 additions & 13 deletions ansi2/src/lex.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::color::AnsiColor;
use crate::color::{AnsiColor, Color8};
use nom::branch::alt;
use nom::bytes::complete::{tag, tag_no_case, take_until};
use nom::character::complete::{anychar, digit0};
Expand Down Expand Up @@ -60,18 +60,22 @@ pub enum Token {
SlowBlink,
RapidBlink,
Strike,
UnStrike,
UnItalic,
PrimaryFont,
DoublyUnderlined,
NotUnderlined,
NotBlinking,
UnUnderlined,
UnBlink,

List(Vec<Token>),

// url, title
Link(String, String),

AlternativeFont(u8),
NotReversed,
Fraktur,
UnReversed,
UnHide,
Unknown(u8),
}

Expand Down Expand Up @@ -243,23 +247,22 @@ pub fn get_sgr(n: u8) -> Token {
9 => Token::Strike,
10 => Token::PrimaryFont,
11..=19 => Token::AlternativeFont(n - 10),
20 => {
todo!()
}
20 => Token::Fraktur,
21 => Token::DoublyUnderlined,
24 => Token::NotUnderlined,
25 => Token::NotBlinking,
24 => Token::UnUnderlined,
25 => Token::UnBlink,
30..=37 | 90..=97 => Token::ColorForeground(AnsiColor::from_u8(n)),
40..=47 | 100..=107 => Token::ColorBackground(AnsiColor::from_u8(n)),
39 => Token::ColorDefaultForeground,
49 => Token::ColorDefaultBackground,
59 => Token::ColorDefaultUnderline,
22 => Token::NormalIntensity,
27 => Token::NotReversed,
27 => Token::UnReversed,
29 => Token::UnStrike,
28 => Token::UnHide,
23 => Token::UnItalic,

_ => {
todo!()
}
_ => Token::Unknown(n),
}
}

Expand Down Expand Up @@ -477,6 +480,89 @@ fn parse_sgr6(input: &str) -> IResult<&str, Token> {
}
todo!()
}

fn parse_sgr7(input: &str) -> IResult<&str, Token> {
let (rem, (_, ctrl, _, a, _, b, _, c, _, d, _, e, _, f, _)) = tuple((
tag("\x1b["),
digit0,
tag(";"),
digit0,
tag(";"),
digit0,
tag(";"),
digit0,
tag(";"),
digit0,
tag(";"),
digit0,
tag(";"),
digit0,
tag_no_case("m"),
))(input)?;
let ctrl = ctrl.parse().unwrap_or(0);
let a = a.parse().unwrap_or(0);
let b = b.parse().unwrap_or(0);
let c = c.parse().unwrap_or(0);
let d = d.parse().unwrap_or(0);
let e = e.parse().unwrap_or(0);
let f = f.parse().unwrap_or(0);
let mut v = vec![get_sgr(ctrl)];

match a {
38 => match b {
5 => {
v.push(Token::ColorForeground(AnsiColor::Color256(c)));
}
2 => {
v.push(Token::ColorForeground(AnsiColor::Color8(Color8::from_u8(
c,
))));
}
_ => {}
},
48 => match b {
5 => {
v.push(Token::ColorBackground(AnsiColor::Color256(c)));
}
2 => {
v.push(Token::ColorBackground(AnsiColor::Color8(Color8::from_u8(
c,
))));
}
_ => {}
},
_ => {}
}

match d {
38 => match e {
5 => {
v.push(Token::ColorForeground(AnsiColor::Color256(f)));
}
2 => {
v.push(Token::ColorForeground(AnsiColor::Color8(Color8::from_u8(
f,
))));
}
_ => {}
},
48 => match e {
5 => {
v.push(Token::ColorBackground(AnsiColor::Color256(f)));
}
2 => {
v.push(Token::ColorBackground(AnsiColor::Color8(Color8::from_u8(
f,
))));
}
_ => {}
},
_ => {}
}

Ok((rem, Token::List(v)))
}

fn parse_sgr10(input: &str) -> IResult<&str, Token> {
let (rem, (_, c1, _, t1, _, r1, _, g1, _, b1, _, c2, _, t2, _, r2, _, g2, _, b2, _)) =
tuple((
Expand Down Expand Up @@ -638,6 +724,7 @@ pub(crate) fn parse_ansi(input: &str) -> IResult<&str, Vec<Token>> {
parse_sgr4,
parse_sgr5,
parse_sgr6,
parse_sgr7,
parse_sgr10,
)),
alt((parse_link_with_title, parse_link_no_title, parse_link_ll)),
Expand Down
33 changes: 30 additions & 3 deletions ansi2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct Node {
pub italic: bool,
pub underline: bool,
pub hide: bool,
pub strike: bool,
}

impl Node {
Expand All @@ -34,6 +35,7 @@ impl Node {
&& self.italic == other.italic
&& self.underline == other.underline
&& self.hide == other.hide
&& self.strike == other.strike
}
}

Expand All @@ -59,6 +61,7 @@ fn set_node(v: &mut Vec<Vec<Node>>, node: Node, x: usize, y: usize) {
italic: false,
underline: false,
hide: false,
strike: false,
};
row.push(empty);
}
Expand Down Expand Up @@ -86,6 +89,7 @@ impl Canvas {
let mut reverse = false;
let mut underline = false;
let mut blink = false;
let mut strike = false;
let mut w = 0;
let mut h = 0;
let mut pixels = Vec::new();
Expand Down Expand Up @@ -115,6 +119,7 @@ impl Canvas {
}

while let Some(i) = q.pop_front() {
// eprintln!("{:?}", i);
match i {
Token::LineFeed => {
cur_y += 1;
Expand All @@ -133,6 +138,7 @@ impl Canvas {
italic,
underline,
hide,
strike,
};
if cur_x >= max_width {
cur_x = 0;
Expand Down Expand Up @@ -168,9 +174,15 @@ impl Canvas {
Token::Italic => {
italic = true;
}
Token::UnItalic => {
italic = false;
}
Token::Underline => {
underline = true;
}
Token::UnUnderlined => {
underline = false;
}
Token::Dim => {
dim = true;
}
Expand All @@ -185,6 +197,7 @@ impl Canvas {
cur_c = AnsiColor::Default;
blink = false;
hide = false;
strike = false;
}
Token::CursorUp(c) => cur_y = cur_y.saturating_sub(c as usize),
Token::CursorDown(c) => {
Expand Down Expand Up @@ -235,6 +248,7 @@ impl Canvas {
ensure_height(&mut pixels, cur_y);
}
Token::SlowBlink | Token::RapidBlink => blink = true,
Token::UnBlink => blink = false,
Token::Reverse => {
reverse = true;
let tmp_c = cur_c;
Expand All @@ -246,11 +260,17 @@ impl Canvas {
dim = false;
bold = false;
}
Token::NotReversed => {
Token::UnReversed => {
reverse = false;
set_bg_color!(AnsiColor::Default);
set_color!(AnsiColor::Default);
}
Token::Strike => {
strike = true;
}
Token::UnStrike => {
strike = false;
}
Token::ColorDefaultForeground => {
if reverse {
set_bg_color!(AnsiColor::Default);
Expand All @@ -271,9 +291,9 @@ impl Canvas {
// FIXME: Avoid the influence of styles in link on subsequent characters
q.push_front(Token::ColorReset);
for i in tokens.into_iter().rev() {
underline = true;
q.push_front(i);
}
q.push_front(Token::Underline);
}
Err(_) => {
for i in title.chars() {
Expand All @@ -294,6 +314,7 @@ impl Canvas {
italic,
underline: true,
hide,
strike,
};

if cur_x >= max_width {
Expand All @@ -308,7 +329,13 @@ impl Canvas {
Token::CursorHide => {
hide = true;
}

Token::UnHide => {
hide = false;
}
Token::DoublyUnderlined => {
bold = false;
underline = true;
}
Token::List(v) => {
for i in v.into_iter().rev() {
q.push_front(i);
Expand Down
8 changes: 8 additions & 0 deletions ansi2/src/snapshots/ansi2__ans__test__min_bold_dim.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
source: ansi2/src/ans.rs
expression: s
---
[
Reset,
Dim,
]
16 changes: 16 additions & 0 deletions ansi2/src/snapshots/ansi2__ans__test__min_color.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
source: ansi2/src/ans.rs
expression: s
---
[
Bg(
Color8(
Yellow,
),
),
Color(
Color8(
Red,
),
),
]
8 changes: 8 additions & 0 deletions ansi2/src/snapshots/ansi2__ans__test__min_italic.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
source: ansi2/src/ans.rs
expression: s
---
[
Reset,
Italic,
]
7 changes: 7 additions & 0 deletions ansi2/src/snapshots/ansi2__ans__test__min_underline.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: ansi2/src/ans.rs
expression: s
---
[
Reset,
]
Loading

0 comments on commit 28e3ca1

Please sign in to comment.