diff --git a/crates/typst/src/eval/methods.rs b/crates/typst/src/eval/methods.rs index 6127a807c..ed11d8a7b 100644 --- a/crates/typst/src/eval/methods.rs +++ b/crates/typst/src/eval/methods.rs @@ -82,6 +82,7 @@ pub fn call( let count = args.named("count")?; string.replace(vm, pattern, with, count)?.into_value() } + "rev" => string.rev().into_value(), "trim" => { let pattern = args.eat()?; let at = args.named("at")?; diff --git a/crates/typst/src/eval/str.rs b/crates/typst/src/eval/str.rs index 30139f10d..b21d2ff9d 100644 --- a/crates/typst/src/eval/str.rs +++ b/crates/typst/src/eval/str.rs @@ -324,6 +324,11 @@ impl Str { Ok(Self(self.0.repeat(n))) } + /// Reverse the string. + pub fn rev(&self) -> Self { + self.as_str().graphemes(true).rev().collect::().into() + } + /// Resolve an index or throw an out of bounds error. fn locate(&self, index: i64) -> StrResult { self.locate_opt(index)? diff --git a/docs/reference/types.md b/docs/reference/types.md index b0ee1bd11..365593f3d 100644 --- a/docs/reference/types.md +++ b/docs/reference/types.md @@ -689,6 +689,11 @@ string and returns the resulting string. If given, only the first `count` matches of the pattern are placed. - returns: string +### rev() +Reverses the grapheme clusters and returns the resulting string. + +- returns: string + ### trim() Removes matches of a pattern from one or both sides of the string, once or repeatedly and returns the resulting string. diff --git a/tests/typ/compiler/string.typ b/tests/typ/compiler/string.typ index 4241361a2..b0708979f 100644 --- a/tests/typ/compiler/string.typ +++ b/tests/typ/compiler/string.typ @@ -210,6 +210,15 @@ #test("a123c".split(regex("\d")), ("a", "", "", "c")) #test("a123c".split(regex("\d+")), ("a", "c")) +--- +// Test the `rev` method. +#test("abc".rev(), "cba") +#test("ax̂e".rev(), "ex̂a") + +--- +// Error: 12-15 unknown variable: arg +#"abc".rev(arg) + --- // Error: 2-2:1 unclosed string #"hello\"