From 45245f069570cbbc63eb4120bf5dbb778b7175ef Mon Sep 17 00:00:00 2001 From: Ian Wrzesinski <133046678+wrzian@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:31:45 -0400 Subject: Fix empty 2-d math args with whitespace/trivia (#3786) Co-authored-by: Laurenz --- crates/typst-syntax/src/parser.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'crates/typst-syntax/src') diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs index ffbd7266..e61618e0 100644 --- a/crates/typst-syntax/src/parser.rs +++ b/crates/typst-syntax/src/parser.rs @@ -592,10 +592,23 @@ fn math_args(p: &mut Parser) { p.wrap(m, SyntaxKind::Args); } +/// Wrap math function arguments in a "Math" SyntaxKind to combine adjacent expressions +/// or create blank content. +/// +/// We don't wrap when `exprs == 1`, as there is only one expression, so the grouping +/// isn't needed, and this would change the type of the expression from potentially +/// non-content to content. +/// +/// Note that `exprs` might be 0 if we have whitespace or trivia before a comma i.e. +/// `mat(; ,)` or `sin(x, , , ,)`. This would create an empty Math element before that +/// trivia if we called `p.wrap()` -- breaking the expected AST for 2-d arguments -- so +/// we instead manually wrap to our current marker using `p.wrap_within()`. fn maybe_wrap_in_math(p: &mut Parser, arg: Marker, named: Option) { let exprs = p.post_process(arg).filter(|node| node.is::()).count(); if exprs != 1 { - p.wrap(arg, SyntaxKind::Math); + // Convert 0 exprs into a blank math element (so empty arguments are allowed). + // Convert 2+ exprs into a math element (so they become a joined sequence). + p.wrap_within(arg, p.marker(), SyntaxKind::Math); } if let Some(m) = named { -- cgit v1.2.3