diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-10-17 17:35:15 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-10-23 20:24:35 +0200 |
| commit | b42ecbd6a67d6af42f06c52c290d88e176cee0ea (patch) | |
| tree | 578e983db4ebfc259fdd109f79c92a7f22b7dd8b /src/eval | |
| parent | 5becb32ba463d6b0ace914ab06bb237483a94fbc (diff) | |
Simplify decorations
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/template.rs | 77 | ||||
| -rw-r--r-- | src/eval/walk.rs | 1 |
2 files changed, 34 insertions, 44 deletions
diff --git a/src/eval/template.rs b/src/eval/template.rs index 11ea3f56..fe3d0cca 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -22,7 +22,7 @@ pub struct Template(Rc<Vec<TemplateNode>>); #[derive(Clone)] enum TemplateNode { /// A word space. - Space(Vec<Decoration>), + Space, /// A line break. Linebreak, /// A paragraph break. @@ -30,11 +30,13 @@ enum TemplateNode { /// A page break. Pagebreak(bool), /// Plain text. - Text(EcoString, Vec<Decoration>), + Text(EcoString), /// Spacing. Spacing(GenAxis, Linear), + /// A decorated template. + Decorated(Decoration, Template), /// An inline node builder. - Inline(Rc<dyn Fn(&Style) -> InlineNode>, Vec<Decoration>), + Inline(Rc<dyn Fn(&Style) -> InlineNode>), /// An block node builder. Block(Rc<dyn Fn(&Style) -> BlockNode>), /// Save the current style. @@ -57,7 +59,7 @@ impl Template { F: Fn(&Style) -> T + 'static, T: Into<InlineNode>, { - let node = TemplateNode::Inline(Rc::new(move |s| f(s).into()), vec![]); + let node = TemplateNode::Inline(Rc::new(move |s| f(s).into())); Self(Rc::new(vec![node])) } @@ -73,7 +75,7 @@ impl Template { /// Add a word space to the template. pub fn space(&mut self) { - self.make_mut().push(TemplateNode::Space(vec![])); + self.make_mut().push(TemplateNode::Space); } /// Add a line break to the template. @@ -93,7 +95,7 @@ impl Template { /// Add text to the template. pub fn text(&mut self, text: impl Into<EcoString>) { - self.make_mut().push(TemplateNode::Text(text.into(), vec![])); + self.make_mut().push(TemplateNode::Text(text.into())); } /// Add text, but in monospace. @@ -109,19 +111,6 @@ impl Template { self.make_mut().push(TemplateNode::Spacing(axis, spacing)); } - /// Add a decoration to all contained nodes. - pub fn decorate(&mut self, deco: Decoration) { - for node in self.make_mut() { - let decos = match node { - TemplateNode::Space(decos) => decos, - TemplateNode::Text(_, decos) => decos, - TemplateNode::Inline(_, decos) => decos, - _ => continue, - }; - decos.push(deco.clone()); - } - } - /// Register a restorable snapshot. pub fn save(&mut self) { self.make_mut().push(TemplateNode::Save); @@ -154,6 +143,11 @@ impl Template { wrapper } + /// Add a decoration to all contained nodes. + pub fn decorate(self, deco: Decoration) -> Self { + Self(Rc::new(vec![TemplateNode::Decorated(deco, self)])) + } + /// Build the stack node resulting from instantiating the template with the /// given style. pub fn to_stack(&self, style: &Style) -> StackNode { @@ -223,7 +217,7 @@ impl Add<Str> for Template { type Output = Self; fn add(mut self, rhs: Str) -> Self::Output { - Rc::make_mut(&mut self.0).push(TemplateNode::Text(rhs.into(), vec![])); + Rc::make_mut(&mut self.0).push(TemplateNode::Text(rhs.into())); self } } @@ -232,7 +226,7 @@ impl Add<Template> for Str { type Output = Template; fn add(self, mut rhs: Template) -> Self::Output { - Rc::make_mut(&mut rhs.0).insert(0, TemplateNode::Text(self.into(), vec![])); + Rc::make_mut(&mut rhs.0).insert(0, TemplateNode::Text(self.into())); rhs } } @@ -283,26 +277,31 @@ impl Builder { self.pagebreak(true, false); } } - TemplateNode::Space(decos) => self.space(decos), + TemplateNode::Space => self.space(), TemplateNode::Linebreak => self.linebreak(), TemplateNode::Parbreak => self.parbreak(), TemplateNode::Pagebreak(keep) => self.pagebreak(*keep, true), - TemplateNode::Text(text, decos) => self.text(text, decos), + TemplateNode::Text(text) => self.text(text), TemplateNode::Spacing(axis, amount) => self.spacing(*axis, *amount), - TemplateNode::Inline(f, decos) => self.inline(f(&self.style), decos), + TemplateNode::Decorated(deco, template) => { + self.stack.par.push(ParChild::Decorate(deco.clone())); + self.template(template); + self.stack.par.push(ParChild::Undecorate); + } + TemplateNode::Inline(f) => self.inline(f(&self.style)), TemplateNode::Block(f) => self.block(f(&self.style)), TemplateNode::Modify(f) => f(&mut self.style), } } /// Push a word space into the active paragraph. - fn space(&mut self, decos: &[Decoration]) { - self.stack.par.push_soft(self.make_text_node(' ', decos.to_vec())); + fn space(&mut self) { + self.stack.par.push_soft(self.make_text_node(' ')); } /// Apply a forced line break. fn linebreak(&mut self) { - self.stack.par.push_hard(self.make_text_node('\n', vec![])); + self.stack.par.push_hard(self.make_text_node('\n')); } /// Apply a forced paragraph break. @@ -322,14 +321,14 @@ impl Builder { } /// Push text into the active paragraph. - fn text(&mut self, text: impl Into<EcoString>, decos: &[Decoration]) { - self.stack.par.push(self.make_text_node(text, decos.to_vec())); + fn text(&mut self, text: impl Into<EcoString>) { + self.stack.par.push(self.make_text_node(text)); } /// Push an inline node into the active paragraph. - fn inline(&mut self, node: impl Into<InlineNode>, decos: &[Decoration]) { + fn inline(&mut self, node: impl Into<InlineNode>) { let align = self.style.aligns.inline; - self.stack.par.push(ParChild::Any(node.into(), align, decos.to_vec())); + self.stack.par.push(ParChild::Any(node.into(), align)); } /// Push a block node into the active stack, finishing the active paragraph. @@ -367,16 +366,11 @@ impl Builder { /// Construct a text node with the given text and settings from the current /// style. - fn make_text_node( - &self, - text: impl Into<EcoString>, - decos: Vec<Decoration>, - ) -> ParChild { + fn make_text_node(&self, text: impl Into<EcoString>) -> ParChild { ParChild::Text( text.into(), self.style.aligns.inline, Rc::clone(&self.style.text), - decos, ) } } @@ -489,14 +483,11 @@ impl ParBuilder { } fn push_inner(&mut self, child: ParChild) { - if let ParChild::Text(curr_text, curr_align, curr_props, curr_decos) = &child { - if let Some(ParChild::Text(prev_text, prev_align, prev_props, prev_decos)) = + if let ParChild::Text(curr_text, curr_align, curr_props) = &child { + if let Some(ParChild::Text(prev_text, prev_align, prev_props)) = self.children.last_mut() { - if prev_align == curr_align - && Rc::ptr_eq(prev_props, curr_props) - && curr_decos == prev_decos - { + if prev_align == curr_align && Rc::ptr_eq(prev_props, curr_props) { prev_text.push_str(&curr_text); return; } diff --git a/src/eval/walk.rs b/src/eval/walk.rs index 2f44f5df..6ac30150 100644 --- a/src/eval/walk.rs +++ b/src/eval/walk.rs @@ -113,7 +113,6 @@ fn walk_item(ctx: &mut EvalContext, label: Str, body: Template) { (&label).into(), style.aligns.inline, Rc::clone(&style.text), - vec![], )], }; StackNode { |
