summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/eval/array.rs24
-rw-r--r--crates/typst/src/eval/methods.rs1
-rw-r--r--docs/reference/types.md6
-rw-r--r--tests/typ/compiler/array.typ7
4 files changed, 38 insertions, 0 deletions
diff --git a/crates/typst/src/eval/array.rs b/crates/typst/src/eval/array.rs
index b98c9296..9afae865 100644
--- a/crates/typst/src/eval/array.rs
+++ b/crates/typst/src/eval/array.rs
@@ -287,6 +287,30 @@ impl Array {
Ok(result)
}
+ /// Returns an array with a copy of the separator value placed between
+ /// adjacent elements.
+ pub fn intersperse(&self, sep: Value) -> Array {
+ // TODO: Use https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.intersperse
+ // once it is stabilized.
+ let size = match self.len() {
+ 0 => return Array::new(),
+ n => (2 * n) - 1,
+ };
+ let mut vec = EcoVec::with_capacity(size);
+ let mut iter = self.iter().cloned();
+
+ if let Some(first) = iter.next() {
+ vec.push(first);
+ }
+
+ for value in iter {
+ vec.push(sep.clone());
+ vec.push(value);
+ }
+
+ Array(vec)
+ }
+
/// Zips the array with another array. If the two arrays are of unequal length, it will only
/// zip up until the last element of the smaller array and the remaining elements will be
/// ignored. The return value is an array where each element is yet another array of size 2.
diff --git a/crates/typst/src/eval/methods.rs b/crates/typst/src/eval/methods.rs
index a47d945b..6df504b5 100644
--- a/crates/typst/src/eval/methods.rs
+++ b/crates/typst/src/eval/methods.rs
@@ -154,6 +154,7 @@ pub fn call(
let last = args.named("last")?;
array.join(sep, last).at(span)?
}
+ "intersperse" => array.intersperse(args.expect("separator")?).into_value(),
"sorted" => array.sorted(vm, span, args.named("key")?)?.into_value(),
"zip" => array.zip(args.expect("other")?).into_value(),
"enumerate" => array
diff --git a/docs/reference/types.md b/docs/reference/types.md
index 3979a454..b0ee1bd1 100644
--- a/docs/reference/types.md
+++ b/docs/reference/types.md
@@ -1029,6 +1029,12 @@ Combine all items in the array into one.
An alternative separator between the last two items
- returns: any
+### intersperse()
+Returns a new array with a separator placed between adjacent items.
+
+- separator: any (positional)
+ The value to insert between each item of the array.
+
### sorted()
Return a new array with the same items, but sorted.
diff --git a/tests/typ/compiler/array.typ b/tests/typ/compiler/array.typ
index e2463cb0..96c6c668 100644
--- a/tests/typ/compiler/array.typ
+++ b/tests/typ/compiler/array.typ
@@ -217,6 +217,13 @@
#([One], [Two], [Three]).join([, ], last: [ and ]).
---
+// Test the `intersperse` method
+#test(().intersperse("a"), ())
+#test((1,).intersperse("a"), (1,))
+#test((1, 2).intersperse("a"), (1, "a", 2))
+#test((1, 2, "b").intersperse("a"), (1, "a", 2, "a", "b"))
+
+---
// Test the `sorted` method.
#test(().sorted(), ())
#test(().sorted(key: x => x), ())