diff options
Diffstat (limited to 'src/layout/model.rs')
| -rw-r--r-- | src/layout/model.rs | 113 |
1 files changed, 49 insertions, 64 deletions
diff --git a/src/layout/model.rs b/src/layout/model.rs index bcec5ceb..73492dd9 100644 --- a/src/layout/model.rs +++ b/src/layout/model.rs @@ -1,5 +1,3 @@ -use std::pin::Pin; -use std::future::Future; use smallvec::smallvec; use crate::error::Error; @@ -9,17 +7,8 @@ use crate::syntax::{SpanVec, Spanned, Span, offset_spans}; use super::*; -pub async fn layout( - model: &SyntaxModel, - ctx: LayoutContext<'_, '_> -) -> Layouted<MultiLayout> { - let mut layouter = ModelLayouter::new(ctx); - layouter.layout_syntax_model(model).await; - layouter.finish() -} - #[derive(Debug, Clone)] -struct ModelLayouter<'a, 'p> { +pub struct ModelLayouter<'a, 'p> { ctx: LayoutContext<'a, 'p>, layouter: LineLayouter, style: LayoutStyle, @@ -28,7 +17,7 @@ struct ModelLayouter<'a, 'p> { impl<'a, 'p> ModelLayouter<'a, 'p> { /// Create a new syntax tree layouter. - fn new(ctx: LayoutContext<'a, 'p>) -> ModelLayouter<'a, 'p> { + pub fn new(ctx: LayoutContext<'a, 'p>) -> ModelLayouter<'a, 'p> { ModelLayouter { layouter: LineLayouter::new(LineContext { spaces: ctx.spaces.clone(), @@ -44,7 +33,7 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { } } - fn layout<'r>( + pub fn layout<'r>( &'r mut self, model: Spanned<&'r dyn Model> ) -> DynFuture<'r, ()> { Box::pin(async move { @@ -60,14 +49,54 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { self.errors.extend(offset_spans(layouted.errors, model.span.start)); for command in commands { - self.execute_command(command, model.span); + self.execute_command(command, model.span).await; } }) } + pub fn layout_syntax_model<'r>( + &'r mut self, + model: &'r SyntaxModel + ) -> DynFuture<'r, ()> { Box::pin(async move { + use Node::*; + + for node in &model.nodes { + match &node.v { + Space => self.layout_space(), + Newline => self.layout_paragraph(), + Text(text) => self.layout_text(text).await, + + ToggleItalic => self.style.text.variant.style.toggle(), + ToggleBolder => { + let fac = if self.style.text.bolder { -1 } else { 1 }; + self.style.text.variant.weight.0 += 300 * fac; + self.style.text.bolder = !self.style.text.bolder; + } + 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::Model(model) => { + self.layout(Spanned::new(model.as_ref(), node.span)).await; + } + } + } + }) } + + pub fn finish(self) -> Layouted<MultiLayout> { + Layouted { + output: self.layouter.finish(), + errors: self.errors, + } + } + fn execute_command<'r>( &'r mut self, command: Command<'r>, - model_span: Span, + span: Span, ) -> DynFuture<'r, ()> { Box::pin(async move { use Command::*; @@ -86,10 +115,8 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { BreakParagraph => self.layout_paragraph(), BreakPage => { if self.ctx.nested { - self.errors.push(Spanned::new( - Error::new( "page break cannot be issued from nested context"), - model_span, - )); + self.errors.push(err!(span; + "page break cannot be issued from nested context")); } else { self.layouter.finish_space(true) } @@ -101,10 +128,8 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { } SetPageStyle(style) => { if self.ctx.nested { - self.errors.push(Spanned::new( - Error::new("page style cannot be changed from nested context"), - model_span, - )); + self.errors.push(err!(span; + "page style cannot be changed from nested context")); } else { self.style.page = style; @@ -128,39 +153,6 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { } }) } - fn layout_syntax_model<'r>( - &'r mut self, - model: &'r SyntaxModel - ) -> DynFuture<'r, ()> { Box::pin(async move { - use Node::*; - - for node in &model.nodes { - match &node.v { - Space => self.layout_space(), - Newline => self.layout_paragraph(), - Text(text) => self.layout_text(text).await, - - ToggleItalic => self.style.text.variant.style.toggle(), - ToggleBolder => { - let fac = if self.style.text.bolder { -1 } else { 1 }; - self.style.text.variant.weight.0 += 300 * fac; - self.style.text.bolder = !self.style.text.bolder; - } - 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::Model(model) => { - self.layout(Spanned::new(model.as_ref(), node.span)).await; - } - } - } - }) } - async fn layout_text(&mut self, text: &str) { self.layouter.add(layout_text(text, TextContext { loader: &self.ctx.loader, @@ -183,11 +175,4 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { SpacingKind::PARAGRAPH, ); } - - fn finish(self) -> Layouted<MultiLayout> { - Layouted { - output: self.layouter.finish(), - errors: self.errors, - } - } } |
