summaryrefslogtreecommitdiff
path: root/src/layout/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout/model.rs')
-rw-r--r--src/layout/model.rs113
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,
- }
- }
}