summaryrefslogtreecommitdiff
path: root/src/layout/tree.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-01-19 21:50:20 +0100
committerLaurenz <laurmaedje@gmail.com>2020-01-19 21:53:24 +0100
commit95e6b078fecddeaa3d6f2c920b617201b74bf01e (patch)
tree1c03b0b16d614a5a2350dccf71a1eb1e34f9a812 /src/layout/tree.rs
parent277f2d2176f5e98305870f90b16af3feae1bb3d1 (diff)
Move to non-fatal errors 🪂 [WIP]
- Dynamic models instead of SyntaxTrees - No more ParseResult/LayoutResult - Errors and Decorations which are propagated to parent contexts - Models are finally clonable
Diffstat (limited to 'src/layout/tree.rs')
-rw-r--r--src/layout/tree.rs163
1 files changed, 0 insertions, 163 deletions
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
deleted file mode 100644
index 86b00f22..00000000
--- a/src/layout/tree.rs
+++ /dev/null
@@ -1,163 +0,0 @@
-use std::pin::Pin;
-use std::future::Future;
-use smallvec::smallvec;
-
-use crate::func::Command;
-use crate::syntax::{SyntaxTree, Node, FuncCall};
-use super::*;
-
-
-type RecursiveResult<'a, T> = Pin<Box<dyn Future<Output=LayoutResult<T>> + 'a>>;
-
-/// Layout a syntax tree into a multibox.
-pub async fn layout(tree: &SyntaxTree, ctx: LayoutContext<'_, '_>) -> LayoutResult<MultiLayout> {
- let mut layouter = TreeLayouter::new(ctx);
- layouter.layout(tree).await?;
- layouter.finish()
-}
-
-#[derive(Debug, Clone)]
-struct TreeLayouter<'a, 'p> {
- ctx: LayoutContext<'a, 'p>,
- layouter: LineLayouter,
- style: LayoutStyle,
-}
-
-impl<'a, 'p> TreeLayouter<'a, 'p> {
- /// Create a new syntax tree layouter.
- fn new(ctx: LayoutContext<'a, 'p>) -> TreeLayouter<'a, 'p> {
- TreeLayouter {
- layouter: LineLayouter::new(LineContext {
- spaces: ctx.spaces.clone(),
- axes: ctx.axes,
- alignment: ctx.alignment,
- repeat: ctx.repeat,
- debug: ctx.debug,
- line_spacing: ctx.style.text.line_spacing(),
- }),
- style: ctx.style.clone(),
- ctx,
- }
- }
-
- fn layout<'b>(&'b mut self, tree: &'b SyntaxTree) -> RecursiveResult<'b, ()> {
- Box::pin(async move {
- for node in &tree.nodes {
- match &node.v {
- Node::Text(text) => self.layout_text(text).await?,
-
- Node::Space => self.layout_space(),
- Node::Newline => self.layout_paragraph()?,
-
- Node::ToggleItalic => self.style.text.variant.style.toggle(),
- Node::ToggleBolder => {
- self.style.text.variant.weight.0 += 300 *
- if self.style.text.bolder { -1 } else { 1 };
- self.style.text.bolder = !self.style.text.bolder;
- }
- Node::ToggleMonospace => {
- let list = &mut self.style.text.fallback.list;
- match list.get(0).map(|s| s.as_str()) {
- Some("monospace") => { list.remove(0); },
- _ => list.insert(0, "monospace".to_string()),
- }
- }
-
- Node::Func(func) => self.layout_func(func).await?,
- }
- }
-
- Ok(())
- })
- }
-
- async fn layout_text(&mut self, text: &str) -> LayoutResult<()> {
- let layout = layout_text(text, TextContext {
- loader: &self.ctx.loader,
- style: &self.style.text,
- axes: self.ctx.axes,
- alignment: self.ctx.alignment,
- }).await?;
-
- self.layouter.add(layout)
- }
-
- fn layout_space(&mut self) {
- self.layouter.add_primary_spacing(self.style.text.word_spacing(), WORD_KIND);
- }
-
- fn layout_paragraph(&mut self) -> LayoutResult<()> {
- self.layouter.add_secondary_spacing(self.style.text.paragraph_spacing(), PARAGRAPH_KIND)
- }
-
- fn layout_func<'b>(&'b mut self, func: &'b FuncCall) -> RecursiveResult<'b, ()> {
- Box::pin(async move {
- let commands = func.0.layout(LayoutContext {
- style: &self.style,
- spaces: self.layouter.remaining(),
- nested: true,
- debug: false,
- .. self.ctx
- }).await?;
-
- for command in commands {
- use Command::*;
-
- match command {
- LayoutTree(tree) => self.layout(tree).await?,
-
- Add(layout) => self.layouter.add(layout)?,
- AddMultiple(layouts) => self.layouter.add_multiple(layouts)?,
- SpacingFunc(space, kind, axis) => match axis {
- Primary => self.layouter.add_primary_spacing(space, kind),
- Secondary => self.layouter.add_secondary_spacing(space, kind)?,
- }
-
- FinishLine => self.layouter.finish_line()?,
- FinishSpace => self.layouter.finish_space(true)?,
- BreakParagraph => self.layout_paragraph()?,
- BreakPage => {
- if self.ctx.nested {
- error!("page break cannot be issued from nested context");
- }
-
- self.layouter.finish_space(true)?
- }
-
- SetTextStyle(style) => {
- self.layouter.set_line_spacing(style.line_spacing());
- self.style.text = style;
- }
- SetPageStyle(style) => {
- if self.ctx.nested {
- error!("page style cannot be altered in nested context");
- }
-
- self.style.page = style;
-
- let margins = style.margins();
- self.ctx.base = style.dimensions.unpadded(margins);
- self.layouter.set_spaces(smallvec![
- LayoutSpace {
- dimensions: style.dimensions,
- padding: margins,
- expansion: LayoutExpansion::new(true, true),
- }
- ], true);
- }
- SetAlignment(alignment) => self.ctx.alignment = alignment,
- SetAxes(axes) => {
- self.layouter.set_axes(axes)?;
- self.ctx.axes = axes;
- }
- }
- }
-
- Ok(())
- })
- }
-
- fn finish(self) -> LayoutResult<MultiLayout> {
- self.layouter.finish()
- }
-}