summaryrefslogtreecommitdiff
path: root/src/library/page.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-16 22:14:27 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-16 22:39:21 +0200
commit30f16bbf6431ca0c174ca0a1abaa6a13ef50ab06 (patch)
treef5a5c0adad15840ebe24b39e77ff467862067c91 /src/library/page.rs
parent9f6137d8a829fe8f34554623495fa620252a0184 (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.rs94
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)
}