diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-02-18 15:02:02 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-02-18 16:57:53 +0100 |
| commit | e01970b20a058ab1b4ebea916f229c9b706c84e4 (patch) | |
| tree | 5c5efc75abd6e607bd45a0602603231edf520503 /src/library | |
| parent | 05ec0f993b4a1b8481e494ee16285d23f000872f (diff) | |
Basic show rules
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/deco.rs | 22 | ||||
| -rw-r--r-- | src/library/heading.rs | 20 | ||||
| -rw-r--r-- | src/library/link.rs | 36 | ||||
| -rw-r--r-- | src/library/list.rs | 35 | ||||
| -rw-r--r-- | src/library/math.rs | 19 | ||||
| -rw-r--r-- | src/library/raw.rs | 14 | ||||
| -rw-r--r-- | src/library/table.rs | 16 | ||||
| -rw-r--r-- | src/library/text.rs | 12 |
8 files changed, 117 insertions, 57 deletions
diff --git a/src/library/deco.rs b/src/library/deco.rs index 79026288..aac79d05 100644 --- a/src/library/deco.rs +++ b/src/library/deco.rs @@ -32,15 +32,19 @@ impl<const L: DecoLine> DecoNode<L> { } impl<const L: DecoLine> Show for DecoNode<L> { - fn show(&self, _: &mut Vm, styles: StyleChain) -> TypResult<Template> { - Ok(self.0.clone().styled(TextNode::LINES, vec![Decoration { - line: L, - stroke: styles.get(Self::STROKE), - thickness: styles.get(Self::THICKNESS), - offset: styles.get(Self::OFFSET), - extent: styles.get(Self::EXTENT), - evade: styles.get(Self::EVADE), - }])) + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + Ok(styles + .show(self, vm, [Value::Template(self.0.clone())])? + .unwrap_or_else(|| { + self.0.clone().styled(TextNode::LINES, vec![Decoration { + line: L, + stroke: styles.get(Self::STROKE), + thickness: styles.get(Self::THICKNESS), + offset: styles.get(Self::OFFSET), + extent: styles.get(Self::EXTENT), + evade: styles.get(Self::EVADE), + }]) + })) } } diff --git a/src/library/heading.rs b/src/library/heading.rs index 1b8fcef9..49975655 100644 --- a/src/library/heading.rs +++ b/src/library/heading.rs @@ -34,6 +34,8 @@ impl HeadingNode { pub const ABOVE: Leveled<Length> = Leveled::Value(Length::zero()); /// The extra padding below the heading. pub const BELOW: Leveled<Length> = Leveled::Value(Length::zero()); + /// Whether the heading is block-level. + pub const BLOCK: Leveled<bool> = Leveled::Value(true); fn construct(_: &mut Vm, args: &mut Args) -> TypResult<Template> { Ok(Template::show(Self { @@ -51,6 +53,14 @@ impl Show for HeadingNode { }; } + // Resolve the user recipe. + let mut body = styles + .show(self, vm, [ + Value::Int(self.level as i64), + Value::Template(self.body.clone()), + ])? + .unwrap_or_else(|| self.body.clone()); + let mut map = StyleMap::new(); map.set(TextNode::SIZE, resolve!(Self::SIZE)); @@ -76,7 +86,6 @@ impl Show for HeadingNode { } let mut seq = vec![]; - let mut body = self.body.clone(); if resolve!(Self::UNDERLINE) { body = body.underlined(); } @@ -93,9 +102,12 @@ impl Show for HeadingNode { seq.push(Template::Vertical(below.into())); } - Ok(Template::block( - Template::sequence(seq).styled_with_map(map), - )) + let mut template = Template::sequence(seq).styled_with_map(map); + if resolve!(Self::BLOCK) { + template = Template::block(template); + } + + Ok(template) } } diff --git a/src/library/link.rs b/src/library/link.rs index 95fff089..41209549 100644 --- a/src/library/link.rs +++ b/src/library/link.rs @@ -10,7 +10,7 @@ pub struct LinkNode { /// The url the link points to. pub url: EcoString, /// How the link is represented. - pub body: Template, + pub body: Option<Template>, } #[class] @@ -22,22 +22,31 @@ impl LinkNode { pub const UNDERLINE: bool = true; fn construct(_: &mut Vm, args: &mut Args) -> TypResult<Template> { - let url = args.expect::<EcoString>("url")?; - let body = args.find()?.unwrap_or_else(|| { - 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() }) - }); - - Ok(Template::show(Self { url, body })) + Ok(Template::show(Self { + url: args.expect::<EcoString>("url")?, + body: args.find()?, + })) } } impl Show for LinkNode { - fn show(&self, _: &mut Vm, styles: StyleChain) -> TypResult<Template> { + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + let mut body = styles + .show(self, vm, [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())); @@ -45,7 +54,6 @@ impl Show for LinkNode { map.set(TextNode::FILL, fill); } - let mut body = self.body.clone(); if styles.get(Self::UNDERLINE) { body = body.underlined(); } diff --git a/src/library/list.rs b/src/library/list.rs index 13f21a04..37dda843 100644 --- a/src/library/list.rs +++ b/src/library/list.rs @@ -8,13 +8,13 @@ use crate::parse::Scanner; /// An unordered or ordered list. #[derive(Debug, Hash)] pub struct ListNode<const L: ListKind> { - /// The individual bulleted or numbered items. - pub items: Vec<ListItem>, + /// Where the list starts. + pub start: usize, /// If true, there is paragraph spacing between the items, if false /// there is list spacing between the items. pub wide: bool, - /// Where the list starts. - pub start: usize, + /// The individual bulleted or numbered items. + pub items: Vec<ListItem>, } /// An item in a list. @@ -23,7 +23,7 @@ pub struct ListItem { /// The number of the item. pub number: Option<usize>, /// The node that produces the item's body. - pub body: LayoutNode, + pub body: Box<Template>, } #[class] @@ -39,19 +39,27 @@ impl<const L: ListKind> ListNode<L> { fn construct(_: &mut Vm, args: &mut Args) -> TypResult<Template> { Ok(Template::show(Self { + start: args.named("start")?.unwrap_or(0), + wide: args.named("wide")?.unwrap_or(false), items: args .all()? .into_iter() - .map(|body| ListItem { number: None, body }) + .map(|body| ListItem { number: None, body: Box::new(body) }) .collect(), - wide: args.named("wide")?.unwrap_or(false), - start: args.named("start")?.unwrap_or(0), })) } } impl<const L: ListKind> Show for ListNode<L> { fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + if let Some(template) = styles.show( + self, + vm, + self.items.iter().map(|item| Value::Template((*item.body).clone())), + )? { + return Ok(template); + } + let mut children = vec![]; let mut number = self.start; @@ -66,7 +74,7 @@ impl<const L: ListKind> Show for ListNode<L> { children.push(LayoutNode::default()); children.push(label.resolve(vm, L, number)?.pack()); children.push(LayoutNode::default()); - children.push(item.body.clone()); + children.push((*item.body).clone().pack()); number += 1; } @@ -119,8 +127,6 @@ pub enum Label { Pattern(EcoString, Numbering, bool, EcoString), /// A bare template. Template(Template), - /// A simple mapping from an item number to a template. - Mapping(fn(usize) -> Template), /// A closure mapping from an item number to a value. Func(Func, Span), } @@ -144,10 +150,9 @@ impl Label { Template::Text(format_eco!("{}{}{}", prefix, mid, suffix)) } Self::Template(template) => template.clone(), - Self::Mapping(mapping) => mapping(number), - &Self::Func(ref func, span) => { - let args = Args::from_values(span, [Value::Int(number as i64)]); - func.call(vm, args)?.cast().at(span)? + Self::Func(func, span) => { + let args = Args::from_values(*span, [Value::Int(number as i64)]); + func.call(vm, args)?.cast().at(*span)? } }) } diff --git a/src/library/math.rs b/src/library/math.rs index d3c8b5e5..40a1990e 100644 --- a/src/library/math.rs +++ b/src/library/math.rs @@ -22,11 +22,18 @@ impl MathNode { } impl Show for MathNode { - fn show(&self, _: &mut Vm, _: StyleChain) -> TypResult<Template> { - let mut template = Template::Text(self.formula.trim().into()); - if self.display { - template = Template::Block(template.pack()); - } - Ok(template.monospaced()) + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + Ok(styles + .show(self, vm, [ + Value::Str(self.formula.clone()), + Value::Bool(self.display), + ])? + .unwrap_or_else(|| { + let mut template = Template::Text(self.formula.trim().into()); + if self.display { + template = Template::Block(template.pack()); + } + template.monospaced() + })) } } diff --git a/src/library/raw.rs b/src/library/raw.rs index da926679..bb4e2c96 100644 --- a/src/library/raw.rs +++ b/src/library/raw.rs @@ -40,8 +40,20 @@ impl RawNode { } impl Show for RawNode { - fn show(&self, _: &mut Vm, styles: StyleChain) -> TypResult<Template> { + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { let lang = styles.get_ref(Self::LANG).as_ref(); + + if let Some(template) = styles.show(self, vm, [ + Value::Str(self.text.clone()), + match lang { + Some(lang) => Value::Str(lang.clone()), + None => Value::None, + }, + Value::Bool(self.block), + ])? { + return Ok(template); + } + let foreground = THEME .settings .foreground diff --git a/src/library/table.rs b/src/library/table.rs index 8c088c09..f4de0f55 100644 --- a/src/library/table.rs +++ b/src/library/table.rs @@ -11,7 +11,7 @@ pub struct TableNode { /// Defines sizing of gutter rows and columns between content. pub gutter: Spec<Vec<TrackSizing>>, /// The nodes to be arranged in the table. - pub children: Vec<LayoutNode>, + pub children: Vec<Template>, } #[class] @@ -55,7 +55,15 @@ impl TableNode { } impl Show for TableNode { - fn show(&self, _: &mut Vm, styles: StyleChain) -> TypResult<Template> { + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + if let Some(template) = styles.show( + self, + vm, + self.children.iter().map(|child| Value::Template(child.clone())), + )? { + return Ok(template); + } + let primary = styles.get(Self::PRIMARY); let secondary = styles.get(Self::SECONDARY); let thickness = styles.get(Self::THICKNESS); @@ -68,8 +76,8 @@ impl Show for TableNode { .iter() .cloned() .enumerate() - .map(|(i, mut child)| { - child = child.padded(Sides::splat(padding)); + .map(|(i, child)| { + let mut child = child.pack().padded(Sides::splat(padding)); if let Some(stroke) = stroke { child = child.stroked(stroke); diff --git a/src/library/text.rs b/src/library/text.rs index 721a8eac..a67fbcf5 100644 --- a/src/library/text.rs +++ b/src/library/text.rs @@ -123,8 +123,10 @@ impl StrongNode { } impl Show for StrongNode { - fn show(&self, _: &mut Vm, _: StyleChain) -> TypResult<Template> { - Ok(self.0.clone().styled(TextNode::STRONG, true)) + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + Ok(styles + .show(self, vm, [Value::Template(self.0.clone())])? + .unwrap_or_else(|| self.0.clone().styled(TextNode::STRONG, true))) } } @@ -140,8 +142,10 @@ impl EmphNode { } impl Show for EmphNode { - fn show(&self, _: &mut Vm, _: StyleChain) -> TypResult<Template> { - Ok(self.0.clone().styled(TextNode::EMPH, true)) + fn show(&self, vm: &mut Vm, styles: StyleChain) -> TypResult<Template> { + Ok(styles + .show(self, vm, [Value::Template(self.0.clone())])? + .unwrap_or_else(|| self.0.clone().styled(TextNode::EMPH, true))) } } |
