diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-16 22:14:27 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-16 22:39:21 +0200 |
| commit | 30f16bbf6431ca0c174ca0a1abaa6a13ef50ab06 (patch) | |
| tree | f5a5c0adad15840ebe24b39e77ff467862067c91 /src/library/page.rs | |
| parent | 9f6137d8a829fe8f34554623495fa620252a0184 (diff) | |
Add Value type and replace dyn-nodes with call-exprs 🏗
- In addition to syntax trees there are now `Value`s, which syntax trees can be evaluated into (e.g. the tree is `5+5` and the value is `10`)
- Parsing is completely pure, function calls are not parsed into nodes, but into simple call expressions, which are resolved later
- Functions aren't dynamic nodes anymore, but simply functions which receive their arguments as a table and the layouting context
- Functions may return any `Value`
- Layouting is powered by functions which return the new `Commands` value, which informs the layouting engine what to do
- When a function returns a non-`Commands` value, the layouter simply dumps the value into the document in monospace
Diffstat (limited to 'src/library/page.rs')
| -rw-r--r-- | src/library/page.rs | 94 |
1 files changed, 31 insertions, 63 deletions
diff --git a/src/library/page.rs b/src/library/page.rs index 7e4e6e54..42f29dbb 100644 --- a/src/library/page.rs +++ b/src/library/page.rs @@ -16,78 +16,46 @@ use super::*; /// - `top`: The top margin (length or relative to height). /// - `bottom`: The bottom margin (length or relative to height). /// - `flip`: Flips custom or paper-defined width and height (boolean). -pub fn page(call: FuncCall, _: &ParseState) -> Pass<SyntaxNode> { +pub async fn page(mut args: TableValue, ctx: LayoutContext<'_>) -> Pass<Value> { let mut f = Feedback::new(); - let mut args = call.args; - let node = PageNode { - paper: args.take::<Paper>(), - width: args.take_with_key::<_, Length>("width", &mut f), - height: args.take_with_key::<_, Length>("height", &mut f), - margins: args.take_with_key::<_, ScaleLength>("margins", &mut f), - left: args.take_with_key::<_, ScaleLength>("left", &mut f), - right: args.take_with_key::<_, ScaleLength>("right", &mut f), - top: args.take_with_key::<_, ScaleLength>("top", &mut f), - bottom: args.take_with_key::<_, ScaleLength>("bottom", &mut f), - flip: args.take_with_key::<_, bool>("flip", &mut f).unwrap_or(false), - }; + let paper = args.take::<Paper>(); + let width = args.take_with_key::<_, Length>("width", &mut f); + let height = args.take_with_key::<_, Length>("height", &mut f); + let margins = args.take_with_key::<_, ScaleLength>("margins", &mut f); + let left = args.take_with_key::<_, ScaleLength>("left", &mut f); + let right = args.take_with_key::<_, ScaleLength>("right", &mut f); + let top = args.take_with_key::<_, ScaleLength>("top", &mut f); + let bottom = args.take_with_key::<_, ScaleLength>("bottom", &mut f); + let flip = args.take_with_key::<_, bool>("flip", &mut f).unwrap_or(false); args.unexpected(&mut f); - Pass::node(node, f) -} - -#[derive(Debug, Clone, PartialEq)] -struct PageNode { - paper: Option<Paper>, - width: Option<Length>, - height: Option<Length>, - margins: Option<ScaleLength>, - left: Option<ScaleLength>, - right: Option<ScaleLength>, - top: Option<ScaleLength>, - bottom: Option<ScaleLength>, - flip: bool, -} -#[async_trait(?Send)] -impl Layout for PageNode { - async fn layout<'a>(&'a self, ctx: LayoutContext<'_>) -> Pass<Commands<'a>> { - let mut style = ctx.style.page; + let mut style = ctx.style.page; - if let Some(paper) = self.paper { - style.class = paper.class; - style.size = paper.size(); - } else if self.width.is_some() || self.height.is_some() { - style.class = PaperClass::Custom; - } - - self.width.with(|v| style.size.x = v.as_raw()); - self.height.with(|v| style.size.y = v.as_raw()); - self.margins.with(|v| style.margins.set_all(Some(v))); - self.left.with(|v| style.margins.left = Some(v)); - self.right.with(|v| style.margins.right = Some(v)); - self.top.with(|v| style.margins.top = Some(v)); - self.bottom.with(|v| style.margins.bottom = Some(v)); + if let Some(paper) = paper { + style.class = paper.class; + style.size = paper.size(); + } else if width.is_some() || height.is_some() { + style.class = PaperClass::Custom; + } - if self.flip { - style.size.swap(); - } + width.with(|v| style.size.x = v.as_raw()); + height.with(|v| style.size.y = v.as_raw()); + margins.with(|v| style.margins.set_all(Some(v))); + left.with(|v| style.margins.left = Some(v)); + right.with(|v| style.margins.right = Some(v)); + top.with(|v| style.margins.top = Some(v)); + bottom.with(|v| style.margins.bottom = Some(v)); - Pass::okay(vec![SetPageStyle(style)]) + if flip { + style.size.swap(); } + + Pass::commands(vec![SetPageStyle(style)], f) } /// `pagebreak`: Ends the current page. -pub fn pagebreak(call: FuncCall, _: &ParseState) -> Pass<SyntaxNode> { +pub async fn pagebreak(args: TableValue, _: LayoutContext<'_>) -> Pass<Value> { let mut f = Feedback::new(); - call.args.unexpected(&mut f); - Pass::node(PageBreakNode, f) -} - -#[derive(Debug, Default, Clone, PartialEq)] -struct PageBreakNode; - -#[async_trait(?Send)] -impl Layout for PageBreakNode { - async fn layout<'a>(&'a self, _: LayoutContext<'_>) -> Pass<Commands<'a>> { - Pass::okay(vec![BreakPage]) - } + args.unexpected(&mut f); + Pass::commands(vec![BreakPage], f) } |
