From 980f898d553bec35bd94171d47fd86cb13e39b23 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 17 Feb 2022 18:56:50 +0100 Subject: [PATCH] Automatic list numbering --- src/eval/mod.rs | 10 +- src/eval/template.rs | 228 ++++++++++++++++++++++++++----------- src/library/list.rs | 77 +++++++++---- tests/ref/markup/enums.png | Bin 6075 -> 7427 bytes tests/ref/markup/lists.png | Bin 21378 -> 21396 bytes tests/typ/markup/enums.typ | 14 ++- 6 files changed, 236 insertions(+), 93 deletions(-) diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 98f840821..32ffb0c9b 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -37,7 +37,7 @@ use unicode_segmentation::UnicodeSegmentation; use crate::diag::{At, Error, StrResult, Trace, Tracepoint, TypResult}; use crate::geom::{Angle, Fractional, Length, Relative}; use crate::layout::Layout; -use crate::library::{self, ORDERED, UNORDERED}; +use crate::library; use crate::syntax::ast::*; use crate::syntax::{Span, Spanned}; use crate::util::EcoString; @@ -180,9 +180,9 @@ impl Eval for ListNode { type Output = Template; fn eval(&self, vm: &mut Vm) -> TypResult { - Ok(Template::show(library::ListNode:: { + Ok(Template::List(library::ListItem { number: None, - child: self.body().eval(vm)?.pack(), + body: self.body().eval(vm)?.pack(), })) } } @@ -191,9 +191,9 @@ impl Eval for EnumNode { type Output = Template; fn eval(&self, vm: &mut Vm) -> TypResult { - Ok(Template::show(library::ListNode:: { + Ok(Template::Enum(library::ListItem { number: self.number(), - child: self.body().eval(vm)?.pack(), + body: self.body().eval(vm)?.pack(), })) } } diff --git a/src/eval/template.rs b/src/eval/template.rs index b1fe07fe9..0db63535f 100644 --- a/src/eval/template.rs +++ b/src/eval/template.rs @@ -13,8 +13,8 @@ use crate::diag::StrResult; use crate::layout::{Layout, LayoutNode}; use crate::library::prelude::*; use crate::library::{ - DecoNode, FlowChild, FlowNode, PageNode, ParChild, ParNode, PlaceNode, SpacingKind, - TextNode, UNDERLINE, + DecoNode, FlowChild, FlowNode, Labelling, ListItem, ListNode, PageNode, ParChild, + ParNode, PlaceNode, SpacingKind, TextNode, ORDERED, UNDERLINE, UNORDERED, }; use crate::util::EcoString; @@ -63,6 +63,10 @@ pub enum Template { Vertical(SpacingKind), /// A block-level node. Block(LayoutNode), + /// An item in an unordered list. + List(ListItem), + /// An item in an ordered list. + Enum(ListItem), /// A page break. Pagebreak, /// A page node. @@ -166,13 +170,13 @@ impl Template { /// Layout this template into a collection of pages. pub fn layout(&self, vm: &mut Vm) -> TypResult>> { - let style_arena = Arena::new(); - let template_arena = Arena::new(); + let sya = Arena::new(); + let tpa = Arena::new(); - let mut builder = Builder::new(&style_arena, &template_arena, true); - let chain = StyleChain::new(vm.styles); - builder.process(self, vm, chain)?; - builder.finish_page(true, false, chain); + let mut builder = Builder::new(&sya, &tpa, true); + let styles = StyleChain::new(vm.styles); + builder.process(vm, self, styles)?; + builder.finish(vm, styles)?; let mut frames = vec![]; let (pages, shared) = builder.pages.unwrap().finish(); @@ -190,43 +194,6 @@ impl Default for Template { } } -impl Debug for Template { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Space => f.pad("Space"), - Self::Linebreak => f.pad("Linebreak"), - Self::Horizontal(kind) => write!(f, "Horizontal({kind:?})"), - Self::Text(text) => write!(f, "Text({text:?})"), - Self::Inline(node) => { - f.write_str("Inline(")?; - node.fmt(f)?; - f.write_str(")") - } - Self::Parbreak => f.pad("Parbreak"), - Self::Colbreak => f.pad("Colbreak"), - Self::Vertical(kind) => write!(f, "Vertical({kind:?})"), - Self::Block(node) => { - f.write_str("Block(")?; - node.fmt(f)?; - f.write_str(")") - } - Self::Pagebreak => f.pad("Pagebreak"), - Self::Page(page) => page.fmt(f), - Self::Show(node) => { - f.write_str("Show(")?; - node.fmt(f)?; - f.write_str(")") - } - Self::Styled(styled) => { - let (sub, map) = styled.as_ref(); - map.fmt(f)?; - sub.fmt(f) - } - Self::Sequence(seq) => f.debug_list().entries(seq.iter()).finish(), - } - } -} - impl Add for Template { type Output = Self; @@ -272,12 +239,12 @@ impl Layout for Template { regions: &Regions, styles: StyleChain, ) -> TypResult>>> { - let style_arena = Arena::new(); - let template_arena = Arena::new(); + let sya = Arena::new(); + let tpa = Arena::new(); - let mut builder = Builder::new(&style_arena, &template_arena, false); - builder.process(self, vm, styles)?; - builder.finish_par(styles); + let mut builder = Builder::new(&sya, &tpa, false); + builder.process(vm, self, styles)?; + builder.finish(vm, styles)?; let (flow, shared) = builder.flow.finish(); FlowNode(flow).layout(vm, regions, shared) @@ -294,11 +261,13 @@ impl Layout for Template { /// Builds a flow or page nodes from a template. struct Builder<'a> { /// An arena where intermediate style chains are stored. - style_arena: &'a Arena>, + sya: &'a Arena>, /// An arena where intermediate templates are stored. - template_arena: &'a Arena