summaryrefslogtreecommitdiff
path: root/src/library/text/link.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-02-28 15:50:48 +0100
committerLaurenz <laurmaedje@gmail.com>2022-02-28 23:54:34 +0100
commit3ca5b238238e1128aa7bbfbd5db9e632045d8600 (patch)
tree2471f4b340a15695b7f4d518c0b39fabaea676c4 /src/library/text/link.rs
parentb63c21c91d99a1554a019dc275f955d3e6a34271 (diff)
Reorganize library
Diffstat (limited to 'src/library/text/link.rs')
-rw-r--r--src/library/text/link.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/library/text/link.rs b/src/library/text/link.rs
new file mode 100644
index 00000000..29f41927
--- /dev/null
+++ b/src/library/text/link.rs
@@ -0,0 +1,64 @@
+use super::TextNode;
+use crate::library::prelude::*;
+use crate::util::EcoString;
+
+/// Link text and other elements to an URL.
+#[derive(Debug, Hash)]
+pub struct LinkNode {
+ /// The url the link points to.
+ pub url: EcoString,
+ /// How the link is represented.
+ pub body: Option<Template>,
+}
+
+#[class]
+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 link.
+ pub const UNDERLINE: bool = true;
+
+ fn construct(_: &mut Context, args: &mut Args) -> TypResult<Template> {
+ Ok(Template::show(Self {
+ url: args.expect::<EcoString>("url")?,
+ body: args.find()?,
+ }))
+ }
+}
+
+impl Show for LinkNode {
+ fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Template> {
+ let mut body = styles
+ .show(self, ctx, [
+ Value::Str(self.url.clone()),
+ match &self.body {
+ Some(body) => Value::Template(body.clone()),
+ None => Value::None,
+ },
+ ])?
+ .or_else(|| self.body.clone())
+ .unwrap_or_else(|| {
+ let url = &self.url;
+ let mut text = url.as_str();
+ for prefix in ["mailto:", "tel:"] {
+ text = text.trim_start_matches(prefix);
+ }
+ let shorter = text.len() < url.len();
+ Template::Text(if shorter { text.into() } else { url.clone() })
+ });
+
+ let mut map = StyleMap::new();
+ map.set(TextNode::LINK, Some(self.url.clone()));
+
+ if let Smart::Custom(fill) = styles.get(Self::FILL) {
+ map.set(TextNode::FILL, fill);
+ }
+
+ if styles.get(Self::UNDERLINE) {
+ body = body.underlined();
+ }
+
+ Ok(body.styled_with_map(map))
+ }
+}