summaryrefslogtreecommitdiff
path: root/library/src/layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-19 22:28:49 +0100
committerLaurenz <laurmaedje@gmail.com>2023-03-19 22:39:19 +0100
commitab43bd802eafe33977a91893907e67553e099569 (patch)
treeaf4dead92b143348f52e2e8f869df3f7dfd7322a /library/src/layout
parentd6aaae0cea1e79eecd85dc94ab85b9ad8eff48e8 (diff)
Renaming and refactoring
Diffstat (limited to 'library/src/layout')
-rw-r--r--library/src/layout/align.rs6
-rw-r--r--library/src/layout/columns.rs16
-rw-r--r--library/src/layout/container.rs30
-rw-r--r--library/src/layout/enum.rs18
-rw-r--r--library/src/layout/flow.rs86
-rw-r--r--library/src/layout/grid.rs10
-rw-r--r--library/src/layout/hide.rs8
-rw-r--r--library/src/layout/list.rs20
-rw-r--r--library/src/layout/measure.rs2
-rw-r--r--library/src/layout/mod.rs183
-rw-r--r--library/src/layout/pad.rs6
-rw-r--r--library/src/layout/page.rs18
-rw-r--r--library/src/layout/par.rs194
-rw-r--r--library/src/layout/place.rs14
-rw-r--r--library/src/layout/regions.rs4
-rw-r--r--library/src/layout/repeat.rs10
-rw-r--r--library/src/layout/spacing.rs24
-rw-r--r--library/src/layout/stack.rs23
-rw-r--r--library/src/layout/table.rs18
-rw-r--r--library/src/layout/terms.rs28
-rw-r--r--library/src/layout/transform.rs18
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(&quotes, node.double(styles), peeked));
+ full.push_str(quoter.quote(&quotes, 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,