typst_library/math/frac.rs
1use typst_syntax::Spanned;
2
3use crate::diag::bail;
4use crate::foundations::{Cast, Content, Value, elem};
5use crate::math::Mathy;
6
7/// A mathematical fraction.
8///
9/// # Example
10/// ```example
11/// $ 1/2 < (x+1)/2 $
12/// $ ((x+1)) / 2 = frac(a, b) $
13/// ```
14///
15/// # Syntax
16/// This function also has dedicated syntax: Use a slash to turn neighbouring
17/// expressions into a fraction. Multiple atoms can be grouped into a single
18/// expression using round grouping parentheses. Such parentheses are removed
19/// from the output, but you can nest multiple to force them.
20#[elem(title = "Fraction", Mathy)]
21pub struct FracElem {
22 /// The fraction's numerator.
23 #[required]
24 pub num: Content,
25
26 /// The fraction's denominator.
27 #[required]
28 pub denom: Content,
29
30 /// How the fraction should be laid out.
31 ///
32 /// ```example:"Styles"
33 /// $ frac(x, y, style: "vertical") $
34 /// $ frac(x, y, style: "skewed") $
35 /// $ frac(x, y, style: "horizontal") $
36 /// ```
37 ///
38 /// ```example:"Setting the default"
39 /// #set math.frac(style: "skewed")
40 /// $ a / b $
41 /// ```
42 ///
43 /// ```example:"Handling of grouping parentheses"
44 /// // Grouping parentheses are removed.
45 /// #set math.frac(style: "vertical")
46 /// $ (a + b) / b $
47 ///
48 /// // Grouping parentheses are removed.
49 /// #set math.frac(style: "skewed")
50 /// $ (a + b) / b $
51 ///
52 /// // Grouping parentheses are retained.
53 /// #set math.frac(style: "horizontal")
54 /// $ (a + b) / b $
55 /// ```
56 #[default(FracStyle::Vertical)]
57 pub style: FracStyle,
58
59 /// Whether the numerator was originally surrounded by parentheses
60 /// that were stripped by the parser.
61 #[internal]
62 #[parse(None)]
63 #[default(false)]
64 pub num_deparenthesized: bool,
65
66 /// Whether the denominator was originally surrounded by parentheses
67 /// that were stripped by the parser.
68 #[internal]
69 #[parse(None)]
70 #[default(false)]
71 pub denom_deparenthesized: bool,
72}
73
74/// Fraction style
75#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Cast)]
76pub enum FracStyle {
77 /// Stacked numerator and denominator with a bar.
78 #[default]
79 Vertical,
80 /// Numerator and denominator separated by a slash.
81 Skewed,
82 /// Numerator and denominator placed inline and parentheses are not
83 /// absorbed.
84 Horizontal,
85}
86
87/// A binomial expression.
88///
89/// # Example
90/// ```example
91/// $ binom(n, k) $
92/// $ binom(n, k_1, k_2, k_3, ..., k_m) $
93/// ```
94#[elem(title = "Binomial", Mathy)]
95pub struct BinomElem {
96 /// The binomial's upper index.
97 #[required]
98 pub upper: Content,
99
100 /// The binomial's lower index.
101 #[required]
102 #[variadic]
103 #[parse(
104 let values = args.all::<Spanned<Value>>()?;
105 if values.is_empty() {
106 // Prevents one element binomials
107 bail!(args.span, "missing argument: lower");
108 }
109 values.into_iter().map(|spanned| spanned.v.display()).collect()
110 )]
111 pub lower: Vec<Content>,
112}