diff --git a/library/src/meta/outline.rs b/library/src/meta/outline.rs index 894c3b8b9..ea3542280 100644 --- a/library/src/meta/outline.rs +++ b/library/src/meta/outline.rs @@ -326,8 +326,8 @@ pub trait Outlinable: Refable { #[derive(Debug, Clone)] pub enum OutlineIndent { Bool(bool), - Length(Spacing), - Function(Func), + Rel(Rel), + Func(Func), } impl OutlineIndent { @@ -338,7 +338,7 @@ impl OutlineIndent { seq: &mut Vec, span: Span, ) -> SourceResult<()> { - match &indent { + match indent { // 'none' | 'false' => no indenting None | Some(Smart::Custom(OutlineIndent::Bool(false))) => {} @@ -366,23 +366,20 @@ impl OutlineIndent { } // Length => indent with some fixed spacing per level - Some(Smart::Custom(OutlineIndent::Length(length))) => { - seq.push(HElem::new(*length).pack().repeat(ancestors.len())); + Some(Smart::Custom(OutlineIndent::Rel(length))) => { + seq.push( + HElem::new(Spacing::Rel(*length)).pack().repeat(ancestors.len()), + ); } // Function => call function with the current depth and take // the returned content - Some(Smart::Custom(OutlineIndent::Function(func))) => { + Some(Smart::Custom(OutlineIndent::Func(func))) => { let depth = ancestors.len(); - let returned = func.call_vt(vt, [depth])?; - let Ok(returned) = returned.cast::() else { - bail!( - span, - "indent function must return content" - ); - }; - if !returned.is_empty() { - seq.push(returned); + let LengthOrContent(content) = + func.call_vt(vt, [depth])?.cast().at(span)?; + if !content.is_empty() { + seq.push(content); } } }; @@ -395,10 +392,18 @@ cast! { OutlineIndent, self => match self { Self::Bool(v) => v.into_value(), - Self::Length(v) => v.into_value(), - Self::Function(v) => v.into_value() + Self::Rel(v) => v.into_value(), + Self::Func(v) => v.into_value() }, v: bool => OutlineIndent::Bool(v), - v: Spacing => OutlineIndent::Length(v), - v: Func => OutlineIndent::Function(v), + v: Rel => OutlineIndent::Rel(v), + v: Func => OutlineIndent::Func(v), +} + +struct LengthOrContent(Content); + +cast! { + LengthOrContent, + v: Rel => Self(HElem::new(Spacing::Rel(v)).pack()), + v: Content => Self(v), } diff --git a/tests/typ/meta/outline-indent.typ b/tests/typ/meta/outline-indent.typ index a4ef6c811..b0132d434 100644 --- a/tests/typ/meta/outline-indent.typ +++ b/tests/typ/meta/outline-indent.typ @@ -35,7 +35,7 @@ #outline(indent: true) #outline(indent: none) #outline(indent: auto) -#outline(indent: 2em) +#outline(indent: n => 2em * n) #outline(indent: n => ([-], [], [==], [====]).at(n)) #outline(indent: n => "!" * calc.pow(2, n)) @@ -54,7 +54,7 @@ #lorem(10) --- -// Error: 2-35 indent function must return content +// Error: 2-35 expected relative length or content, found dictionary #outline(indent: n => (a: "dict")) = Heading