diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-03 11:44:53 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-03 13:35:39 +0100 |
| commit | 37a7afddfaffd44cb9bc013c9506599267e08983 (patch) | |
| tree | 20e7d62d3c5418baff01a21d0406b91bf3096214 /src/library/text/link.rs | |
| parent | 56342bd972a13ffe21beaf2b87ab7eb1597704b4 (diff) | |
Split crates
Diffstat (limited to 'src/library/text/link.rs')
| -rw-r--r-- | src/library/text/link.rs | 114 |
1 files changed, 0 insertions, 114 deletions
diff --git a/src/library/text/link.rs b/src/library/text/link.rs deleted file mode 100644 index 1e9adc3e..00000000 --- a/src/library/text/link.rs +++ /dev/null @@ -1,114 +0,0 @@ -use super::TextNode; -use crate::library::prelude::*; - -/// Link text and other elements to a destination. -#[derive(Debug, Hash)] -pub struct LinkNode { - /// The destination the link points to. - pub dest: Destination, - /// How the link is represented. - pub body: Option<Content>, -} - -impl LinkNode { - /// Create a link node from a URL with its bare text. - pub fn from_url(url: EcoString) -> Self { - Self { dest: Destination::Url(url), body: None } - } -} - -#[node(Show)] -impl LinkNode { - /// The fill color of text in the link. Just the surrounding text color - /// if `auto`. - pub const FILL: Smart<Paint> = Smart::Auto; - /// Whether to underline the link. - pub const UNDERLINE: Smart<bool> = Smart::Auto; - - fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { - let dest = args.expect::<Destination>("destination")?; - let body = match dest { - Destination::Url(_) => args.eat()?, - Destination::Internal(_) => Some(args.expect("body")?), - }; - Ok(Self { dest, body }.pack()) - } -} - -castable! { - Destination, - Expected: "string or dictionary with `page`, `x`, and `y` keys", - Value::Str(string) => Self::Url(string.into()), - Value::Dict(dict) => { - let page = dict.get("page")?.clone().cast()?; - let x: Length = dict.get("x")?.clone().cast()?; - let y: Length = dict.get("y")?.clone().cast()?; - Self::Internal(Location { page, pos: Point::new(x.abs, y.abs) }) - }, -} - -impl Show for LinkNode { - fn unguard_parts(&self, sel: Selector) -> Content { - Self { - dest: self.dest.clone(), - body: self.body.as_ref().map(|body| body.unguard(sel)), - } - .pack() - } - - fn field(&self, name: &str) -> Option<Value> { - match name { - "url" => Some(match &self.dest { - Destination::Url(url) => Value::Str(url.clone().into()), - Destination::Internal(loc) => Value::Dict(loc.encode()), - }), - "body" => Some(match &self.body { - Some(body) => Value::Content(body.clone()), - None => Value::None, - }), - _ => None, - } - } - - fn realize(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { - Ok(self - .body - .clone() - .unwrap_or_else(|| match &self.dest { - Destination::Url(url) => { - let mut text = url.as_str(); - for prefix in ["mailto:", "tel:"] { - text = text.trim_start_matches(prefix); - } - let shorter = text.len() < url.len(); - TextNode(if shorter { text.into() } else { url.clone() }).pack() - } - Destination::Internal(_) => Content::empty(), - }) - .styled(TextNode::LINK, Some(self.dest.clone()))) - } - - fn finalize( - &self, - _: Tracked<dyn World>, - styles: StyleChain, - mut realized: Content, - ) -> SourceResult<Content> { - let mut map = StyleMap::new(); - if let Smart::Custom(fill) = styles.get(Self::FILL) { - map.set(TextNode::FILL, fill); - } - - if match styles.get(Self::UNDERLINE) { - Smart::Auto => match &self.dest { - Destination::Url(_) => true, - Destination::Internal(_) => false, - }, - Smart::Custom(underline) => underline, - } { - realized = realized.underlined(); - } - - Ok(realized.styled_with_map(map)) - } -} |
