diff options
Diffstat (limited to 'library')
| -rw-r--r-- | library/src/layout/page.rs | 2 | ||||
| -rw-r--r-- | library/src/math/mod.rs | 17 | ||||
| -rw-r--r-- | library/src/prelude.rs | 4 | ||||
| -rw-r--r-- | library/src/structure/heading.rs | 18 | ||||
| -rw-r--r-- | library/src/structure/list.rs | 34 | ||||
| -rw-r--r-- | library/src/structure/reference.rs | 20 | ||||
| -rw-r--r-- | library/src/structure/table.rs | 24 | ||||
| -rw-r--r-- | library/src/text/deco.rs | 27 | ||||
| -rw-r--r-- | library/src/text/link.rs | 52 | ||||
| -rw-r--r-- | library/src/text/mod.rs | 44 | ||||
| -rw-r--r-- | library/src/text/raw.rs | 26 | ||||
| -rw-r--r-- | library/src/text/shift.rs | 16 |
12 files changed, 148 insertions, 136 deletions
diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs index e1af6ec5..c308571c 100644 --- a/library/src/layout/page.rs +++ b/library/src/layout/page.rs @@ -200,7 +200,7 @@ impl Cast<Spanned<Value>> for Marginal { fn cast(value: Spanned<Value>) -> StrResult<Self> { match value.v { Value::None => Ok(Self::None), - Value::Str(v) => Ok(Self::Content(TextNode(v.into()).pack())), + Value::Str(v) => Ok(Self::Content(TextNode::packed(v))), Value::Content(v) => Ok(Self::Content(v)), Value::Func(v) => Ok(Self::Func(v, value.span)), v => Err(format!( diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index dae869ed..0fad2939 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -18,7 +18,7 @@ pub struct MathNode { pub display: bool, } -#[node(Show, LayoutInline, Texify)] +#[node(Show, Finalize, LayoutInline, Texify)] impl MathNode { /// The math font family. #[property(referenced)] @@ -29,6 +29,13 @@ impl MathNode { /// The spacing below display math. #[property(resolve, shorthand(around))] pub const BELOW: Option<BlockSpacing> = Some(Ratio::one().into()); + + fn field(&self, name: &str) -> Option<Value> { + match name { + "display" => Some(Value::Bool(self.display)), + _ => None, + } + } } impl Show for MathNode { @@ -36,18 +43,16 @@ impl Show for MathNode { self.clone().pack() } - fn field(&self, _: &str) -> Option<Value> { - None - } - - fn realize(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { Ok(if self.display { self.clone().pack().aligned(Axes::with_x(Some(Align::Center.into()))) } else { self.clone().pack() }) } +} +impl Finalize for MathNode { fn finalize( &self, _: Tracked<dyn World>, diff --git a/library/src/prelude.rs b/library/src/prelude.rs index 11095c67..f51b826f 100644 --- a/library/src/prelude.rs +++ b/library/src/prelude.rs @@ -9,8 +9,8 @@ pub use typst::frame::*; pub use typst::geom::*; pub use typst::model::{ array, capability, castable, dict, dynamic, format_str, node, Args, Array, Cast, - Content, Dict, Fold, Func, Key, Node, Resolve, Scope, Selector, Show, Smart, Str, - StyleChain, StyleMap, StyleVec, Value, Vm, + Content, Dict, Finalize, Fold, Func, Key, Node, Resolve, Scope, Selector, Show, + Smart, Str, StyleChain, StyleMap, StyleVec, Value, Vm, }; pub use typst::syntax::{Span, Spanned}; pub use typst::util::{format_eco, EcoString}; diff --git a/library/src/structure/heading.rs b/library/src/structure/heading.rs index 62a67000..46e98c18 100644 --- a/library/src/structure/heading.rs +++ b/library/src/structure/heading.rs @@ -12,7 +12,7 @@ pub struct HeadingNode { pub body: Content, } -#[node(Show)] +#[node(Show, Finalize)] impl HeadingNode { /// The heading's font family. Just the normal text family if `auto`. #[property(referenced)] @@ -67,12 +67,6 @@ impl HeadingNode { } .pack()) } -} - -impl Show for HeadingNode { - fn unguard_parts(&self, sel: Selector) -> Content { - Self { body: self.body.unguard(sel), ..*self }.pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -81,11 +75,19 @@ impl Show for HeadingNode { _ => None, } } +} - fn realize(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { +impl Show for HeadingNode { + fn unguard_parts(&self, sel: Selector) -> Content { + Self { body: self.body.unguard(sel), ..*self }.pack() + } + + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { Ok(BlockNode(self.body.clone()).pack()) } +} +impl Finalize for HeadingNode { fn finalize( &self, world: Tracked<dyn World>, diff --git a/library/src/structure/list.rs b/library/src/structure/list.rs index a5e1380a..499207a4 100644 --- a/library/src/structure/list.rs +++ b/library/src/structure/list.rs @@ -22,7 +22,7 @@ pub type EnumNode = ListNode<ENUM>; /// A description list. pub type DescNode = ListNode<DESC>; -#[node(Show)] +#[node(Show, Finalize)] impl<const L: ListKind> ListNode<L> { /// How the list is labelled. #[property(referenced)] @@ -80,16 +80,6 @@ impl<const L: ListKind> ListNode<L> { } .pack()) } -} - -impl<const L: ListKind> Show for ListNode<L> { - fn unguard_parts(&self, sel: Selector) -> Content { - Self { - items: self.items.map(|item| item.unguard(sel)), - ..*self - } - .pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -101,8 +91,18 @@ impl<const L: ListKind> Show for ListNode<L> { _ => None, } } +} - fn realize( +impl<const L: ListKind> Show for ListNode<L> { + fn unguard_parts(&self, sel: Selector) -> Content { + Self { + items: self.items.map(|item| item.unguard(sel)), + ..*self + } + .pack() + } + + fn show( &self, world: Tracked<dyn World>, styles: StyleChain, @@ -140,7 +140,7 @@ impl<const L: ListKind> Show for ListNode<L> { ListItem::Enum(_, body) => body.as_ref().clone(), ListItem::Desc(item) => Content::sequence(vec![ HNode { amount: (-body_indent).into(), weak: false }.pack(), - (item.term.clone() + TextNode(':'.into()).pack()).strong(), + (item.term.clone() + TextNode::packed(':')).strong(), SpaceNode.pack(), item.body.clone(), ]), @@ -162,7 +162,9 @@ impl<const L: ListKind> Show for ListNode<L> { } .pack()) } +} +impl<const L: ListKind> Finalize for ListNode<L> { fn finalize( &self, _: Tracked<dyn World>, @@ -312,14 +314,14 @@ impl Label { ) -> SourceResult<Content> { Ok(match self { Self::Default => match kind { - LIST => TextNode('•'.into()).pack(), - ENUM => TextNode(format_eco!("{}.", number)).pack(), + LIST => TextNode::packed('•'), + ENUM => TextNode::packed(format_eco!("{}.", number)), DESC | _ => panic!("description lists don't have a label"), }, Self::Pattern(prefix, numbering, upper, suffix) => { let fmt = numbering.apply(number); let mid = if *upper { fmt.to_uppercase() } else { fmt.to_lowercase() }; - TextNode(format_eco!("{}{}{}", prefix, mid, suffix)).pack() + TextNode::packed(format_eco!("{}{}{}", prefix, mid, suffix)) } Self::Content(content) => content.clone(), Self::Func(func, span) => { diff --git a/library/src/structure/reference.rs b/library/src/structure/reference.rs index 56f8b8e3..18f4eecb 100644 --- a/library/src/structure/reference.rs +++ b/library/src/structure/reference.rs @@ -8,23 +8,23 @@ pub struct RefNode(pub EcoString); #[node(Show)] impl RefNode { fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { - Ok(Self(args.expect("label")?).pack()) - } -} - -impl Show for RefNode { - fn unguard_parts(&self, _: Selector) -> Content { - Self(self.0.clone()).pack() + Ok(Self(args.expect("target")?).pack()) } fn field(&self, name: &str) -> Option<Value> { match name { - "label" => Some(Value::Str(self.0.clone().into())), + "target" => Some(Value::Str(self.0.clone().into())), _ => None, } } +} + +impl Show for RefNode { + fn unguard_parts(&self, _: Selector) -> Content { + Self(self.0.clone()).pack() + } - fn realize(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { - Ok(TextNode(format_eco!("@{}", self.0)).pack()) + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { + Ok(TextNode::packed(format_eco!("@{}", self.0))) } } diff --git a/library/src/structure/table.rs b/library/src/structure/table.rs index 722f11e6..fbf1c7c0 100644 --- a/library/src/structure/table.rs +++ b/library/src/structure/table.rs @@ -12,7 +12,7 @@ pub struct TableNode { pub cells: Vec<Content>, } -#[node(Show)] +#[node(Show, Finalize)] impl TableNode { /// How to fill the cells. #[property(referenced)] @@ -46,6 +46,15 @@ impl TableNode { } .pack()) } + + fn field(&self, name: &str) -> Option<Value> { + match name { + "cells" => Some(Value::Array( + self.cells.iter().cloned().map(Value::Content).collect(), + )), + _ => None, + } + } } impl Show for TableNode { @@ -58,16 +67,7 @@ impl Show for TableNode { .pack() } - fn field(&self, name: &str) -> Option<Value> { - match name { - "cells" => Some(Value::Array( - self.cells.iter().cloned().map(Value::Content).collect(), - )), - _ => None, - } - } - - fn realize( + fn show( &self, world: Tracked<dyn World>, styles: StyleChain, @@ -106,7 +106,9 @@ impl Show for TableNode { } .pack()) } +} +impl Finalize for TableNode { fn finalize( &self, _: Tracked<dyn World>, diff --git a/library/src/text/deco.rs b/library/src/text/deco.rs index 10f3db38..fa0f05a7 100644 --- a/library/src/text/deco.rs +++ b/library/src/text/deco.rs @@ -37,12 +37,6 @@ impl<const L: DecoLine> DecoNode<L> { fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { Ok(Self(args.expect("body")?).pack()) } -} - -impl<const L: DecoLine> Show for DecoNode<L> { - fn unguard_parts(&self, sel: Selector) -> Content { - Self(self.0.unguard(sel)).pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -50,12 +44,14 @@ impl<const L: DecoLine> Show for DecoNode<L> { _ => None, } } +} + +impl<const L: DecoLine> Show for DecoNode<L> { + fn unguard_parts(&self, sel: Selector) -> Content { + Self(self.0.unguard(sel)).pack() + } - fn realize( - &self, - _: Tracked<dyn World>, - styles: StyleChain, - ) -> SourceResult<Content> { + fn show(&self, _: Tracked<dyn World>, styles: StyleChain) -> SourceResult<Content> { Ok(self.0.clone().styled( TextNode::DECO, Decoration { @@ -81,6 +77,15 @@ pub(super) struct Decoration { pub evade: bool, } +impl Fold for Decoration { + type Output = Vec<Self>; + + fn fold(self, mut outer: Self::Output) -> Self::Output { + outer.insert(0, self); + outer + } +} + /// A kind of decorative line. pub type DecoLine = usize; diff --git a/library/src/text/link.rs b/library/src/text/link.rs index 82abe5cd..4312559e 100644 --- a/library/src/text/link.rs +++ b/library/src/text/link.rs @@ -17,7 +17,7 @@ impl LinkNode { } } -#[node(Show)] +#[node(Show, Finalize)] impl LinkNode { /// The fill color of text in the link. Just the surrounding text color /// if `auto`. @@ -33,16 +33,6 @@ impl LinkNode { }; Ok(Self { dest, body }.pack()) } -} - -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 { @@ -57,25 +47,33 @@ impl Show for LinkNode { _ => None, } } +} + +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 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() + fn show(&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); } - Destination::Internal(_) => Content::empty(), - }) - .styled(TextNode::LINK, Some(self.dest.clone()))) + let shorter = text.len() < url.len(); + TextNode::packed(if shorter { text.into() } else { url.clone() }) + } + Destination::Internal(_) => Content::empty(), + })) } +} +impl Finalize for LinkNode { fn finalize( &self, _: Tracked<dyn World>, @@ -83,6 +81,8 @@ impl Show for LinkNode { mut realized: Content, ) -> SourceResult<Content> { let mut map = StyleMap::new(); + map.set(TextNode::LINK, Some(self.dest.clone())); + if let Smart::Custom(fill) = styles.get(Self::FILL) { map.set(TextNode::FILL, fill); } diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs index 6643f821..86c6884a 100644 --- a/library/src/text/mod.rs +++ b/library/src/text/mod.rs @@ -28,6 +28,13 @@ use crate::prelude::*; #[derive(Debug, Clone, Hash)] pub struct TextNode(pub EcoString); +impl TextNode { + /// Create a new packed text node. + pub fn packed(text: impl Into<EcoString>) -> Content { + Self(text.into()).pack() + } +} + #[node] impl TextNode { /// A prioritized sequence of font families. @@ -486,12 +493,6 @@ impl StrongNode { fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { Ok(Self(args.expect("body")?).pack()) } -} - -impl Show for StrongNode { - fn unguard_parts(&self, sel: Selector) -> Content { - Self(self.0.unguard(sel)).pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -499,8 +500,14 @@ impl Show for StrongNode { _ => None, } } +} + +impl Show for StrongNode { + fn unguard_parts(&self, sel: Selector) -> Content { + Self(self.0.unguard(sel)).pack() + } - fn realize(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { Ok(self.0.clone().styled(TextNode::BOLD, Toggle)) } } @@ -514,12 +521,6 @@ impl EmphNode { fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { Ok(Self(args.expect("body")?).pack()) } -} - -impl Show for EmphNode { - fn unguard_parts(&self, sel: Selector) -> Content { - Self(self.0.unguard(sel)).pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -527,8 +528,14 @@ impl Show for EmphNode { _ => None, } } +} + +impl Show for EmphNode { + fn unguard_parts(&self, sel: Selector) -> Content { + Self(self.0.unguard(sel)).pack() + } - fn realize(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { + fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> { Ok(self.0.clone().styled(TextNode::ITALIC, Toggle)) } } @@ -544,12 +551,3 @@ impl Fold for Toggle { !outer } } - -impl Fold for Decoration { - type Output = Vec<Self>; - - fn fold(self, mut outer: Self::Output) -> Self::Output { - outer.insert(0, self); - outer - } -} diff --git a/library/src/text/raw.rs b/library/src/text/raw.rs index 31f1517e..5a98cf3b 100644 --- a/library/src/text/raw.rs +++ b/library/src/text/raw.rs @@ -19,7 +19,7 @@ pub struct RawNode { pub block: bool, } -#[node(Show)] +#[node(Show, Finalize)] impl RawNode { /// The language to syntax-highlight in. #[property(referenced)] @@ -41,12 +41,6 @@ impl RawNode { } .pack()) } -} - -impl Show for RawNode { - fn unguard_parts(&self, _: Selector) -> Content { - Self { text: self.text.clone(), ..*self }.pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -55,12 +49,14 @@ impl Show for RawNode { _ => None, } } +} - fn realize( - &self, - _: Tracked<dyn World>, - styles: StyleChain, - ) -> SourceResult<Content> { +impl Show for RawNode { + fn unguard_parts(&self, _: Selector) -> Content { + Self { text: self.text.clone(), ..*self }.pack() + } + + fn show(&self, _: Tracked<dyn World>, styles: StyleChain) -> SourceResult<Content> { let lang = styles.get(Self::LANG).as_ref().map(|s| s.to_lowercase()); let foreground = THEME .settings @@ -100,7 +96,7 @@ impl Show for RawNode { Content::sequence(seq) } else { - TextNode(self.text.clone()).pack() + TextNode::packed(self.text.clone()) }; if self.block { @@ -114,7 +110,9 @@ impl Show for RawNode { Ok(realized.styled_with_map(map)) } +} +impl Finalize for RawNode { fn finalize( &self, _: Tracked<dyn World>, @@ -134,7 +132,7 @@ impl Show for RawNode { /// Style a piece of text with a syntect style. fn styled(piece: &str, foreground: Paint, style: Style) -> Content { - let mut body = TextNode(piece.into()).pack(); + let mut body = TextNode::packed(piece); let paint = style.foreground.into(); if paint != foreground { diff --git a/library/src/text/shift.rs b/library/src/text/shift.rs index 1117cc00..0f654b5a 100644 --- a/library/src/text/shift.rs +++ b/library/src/text/shift.rs @@ -33,12 +33,6 @@ impl<const S: ShiftKind> ShiftNode<S> { fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { Ok(Self(args.expect("body")?).pack()) } -} - -impl<const S: ShiftKind> Show for ShiftNode<S> { - fn unguard_parts(&self, _: Selector) -> Content { - Self(self.0.clone()).pack() - } fn field(&self, name: &str) -> Option<Value> { match name { @@ -46,8 +40,14 @@ impl<const S: ShiftKind> Show for ShiftNode<S> { _ => None, } } +} + +impl<const S: ShiftKind> Show for ShiftNode<S> { + fn unguard_parts(&self, _: Selector) -> Content { + Self(self.0.clone()).pack() + } - fn realize( + fn show( &self, world: Tracked<dyn World>, styles: StyleChain, @@ -56,7 +56,7 @@ impl<const S: ShiftKind> Show for ShiftNode<S> { if styles.get(Self::TYPOGRAPHIC) { if let Some(text) = search_text(&self.0, S) { if is_shapable(world, &text, styles) { - transformed = Some(TextNode(text).pack()); + transformed = Some(TextNode::packed(text)); } } }; |
