Browse Source

Better ANSI color codes handling

tags/0.8.15^0
Julien Blanchard 10 months ago
parent
commit
75c3cdb9f2
2 changed files with 36 additions and 16 deletions
  1. 33
    13
      src/colors.rs
  2. 3
    3
      src/gemini/parser.rs

+ 33
- 13
src/colors.rs View File

@@ -2,39 +2,57 @@ pub mod colors {
2 2
     use ansi_parser::AnsiSequence;
3 3
     use ansi_parser::{AnsiParser, Output};
4 4
 
5
-    extern crate regex;
6
-    use regex::Regex;
7
-
8
-    const COLOR_CODE_REGEX: &str = r"(?-u)\u{1b}\[[\d|;]+m";
9
-
10 5
     pub fn cleanup(line: &str) -> String {
11
-        let color_code_regexp = Regex::new(COLOR_CODE_REGEX).unwrap();
12
-        let line = color_code_regexp.replace_all(line, "");
13
-        String::from(line)
6
+        let parsed: Vec<Output> = line.ansi_parse().collect();
7
+        let mut s = String::new();
8
+
9
+        for p in parsed {
10
+            match p {
11
+                Output::TextBlock(text) => {
12
+                    let clean_text = glib::markup_escape_text(&text);
13
+                    s.push_str(&clean_text)
14
+                }
15
+                _ => s.push_str(""),
16
+            }
17
+        }
18
+        s
14 19
     }
15 20
 
16 21
     pub fn colorize(line: &str) -> String {
17 22
         let parsed: Vec<Output> = line.ansi_parse().collect();
18 23
 
19 24
         let mut s = String::new();
25
+        let mut span_opened = 0;
26
+
20 27
         for p in parsed {
21 28
             match p {
22 29
                 Output::Escape(AnsiSequence::SetGraphicsMode(colors)) => {
23 30
                     if colors.len() == 1 {
24 31
                         s.push_str("");
25
-                    } else {
32
+                    } else if colors[0] == 38 {
26 33
                         let color = colors.last().unwrap();
34
+                        span_opened += 1;
27 35
                         s.push_str(&format!(
28 36
                             "<span foreground={:?}>",
29 37
                             ansi_color_to_hex(*color)
30 38
                         ))
39
+                    } else {
40
+                        let color = colors.last().unwrap();
41
+                        span_opened += 1;
42
+                        s.push_str(&format!(
43
+                            "<span background={:?}>",
44
+                            ansi_color_to_hex(*color)
45
+                        ))
31 46
                     }
32 47
                 }
33 48
                 Output::TextBlock(text) => {
34
-                    if s.ends_with('>') {
35
-                        s.push_str(&format!("{}</span>", text))
49
+                    let clean_text = glib::markup_escape_text(&text);
50
+                    if span_opened > 0 {
51
+                        let spans = "</span>".repeat(span_opened);
52
+                        span_opened = 0;
53
+                        s.push_str(&format!("{}{}", clean_text, spans))
36 54
                     } else {
37
-                        s.push_str(text)
55
+                        s.push_str(&clean_text)
38 56
                     }
39 57
                 }
40 58
                 _ => s.push_str("something else"),
@@ -45,6 +63,8 @@ pub mod colors {
45 63
 
46 64
     fn ansi_color_to_hex(color: u32) -> &'static str {
47 65
         match color {
66
+            7  => "#dadada",
67
+            8  => "#6c6c6c",
48 68
             10 => "#00ff00",
49 69
             11 => "#ffff00",
50 70
             12 => "#0000ff",
@@ -291,7 +311,7 @@ pub mod colors {
291 311
             253 => "#dadada",
292 312
             254 => "#e4e4e4",
293 313
             255 => "#eeeeee",
294
-            _ => "#00ff00",
314
+            _ => "#000000",
295 315
         }
296 316
     }
297 317
 }

+ 3
- 3
src/gemini/parser.rs View File

@@ -26,10 +26,10 @@ impl FromStr for TextElement {
26 26
         } else if line.starts_with("##") {
27 27
             let text = line.split_at(2).1.trim();
28 28
             Ok(TextElement::H2(String::from(text)))
29
-        } else if line.starts_with("#") {
29
+        } else if line.starts_with('#') {
30 30
             let text = line.split_at(1).1.trim();
31 31
             Ok(TextElement::H1(String::from(text)))
32
-        } else if line.starts_with("*") {
32
+        } else if line.starts_with('*') {
33 33
             let text = line.split_at(1).1.trim();
34 34
             Ok(TextElement::ListItem(String::from(text)))
35 35
         } else if line.starts_with("=>") {
@@ -37,7 +37,7 @@ impl FromStr for TextElement {
37 37
         } else if line.starts_with("```") {
38 38
             let text = line.split_at(3).1.trim();
39 39
             Ok(TextElement::MonoText(String::from(text)))
40
-        } else if line.starts_with(">") {
40
+        } else if line.starts_with('>') {
41 41
             let text = line.split_at(1).1.trim();
42 42
             Ok(TextElement::Quote(String::from(text)))
43 43
         } else {

Loading…
Cancel
Save