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 57c25fa4..9e4d211b 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 @@ -258,6 +258,7 @@ impl Markdown { // Parse in-line markdown tags + image_link(&buffer, &tag, base, &link_color.0, &mut links); link(&buffer, &tag, base, &link_color.0, &mut links); // Context menu @@ -556,6 +557,48 @@ fn link_prefix(request: String, prefix: &str) -> String { format!("{prefix}{}", request.trim_start_matches(prefix)) } +/// Link +fn image_link( + buffer: &TextBuffer, + tag: &Tag, + base: &Uri, + link_color: &RGBA, + links: &mut HashMap, +) { + let start_iter = buffer.start_iter(); + let end_iter = buffer.end_iter(); + let full_content = buffer.text(&start_iter, &end_iter, true).to_string(); + + buffer.set_text(""); + + let mut last_pos = 0; + for cap in Regex::new(r"(?P\[(?P!|)?\[(?P[^\]]+)\]\((?P[^\)]+)\)\]\((?P[^\)]+)\))") + .unwrap() + .captures_iter(&full_content) + { + let full_match = cap.get(0).unwrap(); + let before = &full_content[last_pos..full_match.start()]; + if !before.is_empty() { + buffer.insert(&mut buffer.end_iter(), before); + } + if let Some(link) = Reference::parse( + &cap["link_url"], + None, + base, + ) { + link.into_buffer(buffer, + link_color, + tag, + links) + } + last_pos = full_match.end(); + } + let after = &full_content[last_pos..]; + if !after.is_empty() { + buffer.insert(&mut buffer.end_iter(), after); + } +} + /// Link fn link( buffer: &TextBuffer, @@ -580,7 +623,7 @@ fn link( if !before.is_empty() { buffer.insert(&mut buffer.end_iter(), before); } - match Reference::parse( + if let Some(link) = Reference::parse( &cap["url"], if cap["text"].is_empty() { None @@ -589,21 +632,7 @@ fn link( }, base, ) { - Some(link) => { - let a = TextTag::builder() - .foreground_rgba(link_color) - // .foreground_rgba(&adw::StyleManager::default().accent_color_rgba()) - // @TODO adw 1.6 / ubuntu 24.10+ - .sentence(true) - .wrap_mode(WrapMode::Word) - .build(); - if !tag.text_tag_table.add(&a) { - panic!() - } - buffer.insert_with_tags(&mut buffer.end_iter(), &link.alt, &[&a]); - links.insert(a, link.uri); - } - None => continue, + link.into_buffer(buffer, link_color, tag, links) } last_pos = full_match.end(); } diff --git a/src/app/browser/window/tab/item/page/content/text/markdown/reference.rs b/src/app/browser/window/tab/item/page/content/text/markdown/reference.rs index 3ff177f3..eddd8db0 100644 --- a/src/app/browser/window/tab/item/page/content/text/markdown/reference.rs +++ b/src/app/browser/window/tab/item/page/content/text/markdown/reference.rs @@ -50,4 +50,25 @@ impl Reference { Err(_) => None, } } + pub fn into_buffer( + self, + buffer: >k::TextBuffer, + link_color: >k::gdk::RGBA, + tag: &super::Tag, + links: &mut std::collections::HashMap, + ) { + use gtk::prelude::{TextBufferExt, TextBufferExtManual}; + let a = gtk::TextTag::builder() + .foreground_rgba(link_color) + // .foreground_rgba(&adw::StyleManager::default().accent_color_rgba()) + // @TODO adw 1.6 / ubuntu 24.10+ + .sentence(true) + .wrap_mode(gtk::WrapMode::Word) + .build(); + if !tag.text_tag_table.add(&a) { + panic!() + } + buffer.insert_with_tags(&mut buffer.end_iter(), &self.alt, &[&a]); + links.insert(a, self.uri); + } }