malachite_base/slices/typst.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::strings::typst::ToTypst;
10use core::fmt::{Formatter, Result};
11
12// Writes a sequence of values as one delimited, comma-separated Typst math-mode fragment.
13pub(crate) fn fmt_typst_sequence<'a, T: ToTypst + 'a>(
14 xs: impl Iterator<Item = &'a T>,
15 open: &str,
16 close: &str,
17 f: &mut Formatter,
18) -> Result {
19 f.write_str(open)?;
20 for (i, x) in xs.enumerate() {
21 if i != 0 {
22 f.write_str(", ")?;
23 }
24 x.fmt_typst(f)?;
25 }
26 f.write_str(close)
27}
28
29// Writes a sequence of values as one bracketed, comma-separated Typst math-mode fragment.
30pub(crate) fn fmt_typst_slice<T: ToTypst>(xs: &[T], f: &mut Formatter) -> Result {
31 fmt_typst_sequence(xs.iter(), "[", "]", f)
32}
33
34impl<T: ToTypst> ToTypst for &[T] {
35 /// Writes a slice as a Typst math-mode fragment.
36 ///
37 /// The elements' fragments are separated by commas and wrapped in square brackets, so that a
38 /// slice's fragment is built out of its elements' own.
39 ///
40 /// The brackets are not decoration: without them `[1, 2]` and `[[1], [2]]` would both be `1,
41 /// 2`, and distinct values would have the same fragment. Typst grows a matched pair of
42 /// delimiters to fit what is between them, so they fit an element that is taller than one line,
43 /// such as a fraction or a nested slice, without being asked to.
44 ///
45 /// An empty slice becomes `[]` rather than nothing at all.
46 ///
47 /// # Worst-case complexity
48 /// $T(n) = O(n + \sum_{i=0}^{n-1}T^\prime(i))$
49 ///
50 /// $M(n) = O(\max_{i=0}^{n-1}M^\prime(i))$
51 ///
52 /// where $T$ is time, $M$ is additional memory, $n$ is `self.len()`, $i$ is an element's index,
53 /// and $T^\prime$ and $M^\prime$ are the time and memory functions of `fmt_typst` for `T`.
54 ///
55 /// # Examples
56 /// ```
57 /// use malachite_base::strings::typst::ToTypst;
58 ///
59 /// assert_eq!([0u8; 0].as_slice().to_typst_string(), "[]");
60 /// assert_eq!([5u8].as_slice().to_typst_string(), "[5]");
61 /// assert_eq!([1u8, 2, 3].as_slice().to_typst_string(), "[1, 2, 3]");
62 /// assert_eq!(["hi", "yo"].as_slice().to_typst_string(), r#"["hi", "yo"]"#);
63 /// ```
64 ///
65 /// | value | fragment |
66 /// |----------------|----------------|
67 /// | `[0u8; 0]` | `[]` |
68 /// | `[5u8]` | `[5]` |
69 /// | `[1u8, 2, 3]` | `[1, 2, 3]` |
70 /// | `["hi", "yo"]` | `["hi", "yo"]` |
71 #[inline]
72 fn fmt_typst(&self, f: &mut Formatter) -> Result {
73 fmt_typst_slice(self, f)
74 }
75}
76
77impl<T: ToTypst, const N: usize> ToTypst for [T; N] {
78 /// Writes an array as a Typst math-mode fragment.
79 ///
80 /// This is the same as the slice implementation.
81 ///
82 /// # Worst-case complexity
83 /// $T(n) = O(n + \sum_{i=0}^{n-1}T^\prime(i))$
84 ///
85 /// $M(n) = O(\max_{i=0}^{n-1}M^\prime(i))$
86 ///
87 /// where $T$ is time, $M$ is additional memory, $n$ is `N`, $i$ is an element's index, and
88 /// $T^\prime$ and $M^\prime$ are the time and memory functions of `fmt_typst` for `T`.
89 ///
90 /// # Examples
91 /// ```
92 /// use malachite_base::strings::typst::ToTypst;
93 ///
94 /// assert_eq!([0u8; 0].to_typst_string(), "[]");
95 /// assert_eq!([5u8].to_typst_string(), "[5]");
96 /// assert_eq!([1u8, 2, 3].to_typst_string(), "[1, 2, 3]");
97 /// assert_eq!([[1u8, 2], [3, 4]].to_typst_string(), "[[1, 2], [3, 4]]");
98 /// ```
99 ///
100 /// | value | fragment |
101 /// |----------------------|--------------------|
102 /// | `[0u8; 0]` | `[]` |
103 /// | `[5u8]` | `[5]` |
104 /// | `[1u8, 2, 3]` | `[1, 2, 3]` |
105 /// | `[[1u8, 2], [3, 4]]` | `[[1, 2], [3, 4]]` |
106 #[inline]
107 fn fmt_typst(&self, f: &mut Formatter) -> Result {
108 fmt_typst_slice(self, f)
109 }
110}