summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJosefOlsson <143743179+TheJosefOlsson@users.noreply.github.com>2023-10-09 13:46:16 +0200
committerGitHub <noreply@github.com>2023-10-09 13:46:16 +0200
commit6dab95473b04b3c72c552de0168adc76781cd9e8 (patch)
treeffb070a52501c3c3aeb324661057f8eaab30b649
parent1819a0b2663a44f4a04c916f4f176e78ad706496 (diff)
Multinomial coefficients (#2237)
-rw-r--r--crates/typst-library/src/math/frac.rs21
-rw-r--r--tests/ref/math/frac.pngbin28917 -> 31154 bytes
-rw-r--r--tests/typ/math/frac.typ4
3 files changed, 21 insertions, 4 deletions
diff --git a/crates/typst-library/src/math/frac.rs b/crates/typst-library/src/math/frac.rs
index 93819184..ee582775 100644
--- a/crates/typst-library/src/math/frac.rs
+++ b/crates/typst-library/src/math/frac.rs
@@ -29,7 +29,7 @@ pub struct FracElem {
impl LayoutMath for FracElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- layout(ctx, &self.num(), &self.denom(), false, self.span())
+ layout(ctx, &self.num(), &[self.denom()], false, self.span())
}
}
@@ -38,6 +38,7 @@ impl LayoutMath for FracElem {
/// # Example
/// ```example
/// $ binom(n, k) $
+/// $ binom(n, k_1, k_2, k_3, ..., k_m) $
/// ```
#[elem(title = "Binomial", LayoutMath)]
pub struct BinomElem {
@@ -47,7 +48,16 @@ pub struct BinomElem {
/// The binomial's lower index.
#[required]
- pub lower: Content,
+ #[variadic]
+ #[parse(
+ let values = args.all::<Spanned<Value>>()?;
+ if values.is_empty() {
+ // Prevents one element binomials
+ bail!(args.span, "missing argument: lower");
+ }
+ values.into_iter().map(|spanned| spanned.v.display()).collect()
+ )]
+ pub lower: Vec<Content>,
}
impl LayoutMath for BinomElem {
@@ -60,7 +70,7 @@ impl LayoutMath for BinomElem {
fn layout(
ctx: &mut MathContext,
num: &Content,
- denom: &Content,
+ denom: &[Content],
binom: bool,
span: Span,
) -> SourceResult<()> {
@@ -93,7 +103,10 @@ fn layout(
ctx.unstyle();
ctx.style(ctx.style.for_denominator());
- let denom = ctx.layout_frame(denom)?;
+ let denom = ctx.layout_frame(&Content::sequence(
+ // Add a comma between each element.
+ denom.iter().flat_map(|a| [TextElem::packed(','), a.clone()]).skip(1),
+ ))?;
ctx.unstyle();
let around = FRAC_AROUND.scaled(ctx);
diff --git a/tests/ref/math/frac.png b/tests/ref/math/frac.png
index a4873d20..6d5fe563 100644
--- a/tests/ref/math/frac.png
+++ b/tests/ref/math/frac.png
Binary files differ
diff --git a/tests/typ/math/frac.typ b/tests/typ/math/frac.typ
index f3c31070..0252f430 100644
--- a/tests/typ/math/frac.typ
+++ b/tests/typ/math/frac.typ
@@ -17,6 +17,10 @@ $ x = (-b plus.minus sqrt(b^2 - 4a c))/(2a) $
$ binom(circle, square) $
---
+// Test multinomial coefficients.
+$ binom(n, k_1, k_2, k_3) $
+
+---
// Error: 8-13 missing argument: lower
$ binom(x^2) $