mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 16:45:27 +00:00
separate Reference impl
This commit is contained in:
parent
df419181e6
commit
22c50161af
2 changed files with 80 additions and 54 deletions
|
|
@ -2,6 +2,7 @@ mod ansi;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod gutter;
|
mod gutter;
|
||||||
mod icon;
|
mod icon;
|
||||||
|
mod reference;
|
||||||
mod syntax;
|
mod syntax;
|
||||||
mod tag;
|
mod tag;
|
||||||
|
|
||||||
|
|
@ -13,11 +14,12 @@ use gtk::{
|
||||||
UriLauncher, Window, WrapMode,
|
UriLauncher, Window, WrapMode,
|
||||||
gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY, BUTTON_SECONDARY, RGBA},
|
gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY, BUTTON_SECONDARY, RGBA},
|
||||||
gio::{Cancellable, SimpleAction, SimpleActionGroup},
|
gio::{Cancellable, SimpleAction, SimpleActionGroup},
|
||||||
glib::{Uri, UriFlags, uuid_string_random},
|
glib::{Uri, uuid_string_random},
|
||||||
prelude::{PopoverExt, TextBufferExt, TextBufferExtManual, TextTagExt, TextViewExt, WidgetExt},
|
prelude::{PopoverExt, TextBufferExt, TextBufferExtManual, TextTagExt, TextViewExt, WidgetExt},
|
||||||
};
|
};
|
||||||
use gutter::Gutter;
|
use gutter::Gutter;
|
||||||
use icon::Icon;
|
use icon::Icon;
|
||||||
|
use reference::Reference;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use sourceview::prelude::{ActionExt, ActionMapExt, DisplayExt, ToVariant};
|
use sourceview::prelude::{ActionExt, ActionMapExt, DisplayExt, ToVariant};
|
||||||
use std::{cell::Cell, collections::HashMap, rc::Rc};
|
use std::{cell::Cell, collections::HashMap, rc::Rc};
|
||||||
|
|
@ -569,7 +571,7 @@ fn link(
|
||||||
buffer.set_text("");
|
buffer.set_text("");
|
||||||
|
|
||||||
let mut last_pos = 0;
|
let mut last_pos = 0;
|
||||||
for cap in Regex::new(r"(?P<is_img>!?)\[(?P<text>[^\]]+)\]\((?P<url>[^\)]+)\)")
|
for cap in Regex::new(r"(?P<is_img>!)\[(?P<text>[^\]]+)\]\((?P<url>[^\)]+)\)")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.captures_iter(&full_content)
|
.captures_iter(&full_content)
|
||||||
{
|
{
|
||||||
|
|
@ -578,59 +580,30 @@ fn link(
|
||||||
if !before.is_empty() {
|
if !before.is_empty() {
|
||||||
buffer.insert(&mut buffer.end_iter(), before);
|
buffer.insert(&mut buffer.end_iter(), before);
|
||||||
}
|
}
|
||||||
// Relative scheme patch
|
match Reference::parse(
|
||||||
// https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
|
&cap["url"],
|
||||||
let unresolved_url = match cap["url"].strip_prefix("//") {
|
if cap["text"].is_empty() {
|
||||||
Some(p) => {
|
None
|
||||||
let s = p.trim_start_matches(":");
|
} else {
|
||||||
&format!(
|
Some(&cap["text"])
|
||||||
"{}://{}",
|
|
||||||
base.scheme(),
|
|
||||||
if s.is_empty() {
|
|
||||||
format!("{}/", base.host().unwrap_or_default())
|
|
||||||
} else {
|
|
||||||
s.into()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => &cap["url"],
|
|
||||||
};
|
|
||||||
// Convert address to the valid URI,
|
|
||||||
// resolve to absolute URL format if the target is relative
|
|
||||||
match Uri::resolve_relative(Some(&base.to_string()), unresolved_url, UriFlags::NONE) {
|
|
||||||
Ok(url) => match Uri::parse(&url, UriFlags::NONE) {
|
|
||||||
Ok(uri) => {
|
|
||||||
let alt = {
|
|
||||||
let mut a: Vec<&str> = Vec::with_capacity(2);
|
|
||||||
if uri.scheme() != base.scheme() {
|
|
||||||
a.push("⇖");
|
|
||||||
}
|
|
||||||
if cap["text"].is_empty() {
|
|
||||||
a.push(&cap["url"]);
|
|
||||||
} else {
|
|
||||||
a.push(&cap["text"]);
|
|
||||||
}
|
|
||||||
a.join(" ")
|
|
||||||
};
|
|
||||||
|
|
||||||
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(), &alt, &[&a]);
|
|
||||||
links.insert(a, uri);
|
|
||||||
}
|
|
||||||
Err(_) => todo!(),
|
|
||||||
},
|
},
|
||||||
Err(_) => continue,
|
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,
|
||||||
}
|
}
|
||||||
last_pos = full_match.end();
|
last_pos = full_match.end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
use gtk::glib::{Uri, UriFlags};
|
||||||
|
|
||||||
|
pub struct Reference {
|
||||||
|
pub uri: Uri,
|
||||||
|
pub alt: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Reference {
|
||||||
|
pub fn parse(address: &str, alt: Option<&str>, base: &Uri) -> Option<Self> {
|
||||||
|
// Convert address to the valid URI,
|
||||||
|
// resolve to absolute URL format if the target is relative
|
||||||
|
match Uri::resolve_relative(
|
||||||
|
Some(&base.to_string()),
|
||||||
|
// Relative scheme patch
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
|
||||||
|
&match address.strip_prefix("//") {
|
||||||
|
Some(p) => {
|
||||||
|
let s = p.trim_start_matches(":");
|
||||||
|
format!(
|
||||||
|
"{}://{}",
|
||||||
|
base.scheme(),
|
||||||
|
if s.is_empty() {
|
||||||
|
format!("{}/", base.host().unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
s.into()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => String::new(),
|
||||||
|
},
|
||||||
|
UriFlags::NONE,
|
||||||
|
) {
|
||||||
|
Ok(ref url) => match Uri::parse(url, UriFlags::NONE) {
|
||||||
|
Ok(uri) => {
|
||||||
|
let mut a: Vec<&str> = Vec::with_capacity(2);
|
||||||
|
if uri.scheme() != base.scheme() {
|
||||||
|
a.push("⇖");
|
||||||
|
}
|
||||||
|
match alt {
|
||||||
|
Some(text) => a.push(text),
|
||||||
|
None => a.push(url),
|
||||||
|
}
|
||||||
|
Some(Self {
|
||||||
|
uri,
|
||||||
|
alt: a.join(" "),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(_) => todo!(),
|
||||||
|
},
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue