summaryrefslogtreecommitdiff
path: root/src/layout/tree.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-03 16:01:23 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-03 16:04:55 +0200
commitdbfb3d2ced91e56314dfabbb4df9a338926c0a7a (patch)
tree678264cb18f8abc81ebe28077f5aef2df4e5a4bd /src/layout/tree.rs
parent5a8f2fb73ddafba9fdbe952385ae2676126183ae (diff)
Formatting, documentation and small improvements 🧽
Diffstat (limited to 'src/layout/tree.rs')
-rw-r--r--src/layout/tree.rs100
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(),