diff --git a/crates/typst-utils/src/lib.rs b/crates/typst-utils/src/lib.rs index 831b2374c..79d4bb09b 100644 --- a/crates/typst-utils/src/lib.rs +++ b/crates/typst-utils/src/lib.rs @@ -106,6 +106,18 @@ impl OptionExt for Option { /// Extra methods for [`[T]`](slice). pub trait SliceExt { + /// Returns a slice with all matching elements from the start of the slice + /// removed. + fn trim_start_matches(&self, f: F) -> &[T] + where + F: FnMut(&T) -> bool; + + /// Returns a slice with all matching elements from the end of the slice + /// removed. + fn trim_end_matches(&self, f: F) -> &[T] + where + F: FnMut(&T) -> bool; + /// Split a slice into consecutive runs with the same key and yield for /// each such run the key and the slice of elements with that key. fn group_by_key(&self, f: F) -> GroupByKey<'_, T, F> @@ -115,6 +127,29 @@ pub trait SliceExt { } impl SliceExt for [T] { + fn trim_start_matches(&self, mut f: F) -> &[T] + where + F: FnMut(&T) -> bool, + { + let len = self.len(); + let mut i = 0; + while i < len && f(&self[i]) { + i += 1; + } + &self[i..] + } + + fn trim_end_matches(&self, mut f: F) -> &[T] + where + F: FnMut(&T) -> bool, + { + let mut i = self.len(); + while i > 0 && f(&self[i - 1]) { + i -= 1; + } + &self[..i] + } + fn group_by_key(&self, f: F) -> GroupByKey<'_, T, F> { GroupByKey { slice: self, f } } diff --git a/crates/typst/src/eval/rules.rs b/crates/typst/src/eval/rules.rs index f5d7da178..61fee84a1 100644 --- a/crates/typst/src/eval/rules.rs +++ b/crates/typst/src/eval/rules.rs @@ -24,7 +24,7 @@ impl Eval for ast::SetRule<'_> { }) .at(target.span())?; let args = self.args().eval(vm)?.spanned(self.span()); - Ok(target.set(&mut vm.engine, args)?.spanned(self.span())) + Ok(target.set(&mut vm.engine, args)?.spanned(self.span()).liftable()) } } @@ -46,6 +46,6 @@ impl Eval for ast::ShowRule<'_> { expr => expr.eval(vm)?.cast::().at(span)?, }; - Ok(Recipe { span, selector, transform }) + Ok(Recipe::new(selector, transform, span)) } } diff --git a/crates/typst/src/foundations/content.rs b/crates/typst/src/foundations/content.rs index 656049dd5..b9d1b1897 100644 --- a/crates/typst/src/foundations/content.rs +++ b/crates/typst/src/foundations/content.rs @@ -369,7 +369,7 @@ impl Content { context: Tracked, recipe: Recipe, ) -> SourceResult { - if recipe.selector.is_none() { + if recipe.selector().is_none() { recipe.apply(engine, context, self) } else { Ok(self.styled(recipe)) diff --git a/crates/typst/src/foundations/styles.rs b/crates/typst/src/foundations/styles.rs index 55bb348a0..e74a16499 100644 --- a/crates/typst/src/foundations/styles.rs +++ b/crates/typst/src/foundations/styles.rs @@ -93,6 +93,11 @@ impl Styles { self.0.iter().map(|style| &**style) } + /// Iterate over the contained styles. + pub fn as_slice(&self) -> &[LazyHash