Skip to content

Commit

Permalink
support color256
Browse files Browse the repository at this point in the history
  • Loading branch information
ahaoboy committed Oct 16, 2024
1 parent cbb0d1f commit 94044fd
Show file tree
Hide file tree
Showing 10 changed files with 1,148 additions and 57 deletions.
27 changes: 22 additions & 5 deletions ansi2/src/css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ pub(crate) fn to_style(theme: impl ColorTable, ty: CssType, mode: Option<Mode>)
CssType::Svg => ("fill", "fill"),
};

let mut color256 = Vec::new();
for i in 0..256 {
let (r, g, b) = theme.get(i);
color256.push(format!(".color256_{i}{{ {color_field}: rgb({r},{g},{b}) ;}}"));
}

let mut color256bg = Vec::new();
for i in 0..256 {
let (r, g, b) = theme.get(i);
color256bg.push(format!(".color256_bg_{i}{{ {bg_field}: rgb({r},{g},{b}) ;}}"));
}

let color256_str = color256.join("\n") + &color256bg.join("\n");
let light_colors = [
("black", get_hex(theme.black())),
("red", get_hex(theme.red())),
Expand Down Expand Up @@ -61,7 +74,7 @@ pub(crate) fn to_style(theme: impl ColorTable, ty: CssType, mode: Option<Mode>)
("bright_blue", get_hex(theme.bright_blue())),
("bright_magenta", get_hex(theme.bright_magenta())),
("bright_cyan", get_hex(theme.bright_cyan())),
("bright_white", get_hex(theme.bright_white())),
("bright_white", get_hex(theme.bright_black())),
];

let common_style = r#"
Expand Down Expand Up @@ -113,12 +126,12 @@ opacity: 0;
(Mode::Dark, CssType::Html) => {
format!("div{{color: {} }}", get_hex(theme.white()))
}
(Mode::Dark, CssType::Svg) => format!("text{{fill:{}}}", get_hex(theme.white())),
(Mode::Dark, CssType::Svg) => format!("svg > text{{fill:{}}}", get_hex(theme.white())),
(Mode::Light, CssType::Html) => {
format!("div{{color:{}}}", get_hex(theme.black()))
}
(Mode::Light, CssType::Svg) => {
format!("text{{fill:{}}}", get_hex(theme.black()))
format!("svg > text{{fill:{}}}", get_hex(theme.black()))
}
};

Expand All @@ -139,6 +152,7 @@ opacity: 0;
{common_style}
{color_css}
{bg_color_css}
{color256_str}
"#
)
.trim()
Expand All @@ -148,12 +162,12 @@ opacity: 0;
}

let default_light_text_style = match ty {
CssType::Svg => format!("text{{fill:{}}}", get_hex(theme.black())),
CssType::Svg => format!("svg > text{{fill:{}}}", get_hex(theme.black())),
CssType::Html => format!("div{{color:{}}}", get_hex(theme.black())),
};

let default_dark_text_style = match ty {
CssType::Svg => format!("text{{fill:{}}}", get_hex(theme.white())),
CssType::Svg => format!("svg > text{{fill:{}}}", get_hex(theme.white())),
CssType::Html => format!("div{{color:{}}}", get_hex(theme.white())),
};

Expand Down Expand Up @@ -186,6 +200,9 @@ opacity: 0;
{dark_css}
{common_style}
{color256_str}
"#,
)
.trim()
Expand Down
17 changes: 17 additions & 0 deletions ansi2/src/html.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use crate::{
css::{to_style, CssType, Mode},
theme::ColorTable,
Expand Down Expand Up @@ -30,6 +32,8 @@ pub fn to_html<S: AsRef<str>>(
};

s.push_str("<div class='ansi-main'>\n");

let mut color256 = HashSet::new();
for row in canvas.pixels.iter() {
s.push_str("<div class='row'>");
for c in row.iter() {
Expand All @@ -42,11 +46,21 @@ pub fn to_html<S: AsRef<str>>(
if !c.color.is_default() {
let name = c.color.name();
text_class.push(name);

if let crate::lex::AnsiColor::Rgb(r, g, b) = c.color {
color256.insert(format!(".rgb_{r}_{g}_{b}{{ color: rgb({r},{g},{b}) ;}}\n"));
}
}

if !c.bg_color.is_default() {
let name = "bg-".to_string() + &c.bg_color.name();
bg_class.push(name);

if let crate::lex::AnsiColor::Rgb(r, g, b) = c.color {
color256.insert(format!(
".bg-rgb_{r}_{g}_{b}{{ background: rgb({r},{g},{b}) ;}}\n"
));
}
}

if c.blink {
Expand All @@ -68,6 +82,8 @@ pub fn to_html<S: AsRef<str>>(
}
s.push_str("</div>");
}

let color256_str: String = color256.into_iter().collect();
s.push_str("</div>\n");

format!(
Expand All @@ -79,6 +95,7 @@ pub fn to_html<S: AsRef<str>>(
<style>
{font_style}
{style}
{color256_str}
.ansi-main{{display:flex;flex-direction:column;}}
.row{{display: flex;}}
.char{{
Expand Down
96 changes: 49 additions & 47 deletions ansi2/src/lex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,67 +12,69 @@ use crate::theme::ColorTable;
#[derive(Debug, Clone, Copy)]
pub enum AnsiColor {
Color8(u32),
Color256(u32),
Rgb(u32, u32, u32),
}
impl AnsiColor {
pub fn name(&self) -> String {
match self {
AnsiColor::Color8(n) => {
match n {
30 | 40 => "black".into(),
31 | 41 => "red".into(),
32 | 42 => "green".into(),
33 | 43 => "yellow".into(),
34 | 44 => "blue".into(),
35 | 45 => "magenta".into(),
36 | 46 => "cyan".into(),
37 | 47 => "white".into(),

90 | 100 => "bright_black".into(),
91 | 101 => "bright_red".into(),
92 | 102 => "bright_green".into(),
93 | 103 => "bright_yellow".into(),
94 | 104 => "bright_blue".into(),
95 | 105 => "bright_magenta".into(),
96 | 106 => "bright_cyan".into(),
97 | 107 => "bright_white".into(),
_ => "white".into(),
}
}
AnsiColor::Color8(n) => match n {
30 | 40 => "black".into(),
31 | 41 => "red".into(),
32 | 42 => "green".into(),
33 | 43 => "yellow".into(),
34 | 44 => "blue".into(),
35 | 45 => "magenta".into(),
36 | 46 => "cyan".into(),
37 | 47 => "white".into(),

90 | 100 => "bright_black".into(),
91 | 101 => "bright_red".into(),
92 | 102 => "bright_green".into(),
93 | 103 => "bright_yellow".into(),
94 | 104 => "bright_blue".into(),
95 | 105 => "bright_magenta".into(),
96 | 106 => "bright_cyan".into(),
97 | 107 => "bright_white".into(),
_ => "white".into(),
},
AnsiColor::Rgb(r, g, b) => format!("rgb_{}_{}_{}", r, g, b),
AnsiColor::Color256(c) => format!("color256_{}", c),
}
}

pub fn to_rgb(&self, th: impl ColorTable) -> String {
match self {
AnsiColor::Color8(n) => {
match n {
30 | 40 => format!("rgb{:?}", th.black()),
31 | 41 => format!("rgb{:?}", th.red()),
32 | 42 => format!("rgb{:?}", th.green()),
33 | 43 => format!("rgb{:?}", th.yellow()),
34 | 44 => format!("rgb{:?}", th.blue()),
35 | 45 => format!("rgb{:?}", th.magenta()),
36 | 46 => format!("rgb{:?}", th.cyan()),
37 | 47 => format!("rgb{:?}", th.white()),

90 | 100 => format!("rgb{:?}", th.bright_black()),
91 | 101 => format!("rgb{:?}", th.bright_red()),
92 | 102 => format!("rgb{:?}", th.bright_green()),
93 | 103 => format!("rgb{:?}", th.bright_yellow()),
94 | 104 => format!("rgb{:?}", th.bright_blue()),
95 | 105 => format!("rgb{:?}", th.bright_magenta()),
96 | 106 => format!("rgb{:?}", th.bright_cyan()),
97 | 107 => format!("rgb{:?}", th.bright_white()),
_ => format!("rgb{:?}", th.white()),
}
}
AnsiColor::Color8(n) => match n {
30 | 40 => format!("rgb{:?}", th.black()),
31 | 41 => format!("rgb{:?}", th.red()),
32 | 42 => format!("rgb{:?}", th.green()),
33 | 43 => format!("rgb{:?}", th.yellow()),
34 | 44 => format!("rgb{:?}", th.blue()),
35 | 45 => format!("rgb{:?}", th.magenta()),
36 | 46 => format!("rgb{:?}", th.cyan()),
37 | 47 => format!("rgb{:?}", th.white()),

90 | 100 => format!("rgb{:?}", th.bright_black()),
91 | 101 => format!("rgb{:?}", th.bright_red()),
92 | 102 => format!("rgb{:?}", th.bright_green()),
93 | 103 => format!("rgb{:?}", th.bright_yellow()),
94 | 104 => format!("rgb{:?}", th.bright_blue()),
95 | 105 => format!("rgb{:?}", th.bright_magenta()),
96 | 106 => format!("rgb{:?}", th.bright_cyan()),
97 | 107 => format!("rgb{:?}", th.bright_white()),
_ => format!("rgb{:?}", th.white()),
},
AnsiColor::Rgb(r, g, b) => format!("rgb({}, {}, {})", r, g, b),
AnsiColor::Color256(c) => {
let (r, g, b) = th.get(*c as usize);
format!("rgb({}, {}, {})", r, g, b)
}
}
}

pub fn is_default(&self) -> bool {
matches!(self, AnsiColor::Color8(0))
matches!(self, AnsiColor::Color8(0))
}
}

Expand Down Expand Up @@ -262,7 +264,7 @@ fn parse_color_foreground(input: &str) -> IResult<&str, Token> {
let c = match b {
0..=7 => b + 30,
8..=15 => b + 82,
_ => b,
_ => return Ok((rem, Token::ColorForeground(AnsiColor::Color256(b)))),
};
Ok((rem, Token::ColorForeground(AnsiColor::Color8(c))))
}
Expand All @@ -273,7 +275,7 @@ fn parse_color_background(input: &str) -> IResult<&str, Token> {
let c = match b {
0..=7 => b + 40,
8..=15 => b + 92,
_ => b,
_ => return Ok((rem, Token::ColorBackground(AnsiColor::Color256(b)))),
};
Ok((rem, Token::ColorBackground(AnsiColor::Color8(c))))
}
Expand Down
20 changes: 20 additions & 0 deletions ansi2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,24 @@ mod test {
let r = parse_ansi(s).unwrap();
println!("{:?}", r);
}

#[test]
fn test_color256() {
let s = "ab";
let r = parse_ansi(s).unwrap();
println!("{:?}", r);
}

#[test]
fn test_color24() {
let s = "";
let r = parse_ansi(s).unwrap();
println!("{:?}", r);
}
#[test]
fn test_base() {
let s = "black bright black black bright black";
let r = parse_ansi(s).unwrap();
println!("{:?}", r);
}
}
18 changes: 18 additions & 0 deletions ansi2/src/svg.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use crate::{
css::{to_style, CssType, Mode},
theme::ColorTable,
Expand Down Expand Up @@ -32,6 +34,10 @@ pub fn to_svg<S: AsRef<str>>(
} else {
"".into()
};

let mut color256 = HashSet::new();


for row in canvas.pixels.iter() {
for c in row.iter() {
let mut text_class = vec![];
Expand All @@ -44,11 +50,21 @@ pub fn to_svg<S: AsRef<str>>(
r#"<rect x="{cur_x}px" y="{cur_y}px" width="{fn_w}px" height="{fn_h}px" {class_str}/>"#
,
));

if let crate::lex::AnsiColor::Rgb(r, g, b) = c.color {
color256.insert(format!(".bg-rgb_{r}_{g}_{b}{{ fill: rgb({r},{g},{b}) ;}}\n"));
}
}

if !c.color.is_default() {
let name = c.color.name();
text_class.push(name);

if let crate::lex::AnsiColor::Rgb(r, g, b) = c.color {
color256.insert(format!(
".rgb_{r}_{g}_{b}{{ fill: rgb({r},{g},{b}) ;}}\n"
));
}
};

if c.bold {
Expand Down Expand Up @@ -80,6 +96,7 @@ class_str ,

let svg_w = fn_w * canvas.w;
let svg_h = fn_h * canvas.h;
let color256_str: String = color256.into_iter().collect();

format!(
r#"<svg
Expand All @@ -99,6 +116,7 @@ font-size: {fn_h}px;
}}
{font_style}
{style}
{color256_str}
</style>
{s}
</svg>
Expand Down
2 changes: 1 addition & 1 deletion ansi2/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ pub fn to_text<S: AsRef<str>>(str: S, width: Option<usize>) -> String {
}
list.push('\n')
}
return list.iter().collect();
list.iter().collect()
}
Loading

0 comments on commit 94044fd

Please sign in to comment.