diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-03 16:01:23 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-03 16:04:55 +0200 |
| commit | dbfb3d2ced91e56314dfabbb4df9a338926c0a7a (patch) | |
| tree | 678264cb18f8abc81ebe28077f5aef2df4e5a4bd /src/layout/tree.rs | |
| parent | 5a8f2fb73ddafba9fdbe952385ae2676126183ae (diff) | |
Formatting, documentation and small improvements 🧽
Diffstat (limited to 'src/layout/tree.rs')
| -rw-r--r-- | src/layout/tree.rs | 100 |
1 files changed, 52 insertions, 48 deletions
diff --git a/src/layout/tree.rs b/src/layout/tree.rs index 44c59211..d20fc666 100644 --- a/src/layout/tree.rs +++ b/src/layout/tree.rs @@ -1,19 +1,26 @@ -//! The tree layouter layouts trees (i.e. -//! [syntax trees](crate::syntax::SyntaxTree) and [functions](crate::func)) -//! by executing commands issued by the trees. +//! Layouting of syntax trees. -use crate::{Pass, Feedback, DynFuture}; use crate::style::LayoutStyle; use crate::syntax::decoration::Decoration; -use crate::syntax::tree::{SyntaxTree, SyntaxNode, DynamicNode}; use crate::syntax::span::{Span, Spanned}; -use super::line::{LineLayouter, LineContext}; +use crate::syntax::tree::{DynamicNode, SyntaxNode, SyntaxTree}; +use crate::{DynFuture, Feedback, Pass}; +use super::line::{LineContext, LineLayouter}; use super::text::{layout_text, TextContext}; use super::*; +/// Layout a syntax tree into a collection of boxes. +pub async fn layout_tree( + tree: &SyntaxTree, + ctx: LayoutContext<'_>, +) -> Pass<MultiLayout> { + let mut layouter = TreeLayouter::new(ctx); + layouter.layout_tree(tree).await; + layouter.finish() +} + /// Performs the tree layouting. -#[derive(Debug)] -pub struct TreeLayouter<'a> { +struct TreeLayouter<'a> { ctx: LayoutContext<'a>, layouter: LineLayouter, style: LayoutStyle, @@ -21,9 +28,8 @@ pub struct TreeLayouter<'a> { } impl<'a> TreeLayouter<'a> { - /// Create a new tree layouter. - pub fn new(ctx: LayoutContext<'a>) -> TreeLayouter<'a> { - TreeLayouter { + fn new(ctx: LayoutContext<'a>) -> Self { + Self { layouter: LineLayouter::new(LineContext { spaces: ctx.spaces.clone(), axes: ctx.axes, @@ -37,15 +43,17 @@ impl<'a> TreeLayouter<'a> { } } - /// Layout a syntax tree by directly processing the nodes instead of using - /// the command based architecture. - pub async fn layout_tree(&mut self, tree: &SyntaxTree) { + async fn layout_tree(&mut self, tree: &SyntaxTree) { for node in tree { self.layout_node(node).await; } } - pub async fn layout_node(&mut self, node: &Spanned<SyntaxNode>) { + fn finish(self) -> Pass<MultiLayout> { + Pass::new(self.layouter.finish(), self.feedback) + } + + async fn layout_node(&mut self, node: &Spanned<SyntaxNode>) { let decorate = |this: &mut TreeLayouter, deco| { this.feedback.decorations.push(Spanned::new(deco, node.span)); }; @@ -80,7 +88,10 @@ impl<'a> TreeLayouter<'a> { SyntaxNode::Raw(lines) => { // TODO: Make this more efficient. let fallback = self.style.text.fallback.clone(); - self.style.text.fallback.list_mut().insert(0, "monospace".to_string()); + self.style.text.fallback + .list_mut() + .insert(0, "monospace".to_string()); + self.style.text.fallback.flatten(); // Layout the first line. @@ -104,17 +115,15 @@ impl<'a> TreeLayouter<'a> { } } - /// Layout a node into this layouting process. - pub async fn layout_dyn(&mut self, dynamic: Spanned<&dyn DynamicNode>) { - // Execute the tree's layout function which generates the commands. + async fn layout_dyn(&mut self, dynamic: Spanned<&dyn DynamicNode>) { + // Execute the tree's command-generating layout function. let layouted = dynamic.v.layout(LayoutContext { style: &self.style, spaces: self.layouter.remaining(), - nested: true, - .. self.ctx + root: true, + ..self.ctx }).await; - // Add the errors generated by the tree to the error list. self.feedback.extend_offset(layouted.feedback, dynamic.span.start); for command in layouted.output { @@ -122,13 +131,6 @@ impl<'a> TreeLayouter<'a> { } } - /// Compute the finished list of boxes. - pub fn finish(self) -> Pass<MultiLayout> { - Pass::new(self.layouter.finish(), self.feedback) - } - - /// Execute a command issued by a tree. When the command is errorful, the - /// given span is stored with the error. fn execute_command<'r>( &'r mut self, command: Command<'r>, @@ -149,13 +151,13 @@ impl<'a> TreeLayouter<'a> { BreakLine => self.layouter.finish_line(), BreakParagraph => self.layout_paragraph(), BreakPage => { - if self.ctx.nested { + if self.ctx.root { + self.layouter.finish_space(true) + } else { error!( @self.feedback, tree_span, - "page break cannot be issued from nested context", + "page break cannot only be issued from root context", ); - } else { - self.layouter.finish_space(true) } } @@ -164,12 +166,7 @@ impl<'a> TreeLayouter<'a> { self.style.text = style; } SetPageStyle(style) => { - if self.ctx.nested { - error!( - @self.feedback, tree_span, - "page style cannot be changed from nested context", - ); - } else { + if self.ctx.root { self.style.page = style; // The line layouter has no idea of page styles and thus we @@ -184,6 +181,11 @@ impl<'a> TreeLayouter<'a> { expansion: LayoutExpansion::new(true, true), } ], true); + } else { + error!( + @self.feedback, tree_span, + "page style cannot only be changed from root context", + ); } } @@ -195,17 +197,20 @@ impl<'a> TreeLayouter<'a> { } }) } - /// Layout a continous piece of text and add it to the line layouter. async fn layout_text(&mut self, text: &str) { - self.layouter.add(layout_text(text, TextContext { - loader: &self.ctx.loader, - style: &self.style.text, - axes: self.ctx.axes, - align: self.ctx.align, - }).await) + self.layouter.add( + layout_text( + text, + TextContext { + loader: &self.ctx.loader, + style: &self.style.text, + dir: self.ctx.axes.primary, + align: self.ctx.align, + } + ).await + ); } - /// Add the spacing for a syntactic space node. fn layout_space(&mut self) { self.layouter.add_primary_spacing( self.style.text.word_spacing(), @@ -213,7 +218,6 @@ impl<'a> TreeLayouter<'a> { ); } - /// Finish the paragraph and add paragraph spacing. fn layout_paragraph(&mut self) { self.layouter.add_secondary_spacing( self.style.text.paragraph_spacing(), |
