move regex logic, add annotation tag, add some tests

This commit is contained in:
yggverse 2026-03-08 20:44:46 +02:00
parent e61b6c400a
commit 5675809320

View file

@ -1,5 +1,10 @@
use gtk::glib::{Uri, UriFlags};
pub const REGEX_LINK: &str = r"\[(?P<text>[^\]]+)\]\((?P<url>[^\)]+)\)";
pub const REGEX_IMAGE_LINK: &str =
r"\[(?P<is_img>!)\[(?P<alt>[^\]]+)\]\((?P<img_url>[^\)]+)\)\]\((?P<link_url>[^\)]+)\)";
pub struct Reference {
pub uri: Uri,
pub alt: String,
@ -53,22 +58,74 @@ impl Reference {
pub fn into_buffer(
self,
buffer: &gtk::TextBuffer,
position: &mut gtk::TextIter,
link_color: &gtk::gdk::RGBA,
tag: &super::Tag,
is_annotation: bool,
links: &mut std::collections::HashMap<gtk::TextTag, Uri>,
) {
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");
}