From 0cc9c694380d5248f54ff3f4e757f24e30c17258 Mon Sep 17 00:00:00 2001 From: yggverse Date: Mon, 9 Mar 2026 18:22:46 +0200 Subject: [PATCH] implement code highlight and ansi features for the `preformatted` tag --- .../tab/item/page/content/text/markdown.rs | 96 +------ .../item/page/content/text/markdown/error.rs | 3 - .../item/page/content/text/markdown/tags.rs | 6 +- .../page/content/text/markdown/tags/bold.rs | 12 +- .../page/content/text/markdown/tags/pre.rs | 42 ++- .../text/markdown/{ => tags/pre}/ansi.rs | 0 .../text/markdown/tags/pre/ansi/rgba.rs | 256 ++++++++++++++++++ .../text/markdown/tags/pre/ansi/tag.rs | 29 ++ .../text/markdown/{ => tags/pre}/syntax.rs | 0 .../markdown/{ => tags/pre}/syntax/error.rs | 0 .../markdown/{ => tags/pre}/syntax/tag.rs | 0 .../content/text/markdown/tags/reference.rs | 12 +- .../page/content/text/markdown/tags/strike.rs | 12 +- .../content/text/markdown/tags/underline.rs | 12 +- 14 files changed, 329 insertions(+), 151 deletions(-) delete mode 100644 src/app/browser/window/tab/item/page/content/text/markdown/error.rs rename src/app/browser/window/tab/item/page/content/text/markdown/{ => tags/pre}/ansi.rs (100%) create mode 100644 src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/rgba.rs create mode 100644 src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/tag.rs rename src/app/browser/window/tab/item/page/content/text/markdown/{ => tags/pre}/syntax.rs (100%) rename src/app/browser/window/tab/item/page/content/text/markdown/{ => tags/pre}/syntax/error.rs (100%) rename src/app/browser/window/tab/item/page/content/text/markdown/{ => tags/pre}/syntax/tag.rs (100%) diff --git a/src/app/browser/window/tab/item/page/content/text/markdown.rs b/src/app/browser/window/tab/item/page/content/text/markdown.rs index 78a7df54..ebcaf16e 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown.rs @@ -1,7 +1,4 @@ -mod ansi; -pub mod error; mod gutter; -mod syntax; mod tags; use super::{ItemAction, WindowAction}; @@ -17,7 +14,6 @@ use gtk::{ use gutter::Gutter; use sourceview::prelude::{ActionExt, ActionMapExt, DisplayExt, ToVariant}; use std::{cell::Cell, collections::HashMap, rc::Rc}; -use syntax::Syntax; use tags::Tags; pub struct Markdown { @@ -51,9 +47,6 @@ impl Markdown { RGBA::new(0.208, 0.518, 0.894, 0.9), ); - // Init syntect highlight features - let syntax = Syntax::new(); - // Init tags let mut tags = Tags::new(); @@ -81,94 +74,7 @@ impl Markdown { let gutter = Gutter::build(&text_view); // Render markdown tags - let title = tags.render(&buffer, &base, &link_color.0, &mut links); - - // Parse single-line markdown tags - /*'l: for line in markdown.lines() { - if is_code_enabled { - use ggemtext::line::Code; - match code { - None => { - // Open tag found - if let Some(c) = Code::begin_from(line) { - // Begin next lines collection into the code buffer - code = Some(c); - - // Skip other actions for this line - continue; - } - } - Some(ref mut c) => { - match c.continue_from(line) { - Ok(()) => { - // Close tag found: - if c.is_completed { - // Is alt provided - let alt = match c.alt { - Some(ref alt) => { - // Insert alt value to the main buffer - buffer.insert_with_tags( - &mut buffer.end_iter(), - alt.as_str(), - &[&tag.title], - ); - - // Append new line after alt text - buffer.insert(&mut buffer.end_iter(), NEW_LINE); - - // Return value as wanted also for syntax highlight detection - Some(alt) - } - None => None, - }; - - // Begin code block construction - // Try auto-detect code syntax for given `value` and `alt` @TODO optional - match syntax.highlight(&c.value, alt) { - Ok(highlight) => { - for (syntax_tag, entity) in highlight { - // Register new tag - if !tag.text_tag_table.add(&syntax_tag) { - todo!() - } - // Append tag to buffer - buffer.insert_with_tags( - &mut buffer.end_iter(), - &entity, - &[&syntax_tag], - ); - } - } - Err(_) => { - // Try ANSI/SGR format (terminal emulation) @TODO optional - for (syntax_tag, entity) in ansi::format(&c.value) { - // Register new tag - if !tag.text_tag_table.add(&syntax_tag) { - todo!() - } - // Append tag to buffer - buffer.insert_with_tags( - &mut buffer.end_iter(), - &entity, - &[&syntax_tag], - ); - } - } // @TODO handle - } - - // Reset - code = None; - } - - // Skip other actions for this line - continue; - } - Err(_) => todo!(), - } - } - } - } - }*/ + let title = tags.render(&buffer, base, &link_color.0, &mut links); // Context menu let action_link_tab = diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/error.rs b/src/app/browser/window/tab/item/page/content/text/markdown/error.rs deleted file mode 100644 index e2b6650a..00000000 --- a/src/app/browser/window/tab/item/page/content/text/markdown/error.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub enum Error { - Markup(String, super::Markdown), -} diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags.rs index 779c236d..30829775 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/tags.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags.rs @@ -62,9 +62,9 @@ impl Tags { self.strike.render(buffer); self.underline.render(buffer); - reference::render_images_links(&buffer, base, &link_color, links); - reference::render_images(&buffer, base, &link_color, links); - reference::render_links(&buffer, base, &link_color, links); + reference::render_images_links(buffer, base, link_color, links); + reference::render_images(buffer, base, link_color, links); + reference::render_links(buffer, base, link_color, links); self.pre.render(buffer); diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/bold.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/bold.rs index 8060c6ad..a1f04579 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/tags/bold.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/bold.rs @@ -43,11 +43,7 @@ impl Bold { pub fn strip_tags(value: &str) -> String { let mut result = String::from(value); - for cap in Regex::new(REGEX_BOLD) - .unwrap() - .captures_iter(&value) - .into_iter() - { + for cap in Regex::new(REGEX_BOLD).unwrap().captures_iter(value) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } @@ -59,11 +55,7 @@ pub fn strip_tags(value: &str) -> String { fn test_strip_tags() { const VALUE: &str = r"Some **bold 1** and **bold 2** with ![img](https://link.com)"; let mut result = String::from(VALUE); - for cap in Regex::new(REGEX_BOLD) - .unwrap() - .captures_iter(VALUE) - .into_iter() - { + for cap in Regex::new(REGEX_BOLD).unwrap().captures_iter(VALUE) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre.rs index dd0df5c0..2f7e47d1 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre.rs @@ -1,11 +1,14 @@ +mod ansi; +mod syntax; + use gtk::{ - TextBuffer, TextSearchFlags, TextTag, - WrapMode::Word, + TextBuffer, TextSearchFlags, TextTag, WrapMode, glib::{GString, uuid_string_random}, prelude::{TextBufferExt, TextBufferExtManual}, }; use regex::Regex; use std::collections::HashMap; +use syntax::Syntax; const REGEX_PRE: &str = r"(?s)```[ \t]*(?P.*?)\n(?P.*?)```"; @@ -16,14 +19,19 @@ struct Entry { pub struct Pre { index: HashMap, - tag: TextTag, + alt: TextTag, } impl Pre { pub fn new() -> Self { Self { index: HashMap::new(), - tag: TextTag::builder().wrap_mode(Word).build(), // @TODO + alt: TextTag::builder() + .pixels_above_lines(4) + .pixels_below_lines(8) + .weight(500) + .wrap_mode(WrapMode::None) + .build(), } } @@ -67,7 +75,8 @@ impl Pre { /// Apply preformatted `Tag` to given `TextBuffer` using `Self.index` pub fn render(&mut self, buffer: &TextBuffer) { - assert!(buffer.tag_table().add(&self.tag)); + let syntax = Syntax::new(); + assert!(buffer.tag_table().add(&self.alt)); for (k, v) in self.index.iter() { while let Some((mut m_start, mut m_end)) = buffer @@ -75,11 +84,24 @@ impl Pre { .forward_search(k, TextSearchFlags::VISIBLE_ONLY, None) { buffer.delete(&mut m_start, &mut m_end); - - let alt_text = v.alt.as_deref().unwrap_or(""); - let display_text = format!("{} |\n {}", alt_text, v.data); - - buffer.insert_with_tags(&mut m_start, &display_text, &[&self.tag]); + if let Some(ref alt) = v.alt { + buffer.insert_with_tags(&mut m_start, &format!("{alt}\n"), &[&self.alt]) + } + match syntax.highlight(&v.data, v.alt.as_ref()) { + Ok(highlight) => { + for (syntax_tag, entity) in highlight { + assert!(buffer.tag_table().add(&syntax_tag)); + buffer.insert_with_tags(&mut m_start, &entity, &[&syntax_tag]) + } + } + Err(_) => { + // Try ANSI/SGR format (terminal emulation) @TODO optional + for (syntax_tag, entity) in ansi::format(&v.data) { + assert!(buffer.tag_table().add(&syntax_tag)); + buffer.insert_with_tags(&mut m_start, &entity, &[&syntax_tag]) + } + } + } } } } diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/ansi.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi.rs similarity index 100% rename from src/app/browser/window/tab/item/page/content/text/markdown/ansi.rs rename to src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi.rs diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/rgba.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/rgba.rs new file mode 100644 index 00000000..d1398d2f --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/rgba.rs @@ -0,0 +1,256 @@ +use gtk::gdk::RGBA; + +/// Default RGBa palette for ANSI terminal emulation +pub fn default(color: u8) -> Option { + match color { + 7 => Some(RGBA::new(0.854, 0.854, 0.854, 1.0)), + 8 => Some(RGBA::new(0.424, 0.424, 0.424, 1.0)), + 10 => Some(RGBA::new(0.0, 1.0, 0.0, 1.0)), + 11 => Some(RGBA::new(1.0, 1.0, 0.0, 1.0)), + 12 => Some(RGBA::new(0.0, 0.0, 1.0, 1.0)), + 13 => Some(RGBA::new(1.0, 0.0, 1.0, 1.0)), + 14 => Some(RGBA::new(0.0, 1.0, 1.0, 1.0)), + 15 => Some(RGBA::new(1.0, 1.0, 1.0, 1.0)), + 16 => Some(RGBA::new(0.0, 0.0, 0.0, 1.0)), + 17 => Some(RGBA::new(0.0, 0.020, 0.373, 1.0)), + 18 => Some(RGBA::new(0.0, 0.031, 0.529, 1.0)), + 19 => Some(RGBA::new(0.0, 0.0, 0.686, 1.0)), + 20 => Some(RGBA::new(0.0, 0.0, 0.823, 1.0)), + 21 => Some(RGBA::new(0.0, 0.0, 1.0, 1.0)), + 22 => Some(RGBA::new(0.0, 0.373, 0.0, 1.0)), + 23 => Some(RGBA::new(0.0, 0.373, 0.373, 1.0)), + 24 => Some(RGBA::new(0.0, 0.373, 0.529, 1.0)), + 25 => Some(RGBA::new(0.0, 0.373, 0.686, 1.0)), + 26 => Some(RGBA::new(0.0, 0.373, 0.823, 1.0)), + 27 => Some(RGBA::new(0.0, 0.373, 1.0, 1.0)), + 28 => Some(RGBA::new(0.0, 0.533, 0.0, 1.0)), + 29 => Some(RGBA::new(0.0, 0.533, 0.373, 1.0)), + 30 => Some(RGBA::new(0.0, 0.533, 0.533, 1.0)), + 31 => Some(RGBA::new(0.0, 0.533, 0.686, 1.0)), + 32 => Some(RGBA::new(0.0, 0.533, 0.823, 1.0)), + 33 => Some(RGBA::new(0.0, 0.533, 1.0, 1.0)), + 34 => Some(RGBA::new(0.039, 0.686, 0.0, 1.0)), + 35 => Some(RGBA::new(0.039, 0.686, 0.373, 1.0)), + 36 => Some(RGBA::new(0.039, 0.686, 0.529, 1.0)), + 37 => Some(RGBA::new(0.039, 0.686, 0.686, 1.0)), + 38 => Some(RGBA::new(0.039, 0.686, 0.823, 1.0)), + 39 => Some(RGBA::new(0.039, 0.686, 1.0, 1.0)), + 40 => Some(RGBA::new(0.0, 0.843, 0.0, 1.0)), + 41 => Some(RGBA::new(0.0, 0.843, 0.373, 1.0)), + 42 => Some(RGBA::new(0.0, 0.843, 0.529, 1.0)), + 43 => Some(RGBA::new(0.0, 0.843, 0.686, 1.0)), + 44 => Some(RGBA::new(0.0, 0.843, 0.843, 1.0)), + 45 => Some(RGBA::new(0.0, 0.843, 1.0, 1.0)), + 46 => Some(RGBA::new(0.0, 1.0, 0.0, 1.0)), + 47 => Some(RGBA::new(0.0, 1.0, 0.373, 1.0)), + 48 => Some(RGBA::new(0.0, 1.0, 0.529, 1.0)), + 49 => Some(RGBA::new(0.0, 1.0, 0.686, 1.0)), + 50 => Some(RGBA::new(0.0, 1.0, 0.843, 1.0)), + 51 => Some(RGBA::new(0.0, 1.0, 1.0, 1.0)), + 52 => Some(RGBA::new(0.373, 0.0, 0.0, 1.0)), + 53 => Some(RGBA::new(0.373, 0.0, 0.373, 1.0)), + 54 => Some(RGBA::new(0.373, 0.0, 0.529, 1.0)), + 55 => Some(RGBA::new(0.373, 0.0, 0.686, 1.0)), + 56 => Some(RGBA::new(0.373, 0.0, 0.843, 1.0)), + 57 => Some(RGBA::new(0.373, 0.0, 1.0, 1.0)), + 58 => Some(RGBA::new(0.373, 0.373, 0.0, 1.0)), + 59 => Some(RGBA::new(0.373, 0.373, 0.373, 1.0)), + 60 => Some(RGBA::new(0.373, 0.373, 0.529, 1.0)), + 61 => Some(RGBA::new(0.373, 0.373, 0.686, 1.0)), + 62 => Some(RGBA::new(0.373, 0.373, 0.843, 1.0)), + 63 => Some(RGBA::new(0.373, 0.373, 1.0, 1.0)), + 64 => Some(RGBA::new(0.373, 0.529, 0.0, 1.0)), + 65 => Some(RGBA::new(0.373, 0.529, 0.373, 1.0)), + 66 => Some(RGBA::new(0.373, 0.529, 0.529, 1.0)), + 67 => Some(RGBA::new(0.373, 0.529, 0.686, 1.0)), + 68 => Some(RGBA::new(0.373, 0.529, 0.843, 1.0)), + 69 => Some(RGBA::new(0.373, 0.529, 1.0, 1.0)), + 70 => Some(RGBA::new(0.373, 0.686, 0.0, 1.0)), + 71 => Some(RGBA::new(0.373, 0.686, 0.373, 1.0)), + 72 => Some(RGBA::new(0.373, 0.686, 0.529, 1.0)), + 73 => Some(RGBA::new(0.373, 0.686, 0.686, 1.0)), + 74 => Some(RGBA::new(0.373, 0.686, 0.843, 1.0)), + 75 => Some(RGBA::new(0.373, 0.686, 1.0, 1.0)), + 76 => Some(RGBA::new(0.373, 0.843, 0.0, 1.0)), + 77 => Some(RGBA::new(0.373, 0.843, 0.373, 1.0)), + 78 => Some(RGBA::new(0.373, 0.843, 0.529, 1.0)), + 79 => Some(RGBA::new(0.373, 0.843, 0.686, 1.0)), + 80 => Some(RGBA::new(0.373, 0.843, 0.843, 1.0)), + 81 => Some(RGBA::new(0.373, 0.843, 1.0, 1.0)), + 82 => Some(RGBA::new(0.373, 1.0, 0.0, 1.0)), + 83 => Some(RGBA::new(0.373, 1.0, 0.373, 1.0)), + 84 => Some(RGBA::new(0.373, 1.0, 0.529, 1.0)), + 85 => Some(RGBA::new(0.373, 1.0, 0.686, 1.0)), + 86 => Some(RGBA::new(0.373, 1.0, 0.843, 1.0)), + 87 => Some(RGBA::new(0.373, 1.0, 1.0, 1.0)), + 88 => Some(RGBA::new(0.529, 0.0, 0.0, 1.0)), + 89 => Some(RGBA::new(0.529, 0.0, 0.373, 1.0)), + 90 => Some(RGBA::new(0.529, 0.0, 0.529, 1.0)), + 91 => Some(RGBA::new(0.529, 0.0, 0.686, 1.0)), + 92 => Some(RGBA::new(0.529, 0.0, 0.843, 1.0)), + 93 => Some(RGBA::new(0.529, 0.0, 1.0, 1.0)), + 94 => Some(RGBA::new(0.529, 0.373, 0.0, 1.0)), + 95 => Some(RGBA::new(0.529, 0.373, 0.373, 1.0)), + 96 => Some(RGBA::new(0.529, 0.373, 0.529, 1.0)), + 97 => Some(RGBA::new(0.529, 0.373, 0.686, 1.0)), + 98 => Some(RGBA::new(0.529, 0.373, 0.843, 1.0)), + 99 => Some(RGBA::new(0.529, 0.373, 1.0, 1.0)), + 100 => Some(RGBA::new(0.529, 0.529, 0.0, 1.0)), + 101 => Some(RGBA::new(0.529, 0.529, 0.373, 1.0)), + 102 => Some(RGBA::new(0.529, 0.529, 0.529, 1.0)), + 103 => Some(RGBA::new(0.529, 0.529, 0.686, 1.0)), + 104 => Some(RGBA::new(0.529, 0.529, 0.843, 1.0)), + 105 => Some(RGBA::new(0.529, 0.529, 1.0, 1.0)), + 106 => Some(RGBA::new(0.533, 0.686, 0.0, 1.0)), + 107 => Some(RGBA::new(0.533, 0.686, 0.373, 1.0)), + 108 => Some(RGBA::new(0.533, 0.686, 0.529, 1.0)), + 109 => Some(RGBA::new(0.533, 0.686, 0.686, 1.0)), + 110 => Some(RGBA::new(0.533, 0.686, 0.843, 1.0)), + 111 => Some(RGBA::new(0.533, 0.686, 1.0, 1.0)), + 112 => Some(RGBA::new(0.533, 0.843, 0.0, 1.0)), + 113 => Some(RGBA::new(0.533, 0.843, 0.373, 1.0)), + 114 => Some(RGBA::new(0.533, 0.843, 0.529, 1.0)), + 115 => Some(RGBA::new(0.533, 0.843, 0.686, 1.0)), + 116 => Some(RGBA::new(0.533, 0.843, 0.843, 1.0)), + 117 => Some(RGBA::new(0.533, 0.843, 1.0, 1.0)), + 118 => Some(RGBA::new(0.533, 1.0, 0.0, 1.0)), + 119 => Some(RGBA::new(0.533, 1.0, 0.373, 1.0)), + 120 => Some(RGBA::new(0.533, 1.0, 0.529, 1.0)), + 121 => Some(RGBA::new(0.533, 1.0, 0.686, 1.0)), + 122 => Some(RGBA::new(0.533, 1.0, 0.843, 1.0)), + 123 => Some(RGBA::new(0.533, 1.0, 1.0, 1.0)), + 124 => Some(RGBA::new(0.686, 0.0, 0.0, 1.0)), + 125 => Some(RGBA::new(0.686, 0.0, 0.373, 1.0)), + 126 => Some(RGBA::new(0.686, 0.0, 0.529, 1.0)), + 127 => Some(RGBA::new(0.686, 0.0, 0.686, 1.0)), + 128 => Some(RGBA::new(0.686, 0.0, 0.843, 1.0)), + 129 => Some(RGBA::new(0.686, 0.0, 1.0, 1.0)), + 130 => Some(RGBA::new(0.686, 0.373, 0.0, 1.0)), + 131 => Some(RGBA::new(0.686, 0.373, 0.373, 1.0)), + 132 => Some(RGBA::new(0.686, 0.373, 0.529, 1.0)), + 133 => Some(RGBA::new(0.686, 0.373, 0.686, 1.0)), + 134 => Some(RGBA::new(0.686, 0.373, 0.843, 1.0)), + 135 => Some(RGBA::new(0.686, 0.373, 1.0, 1.0)), + 136 => Some(RGBA::new(0.686, 0.529, 0.0, 1.0)), + 137 => Some(RGBA::new(0.686, 0.529, 0.373, 1.0)), + 138 => Some(RGBA::new(0.686, 0.529, 0.529, 1.0)), + 139 => Some(RGBA::new(0.686, 0.529, 0.686, 1.0)), + 140 => Some(RGBA::new(0.686, 0.529, 0.843, 1.0)), + 141 => Some(RGBA::new(0.686, 0.529, 1.0, 1.0)), + 142 => Some(RGBA::new(0.686, 0.686, 0.0, 1.0)), + 143 => Some(RGBA::new(0.686, 0.686, 0.373, 1.0)), + 144 => Some(RGBA::new(0.686, 0.686, 0.529, 1.0)), + 145 => Some(RGBA::new(0.686, 0.686, 0.686, 1.0)), + 146 => Some(RGBA::new(0.686, 0.686, 0.843, 1.0)), + 147 => Some(RGBA::new(0.686, 0.686, 1.0, 1.0)), + 148 => Some(RGBA::new(0.686, 0.843, 0.0, 1.0)), + 149 => Some(RGBA::new(0.686, 0.843, 0.373, 1.0)), + 150 => Some(RGBA::new(0.686, 0.843, 0.529, 1.0)), + 151 => Some(RGBA::new(0.686, 0.843, 0.686, 1.0)), + 152 => Some(RGBA::new(0.686, 0.843, 0.843, 1.0)), + 153 => Some(RGBA::new(0.686, 0.843, 1.0, 1.0)), + 154 => Some(RGBA::new(0.686, 1.0, 0.0, 1.0)), + 155 => Some(RGBA::new(0.686, 1.0, 0.373, 1.0)), + 156 => Some(RGBA::new(0.686, 1.0, 0.529, 1.0)), + 157 => Some(RGBA::new(0.686, 1.0, 0.686, 1.0)), + 158 => Some(RGBA::new(0.686, 1.0, 0.843, 1.0)), + 159 => Some(RGBA::new(0.686, 1.0, 1.0, 1.0)), + 160 => Some(RGBA::new(0.847, 0.0, 0.0, 1.0)), + 161 => Some(RGBA::new(0.847, 0.0, 0.373, 1.0)), + 162 => Some(RGBA::new(0.847, 0.0, 0.529, 1.0)), + 163 => Some(RGBA::new(0.847, 0.0, 0.686, 1.0)), + 164 => Some(RGBA::new(0.847, 0.0, 0.843, 1.0)), + 165 => Some(RGBA::new(0.847, 0.0, 1.0, 1.0)), + 166 => Some(RGBA::new(0.847, 0.373, 0.0, 1.0)), + 167 => Some(RGBA::new(0.847, 0.373, 0.373, 1.0)), + 168 => Some(RGBA::new(0.847, 0.373, 0.529, 1.0)), + 169 => Some(RGBA::new(0.847, 0.373, 0.686, 1.0)), + 170 => Some(RGBA::new(0.847, 0.373, 0.843, 1.0)), + 171 => Some(RGBA::new(0.847, 0.373, 1.0, 1.0)), + 172 => Some(RGBA::new(0.847, 0.529, 0.0, 1.0)), + 173 => Some(RGBA::new(0.847, 0.529, 0.373, 1.0)), + 174 => Some(RGBA::new(0.847, 0.529, 0.529, 1.0)), + 175 => Some(RGBA::new(0.847, 0.529, 0.686, 1.0)), + 176 => Some(RGBA::new(0.847, 0.529, 0.843, 1.0)), + 177 => Some(RGBA::new(0.847, 0.529, 1.0, 1.0)), + 178 => Some(RGBA::new(0.847, 0.686, 0.0, 1.0)), + 179 => Some(RGBA::new(0.847, 0.686, 0.373, 1.0)), + 180 => Some(RGBA::new(0.847, 0.686, 0.529, 1.0)), + 181 => Some(RGBA::new(0.847, 0.686, 0.686, 1.0)), + 182 => Some(RGBA::new(0.847, 0.686, 0.843, 1.0)), + 183 => Some(RGBA::new(0.847, 0.686, 1.0, 1.0)), + 184 => Some(RGBA::new(0.847, 0.843, 0.0, 1.0)), + 185 => Some(RGBA::new(0.847, 0.843, 0.373, 1.0)), + 186 => Some(RGBA::new(0.847, 0.843, 0.529, 1.0)), + 187 => Some(RGBA::new(0.847, 0.843, 0.686, 1.0)), + 188 => Some(RGBA::new(0.847, 0.843, 0.843, 1.0)), + 189 => Some(RGBA::new(0.847, 0.843, 1.0, 1.0)), + 190 => Some(RGBA::new(0.847, 1.0, 0.0, 1.0)), + 191 => Some(RGBA::new(0.847, 1.0, 0.373, 1.0)), + 192 => Some(RGBA::new(0.847, 1.0, 0.529, 1.0)), + 193 => Some(RGBA::new(0.847, 1.0, 0.686, 1.0)), + 194 => Some(RGBA::new(0.847, 1.0, 0.843, 1.0)), + 195 => Some(RGBA::new(0.847, 1.0, 1.0, 1.0)), + 196 => Some(RGBA::new(1.0, 0.0, 0.0, 1.0)), + 197 => Some(RGBA::new(1.0, 0.0, 0.373, 1.0)), + 198 => Some(RGBA::new(1.0, 0.0, 0.529, 1.0)), + 199 => Some(RGBA::new(1.0, 0.0, 0.686, 1.0)), + 200 => Some(RGBA::new(1.0, 0.0, 0.843, 1.0)), + 201 => Some(RGBA::new(1.0, 0.0, 1.0, 1.0)), + 202 => Some(RGBA::new(1.0, 0.373, 0.0, 1.0)), + 203 => Some(RGBA::new(1.0, 0.373, 0.373, 1.0)), + 204 => Some(RGBA::new(1.0, 0.373, 0.529, 1.0)), + 205 => Some(RGBA::new(1.0, 0.373, 0.686, 1.0)), + 206 => Some(RGBA::new(1.0, 0.373, 0.843, 1.0)), + 207 => Some(RGBA::new(1.0, 0.373, 1.0, 1.0)), + 208 => Some(RGBA::new(1.0, 0.529, 0.0, 1.0)), + 209 => Some(RGBA::new(1.0, 0.529, 0.373, 1.0)), + 210 => Some(RGBA::new(1.0, 0.529, 0.529, 1.0)), + 211 => Some(RGBA::new(1.0, 0.529, 0.686, 1.0)), + 212 => Some(RGBA::new(1.0, 0.529, 0.843, 1.0)), + 213 => Some(RGBA::new(1.0, 0.529, 1.0, 1.0)), + 214 => Some(RGBA::new(1.0, 0.686, 0.0, 1.0)), + 215 => Some(RGBA::new(1.0, 0.686, 0.373, 1.0)), + 216 => Some(RGBA::new(1.0, 0.686, 0.529, 1.0)), + 217 => Some(RGBA::new(1.0, 0.686, 0.686, 1.0)), + 218 => Some(RGBA::new(1.0, 0.686, 0.843, 1.0)), + 219 => Some(RGBA::new(1.0, 0.686, 1.0, 1.0)), + 220 => Some(RGBA::new(1.0, 0.843, 0.0, 1.0)), + 221 => Some(RGBA::new(1.0, 0.843, 0.373, 1.0)), + 222 => Some(RGBA::new(1.0, 0.843, 0.529, 1.0)), + 223 => Some(RGBA::new(1.0, 0.843, 0.686, 1.0)), + 224 => Some(RGBA::new(1.0, 0.843, 0.843, 1.0)), + 225 => Some(RGBA::new(1.0, 0.843, 1.0, 1.0)), + 226 => Some(RGBA::new(1.0, 1.0, 0.0, 1.0)), + 227 => Some(RGBA::new(1.0, 1.0, 0.373, 1.0)), + 228 => Some(RGBA::new(1.0, 1.0, 0.529, 1.0)), + 229 => Some(RGBA::new(1.0, 1.0, 0.686, 1.0)), + 230 => Some(RGBA::new(1.0, 1.0, 0.843, 1.0)), + 231 => Some(RGBA::new(1.0, 1.0, 1.0, 1.0)), + 232 => Some(RGBA::new(0.031, 0.031, 0.031, 1.0)), + 233 => Some(RGBA::new(0.071, 0.071, 0.071, 1.0)), + 234 => Some(RGBA::new(0.110, 0.110, 0.110, 1.0)), + 235 => Some(RGBA::new(0.149, 0.149, 0.149, 1.0)), + 236 => Some(RGBA::new(0.188, 0.188, 0.188, 1.0)), + 237 => Some(RGBA::new(0.227, 0.227, 0.227, 1.0)), + 238 => Some(RGBA::new(0.267, 0.267, 0.267, 1.0)), + 239 => Some(RGBA::new(0.306, 0.306, 0.306, 1.0)), + 240 => Some(RGBA::new(0.345, 0.345, 0.345, 1.0)), + 241 => Some(RGBA::new(0.384, 0.384, 0.384, 1.0)), + 242 => Some(RGBA::new(0.424, 0.424, 0.424, 1.0)), + 243 => Some(RGBA::new(0.462, 0.462, 0.462, 1.0)), + 244 => Some(RGBA::new(0.502, 0.502, 0.502, 1.0)), + 245 => Some(RGBA::new(0.541, 0.541, 0.541, 1.0)), + 246 => Some(RGBA::new(0.580, 0.580, 0.580, 1.0)), + 247 => Some(RGBA::new(0.620, 0.620, 0.620, 1.0)), + 248 => Some(RGBA::new(0.659, 0.659, 0.659, 1.0)), + 249 => Some(RGBA::new(0.694, 0.694, 0.694, 1.0)), + 250 => Some(RGBA::new(0.733, 0.733, 0.733, 1.0)), + 251 => Some(RGBA::new(0.777, 0.777, 0.777, 1.0)), + 252 => Some(RGBA::new(0.816, 0.816, 0.816, 1.0)), + 253 => Some(RGBA::new(0.855, 0.855, 0.855, 1.0)), + 254 => Some(RGBA::new(0.890, 0.890, 0.890, 1.0)), + 255 => Some(RGBA::new(0.933, 0.933, 0.933, 1.0)), + _ => None, + } +} diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/tag.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/tag.rs new file mode 100644 index 00000000..7154b1f3 --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/ansi/tag.rs @@ -0,0 +1,29 @@ +use gtk::{TextTag, WrapMode}; + +/// Default [TextTag](https://docs.gtk.org/gtk4/class.TextTag.html) preset +/// for ANSI buffer +pub struct Tag { + pub text_tag: TextTag, +} + +impl Default for Tag { + fn default() -> Self { + Self::new() + } +} + +impl Tag { + // Constructors + + /// Create new `Self` + pub fn new() -> Self { + Self { + text_tag: TextTag::builder() + .family("monospace") // @TODO + .left_margin(28) + .scale(0.81) // * the rounded `0.8` value crops text for some reason @TODO + .wrap_mode(WrapMode::None) + .build(), + } + } +} diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/syntax.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/syntax.rs similarity index 100% rename from src/app/browser/window/tab/item/page/content/text/markdown/syntax.rs rename to src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/syntax.rs diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/syntax/error.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/syntax/error.rs similarity index 100% rename from src/app/browser/window/tab/item/page/content/text/markdown/syntax/error.rs rename to src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/syntax/error.rs diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/syntax/tag.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/syntax/tag.rs similarity index 100% rename from src/app/browser/window/tab/item/page/content/text/markdown/syntax/tag.rs rename to src/app/browser/window/tab/item/page/content/text/markdown/tags/pre/syntax/tag.rs diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/reference.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/reference.rs index 5ee0eaaa..c7b828e6 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/tags/reference.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/reference.rs @@ -223,11 +223,7 @@ pub fn render_links( pub fn strip_tags(value: &str) -> String { let mut result = String::from(value); - for cap in Regex::new(REGEX_LINK) - .unwrap() - .captures_iter(&value) - .into_iter() - { + for cap in Regex::new(REGEX_LINK).unwrap().captures_iter(value) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } @@ -239,11 +235,7 @@ pub fn strip_tags(value: &str) -> String { fn test_strip_tags() { const VALUE: &str = r"Some text [link1](https://link1.com) [link2](https://link2.com)"; let mut result = String::from(VALUE); - for cap in Regex::new(REGEX_LINK) - .unwrap() - .captures_iter(VALUE) - .into_iter() - { + for cap in Regex::new(REGEX_LINK).unwrap().captures_iter(VALUE) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/strike.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/strike.rs index 406ee80b..1ec48f7c 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/tags/strike.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/strike.rs @@ -48,11 +48,7 @@ impl Strike { pub fn strip_tags(value: &str) -> String { let mut result = String::from(value); - for cap in Regex::new(REGEX_STRIKE) - .unwrap() - .captures_iter(&value) - .into_iter() - { + for cap in Regex::new(REGEX_STRIKE).unwrap().captures_iter(value) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } @@ -64,11 +60,7 @@ pub fn strip_tags(value: &str) -> String { fn test_strip_tags() { const VALUE: &str = r"Some ~~strike 1~~ and ~~strike 2~~ with ![img](https://link.com)"; let mut result = String::from(VALUE); - for cap in Regex::new(REGEX_STRIKE) - .unwrap() - .captures_iter(VALUE) - .into_iter() - { + for cap in Regex::new(REGEX_STRIKE).unwrap().captures_iter(VALUE) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/tags/underline.rs b/src/app/browser/window/tab/item/page/content/text/markdown/tags/underline.rs index 0b04115e..8f8f25e2 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/tags/underline.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/tags/underline.rs @@ -44,11 +44,7 @@ impl Underline { pub fn strip_tags(value: &str) -> String { let mut result = String::from(value); - for cap in Regex::new(REGEX_UNDERLINE) - .unwrap() - .captures_iter(&value) - .into_iter() - { + for cap in Regex::new(REGEX_UNDERLINE).unwrap().captures_iter(value) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); } @@ -60,11 +56,7 @@ pub fn strip_tags(value: &str) -> String { fn test_strip_tags() { const VALUE: &str = r"Some _underline 1_ and _underline 2_ with ![img](https://link.com)"; let mut result = String::from(VALUE); - for cap in Regex::new(REGEX_UNDERLINE) - .unwrap() - .captures_iter(VALUE) - .into_iter() - { + for cap in Regex::new(REGEX_UNDERLINE).unwrap().captures_iter(VALUE) { if let Some(m) = cap.get(0) { result = result.replace(m.as_str(), &cap["text"]); }