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 f35952bd..d9c5583d 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 @@ -1,5 +1,10 @@ use gtk::glib::{Uri, UriFlags}; +pub const REGEX_LINK: &str = r"\[(?P[^\]]+)\]\((?P[^\)]+)\)"; + +pub const REGEX_IMAGE_LINK: &str = + r"\[(?P!)\[(?P[^\]]+)\]\((?P[^\)]+)\)\]\((?P[^\)]+)\)"; + pub struct Reference { pub uri: Uri, pub alt: String, @@ -53,22 +58,74 @@ impl Reference { pub fn into_buffer( self, buffer: >k::TextBuffer, + position: &mut gtk::TextIter, link_color: >k::gdk::RGBA, tag: &super::Tag, + is_annotation: bool, 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(); + use gtk::{TextTag, WrapMode, prelude::TextBufferExtManual}; + let a = if is_annotation { + buffer.insert_with_tags(position, " ", &[]); + TextTag::builder() + .foreground_rgba(link_color) + // .foreground_rgba(&adw::StyleManager::default().accent_color_rgba()) + // @TODO adw 1.6 / ubuntu 24.10+ + .pixels_above_lines(4) + .pixels_below_lines(4) + .rise(5000) + .scale(0.8) + .wrap_mode(WrapMode::Word) + .build() + } else { + 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(), &self.alt, &[&a]); + buffer.insert_with_tags(position, &self.alt, &[&a]); links.insert(a, self.uri); } } + +#[test] +fn test_regex_link() { + let cap: Vec<_> = regex::Regex::new(REGEX_LINK) + .unwrap() + .captures_iter(r#"[link1](https://link1.com) [link2](https://link2.com)"#) + .collect(); + + let first = cap.get(0).unwrap(); + assert_eq!(&first["text"], "link1"); + assert_eq!(&first["url"], "https://link1.com"); + + let second = cap.get(1).unwrap(); + assert_eq!(&second["text"], "link2"); + assert_eq!(&second["url"], "https://link2.com"); +} + +#[test] +fn test_regex_image_link() { + let cap: Vec<_> = regex::Regex::new( + REGEX_IMAGE_LINK, + ) + .unwrap().captures_iter( + r#"[![image1](https://image1.com)](https://image2.com) [![image3](https://image3.com)](https://image4.com)"# + ).collect(); + + let first = cap.get(0).unwrap(); + assert_eq!(&first["alt"], "image1"); + assert_eq!(&first["img_url"], "https://image1.com"); + assert_eq!(&first["link_url"], "https://image2.com"); + + let second = cap.get(1).unwrap(); + assert_eq!(&second["alt"], "image3"); + assert_eq!(&second["img_url"], "https://image3.com"); + assert_eq!(&second["link_url"], "https://image4.com"); +}