diff --git a/docs/Cargo.toml b/docs/Cargo.toml index b168fde88..af44dd88c 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -5,7 +5,6 @@ authors = ["The Typst Project Developers"] edition = "2021" [lib] -test = false doctest = false bench = false diff --git a/docs/src/html.rs b/docs/src/html.rs index 7802ee105..33003349c 100644 --- a/docs/src/html.rs +++ b/docs/src/html.rs @@ -309,7 +309,10 @@ fn code_block(resolver: &dyn Resolver, lang: &str, text: &str) -> Html { let world = DocWorld(source); let mut frames = match typst::compile(&world, &world.0) { Ok(doc) => doc.pages, - Err(err) => panic!("failed to compile {text}: {err:?}"), + Err(err) => { + let msg = &err[0].message; + panic!("while trying to compile {text}:\n\nerror: {msg}"); + } }; if let Some([x, y, w, h]) = zoom { diff --git a/docs/src/lib.rs b/docs/src/lib.rs index c32f9ff97..7ddc1c70c 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -745,3 +745,29 @@ const TYPE_ORDER: &[&str] = &[ "selector", "stroke", ]; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_docs() { + provide(&TestResolver); + } + + struct TestResolver; + + impl Resolver for TestResolver { + fn link(&self, _: &str) -> Option { + None + } + + fn example(&self, _: Html, _: &[Frame]) -> Html { + Html::new(String::new()) + } + + fn image(&self, _: &str, _: &[u8]) -> String { + String::new() + } + } +} diff --git a/docs/src/reference/styling.md b/docs/src/reference/styling.md index cdc47f29c..43585b136 100644 --- a/docs/src/reference/styling.md +++ b/docs/src/reference/styling.md @@ -85,8 +85,8 @@ fantasy encyclopedia. #set heading(numbering: "(I)") #show heading: it => block[ #set align(center) - \~ _#it.title;_ #set text(font: "Inria Serif") + \~ _#it.body;_ #it.numbers \~ ] diff --git a/docs/src/tutorial/3-advanced.md b/docs/src/tutorial/3-advanced.md index 0e337d86b..3784bc8e0 100644 --- a/docs/src/tutorial/3-advanced.md +++ b/docs/src/tutorial/3-advanced.md @@ -359,7 +359,7 @@ a way to set any of that, we need to write our own heading show rule. #show heading: it => block[ #set align(center) #set text(12pt, weight: "regular") - #smallcaps(it.title) + #smallcaps(it.body) ] <<< ... @@ -441,7 +441,7 @@ differentiate between section and subsection headings: ): it => block[ #set align(center) #set text(12pt, weight: "regular") - #smallcaps(it.title) + #smallcaps(it.body) ] #show heading.where( @@ -450,7 +450,7 @@ differentiate between section and subsection headings: size: 11pt, weight: "regular", style: "italic", - it.title + [.], + it.body + [.], ) >>> >>> #align(center, text( diff --git a/docs/src/tutorial/4-template.md b/docs/src/tutorial/4-template.md index c97ebbc97..47f9dfc60 100644 --- a/docs/src/tutorial/4-template.md +++ b/docs/src/tutorial/4-template.md @@ -107,7 +107,7 @@ previous chapter. >>> text( >>> 13pt, >>> weight: "regular", ->>> smallcaps(it.title), +>>> smallcaps(it.body), >>> ) >>> ), >>> ) @@ -118,7 +118,7 @@ previous chapter. >>> 11pt, >>> weight: "regular", >>> style: "italic", ->>> it.title + [.], +>>> it.body + [.], >>> ) >>> ) @@ -288,7 +288,7 @@ path of the file after the `{from}` keyword. >>> text( >>> 13pt, >>> weight: "regular", ->>> smallcaps(it.title), +>>> smallcaps(it.body), >>> ) >>> ), >>> ) @@ -299,7 +299,7 @@ path of the file after the `{from}` keyword. >>> 11pt, >>> weight: "regular", >>> style: "italic", ->>> it.title + [.], +>>> it.body + [.], >>> ) >>> ) >>> diff --git a/library/src/layout/align.rs b/library/src/layout/align.rs index bd9c60fa3..e0df04361 100644 --- a/library/src/layout/align.rs +++ b/library/src/layout/align.rs @@ -20,11 +20,6 @@ use crate::prelude::*; styles.set(Self::ALIGNMENT, aligns); })] pub struct AlignNode { - /// The content to align. - #[positional] - #[required] - pub body: Content, - /// The alignment along both axes. /// /// Possible values for horizontal alignments are: @@ -62,6 +57,11 @@ pub struct AlignNode { #[skip] #[default(Axes::new(GenAlign::Start, GenAlign::Specific(Align::Top)))] pub alignment: Axes>, + + /// The content to align. + #[positional] + #[required] + pub body: Content, } impl Show for AlignNode { diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs index 67504ca3f..8f5d69cc1 100644 --- a/library/src/layout/container.rs +++ b/library/src/layout/container.rs @@ -26,7 +26,7 @@ pub struct BoxNode { /// The contents of the box. #[positional] #[default] - pub body: Content, + pub body: Option, /// The width of the box. /// @@ -133,16 +133,16 @@ impl Layout for BoxNode { .unwrap_or(regions.base()); // Apply inset. - let mut child = self.body(); + let mut body = self.body().unwrap_or_default(); let inset = styles.get(Self::INSET); if inset.iter().any(|v| !v.is_zero()) { - child = child.padded(inset.map(|side| side.map(Length::from))); + body = body.padded(inset.map(|side| side.map(Length::from))); } // Select the appropriate base and expansion for the child depending // on whether it is automatically or relatively sized. let pod = Regions::one(size, expand); - let mut frame = child.layout(vt, styles, pod)?.into_frame(); + let mut frame = body.layout(vt, styles, pod)?.into_frame(); // Apply baseline shift. let shift = styles.get(Self::BASELINE).relative_to(frame.height()); @@ -191,11 +191,11 @@ impl Layout for BoxNode { /// Blocks are also useful to force elements that would otherwise be inline to /// become block-level, especially when writing show rules. /// ```example -/// #show heading: it => it.title +/// #show heading: it => it.body /// = Blockless /// More text. /// -/// #show heading: it => block(it.title) +/// #show heading: it => block(it.body) /// = Blocky /// More text. /// ``` @@ -236,7 +236,7 @@ pub struct BlockNode { /// The contents of the block. #[positional] #[default] - pub body: Content, + pub body: Option, /// The block's width. /// @@ -360,10 +360,10 @@ impl Layout for BlockNode { regions: Regions, ) -> SourceResult { // Apply inset. - let mut child = self.body(); + let mut body = self.body().unwrap_or_default(); let inset = styles.get(Self::INSET); if inset.iter().any(|v| !v.is_zero()) { - child = child.clone().padded(inset.map(|side| side.map(Length::from))); + body = body.clone().padded(inset.map(|side| side.map(Length::from))); } // Resolve the sizing to a concrete size. @@ -380,7 +380,7 @@ impl Layout for BlockNode { // Measure to ensure frames for all regions have the same width. if sizing.x == Smart::Auto { let pod = Regions::one(size, Axes::splat(false)); - let frame = child.layout(vt, styles, pod)?.into_frame(); + let frame = body.layout(vt, styles, pod)?.into_frame(); size.x = frame.width(); expand.x = true; } @@ -407,10 +407,10 @@ impl Layout for BlockNode { pod.last = None; } - child.layout(vt, styles, pod)?.into_frames() + body.layout(vt, styles, pod)?.into_frames() } else { let pod = Regions::one(size, expand); - child.layout(vt, styles, pod)?.into_frames() + body.layout(vt, styles, pod)?.into_frames() }; // Prepare fill and stroke. diff --git a/library/src/layout/enum.rs b/library/src/layout/enum.rs index edc954d0d..853a7a672 100644 --- a/library/src/layout/enum.rs +++ b/library/src/layout/enum.rs @@ -77,7 +77,7 @@ pub struct EnumNode { /// ) [+ #phase] /// ``` #[variadic] - pub items: Vec, + pub children: Vec, /// If this is `{false}`, the items are spaced apart with /// [enum spacing]($func/enum.spacing). If it is `{true}`, they use normal @@ -203,7 +203,7 @@ impl Layout for EnumNode { let mut parents = styles.get(Self::PARENTS); let full = styles.get(Self::FULL); - for item in self.items() { + for item in self.children() { number = item.number().unwrap_or(number); let resolved = if full { diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs index 02f348576..8554bd981 100644 --- a/library/src/layout/flow.rs +++ b/library/src/layout/flow.rs @@ -34,7 +34,7 @@ impl Layout for FlowNode { if let Some(node) = child.to::() { map = node.map(); styles = outer.chain(&map); - child = node.sub(); + child = node.body(); } if let Some(node) = child.to::() { diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs index d3758fd61..b6465e1c3 100644 --- a/library/src/layout/grid.rs +++ b/library/src/layout/grid.rs @@ -73,7 +73,7 @@ pub struct GridNode { /// /// The cells are populated in row-major order. #[variadic] - pub cells: Vec, + pub children: Vec, /// Defines the column sizes. /// @@ -114,7 +114,7 @@ impl Layout for GridNode { regions: Regions, ) -> SourceResult { // Prepare grid layout by unifying content and gutter tracks. - let cells = self.cells(); + let cells = self.children(); let layouter = GridLayouter::new( vt, Axes::new(&self.columns().0, &self.rows().0), diff --git a/library/src/layout/list.rs b/library/src/layout/list.rs index 69d2e717e..5ba6b9b0f 100644 --- a/library/src/layout/list.rs +++ b/library/src/layout/list.rs @@ -49,7 +49,7 @@ pub struct ListNode { /// ] /// ``` #[variadic] - pub items: Vec, + pub children: Vec, /// If this is `{false}`, the items are spaced apart with [list /// spacing]($func/list.spacing). If it is `{true}`, they use normal @@ -141,7 +141,7 @@ impl Layout for ListNode { let marker = styles.get(Self::MARKER).resolve(vt.world(), depth)?; let mut cells = vec![]; - for item in self.items() { + for item in self.children() { cells.push(Content::empty()); cells.push(marker.clone()); cells.push(Content::empty()); diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs index afdfd7958..96d16ec84 100644 --- a/library/src/layout/mod.rs +++ b/library/src/layout/mod.rs @@ -307,7 +307,7 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> { ) -> SourceResult<()> { let map = self.scratch.maps.alloc(styled.map()); let stored = self.scratch.styles.alloc(styles); - let content = self.scratch.content.alloc(styled.sub()); + let content = self.scratch.content.alloc(styled.body()); let styles = stored.chain(map); self.interrupt_style(&map, None)?; self.accept(content, styles)?; diff --git a/library/src/layout/par.rs b/library/src/layout/par.rs index a55b2dc33..2564940c0 100644 --- a/library/src/layout/par.rs +++ b/library/src/layout/par.rs @@ -521,7 +521,7 @@ fn collect<'a>( let outer = styles; let mut styles = *styles; if let Some(node) = child.to::() { - child = Box::leak(Box::new(node.sub())); + child = Box::leak(Box::new(node.body())); styles = outer.chain(Box::leak(Box::new(node.map()))); } diff --git a/library/src/layout/table.rs b/library/src/layout/table.rs index 33ce9088c..0083a7bf5 100644 --- a/library/src/layout/table.rs +++ b/library/src/layout/table.rs @@ -40,7 +40,7 @@ use crate::prelude::*; pub struct TableNode { /// The contents of the table cells. #[variadic] - pub cells: Vec, + pub children: Vec, /// Defines the column sizes. /// See the [grid documentation]($func/grid) for more information on track @@ -135,7 +135,7 @@ impl Layout for TableNode { let gutter = Axes::new(self.column_gutter().0, self.row_gutter().0); let cols = tracks.x.len().max(1); let cells: Vec<_> = self - .cells() + .children() .into_iter() .enumerate() .map(|(i, child)| { diff --git a/library/src/layout/terms.rs b/library/src/layout/terms.rs index e8adfdda1..2933ea20a 100644 --- a/library/src/layout/terms.rs +++ b/library/src/layout/terms.rs @@ -36,7 +36,7 @@ pub struct TermsNode { /// ) [/ #product: Born in #year.] /// ``` #[variadic] - pub items: Vec, + pub children: Vec, /// If this is `{false}`, the items are spaced apart with [term list /// spacing]($func/terms.spacing). If it is `{true}`, they use normal @@ -101,12 +101,12 @@ impl Layout for TermsNode { }; let mut cells = vec![]; - for item in self.items() { + for child in self.children() { let body = Content::sequence(vec![ HNode::new((-body_indent).into()).pack(), - (item.term() + TextNode::packed(':')).strong(), + (child.term() + TextNode::packed(':')).strong(), SpaceNode::new().pack(), - item.description(), + child.description(), ]); cells.push(Content::empty()); diff --git a/library/src/math/attach.rs b/library/src/math/attach.rs index 9181ab7c5..7ba1484a6 100644 --- a/library/src/math/attach.rs +++ b/library/src/math/attach.rs @@ -79,12 +79,12 @@ pub struct ScriptsNode { /// The base to attach the scripts to. #[positional] #[required] - pub base: Content, + pub body: Content, } impl LayoutMath for ScriptsNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - self.base().layout_math(ctx) + self.body().layout_math(ctx) } } @@ -102,12 +102,12 @@ pub struct LimitsNode { /// The base to attach the limits to. #[positional] #[required] - pub base: Content, + pub body: Content, } impl LayoutMath for LimitsNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - self.base().layout_math(ctx) + self.body().layout_math(ctx) } } diff --git a/library/src/math/matrix.rs b/library/src/math/matrix.rs index 3e2573853..c73037353 100644 --- a/library/src/math/matrix.rs +++ b/library/src/math/matrix.rs @@ -20,7 +20,7 @@ const VERTICAL_PADDING: Ratio = Ratio::new(0.1); pub struct VecNode { /// The elements of the vector. #[variadic] - pub elements: Vec, + pub children: Vec, /// The delimiter to use. /// @@ -36,7 +36,7 @@ pub struct VecNode { impl LayoutMath for VecNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = ctx.styles().get(Self::DELIM); - let frame = layout_vec_body(ctx, &self.elements(), Align::Center)?; + let frame = layout_vec_body(ctx, &self.children(), Align::Center)?; layout_delimiters(ctx, frame, Some(delim.open()), Some(delim.close())) } } @@ -141,7 +141,7 @@ impl LayoutMath for MatNode { pub struct CasesNode { /// The branches of the case distinction. #[variadic] - pub branches: Vec, + pub children: Vec, /// The delimiter to use. /// @@ -157,7 +157,7 @@ pub struct CasesNode { impl LayoutMath for CasesNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = ctx.styles().get(Self::DELIM); - let frame = layout_vec_body(ctx, &self.branches(), Align::Left)?; + let frame = layout_vec_body(ctx, &self.children(), Align::Left)?; layout_delimiters(ctx, frame, Some(delim.open()), None) } } diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index d719cb1a8..6f5e59077 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -242,7 +242,7 @@ impl LayoutMath for Content { let prev_size = ctx.size; ctx.map.apply(prev_map.clone()); ctx.size = ctx.styles().get(TextNode::SIZE); - styled.sub().layout_math(ctx)?; + styled.body().layout_math(ctx)?; ctx.size = prev_size; ctx.map = prev_map; return Ok(()); diff --git a/library/src/meta/document.rs b/library/src/meta/document.rs index 0d03b4969..29ed38fec 100644 --- a/library/src/meta/document.rs +++ b/library/src/meta/document.rs @@ -44,7 +44,7 @@ impl LayoutRoot for DocumentNode { if let Some(node) = child.to::() { map = node.map(); styles = outer.chain(&map); - child = node.sub(); + child = node.body(); } if let Some(page) = child.to::() { diff --git a/library/src/meta/heading.rs b/library/src/meta/heading.rs index 38890885c..bd95001b4 100644 --- a/library/src/meta/heading.rs +++ b/library/src/meta/heading.rs @@ -45,7 +45,7 @@ pub struct HeadingNode { /// The heading's title. #[positional] #[required] - pub title: Content, + pub body: Content, /// The logical nesting depth of the heading, starting from one. #[named] @@ -120,14 +120,14 @@ impl Prepare for HeadingNode { impl Show for HeadingNode { fn show(&self, _: &mut Vt, this: &Content, _: StyleChain) -> SourceResult { - let mut realized = self.title(); + let mut realized = self.body(); let numbers = this.field("numbers").unwrap(); if *numbers != Value::None { realized = numbers.clone().display() + HNode::new(Em::new(0.3).into()).with_weak(true).pack() + realized; } - Ok(BlockNode::new().with_body(realized).pack()) + Ok(BlockNode::new().with_body(Some(realized)).pack()) } } diff --git a/library/src/meta/outline.rs b/library/src/meta/outline.rs index 7bc08bf99..4b5a44f73 100644 --- a/library/src/meta/outline.rs +++ b/library/src/meta/outline.rs @@ -103,7 +103,7 @@ impl Show for OutlineNode { ) -> SourceResult { let mut seq = vec![ParbreakNode::new().pack()]; if let Some(title) = styles.get(Self::TITLE) { - let body = title.clone().unwrap_or_else(|| { + let title = title.clone().unwrap_or_else(|| { TextNode::packed(match styles.get(TextNode::LANG) { Lang::GERMAN => "Inhaltsverzeichnis", Lang::ENGLISH | _ => "Contents", @@ -111,7 +111,7 @@ impl Show for OutlineNode { }); seq.push( - HeadingNode::new(body) + HeadingNode::new(title) .pack() .styled(HeadingNode::NUMBERING, None) .styled(HeadingNode::OUTLINED, false), @@ -161,7 +161,7 @@ impl Show for OutlineNode { } // Format the numbering. - let mut start = heading.title(); + let mut start = heading.body(); let numbers = node.field("numbers").unwrap(); if *numbers != Value::None { start = numbers.clone().display() + SpaceNode::new().pack() + start; @@ -175,7 +175,7 @@ impl Show for OutlineNode { seq.push(SpaceNode::new().pack()); seq.push( BoxNode::new() - .with_body(filler.clone()) + .with_body(Some(filler.clone())) .with_width(Fr::one().into()) .pack(), ); diff --git a/library/src/text/raw.rs b/library/src/text/raw.rs index 8c40c6ea5..4eefb0eac 100644 --- a/library/src/text/raw.rs +++ b/library/src/text/raw.rs @@ -171,7 +171,7 @@ impl Show for RawNode { }; if self.block() { - realized = BlockNode::new().with_body(realized).pack(); + realized = BlockNode::new().with_body(Some(realized)).pack(); } Ok(realized) diff --git a/src/model/content.rs b/src/model/content.rs index 189ee23a5..1b87aaea3 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -55,7 +55,7 @@ impl Content { /// Attach a span to the content. pub fn spanned(mut self, span: Span) -> Self { if let Some(styled) = self.to::() { - self = StyledNode::new(styled.sub().spanned(span), styled.map()).pack(); + self = StyledNode::new(styled.body().spanned(span), styled.map()).pack(); } self.span = Some(span); self @@ -83,7 +83,7 @@ impl Content { } else if let Some(styled) = self.to::() { let mut map = styled.map(); map.apply(styles); - StyledNode::new(styled.sub(), map).pack() + StyledNode::new(styled.body(), map).pack() } else { StyledNode::new(self, styles).pack() } @@ -268,7 +268,7 @@ impl Debug for Content { if let Some(styled) = self.to::() { styled.map().fmt(f)?; - styled.sub().fmt(f) + styled.body().fmt(f) } else if let Some(seq) = self.to::() { f.debug_list().entries(&seq.children()).finish() } else if self.id.name() == "space" { @@ -334,7 +334,7 @@ pub struct StyledNode { /// The styled content. #[positional] #[required] - pub sub: Content, + pub body: Content, /// The styles. #[positional] diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 75931a8c5..2fdedbcf6 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -165,7 +165,7 @@ pub enum Expr { Let(LetBinding), /// A set rule: `set text(...)`. Set(SetRule), - /// A show rule: `show heading: it => [*{it.body}*]`. + /// A show rule: `show heading: it => emph(it.body)`. Show(ShowRule), /// An if-else conditional: `if x { y } else { z }`. Conditional(Conditional), @@ -1591,7 +1591,7 @@ impl SetRule { } node! { - /// A show rule: `show heading: it => [*{it.body}*]`. + /// A show rule: `show heading: it => emph(it.body)`. ShowRule } diff --git a/src/syntax/kind.rs b/src/syntax/kind.rs index cf973e6ad..47b5da317 100644 --- a/src/syntax/kind.rs +++ b/src/syntax/kind.rs @@ -224,7 +224,7 @@ pub enum SyntaxKind { LetBinding, /// A set rule: `set text(...)`. SetRule, - /// A show rule: `show heading: it => [*{it.body}*]`. + /// A show rule: `show heading: it => emph(it.body)`. ShowRule, /// An if-else conditional: `if x { y } else { z }`. Conditional, diff --git a/tests/typ/compiler/field.typ b/tests/typ/compiler/field.typ index 1d7d0b7a9..27b31f7df 100644 --- a/tests/typ/compiler/field.typ +++ b/tests/typ/compiler/field.typ @@ -15,7 +15,7 @@ --- // Test field on node. #show list: node => { - test(node.items.len(), 3) + test(node.children.len(), 3) } - A diff --git a/tests/typ/compiler/show-node.typ b/tests/typ/compiler/show-node.typ index 6416043cf..f87b19712 100644 --- a/tests/typ/compiler/show-node.typ +++ b/tests/typ/compiler/show-node.typ @@ -2,7 +2,7 @@ --- // Override lists. -#show list: it => "(" + it.items.map(item => item.body).join(", ") + ")" +#show list: it => "(" + it.children.map(v => v.body).join(", ") + ")" - A - B @@ -31,9 +31,9 @@ my heading? box(move(dy: -1pt)[📖]) h(5pt) if it.level == 1 { - underline(text(1.25em, blue, it.title)) + underline(text(1.25em, blue, it.body)) } else { - text(red, it.title) + text(red, it.body) } }) @@ -51,7 +51,7 @@ Another text. #show heading: it => { set text(red) show "ding": [🛎] - it.title + it.body } = Heading diff --git a/tests/typ/layout/terms.typ b/tests/typ/layout/terms.typ index 0be8ddc7a..fa94ae123 100644 --- a/tests/typ/layout/terms.typ +++ b/tests/typ/layout/terms.typ @@ -35,7 +35,7 @@ #show terms: it => table( columns: 2, inset: 3pt, - ..it.items.map(item => (emph(item.term), item.description)).flatten(), + ..it.children.map(v => (emph(v.term), v.description)).flatten(), ) / A: One letter diff --git a/tests/typ/meta/heading.typ b/tests/typ/meta/heading.typ index 992c0bb45..7db2a5cfd 100644 --- a/tests/typ/meta/heading.typ +++ b/tests/typ/meta/heading.typ @@ -38,7 +38,7 @@ multiline. --- // Test styling. #show heading.where(level: 5): it => block( - text(font: "Roboto", fill: eastern, it.title + [!]) + text(font: "Roboto", fill: eastern, it.body + [!]) ) = Heading