diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-19 22:28:49 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-19 22:39:19 +0100 |
| commit | ab43bd802eafe33977a91893907e67553e099569 (patch) | |
| tree | af4dead92b143348f52e2e8f869df3f7dfd7322a /library/src/layout | |
| parent | d6aaae0cea1e79eecd85dc94ab85b9ad8eff48e8 (diff) | |
Renaming and refactoring
Diffstat (limited to 'library/src/layout')
| -rw-r--r-- | library/src/layout/align.rs | 6 | ||||
| -rw-r--r-- | library/src/layout/columns.rs | 16 | ||||
| -rw-r--r-- | library/src/layout/container.rs | 30 | ||||
| -rw-r--r-- | library/src/layout/enum.rs | 18 | ||||
| -rw-r--r-- | library/src/layout/flow.rs | 86 | ||||
| -rw-r--r-- | library/src/layout/grid.rs | 10 | ||||
| -rw-r--r-- | library/src/layout/hide.rs | 8 | ||||
| -rw-r--r-- | library/src/layout/list.rs | 20 | ||||
| -rw-r--r-- | library/src/layout/measure.rs | 2 | ||||
| -rw-r--r-- | library/src/layout/mod.rs | 183 | ||||
| -rw-r--r-- | library/src/layout/pad.rs | 6 | ||||
| -rw-r--r-- | library/src/layout/page.rs | 18 | ||||
| -rw-r--r-- | library/src/layout/par.rs | 194 | ||||
| -rw-r--r-- | library/src/layout/place.rs | 14 | ||||
| -rw-r--r-- | library/src/layout/regions.rs | 4 | ||||
| -rw-r--r-- | library/src/layout/repeat.rs | 10 | ||||
| -rw-r--r-- | library/src/layout/spacing.rs | 24 | ||||
| -rw-r--r-- | library/src/layout/stack.rs | 23 | ||||
| -rw-r--r-- | library/src/layout/table.rs | 18 | ||||
| -rw-r--r-- | library/src/layout/terms.rs | 28 | ||||
| -rw-r--r-- | library/src/layout/transform.rs | 18 |
21 files changed, 354 insertions, 382 deletions
diff --git a/library/src/layout/align.rs b/library/src/layout/align.rs index 2a3998bf..c2f8262e 100644 --- a/library/src/layout/align.rs +++ b/library/src/layout/align.rs @@ -14,8 +14,8 @@ use crate::prelude::*; /// /// Display: Align /// Category: layout -#[node(Show)] -pub struct AlignNode { +#[element(Show)] +pub struct AlignElem { /// The alignment along both axes. /// /// Possible values for horizontal alignments are: @@ -57,7 +57,7 @@ pub struct AlignNode { pub body: Content, } -impl Show for AlignNode { +impl Show for AlignElem { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { Ok(self .body() diff --git a/library/src/layout/columns.rs b/library/src/layout/columns.rs index 7704e9c4..3a1b012a 100644 --- a/library/src/layout/columns.rs +++ b/library/src/layout/columns.rs @@ -1,5 +1,5 @@ use crate::prelude::*; -use crate::text::TextNode; +use crate::text::TextElem; /// Separate a region into multiple equally sized columns. /// @@ -32,8 +32,8 @@ use crate::text::TextNode; /// /// Display: Columns /// Category: layout -#[node(Layout)] -pub struct ColumnsNode { +#[element(Layout)] +pub struct ColumnsElem { /// The number of columns. #[positional] #[default(NonZeroUsize::new(2).unwrap())] @@ -49,7 +49,7 @@ pub struct ColumnsNode { pub body: Content, } -impl Layout for ColumnsNode { +impl Layout for ColumnsElem { fn layout( &self, vt: &mut Vt, @@ -88,7 +88,7 @@ impl Layout for ColumnsNode { let mut frames = body.layout(vt, styles, pod)?.into_iter(); let mut finished = vec![]; - let dir = TextNode::dir_in(styles); + let dir = TextElem::dir_in(styles); let total_regions = (frames.len() as f32 / columns as f32).ceil() as usize; // Stitch together the columns for each region. @@ -151,15 +151,15 @@ impl Layout for ColumnsNode { /// /// Display: Column Break /// Category: layout -#[node(Behave)] -pub struct ColbreakNode { +#[element(Behave)] +pub struct ColbreakElem { /// If `{true}`, the column break is skipped if the current column is /// already empty. #[default(false)] pub weak: bool, } -impl Behave for ColbreakNode { +impl Behave for ColbreakElem { fn behaviour(&self) -> Behaviour { if self.weak(StyleChain::default()) { Behaviour::Weak(1) diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs index bdc147c3..ef7def7a 100644 --- a/library/src/layout/container.rs +++ b/library/src/layout/container.rs @@ -1,4 +1,4 @@ -use super::VNode; +use super::VElem; use crate::layout::Spacing; use crate::prelude::*; @@ -21,8 +21,8 @@ use crate::prelude::*; /// /// Display: Box /// Category: layout -#[node(Layout)] -pub struct BoxNode { +#[element(Layout)] +pub struct BoxElem { /// The width of the box. /// /// Boxes can have [fractional]($type/fraction) widths, as the example @@ -93,7 +93,7 @@ pub struct BoxNode { pub body: Option<Content>, } -impl Layout for BoxNode { +impl Layout for BoxElem { fn layout( &self, vt: &mut Vt, @@ -183,8 +183,8 @@ impl Layout for BoxNode { /// /// Display: Block /// Category: layout -#[node(Layout)] -pub struct BlockNode { +#[element(Layout)] +pub struct BlockElem { /// The block's width. /// /// ```example @@ -278,11 +278,11 @@ pub struct BlockNode { #[parse( let spacing = args.named("spacing")?; args.named("above")? - .map(VNode::block_around) - .or_else(|| spacing.map(VNode::block_spacing)) + .map(VElem::block_around) + .or_else(|| spacing.map(VElem::block_spacing)) )] - #[default(VNode::block_spacing(Em::new(1.2).into()))] - pub above: VNode, + #[default(VElem::block_spacing(Em::new(1.2).into()))] + pub above: VElem, /// The spacing between this block and its successor. Takes precedence /// over `spacing`. @@ -290,11 +290,11 @@ pub struct BlockNode { /// The default value is `{1.2em}`. #[parse( args.named("below")? - .map(VNode::block_around) - .or_else(|| spacing.map(VNode::block_spacing)) + .map(VElem::block_around) + .or_else(|| spacing.map(VElem::block_spacing)) )] - #[default(VNode::block_spacing(Em::new(1.2).into()))] - pub below: VNode, + #[default(VElem::block_spacing(Em::new(1.2).into()))] + pub below: VElem, /// The contents of the block. #[positional] @@ -308,7 +308,7 @@ pub struct BlockNode { pub sticky: bool, } -impl Layout for BlockNode { +impl Layout for BlockElem { fn layout( &self, vt: &mut Vt, diff --git a/library/src/layout/enum.rs b/library/src/layout/enum.rs index 05b42bd8..1be57d4c 100644 --- a/library/src/layout/enum.rs +++ b/library/src/layout/enum.rs @@ -1,9 +1,9 @@ use std::str::FromStr; -use crate::layout::{BlockNode, ParNode, Sizing, Spacing}; +use crate::layout::{BlockElem, ParElem, Sizing, Spacing}; use crate::meta::{Numbering, NumberingPattern}; use crate::prelude::*; -use crate::text::TextNode; +use crate::text::TextElem; use super::GridLayouter; @@ -50,8 +50,8 @@ use super::GridLayouter; /// /// Display: Numbered List /// Category: layout -#[node(Layout)] -pub struct EnumNode { +#[element(Layout)] +pub struct EnumElem { /// If this is `{false}`, the items are spaced apart with /// [enum spacing]($func/enum.spacing). If it is `{true}`, they use normal /// [leading]($func/par.leading) instead. This makes the enumeration more @@ -153,7 +153,7 @@ pub struct EnumNode { parents: Parent, } -impl Layout for EnumNode { +impl Layout for EnumElem { fn layout( &self, vt: &mut Vt, @@ -164,10 +164,10 @@ impl Layout for EnumNode { let indent = self.indent(styles); let body_indent = self.body_indent(styles); let gutter = if self.tight(styles) { - ParNode::leading_in(styles).into() + ParElem::leading_in(styles).into() } else { self.spacing(styles) - .unwrap_or_else(|| BlockNode::below_in(styles).amount()) + .unwrap_or_else(|| BlockElem::below_in(styles).amount()) }; let mut cells = vec![]; @@ -186,7 +186,7 @@ impl Layout for EnumNode { } else { match &numbering { Numbering::Pattern(pattern) => { - TextNode::packed(pattern.apply_kth(parents.len(), number)) + TextElem::packed(pattern.apply_kth(parents.len(), number)) } other => other.apply_vt(vt, &[number])?.display(), } @@ -221,7 +221,7 @@ impl Layout for EnumNode { /// /// Display: Numbered List Item /// Category: layout -#[node] +#[element] pub struct EnumItem { /// The item's number. #[positional] diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs index 096c575e..b6476816 100644 --- a/library/src/layout/flow.rs +++ b/library/src/layout/flow.rs @@ -1,24 +1,22 @@ -use typst::model::StyledNode; - -use super::{AlignNode, BlockNode, ColbreakNode, ParNode, PlaceNode, Spacing, VNode}; +use super::{AlignElem, BlockElem, ColbreakElem, ParElem, PlaceElem, Spacing, VElem}; use crate::prelude::*; -use crate::visualize::{CircleNode, EllipseNode, ImageNode, RectNode, SquareNode}; +use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem}; -/// Arrange spacing, paragraphs and block-level nodes into a flow. +/// Arrange spacing, paragraphs and block-level elements into a flow. /// -/// This node is responsible for layouting both the top-level content flow and +/// This element is responsible for layouting both the top-level content flow and /// the contents of boxes. /// /// Display: Flow /// Category: layout -#[node(Layout)] -pub struct FlowNode { +#[element(Layout)] +pub struct FlowElem { /// The children that will be arranges into a flow. #[variadic] pub children: Vec<Content>, } -impl Layout for FlowNode { +impl Layout for FlowElem { fn layout( &self, vt: &mut Vt, @@ -27,29 +25,27 @@ impl Layout for FlowNode { ) -> SourceResult<Fragment> { let mut layouter = FlowLayouter::new(regions); - for mut child in self.children() { - let map; + for mut child in &self.children() { let outer = styles; - let mut styles = outer; - if let Some(node) = child.to::<StyledNode>() { - map = node.styles(); + let mut styles = styles; + if let Some((elem, map)) = child.to_styled() { + child = elem; styles = outer.chain(&map); - child = node.body(); } - if let Some(node) = child.to::<VNode>() { - layouter.layout_spacing(node, styles); - } else if let Some(node) = child.to::<ParNode>() { - layouter.layout_par(vt, node, styles)?; - } else if child.is::<RectNode>() - || child.is::<SquareNode>() - || child.is::<EllipseNode>() - || child.is::<CircleNode>() - || child.is::<ImageNode>() + if let Some(elem) = child.to::<VElem>() { + layouter.layout_spacing(elem, styles); + } else if let Some(elem) = child.to::<ParElem>() { + layouter.layout_par(vt, elem, styles)?; + } else if child.is::<RectElem>() + || child.is::<SquareElem>() + || child.is::<EllipseElem>() + || child.is::<CircleElem>() + || child.is::<ImageElem>() { let layoutable = child.with::<dyn Layout>().unwrap(); layouter.layout_single(vt, layoutable, styles)?; - } else if child.is::<MetaNode>() { + } else if child.is::<MetaElem>() { let mut frame = Frame::new(Size::zero()); frame.meta(styles, true); layouter.items.push(FlowItem::Frame( @@ -59,7 +55,7 @@ impl Layout for FlowNode { )); } else if child.can::<dyn Layout>() { layouter.layout_multiple(vt, &child, styles)?; - } else if child.is::<ColbreakNode>() { + } else if child.is::<ColbreakElem>() { if !layouter.regions.backlog.is_empty() || layouter.regions.last.is_some() { layouter.finish_region(); @@ -122,13 +118,13 @@ impl<'a> FlowLayouter<'a> { } /// Layout vertical spacing. - fn layout_spacing(&mut self, node: &VNode, styles: StyleChain) { - self.layout_item(match node.amount() { - Spacing::Rel(v) => FlowItem::Absolute( - v.resolve(styles).relative_to(self.initial.y), - node.weakness(styles) > 0, + fn layout_spacing(&mut self, v: &VElem, styles: StyleChain) { + self.layout_item(match v.amount() { + Spacing::Rel(rel) => FlowItem::Absolute( + rel.resolve(styles).relative_to(self.initial.y), + v.weakness(styles) > 0, ), - Spacing::Fr(v) => FlowItem::Fractional(v), + Spacing::Fr(fr) => FlowItem::Fractional(fr), }); } @@ -136,11 +132,11 @@ impl<'a> FlowLayouter<'a> { fn layout_par( &mut self, vt: &mut Vt, - par: &ParNode, + par: &ParElem, styles: StyleChain, ) -> SourceResult<()> { - let aligns = AlignNode::alignment_in(styles).resolve(styles); - let leading = ParNode::leading_in(styles); + let aligns = AlignElem::alignment_in(styles).resolve(styles); + let leading = ParElem::leading_in(styles); let consecutive = self.last_was_par; let frames = par .layout(vt, styles, consecutive, self.regions.base(), self.regions.expand.x)? @@ -185,8 +181,8 @@ impl<'a> FlowLayouter<'a> { content: &dyn Layout, styles: StyleChain, ) -> SourceResult<()> { - let aligns = AlignNode::alignment_in(styles).resolve(styles); - let sticky = BlockNode::sticky_in(styles); + let aligns = AlignElem::alignment_in(styles).resolve(styles); + let sticky = BlockElem::sticky_in(styles); let pod = Regions::one(self.regions.base(), Axes::splat(false)); let frame = content.layout(vt, styles, pod)?.into_frame(); self.layout_item(FlowItem::Frame(frame, aligns, sticky)); @@ -201,9 +197,9 @@ impl<'a> FlowLayouter<'a> { block: &Content, styles: StyleChain, ) -> SourceResult<()> { - // Placed nodes that are out of flow produce placed items which aren't - // aligned later. - if let Some(placed) = block.to::<PlaceNode>() { + // Placed elements that are out of flow produce placed items which + // aren't aligned later. + if let Some(placed) = block.to::<PlaceElem>() { if placed.out_of_flow(styles) { let frame = block.layout(vt, styles, self.regions)?.into_frame(); self.layout_item(FlowItem::Placed(frame)); @@ -212,17 +208,17 @@ impl<'a> FlowLayouter<'a> { } // How to align the block. - let aligns = if let Some(align) = block.to::<AlignNode>() { + let aligns = if let Some(align) = block.to::<AlignElem>() { align.alignment(styles) - } else if let Some(styled) = block.to::<StyledNode>() { - AlignNode::alignment_in(styles.chain(&styled.styles())) + } else if let Some((_, local)) = block.to_styled() { + AlignElem::alignment_in(styles.chain(local)) } else { - AlignNode::alignment_in(styles) + AlignElem::alignment_in(styles) } .resolve(styles); // Layout the block itself. - let sticky = BlockNode::sticky_in(styles); + let sticky = BlockElem::sticky_in(styles); let fragment = block.layout(vt, styles, self.regions)?; for (i, frame) in fragment.into_iter().enumerate() { if i > 0 { diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs index 47d3ab86..5c3d132e 100644 --- a/library/src/layout/grid.rs +++ b/library/src/layout/grid.rs @@ -1,5 +1,5 @@ use crate::prelude::*; -use crate::text::TextNode; +use crate::text::TextElem; use super::Sizing; @@ -61,8 +61,8 @@ use super::Sizing; /// /// Display: Grid /// Category: layout -#[node(Layout)] -pub struct GridNode { +#[element(Layout)] +pub struct GridElem { /// Defines the column sizes. /// /// Either specify a track size array or provide an integer to create a grid @@ -101,7 +101,7 @@ pub struct GridNode { pub children: Vec<Content>, } -impl Layout for GridNode { +impl Layout for GridElem { fn layout( &self, vt: &mut Vt, @@ -257,7 +257,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> { } // Reverse for RTL. - let is_rtl = TextNode::dir_in(styles) == Dir::RTL; + let is_rtl = TextElem::dir_in(styles) == Dir::RTL; if is_rtl { cols.reverse(); } diff --git a/library/src/layout/hide.rs b/library/src/layout/hide.rs index 1d87d3e8..d9bee317 100644 --- a/library/src/layout/hide.rs +++ b/library/src/layout/hide.rs @@ -15,15 +15,15 @@ use crate::prelude::*; /// /// Display: Hide /// Category: layout -#[node(Show)] -pub struct HideNode { +#[element(Show)] +pub struct HideElem { /// The content to hide. #[required] pub body: Content, } -impl Show for HideNode { +impl Show for HideElem { fn show(&self, _: &mut Vt, _: StyleChain) -> SourceResult<Content> { - Ok(self.body().styled(MetaNode::set_data(vec![Meta::Hide]))) + Ok(self.body().styled(MetaElem::set_data(vec![Meta::Hide]))) } } diff --git a/library/src/layout/list.rs b/library/src/layout/list.rs index fe78131d..179c93eb 100644 --- a/library/src/layout/list.rs +++ b/library/src/layout/list.rs @@ -1,6 +1,6 @@ -use crate::layout::{BlockNode, ParNode, Sizing, Spacing}; +use crate::layout::{BlockElem, ParElem, Sizing, Spacing}; use crate::prelude::*; -use crate::text::TextNode; +use crate::text::TextElem; use super::GridLayouter; @@ -36,8 +36,8 @@ use super::GridLayouter; /// /// Display: Bullet List /// Category: layout -#[node(Layout)] -pub struct ListNode { +#[element(Layout)] +pub struct ListElem { /// If this is `{false}`, the items are spaced apart with [list /// spacing]($func/list.spacing). If it is `{true}`, they use normal /// [leading]($func/par.leading) instead. This makes the list more compact, @@ -111,7 +111,7 @@ pub struct ListNode { depth: Depth, } -impl Layout for ListNode { +impl Layout for ListElem { fn layout( &self, vt: &mut Vt, @@ -121,10 +121,10 @@ impl Layout for ListNode { let indent = self.indent(styles); let body_indent = self.body_indent(styles); let gutter = if self.tight(styles) { - ParNode::leading_in(styles).into() + ParElem::leading_in(styles).into() } else { self.spacing(styles) - .unwrap_or_else(|| BlockNode::below_in(styles).amount()) + .unwrap_or_else(|| BlockElem::below_in(styles).amount()) }; let depth = self.depth(styles); @@ -160,7 +160,7 @@ impl Layout for ListNode { /// /// Display: Bullet List Item /// Category: layout -#[node] +#[element] pub struct ListItem { /// The item's body. #[required] @@ -187,7 +187,7 @@ impl ListMarker { .get(depth) .or(list.last()) .cloned() - .unwrap_or_else(|| TextNode::packed('•')), + .unwrap_or_else(|| TextElem::packed('•')), Self::Func(func) => func.call_vt(vt, [Value::Int(depth as i64)])?.display(), }) } @@ -198,7 +198,7 @@ cast_from_value! { v: Content => Self::Content(vec![v]), array: Array => { if array.len() == 0 { - Err("must contain at least one marker")?; + Err("array must contain at least one marker")?; } Self::Content(array.into_iter().map(Value::display).collect()) }, diff --git a/library/src/layout/measure.rs b/library/src/layout/measure.rs index b116cbf8..df66d67f 100644 --- a/library/src/layout/measure.rs +++ b/library/src/layout/measure.rs @@ -10,7 +10,7 @@ pub fn measure( /// The content whose size to measure. content: Content, /// The styles with which to layout the content. - styles: StyleMap, + styles: Styles, ) -> Value { let pod = Regions::one(Axes::splat(Abs::inf()), Axes::splat(false)); let styles = StyleChain::new(&styles); diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs index b6ecce51..02d3bca5 100644 --- a/library/src/layout/mod.rs +++ b/library/src/layout/mod.rs @@ -50,14 +50,14 @@ use std::mem; use typed_arena::Arena; use typst::diag::SourceResult; use typst::eval::Tracer; -use typst::model::{applicable, realize, SequenceNode, StyleVecBuilder, StyledNode}; +use typst::model::{applicable, realize, StyleVecBuilder}; -use crate::math::{EquationNode, LayoutMath}; -use crate::meta::DocumentNode; +use crate::math::{EquationElem, LayoutMath}; +use crate::meta::DocumentElem; use crate::prelude::*; use crate::shared::BehavedBuilder; -use crate::text::{LinebreakNode, SmartQuoteNode, SpaceNode, TextNode}; -use crate::visualize::{CircleNode, EllipseNode, ImageNode, RectNode, SquareNode}; +use crate::text::{LinebreakElem, SmartQuoteElem, SpaceElem, TextElem}; +use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem}; /// Root-level layout. pub trait LayoutRoot { @@ -69,7 +69,7 @@ impl LayoutRoot for Content { fn layout_root(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Document> { #[comemo::memoize] fn cached( - node: &Content, + content: &Content, world: Tracked<dyn World>, tracer: TrackedMut<Tracer>, provider: TrackedMut<StabilityProvider>, @@ -78,7 +78,7 @@ impl LayoutRoot for Content { ) -> SourceResult<Document> { let mut vt = Vt { world, tracer, provider, introspector }; let scratch = Scratch::default(); - let (realized, styles) = realize_root(&mut vt, &scratch, node, styles)?; + let (realized, styles) = realize_root(&mut vt, &scratch, content, styles)?; realized .with::<dyn LayoutRoot>() .unwrap() @@ -108,8 +108,8 @@ pub trait Layout { /// Layout without side effects. /// - /// This node must be layouted again in the same order for the results to be - /// valid. + /// This element must be layouted again in the same order for the results to + /// be valid. fn measure( &self, vt: &mut Vt, @@ -132,7 +132,7 @@ impl Layout for Content { ) -> SourceResult<Fragment> { #[comemo::memoize] fn cached( - node: &Content, + content: &Content, world: Tracked<dyn World>, tracer: TrackedMut<Tracer>, provider: TrackedMut<StabilityProvider>, @@ -142,7 +142,7 @@ impl Layout for Content { ) -> SourceResult<Fragment> { let mut vt = Vt { world, tracer, provider, introspector }; let scratch = Scratch::default(); - let (realized, styles) = realize_block(&mut vt, &scratch, node, styles)?; + let (realized, styles) = realize_block(&mut vt, &scratch, content, styles)?; realized .with::<dyn Layout>() .unwrap() @@ -161,7 +161,7 @@ impl Layout for Content { } } -/// Realize into a node that is capable of root-level layout. +/// Realize into an element that is capable of root-level layout. fn realize_root<'a>( vt: &mut Vt, scratch: &'a Scratch<'a>, @@ -176,10 +176,10 @@ fn realize_root<'a>( builder.accept(content, styles)?; builder.interrupt_page(Some(styles))?; let (pages, shared) = builder.doc.unwrap().pages.finish(); - Ok((DocumentNode::new(pages.to_vec()).pack(), shared)) + Ok((DocumentElem::new(pages.to_vec()).pack(), shared)) } -/// Realize into a node that is capable of block-level layout. +/// Realize into an element that is capable of block-level layout. fn realize_block<'a>( vt: &mut Vt, scratch: &'a Scratch<'a>, @@ -187,11 +187,11 @@ fn realize_block<'a>( styles: StyleChain<'a>, ) -> SourceResult<(Content, StyleChain<'a>)> { if content.can::<dyn Layout>() - && !content.is::<RectNode>() - && !content.is::<SquareNode>() - && !content.is::<EllipseNode>() - && !content.is::<CircleNode>() - && !content.is::<ImageNode>() + && !content.is::<RectElem>() + && !content.is::<SquareElem>() + && !content.is::<EllipseElem>() + && !content.is::<CircleElem>() + && !content.is::<ImageElem>() && !applicable(content, styles) { return Ok((content.clone(), styles)); @@ -201,10 +201,10 @@ fn realize_block<'a>( builder.accept(content, styles)?; builder.interrupt_par()?; let (children, shared) = builder.flow.0.finish(); - Ok((FlowNode::new(children.to_vec()).pack(), shared)) + Ok((FlowElem::new(children.to_vec()).pack(), shared)) } -/// Builds a document or a flow node from content. +/// Builds a document or a flow element from content. struct Builder<'a, 'v, 't> { /// The virtual typesetter. vt: &'v mut Vt<'t>, @@ -227,7 +227,6 @@ struct Scratch<'a> { styles: Arena<StyleChain<'a>>, /// An arena where intermediate content resulting from show rules is stored. content: Arena<Content>, - maps: Arena<StyleMap>, } impl<'a, 'v, 't> Builder<'a, 'v, 't> { @@ -247,19 +246,18 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> { mut content: &'a Content, styles: StyleChain<'a>, ) -> SourceResult<()> { - if content.can::<dyn LayoutMath>() && !content.is::<EquationNode>() { + if content.can::<dyn LayoutMath>() && !content.is::<EquationElem>() { content = - self.scratch.content.alloc(EquationNode::new(content.clone()).pack()); + self.scratch.content.alloc(EquationElem::new(content.clone()).pack()); } - if let Some(styled) = content.to::<StyledNode>() { - return self.styled(styled, styles); + if let Some((elem, local)) = content.to_styled() { + return self.styled(elem, local, styles); } - if let Some(seq) = content.to::<SequenceNode>() { - for sub in seq.children() { - let stored = self.scratch.content.alloc(sub); - self.accept(stored, styles)?; + if let Some(children) = content.to_sequence() { + for elem in children { + self.accept(elem, styles)?; } return Ok(()); } @@ -290,7 +288,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> { } let keep = content - .to::<PagebreakNode>() + .to::<PagebreakElem>() .map_or(false, |pagebreak| !pagebreak.weak(styles)); self.interrupt_page(keep.then(|| styles))?; @@ -301,52 +299,55 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> { } } - bail!(content.span(), "not allowed here"); + if content.is::<PagebreakElem>() { + bail!(content.span(), "pagebreaks are not allowed inside of containers"); + } else { + bail!(content.span(), "{} is not allowed here", content.func().name()); + } } fn styled( &mut self, - styled: &'a StyledNode, + elem: &'a Content, + map: &'a Styles, styles: StyleChain<'a>, ) -> SourceResult<()> { - let map = self.scratch.maps.alloc(styled.styles()); let stored = self.scratch.styles.alloc(styles); - let content = self.scratch.content.alloc(styled.body()); let styles = stored.chain(map); self.interrupt_style(&map, None)?; - self.accept(content, styles)?; + self.accept(elem, styles)?; self.interrupt_style(map, Some(styles))?; Ok(()) } fn interrupt_style( &mut self, - map: &StyleMap, - styles: Option<StyleChain<'a>>, + local: &Styles, + outer: Option<StyleChain<'a>>, ) -> SourceResult<()> { - if let Some(Some(span)) = map.interruption::<DocumentNode>() { + if let Some(Some(span)) = local.interruption::<DocumentElem>() { if self.doc.is_none() { - bail!(span, "not allowed here"); + bail!(span, "document set rules are not allowed inside of containers"); } - if styles.is_none() + if outer.is_none() && (!self.flow.0.is_empty() || !self.par.0.is_empty() || !self.list.items.is_empty()) { - bail!(span, "must appear before any content"); + bail!(span, "document set rules must appear before any content"); } - } else if let Some(Some(span)) = map.interruption::<PageNode>() { + } else if let Some(Some(span)) = local.interruption::<PageElem>() { if self.doc.is_none() { - bail!(span, "not allowed here"); + bail!(span, "page configuration is not allowed inside of containers"); } - self.interrupt_page(styles)?; - } else if map.interruption::<ParNode>().is_some() - || map.interruption::<AlignNode>().is_some() + self.interrupt_page(outer)?; + } else if local.interruption::<ParElem>().is_some() + || local.interruption::<AlignElem>().is_some() { self.interrupt_par()?; - } else if map.interruption::<ListNode>().is_some() - || map.interruption::<EnumNode>().is_some() - || map.interruption::<TermsNode>().is_some() + } else if local.interruption::<ListElem>().is_some() + || local.interruption::<EnumElem>().is_some() + || local.interruption::<TermsElem>().is_some() { self.interrupt_list()?; } @@ -387,7 +388,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> { } else { shared }; - let page = PageNode::new(FlowNode::new(flow.to_vec()).pack()).pack(); + let page = PageElem::new(FlowElem::new(flow.to_vec()).pack()).pack(); let stored = self.scratch.content.alloc(page); self.accept(stored, styles)?; } @@ -405,12 +406,12 @@ struct DocBuilder<'a> { impl<'a> DocBuilder<'a> { fn accept(&mut self, content: &Content, styles: StyleChain<'a>) -> bool { - if let Some(pagebreak) = content.to::<PagebreakNode>() { + if let Some(pagebreak) = content.to::<PagebreakElem>() { self.keep_next = !pagebreak.weak(styles); return true; } - if content.is::<PageNode>() { + if content.is::<PageElem>() { self.pages.push(content.clone(), styles); self.keep_next = false; return true; @@ -432,7 +433,7 @@ struct FlowBuilder<'a>(BehavedBuilder<'a>, bool); impl<'a> FlowBuilder<'a> { fn accept(&mut self, content: &'a Content, styles: StyleChain<'a>) -> bool { - if content.is::<ParbreakNode>() { + if content.is::<ParbreakElem>() { self.1 = true; return true; } @@ -440,33 +441,33 @@ impl<'a> FlowBuilder<'a> { let last_was_parbreak = self.1; self.1 = false; - if content.is::<VNode>() - || content.is::<ColbreakNode>() - || content.is::<MetaNode>() + if content.is::<VElem>() + || content.is::<ColbreakElem>() + || content.is::<MetaElem>() { self.0.push(content.clone(), styles); return true; } - if content.can::<dyn Layout>() || content.is::<ParNode>() { - let is_tight_list = if let Some(node) = content.to::<ListNode>() { - node.tight(styles) - } else if let Some(node) = content.to::<EnumNode>() { - node.tight(styles) - } else if let Some(node) = content.to::<TermsNode>() { - node.tight(styles) + if content.can::<dyn Layout>() || content.is::<ParElem>() { + let is_tight_list = if let Some(elem) = content.to::<ListElem>() { + elem.tight(styles) + } else if let Some(elem) = content.to::<EnumElem>() { + elem.tight(styles) + } else if let Some(elem) = content.to::<TermsElem>() { + elem.tight(styles) } else { false }; if !last_was_parbreak && is_tight_list { - let leading = ParNode::leading_in(styles); - let spacing = VNode::list_attach(leading.into()); + let leading = ParElem::leading_in(styles); + let spacing = VElem::list_attach(leading.into()); self.0.push(spacing.pack(), styles); } - let above = BlockNode::above_in(styles); - let below = BlockNode::below_in(styles); + let above = BlockElem::above_in(styles); + let below = BlockElem::below_in(styles); self.0.push(above.clone().pack(), styles); self.0.push(content.clone(), styles); self.0.push(below.clone().pack(), styles); @@ -483,18 +484,18 @@ struct ParBuilder<'a>(BehavedBuilder<'a>); impl<'a> ParBuilder<'a> { fn accept(&mut self, content: &'a Content, styles: StyleChain<'a>) -> bool { - if content.is::<MetaNode>() { + if content.is::<MetaElem>() { if !self.0.is_basically_empty() { self.0.push(content.clone(), styles); return true; } - } else if content.is::<SpaceNode>() - || content.is::<TextNode>() - || content.is::<HNode>() - || content.is::<LinebreakNode>() - || content.is::<SmartQuoteNode>() - || content.to::<EquationNode>().map_or(false, |node| !node.block(styles)) - || content.is::<BoxNode>() + } else if content.is::<SpaceElem>() + || content.is::<TextElem>() + || content.is::<HElem>() + || content.is::<LinebreakElem>() + || content.is::<SmartQuoteElem>() + || content.to::<EquationElem>().map_or(false, |elem| !elem.block(styles)) + || content.is::<BoxElem>() { self.0.push(content.clone(), styles); return true; @@ -505,7 +506,7 @@ impl<'a> ParBuilder<'a> { fn finish(self) -> (Content, StyleChain<'a>) { let (children, shared) = self.0.finish(); - (ParNode::new(children.to_vec()).pack(), shared) + (ParElem::new(children.to_vec()).pack(), shared) } } @@ -522,7 +523,7 @@ struct ListBuilder<'a> { impl<'a> ListBuilder<'a> { fn accept(&mut self, content: &'a Content, styles: StyleChain<'a>) -> bool { if !self.items.is_empty() - && (content.is::<SpaceNode>() || content.is::<ParbreakNode>()) + && (content.is::<SpaceElem>() || content.is::<ParbreakElem>()) { self.staged.push((content, styles)); return true; @@ -533,12 +534,12 @@ impl<'a> ListBuilder<'a> { || content.is::<TermItem>()) && self .items - .items() + .elems() .next() - .map_or(true, |first| first.id() == content.id()) + .map_or(true, |first| first.func() == content.func()) { self.items.push(content.clone(), styles); - self.tight &= self.staged.drain(..).all(|(t, _)| !t.is::<ParbreakNode>()); + self.tight &= self.staged.drain(..).all(|(t, _)| !t.is::<ParbreakElem>()); return true; } @@ -549,39 +550,39 @@ impl<'a> ListBuilder<'a> { let (items, shared) = self.items.finish(); let item = items.items().next().unwrap(); let output = if item.is::<ListItem>() { - ListNode::new( + ListElem::new( items .iter() - .map(|(item, map)| { + .map(|(item, local)| { let item = item.to::<ListItem>().unwrap(); - item.clone().with_body(item.body().styled_with_map(map.clone())) + item.clone().with_body(item.body().styled_with_map(local.clone())) }) .collect::<Vec<_>>(), ) .with_tight(self.tight) .pack() } else if item.is::<EnumItem>() { - EnumNode::new( + EnumElem::new( items .iter() - .map(|(item, map)| { + .map(|(item, local)| { let item = item.to::<EnumItem>().unwrap(); - item.clone().with_body(item.body().styled_with_map(map.clone())) + item.clone().with_body(item.body().styled_with_map(local.clone())) }) .collect::<Vec<_>>(), ) .with_tight(self.tight) .pack() } else if item.is::<TermItem>() { - TermsNode::new( + TermsElem::new( items .iter() - .map(|(item, map)| { + .map(|(item, local)| { let item = item.to::<TermItem>().unwrap(); item.clone() - .with_term(item.term().styled_with_map(map.clone())) + .with_term(item.term().styled_with_map(local.clone())) .with_description( - item.description().styled_with_map(map.clone()), + item.description().styled_with_map(local.clone()), ) }) .collect::<Vec<_>>(), diff --git a/library/src/layout/pad.rs b/library/src/layout/pad.rs index e8171560..441aa211 100644 --- a/library/src/layout/pad.rs +++ b/library/src/layout/pad.rs @@ -17,8 +17,8 @@ use crate::prelude::*; /// /// Display: Padding /// Category: layout -#[node(Layout)] -pub struct PadNode { +#[element(Layout)] +pub struct PadElem { /// The padding at the left side. #[parse( let all = args.named("rest")?.or(args.find()?); @@ -59,7 +59,7 @@ pub struct PadNode { pub body: Content, } -impl Layout for PadNode { +impl Layout for PadElem { fn layout( &self, vt: &mut Vt, diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs index 93ee08ce..a8a806ad 100644 --- a/library/src/layout/page.rs +++ b/library/src/layout/page.rs @@ -1,7 +1,7 @@ use std::ptr; use std::str::FromStr; -use super::{AlignNode, ColumnsNode}; +use super::{AlignElem, ColumnsElem}; use crate::meta::{Counter, CounterKey, Numbering}; use crate::prelude::*; @@ -24,8 +24,8 @@ use crate::prelude::*; /// /// Display: Page /// Category: layout -#[node] -pub struct PageNode { +#[element] +pub struct PageElem { /// A standard paper size to set width and height. When this is not /// specified, Typst defaults to `{"a4"}` paper. #[external] @@ -270,7 +270,7 @@ pub struct PageNode { pub body: Content, } -impl PageNode { +impl PageElem { /// Layout the page run into a sequence of frames, one per page. pub fn layout(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Fragment> { // When one of the lengths is infinite the page fits its content along @@ -296,7 +296,7 @@ impl PageNode { // Realize columns. let columns = self.columns(styles); if columns.get() > 1 { - child = ColumnsNode::new(child).with_count(columns).pack(); + child = ColumnsElem::new(child).with_count(columns).pack(); } // Realize margins. @@ -356,7 +356,7 @@ impl PageNode { let pod = Regions::one(area, Axes::splat(true)); let sub = content .clone() - .styled(AlignNode::set_alignment(align)) + .styled(AlignElem::set_alignment(align)) .layout(vt, styles, pod)? .into_frame(); if ptr::eq(marginal, &header) || ptr::eq(marginal, &background) { @@ -387,8 +387,8 @@ impl PageNode { /// /// Display: Page Break /// Category: layout -#[node] -pub struct PagebreakNode { +#[element] +pub struct PagebreakElem { /// If `{true}`, the page break is skipped if the current page is already /// empty. #[default(false)] @@ -467,7 +467,7 @@ macro_rules! papers { fn from_str(name: &str) -> Result<Self, Self::Err> { match name.to_lowercase().as_str() { $($pat => Ok(Self::$var),)* - _ => Err("invalid paper name"), + _ => Err("unknown paper size"), } } } diff --git a/library/src/layout/par.rs b/library/src/layout/par.rs index cef0d11c..db65b125 100644 --- a/library/src/layout/par.rs +++ b/library/src/layout/par.rs @@ -3,17 +3,15 @@ use unicode_bidi::{BidiInfo, Level as BidiLevel}; use unicode_script::{Script, UnicodeScript}; use xi_unicode::LineBreakIterator; -use typst::model::StyledNode; - -use super::{BoxNode, HNode, Sizing, Spacing}; -use crate::layout::AlignNode; -use crate::math::EquationNode; +use super::{BoxElem, HElem, Sizing, Spacing}; +use crate::layout::AlignElem; +use crate::math::EquationElem; use crate::prelude::*; use crate::text::{ - shape, LinebreakNode, Quoter, Quotes, ShapedText, SmartQuoteNode, SpaceNode, TextNode, + shape, LinebreakElem, Quoter, Quotes, ShapedText, SmartQuoteElem, SpaceElem, TextElem, }; -/// Arrange text, spacing and inline-level nodes into a paragraph. +/// Arrange text, spacing and inline-level elements into a paragraph. /// /// Although this function is primarily used in set rules to affect paragraph /// properties, it can also be used to explicitly render its argument onto a @@ -38,8 +36,8 @@ use crate::text::{ /// /// Display: Paragraph /// Category: layout -#[node(Construct)] -pub struct ParNode { +#[element(Construct)] +pub struct ParElem { /// The spacing between lines. /// /// The default value is `{0.65em}`. @@ -110,22 +108,22 @@ pub struct ParNode { pub children: Vec<Content>, } -impl Construct for ParNode { - fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> { +impl Construct for ParElem { + fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> { // The paragraph constructor is special: It doesn't create a paragraph - // node. Instead, it just ensures that the passed content lives in a + // element. Instead, it just ensures that the passed content lives in a // separate paragraph and styles it. let styles = Self::set(args)?; let body = args.expect::<Content>("body")?; - Ok(Content::sequence(vec![ - ParbreakNode::new().pack(), + Ok(Content::sequence([ + ParbreakElem::new().pack(), body.styled_with_map(styles), - ParbreakNode::new().pack(), + ParbreakElem::new().pack(), ])) } } -impl ParNode { +impl ParElem { /// Layout the paragraph into a collection of lines. pub fn layout( &self, @@ -137,7 +135,7 @@ impl ParNode { ) -> SourceResult<Fragment> { #[comemo::memoize] fn cached( - par: &ParNode, + par: &ParElem, world: Tracked<dyn World>, tracer: TrackedMut<Tracer>, provider: TrackedMut<StabilityProvider>, @@ -179,26 +177,6 @@ impl ParNode { } } -/// A horizontal alignment. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct HorizontalAlign(pub GenAlign); - -cast_from_value! { - HorizontalAlign, - align: GenAlign => match align.axis() { - Axis::X => Self(align), - Axis::Y => Err("must be horizontal")?, - }, -} - -impl Resolve for HorizontalAlign { - type Output = Align; - - fn resolve(self, styles: StyleChain) -> Self::Output { - self.0.resolve(styles) - } -} - /// How to determine line breaks in a paragraph. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)] pub enum Linebreaks { @@ -232,10 +210,10 @@ pub enum Linebreaks { /// /// Display: Paragraph Break /// Category: layout -#[node(Unlabellable)] -pub struct ParbreakNode {} +#[element(Unlabellable)] +pub struct ParbreakElem {} -impl Unlabellable for ParbreakNode {} +impl Unlabellable for ParbreakElem {} /// Range of a substring of text. type Range = std::ops::Range<usize>; @@ -243,7 +221,7 @@ type Range = std::ops::Range<usize>; // The characters by which spacing, inline content and pins are replaced in the // paragraph's full text. const SPACING_REPLACE: char = ' '; // Space -const NODE_REPLACE: char = '\u{FFFC}'; // Object Replacement Character +const OBJ_REPLACE: char = '\u{FFFC}'; // Object Replacement Character /// A paragraph representation in which children are already layouted and text /// is already preshaped. @@ -254,7 +232,7 @@ const NODE_REPLACE: char = '\u{FFFC}'; // Object Replacement Character struct Preparation<'a> { /// Bidirectional text embedding levels for the paragraph. bidi: BidiInfo<'a>, - /// Text runs, spacing and layouted nodes. + /// Text runs, spacing and layouted elements. items: Vec<Item<'a>>, /// The span mapper. spans: SpanMapper, @@ -325,9 +303,9 @@ enum Segment<'a> { /// Horizontal spacing between other segments. Spacing(Spacing), /// A mathematical equation. - Equation(&'a EquationNode), + Equation(&'a EquationElem), /// A box with arbitrary content. - Box(&'a BoxNode, bool), + Box(&'a BoxElem, bool), /// Metadata. Meta, } @@ -339,7 +317,7 @@ impl Segment<'_> { Self::Text(len) => len, Self::Spacing(_) => SPACING_REPLACE.len_utf8(), Self::Box(_, true) => SPACING_REPLACE.len_utf8(), - Self::Equation(_) | Self::Box(_, _) | Self::Meta => NODE_REPLACE.len_utf8(), + Self::Equation(_) | Self::Box(_, _) | Self::Meta => OBJ_REPLACE.len_utf8(), } } } @@ -352,7 +330,7 @@ enum Item<'a> { /// Absolute spacing between other items. Absolute(Abs), /// Fractional spacing between other items. - Fractional(Fr, Option<(&'a BoxNode, StyleChain<'a>)>), + Fractional(Fr, Option<(&'a BoxElem, StyleChain<'a>)>), /// Layouted inline-level content. Frame(Frame), } @@ -371,7 +349,7 @@ impl<'a> Item<'a> { match self { Self::Text(shaped) => shaped.text.len(), Self::Absolute(_) | Self::Fractional(_, _) => SPACING_REPLACE.len_utf8(), - Self::Frame(_) => NODE_REPLACE.len_utf8(), + Self::Frame(_) => OBJ_REPLACE.len_utf8(), } } @@ -520,7 +498,7 @@ fn collect<'a>( let mut iter = children.iter().peekable(); if consecutive { - let first_line_indent = ParNode::first_line_indent_in(*styles); + let first_line_indent = ParElem::first_line_indent_in(*styles); if !first_line_indent.is_zero() && children .iter() @@ -529,7 +507,7 @@ fn collect<'a>( behaved.behaviour() == Behaviour::Ignorant }) { None - } else if child.is::<TextNode>() || child.is::<SmartQuoteNode>() { + } else if child.is::<TextElem>() || child.is::<SmartQuoteElem>() { Some(true) } else { Some(false) @@ -542,7 +520,7 @@ fn collect<'a>( } } - let hang = ParNode::hanging_indent_in(*styles); + let hang = ParElem::hanging_indent_in(*styles); if !hang.is_zero() { full.push(SPACING_REPLACE); segments.push((Segment::Spacing((-hang).into()), *styles)); @@ -551,61 +529,61 @@ fn collect<'a>( while let Some(mut child) = iter.next() { let outer = styles; let mut styles = *styles; - if let Some(node) = child.to::<StyledNode>() { - child = Box::leak(Box::new(node.body())); - styles = outer.chain(Box::leak(Box::new(node.styles()))); + if let Some((elem, local)) = child.to_styled() { + child = elem; + styles = outer.chain(local); } - let segment = if child.is::<SpaceNode>() { + let segment = if child.is::<SpaceElem>() { full.push(' '); Segment::Text(1) - } else if let Some(node) = child.to::<TextNode>() { + } else if let Some(elem) = child.to::<TextElem>() { let prev = full.len(); - if let Some(case) = TextNode::case_in(styles) { - full.push_str(&case.apply(&node.text())); + if let Some(case) = TextElem::case_in(styles) { + full.push_str(&case.apply(&elem.text())); } else { - full.push_str(&node.text()); + full.push_str(&elem.text()); } Segment::Text(full.len() - prev) - } else if let Some(node) = child.to::<HNode>() { + } else if let Some(elem) = child.to::<HElem>() { full.push(SPACING_REPLACE); - Segment::Spacing(node.amount()) - } else if let Some(node) = child.to::<LinebreakNode>() { - let c = if node.justify(styles) { '\u{2028}' } else { '\n' }; + Segment::Spacing(elem.amount()) + } else if let Some(elem) = child.to::<LinebreakElem>() { + let c = if elem.justify(styles) { '\u{2028}' } else { '\n' }; full.push(c); Segment::Text(c.len_utf8()) - } else if let Some(node) = child.to::<SmartQuoteNode>() { + } else if let Some(elem) = child.to::<SmartQuoteElem>() { let prev = full.len(); - if SmartQuoteNode::enabled_in(styles) { - let lang = TextNode::lang_in(styles); - let region = TextNode::region_in(styles); + if SmartQuoteElem::enabled_in(styles) { + let lang = TextElem::lang_in(styles); + let region = TextElem::region_in(styles); let quotes = Quotes::from_lang(lang, region); let peeked = iter.peek().and_then(|child| { - if let Some(node) = child.to::<TextNode>() { - node.text().chars().next() - } else if child.is::<SmartQuoteNode>() { + if let Some(elem) = child.to::<TextElem>() { + elem.text().chars().next() + } else if child.is::<SmartQuoteElem>() { Some('"') - } else if child.is::<SpaceNode>() || child.is::<HNode>() { + } else if child.is::<SpaceElem>() || child.is::<HElem>() { Some(SPACING_REPLACE) } else { - Some(NODE_REPLACE) + Some(OBJ_REPLACE) } }); - full.push_str(quoter.quote("es, node.double(styles), peeked)); + full.push_str(quoter.quote("es, elem.double(styles), peeked)); } else { - full.push(if node.double(styles) { '"' } else { '\'' }); + full.push(if elem.double(styles) { '"' } else { '\'' }); } Segment::Text(full.len() - prev) - } else if let Some(node) = child.to::<EquationNode>() { - full.push(NODE_REPLACE); - Segment::Equation(node) - } else if let Some(node) = child.to::<BoxNode>() { - let frac = node.width(styles).is_fractional(); - full.push(if frac { SPACING_REPLACE } else { NODE_REPLACE }); - Segment::Box(node, frac) - } else if child.is::<MetaNode>() { - full.push(NODE_REPLACE); + } else if let Some(elem) = child.to::<EquationElem>() { + full.push(OBJ_REPLACE); + Segment::Equation(elem) + } else if let Some(elem) = child.to::<BoxElem>() { + let frac = elem.width(styles).is_fractional(); + full.push(if frac { SPACING_REPLACE } else { OBJ_REPLACE }); + Segment::Box(elem, frac) + } else if child.is::<MetaElem>() { + full.push(OBJ_REPLACE); Segment::Meta } else { bail!(child.span(), "unexpected paragraph child"); @@ -645,7 +623,7 @@ fn prepare<'a>( ) -> SourceResult<Preparation<'a>> { let bidi = BidiInfo::new( text, - match TextNode::dir_in(styles) { + match TextElem::dir_in(styles) { Dir::LTR => Some(BidiLevel::ltr()), Dir::RTL => Some(BidiLevel::rtl()), _ => None, @@ -674,16 +652,16 @@ fn prepare<'a>( Segment::Equation(equation) => { let pod = Regions::one(region, Axes::splat(false)); let mut frame = equation.layout(vt, styles, pod)?.into_frame(); - frame.translate(Point::with_y(TextNode::baseline_in(styles))); + frame.translate(Point::with_y(TextElem::baseline_in(styles))); items.push(Item::Frame(frame)); } - Segment::Box(node, _) => { - if let Sizing::Fr(v) = node.width(styles) { - items.push(Item::Fractional(v, Some((node, styles)))); + Segment::Box(elem, _) => { + if let Sizing::Fr(v) = elem.width(styles) { + items.push(Item::Fractional(v, Some((elem, styles)))); } else { let pod = Regions::one(region, Axes::splat(false)); - let mut frame = node.layout(vt, styles, pod)?.into_frame(); - frame.translate(Point::with_y(TextNode::baseline_in(styles))); + let mut frame = elem.layout(vt, styles, pod)?.into_frame(); + frame.translate(Point::with_y(TextElem::baseline_in(styles))); items.push(Item::Frame(frame)); } } @@ -702,11 +680,11 @@ fn prepare<'a>( items, spans, styles, - hyphenate: shared_get(styles, children, TextNode::hyphenate_in), - lang: shared_get(styles, children, TextNode::lang_in), - align: AlignNode::alignment_in(styles).x.resolve(styles), - justify: ParNode::justify_in(styles), - hang: ParNode::hanging_indent_in(styles), + hyphenate: shared_get(styles, children, TextElem::hyphenate_in), + lang: shared_get(styles, children, TextElem::lang_in), + align: AlignElem::alignment_in(styles).x.resolve(styles), + justify: ParElem::justify_in(styles), + hang: ParElem::hanging_indent_in(styles), }) } @@ -775,15 +753,15 @@ fn shared_get<'a, T: PartialEq>( let value = getter(styles); children .iter() - .filter_map(|child| child.to::<StyledNode>()) - .all(|node| getter(styles.chain(&node.styles())) == value) + .filter_map(|child| child.to_styled()) + .all(|(_, local)| getter(styles.chain(&local)) == value) .then(|| value) } /// Find suitable linebreaks. fn linebreak<'a>(vt: &Vt, p: &'a Preparation<'a>, width: Abs) -> Vec<Line<'a>> { - let linebreaks = ParNode::linebreaks_in(p.styles).unwrap_or_else(|| { - if ParNode::justify_in(p.styles) { + let linebreaks = ParElem::linebreaks_in(p.styles).unwrap_or_else(|| { + if ParElem::justify_in(p.styles) { Linebreaks::Optimized } else { Linebreaks::Simple @@ -881,7 +859,7 @@ fn linebreak_optimized<'a>(vt: &Vt, p: &'a Preparation<'a>, width: Abs) -> Vec<L line: line(vt, p, 0..0, false, false), }]; - let em = TextNode::size_in(p.styles); + let em = TextElem::size_in(p.styles); for (end, mandatory, hyphen) in breakpoints(p) { let k = table.len(); @@ -1046,7 +1024,7 @@ impl Breakpoints<'_> { .hyphenate .or_else(|| { let shaped = self.p.find(offset)?.text()?; - Some(TextNode::hyphenate_in(shaped.styles)) + Some(TextElem::hyphenate_in(shaped.styles)) }) .unwrap_or(false) } @@ -1055,7 +1033,7 @@ impl Breakpoints<'_> { fn lang(&self, offset: usize) -> Option<hypher::Lang> { let lang = self.p.lang.or_else(|| { let shaped = self.p.find(offset)?.text()?; - Some(TextNode::lang_in(shaped.styles)) + Some(TextElem::lang_in(shaped.styles)) })?; let bytes = lang.as_str().as_bytes().try_into().ok()?; @@ -1196,7 +1174,7 @@ fn finalize( .collect::<SourceResult<_>>()?; // Prevent orphans. - let leading = ParNode::leading_in(p.styles); + let leading = ParElem::leading_in(p.styles); if frames.len() >= 2 && !frames[1].is_empty() { let second = frames.remove(1); let first = &mut frames[0]; @@ -1243,7 +1221,7 @@ fn commit( if let Some(Item::Text(text)) = reordered.first() { if let Some(glyph) = text.glyphs.first() { if !text.dir.is_positive() - && TextNode::overhang_in(text.styles) + && TextElem::overhang_in(text.styles) && (reordered.len() > 1 || text.glyphs.len() > 1) { let amount = overhang(glyph.c) * glyph.x_advance.at(text.size); @@ -1257,7 +1235,7 @@ fn commit( if let Some(Item::Text(text)) = reordered.last() { if let Some(glyph) = text.glyphs.last() { if text.dir.is_positive() - && TextNode::overhang_in(text.styles) + && TextElem::overhang_in(text.styles) && (reordered.len() > 1 || text.glyphs.len() > 1) { let amount = overhang(glyph.c) * glyph.x_advance.at(text.size); @@ -1295,13 +1273,13 @@ fn commit( Item::Absolute(v) => { offset += *v; } - Item::Fractional(v, node) => { + Item::Fractional(v, elem) => { let amount = v.share(fr, remaining); - if let Some((node, styles)) = node { + if let Some((elem, styles)) = elem { let region = Size::new(amount, full); let pod = Regions::one(region, Axes::new(true, false)); - let mut frame = node.layout(vt, *styles, pod)?.into_frame(); - frame.translate(Point::with_y(TextNode::baseline_in(*styles))); + let mut frame = elem.layout(vt, *styles, pod)?.into_frame(); + frame.translate(Point::with_y(TextElem::baseline_in(*styles))); push(&mut offset, frame); } else { offset += amount; diff --git a/library/src/layout/place.rs b/library/src/layout/place.rs index bfabd0f3..057278df 100644 --- a/library/src/layout/place.rs +++ b/library/src/layout/place.rs @@ -23,8 +23,8 @@ use crate::prelude::*; /// /// Display: Place /// Category: layout -#[node(Layout, Behave)] -pub struct PlaceNode { +#[element(Layout, Behave)] +pub struct PlaceElem { /// Relative to which position in the parent container to place the content. /// /// When an axis of the page is `{auto}` sized, all alignments relative to that @@ -53,7 +53,7 @@ pub struct PlaceNode { pub body: Content, } -impl Layout for PlaceNode { +impl Layout for PlaceElem { fn layout( &self, vt: &mut Vt, @@ -86,16 +86,16 @@ impl Layout for PlaceNode { } } -impl PlaceNode { - /// Whether this node wants to be placed relative to its its parent's base - /// origin. Instead of relative to the parent's current flow/cursor +impl PlaceElem { + /// Whether this element wants to be placed relative to its its parent's + /// base origin. Instead of relative to the parent's current flow/cursor /// position. pub fn out_of_flow(&self, styles: StyleChain) -> bool { self.alignment(styles).y.is_some() } } -impl Behave for PlaceNode { +impl Behave for PlaceElem { fn behaviour(&self) -> Behaviour { Behaviour::Ignorant } diff --git a/library/src/layout/regions.rs b/library/src/layout/regions.rs index 94c81704..5a4db178 100644 --- a/library/src/layout/regions.rs +++ b/library/src/layout/regions.rs @@ -14,8 +14,8 @@ pub struct Regions<'a> { /// The height of the final region that is repeated once the backlog is /// drained. The width is the same for all regions. pub last: Option<Abs>, - /// Whether nodes should expand to fill the regions instead of shrinking to - /// fit the content. + /// Whether elements should expand to fill the regions instead of shrinking + /// to fit the content. pub expand: Axes<bool>, } diff --git a/library/src/layout/repeat.rs b/library/src/layout/repeat.rs index c8f63ac3..a44bd075 100644 --- a/library/src/layout/repeat.rs +++ b/library/src/layout/repeat.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use super::AlignNode; +use super::AlignElem; /// Repeats content to the available space. /// @@ -23,14 +23,14 @@ use super::AlignNode; /// /// Display: Repeat /// Category: layout -#[node(Layout)] -pub struct RepeatNode { +#[element(Layout)] +pub struct RepeatElem { /// The content to repeat. #[required] pub body: Content, } -impl Layout for RepeatNode { +impl Layout for RepeatElem { fn layout( &self, vt: &mut Vt, @@ -39,7 +39,7 @@ impl Layout for RepeatNode { ) -> SourceResult<Fragment> { let pod = Regions::one(regions.size, Axes::new(false, false)); let piece = self.body().layout(vt, styles, pod)?.into_frame(); - let align = AlignNode::alignment_in(styles).x.resolve(styles); + let align = AlignElem::alignment_in(styles).x.resolve(styles); let fill = regions.size.x; let width = piece.width(); diff --git a/library/src/layout/spacing.rs b/library/src/layout/spacing.rs index e67fec03..9253c497 100644 --- a/library/src/layout/spacing.rs +++ b/library/src/layout/spacing.rs @@ -21,8 +21,8 @@ use crate::prelude::*; /// /// Display: Spacing (H) /// Category: layout -#[node(Behave)] -pub struct HNode { +#[element(Behave)] +pub struct HElem { /// How much spacing to insert. #[required] pub amount: Spacing, @@ -45,7 +45,7 @@ pub struct HNode { pub weak: bool, } -impl Behave for HNode { +impl Behave for HElem { fn behaviour(&self) -> Behaviour { if self.amount().is_fractional() { Behaviour::Destructive @@ -85,8 +85,8 @@ impl Behave for HNode { /// /// Display: Spacing (V) /// Category: layout -#[node(Behave)] -pub struct VNode { +#[element(Behave)] +pub struct VElem { /// How much spacing to insert. #[required] pub amount: Spacing, @@ -107,13 +107,13 @@ pub struct VNode { #[external] pub weak: bool, - /// The node's weakness level, see also [`Behaviour`]. + /// The elements's weakness level, see also [`Behaviour`]. #[internal] #[parse(args.named("weak")?.map(|v: bool| v as usize))] pub weakness: usize, } -impl VNode { +impl VElem { /// Normal strong spacing. pub fn strong(amount: Spacing) -> Self { Self::new(amount).with_weakness(0) @@ -129,18 +129,18 @@ impl VNode { Self::new(amount).with_weakness(2) } - /// Weak spacing with BlockNode::ABOVE/BELOW weakness. + /// Weak spacing with BlockElem::ABOVE/BELOW weakness. pub fn block_around(amount: Spacing) -> Self { Self::new(amount).with_weakness(3) } - /// Weak spacing with BlockNode::SPACING weakness. + /// Weak spacing with BlockElem::SPACING weakness. pub fn block_spacing(amount: Spacing) -> Self { Self::new(amount).with_weakness(4) } } -impl Behave for VNode { +impl Behave for VElem { fn behaviour(&self) -> Behaviour { if self.amount().is_fractional() { Behaviour::Destructive @@ -158,8 +158,8 @@ impl Behave for VNode { } cast_from_value! { - VNode, - v: Content => v.to::<Self>().cloned().ok_or("expected vnode")?, + VElem, + v: Content => v.to::<Self>().cloned().ok_or("expected `v` element")?, } /// Kinds of spacing. diff --git a/library/src/layout/stack.rs b/library/src/layout/stack.rs index 1dd81a60..77cd3f8f 100644 --- a/library/src/layout/stack.rs +++ b/library/src/layout/stack.rs @@ -1,6 +1,4 @@ -use typst::model::StyledNode; - -use super::{AlignNode, Spacing}; +use super::{AlignElem, Spacing}; use crate::prelude::*; /// Arrange content and spacing horizontally or vertically. @@ -20,8 +18,8 @@ use crate::prelude::*; /// /// Display: Stack /// Category: layout -#[node(Layout)] -pub struct StackNode { +#[element(Layout)] +pub struct StackElem { /// The direction along which the items are stacked. Possible values are: /// /// - `{ltr}`: Left to right. @@ -39,7 +37,7 @@ pub struct StackNode { pub children: Vec<StackChild>, } -impl Layout for StackNode { +impl Layout for StackElem { fn layout( &self, vt: &mut Vt, @@ -73,7 +71,7 @@ impl Layout for StackNode { } } -/// A child of a stack node. +/// A child of a stack element. #[derive(Hash)] pub enum StackChild { /// Spacing between other children. @@ -196,14 +194,13 @@ impl<'a> StackLayouter<'a> { self.finish_region(); } - // Block-axis alignment of the `AlignNode` is respected - // by the stack node. - let aligns = if let Some(align) = block.to::<AlignNode>() { + // Block-axis alignment of the `AlignElement` is respected by stacks. + let aligns = if let Some(align) = block.to::<AlignElem>() { align.alignment(styles) - } else if let Some(styled) = block.to::<StyledNode>() { - AlignNode::alignment_in(styles.chain(&styled.styles())) + } else if let Some((_, local)) = block.to_styled() { + AlignElem::alignment_in(styles.chain(&local)) } else { - AlignNode::alignment_in(styles) + AlignElem::alignment_in(styles) } .resolve(styles); diff --git a/library/src/layout/table.rs b/library/src/layout/table.rs index d4b6e7d7..809c7ea7 100644 --- a/library/src/layout/table.rs +++ b/library/src/layout/table.rs @@ -1,4 +1,4 @@ -use crate::layout::{AlignNode, GridLayouter, TrackSizings}; +use crate::layout::{AlignElem, GridLayouter, TrackSizings}; use crate::meta::LocalName; use crate::prelude::*; @@ -32,8 +32,8 @@ use crate::prelude::*; /// /// Display: Table /// Category: layout -#[node(Layout, LocalName)] -pub struct TableNode { +#[element(Layout, LocalName)] +pub struct TableElem { /// Defines the column sizes. See the [grid documentation]($func/grid) for /// more information on track sizing. pub columns: TrackSizings, @@ -109,7 +109,7 @@ pub struct TableNode { pub children: Vec<Content>, } -impl Layout for TableNode { +impl Layout for TableElem { fn layout( &self, vt: &mut Vt, @@ -132,7 +132,7 @@ impl Layout for TableNode { let x = i % cols; let y = i / cols; if let Smart::Custom(alignment) = align.resolve(vt, x, y)? { - child = child.styled(AlignNode::set_alignment(alignment)); + child = child.styled(AlignElem::set_alignment(alignment)); } Ok(child) @@ -168,7 +168,7 @@ impl Layout for TableNode { let hline = Geometry::Line(target).stroked(stroke); frame.prepend( Point::new(-half, offset), - Element::Shape(hline, self.span()), + FrameItem::Shape(hline, self.span()), ); } @@ -178,7 +178,7 @@ impl Layout for TableNode { let vline = Geometry::Line(target).stroked(stroke); frame.prepend( Point::new(offset, -half), - Element::Shape(vline, self.span()), + FrameItem::Shape(vline, self.span()), ); } } @@ -192,7 +192,7 @@ impl Layout for TableNode { let pos = Point::new(dx, dy); let size = Size::new(col, row.height); let rect = Geometry::Rect(size).filled(fill); - frame.prepend(pos, Element::Shape(rect, self.span())); + frame.prepend(pos, FrameItem::Shape(rect, self.span())); } dy += row.height; } @@ -271,7 +271,7 @@ impl<T: Into<Value>> From<Celled<T>> for Value { } } -impl LocalName for TableNode { +impl LocalName for TableElem { fn local_name(&self, lang: Lang) -> &'static str { match lang { Lang::GERMAN => "Tabelle", diff --git a/library/src/layout/terms.rs b/library/src/layout/terms.rs index 853dd32d..1200076f 100644 --- a/library/src/layout/terms.rs +++ b/library/src/layout/terms.rs @@ -1,7 +1,7 @@ -use super::{HNode, VNode}; -use crate::layout::{BlockNode, ParNode, Spacing}; +use super::{HElem, VElem}; +use crate::layout::{BlockElem, ParElem, Spacing}; use crate::prelude::*; -use crate::text::{SpaceNode, TextNode}; +use crate::text::{SpaceElem, TextElem}; /// A list of terms and their descriptions. /// @@ -22,8 +22,8 @@ use crate::text::{SpaceNode, TextNode}; /// /// Display: Term List /// Category: layout -#[node(Layout)] -pub struct TermsNode { +#[element(Layout)] +pub struct TermsElem { /// If this is `{false}`, the items are spaced apart with [term list /// spacing]($func/terms.spacing). If it is `{true}`, they use normal /// [leading]($func/par.leading) instead. This makes the term list more @@ -76,7 +76,7 @@ pub struct TermsNode { pub children: Vec<TermItem>, } -impl Layout for TermsNode { +impl Layout for TermsElem { fn layout( &self, vt: &mut Vt, @@ -86,27 +86,27 @@ impl Layout for TermsNode { let indent = self.indent(styles); let hanging_indent = self.hanging_indent(styles); let gutter = if self.tight(styles) { - ParNode::leading_in(styles).into() + ParElem::leading_in(styles).into() } else { self.spacing(styles) - .unwrap_or_else(|| BlockNode::below_in(styles).amount()) + .unwrap_or_else(|| BlockElem::below_in(styles).amount()) }; let mut seq = vec![]; for (i, child) in self.children().into_iter().enumerate() { if i > 0 { - seq.push(VNode::new(gutter).with_weakness(1).pack()); + seq.push(VElem::new(gutter).with_weakness(1).pack()); } if indent.is_zero() { - seq.push(HNode::new(indent.into()).pack()); + seq.push(HElem::new(indent.into()).pack()); } - seq.push((child.term() + TextNode::packed(':')).strong()); - seq.push(SpaceNode::new().pack()); + seq.push((child.term() + TextElem::packed(':')).strong()); + seq.push(SpaceElem::new().pack()); seq.push(child.description()); } Content::sequence(seq) - .styled(ParNode::set_hanging_indent(hanging_indent + indent)) + .styled(ParElem::set_hanging_indent(hanging_indent + indent)) .layout(vt, styles, regions) } } @@ -115,7 +115,7 @@ impl Layout for TermsNode { /// /// Display: Term List Item /// Category: layout -#[node] +#[element] pub struct TermItem { /// The term described by the list item. #[required] diff --git a/library/src/layout/transform.rs b/library/src/layout/transform.rs index 2afe8201..2045e9ed 100644 --- a/library/src/layout/transform.rs +++ b/library/src/layout/transform.rs @@ -23,8 +23,8 @@ use crate::prelude::*; /// /// Display: Move /// Category: layout -#[node(Layout)] -pub struct MoveNode { +#[element(Layout)] +pub struct MoveElem { /// The horizontal displacement of the content. pub dx: Rel<Length>, @@ -36,7 +36,7 @@ pub struct MoveNode { pub body: Content, } -impl Layout for MoveNode { +impl Layout for MoveElem { fn layout( &self, vt: &mut Vt, @@ -69,8 +69,8 @@ impl Layout for MoveNode { /// /// Display: Rotate /// Category: layout -#[node(Layout)] -pub struct RotateNode { +#[element(Layout)] +pub struct RotateElem { /// The amount of rotation. /// /// ```example @@ -104,7 +104,7 @@ pub struct RotateNode { pub body: Content, } -impl Layout for RotateNode { +impl Layout for RotateElem { fn layout( &self, vt: &mut Vt, @@ -137,8 +137,8 @@ impl Layout for RotateNode { /// /// Display: Scale /// Category: layout -#[node(Layout)] -pub struct ScaleNode { +#[element(Layout)] +pub struct ScaleElem { /// The horizontal scaling factor. /// /// The body will be mirrored horizontally if the parameter is negative. @@ -172,7 +172,7 @@ pub struct ScaleNode { pub body: Content, } -impl Layout for ScaleNode { +impl Layout for ScaleElem { fn layout( &self, vt: &mut Vt, |
