Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Another precedence issue in math parsing #55

Closed
mathmil opened this issue Nov 21, 2024 · 13 comments
Closed

Another precedence issue in math parsing #55

mathmil opened this issue Nov 21, 2024 · 13 comments

Comments

@mathmil
Copy link

mathmil commented Nov 21, 2024

Thanks for fixing my last bug report so quickly, this one is quite similar.
typst:

$
  (b)(c)/(d)
  !(a)/(b)
  \ !(a)/(b)
$

typst output:
typst

pandoc latex output, identical for newest nightly build and newest release:

\[\begin{array}{r}
\frac{(b)(c)}{d}\frac{!(a)}{b} \\
!\frac{a}{b}
\end{array}\]

Only the first two cases are wrong, but I find it weird that the second and third one differ.

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

Yes, this is definitely quite puzzling:

$  
!(a)/b
\
!(a)/b
$

I can't currently see why these two cells would be parsed differently.

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

Pandoc yields

\frac{!(a)}{b} \\
!\frac{a}{b}

And neither is correct. It should be !\frac{a}{b}.

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

Related case

$
+(a)/(b)
$

Here pandoc treats the + as part of the numerator, while typst does not.

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

I think what's happening here is that code intended to get the right grouping for

f(x)/3

is doing the wrong this for

!(x)/3

and

+(x)/3

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

It's hard to guess the exact rule typst is using. Note that

f(x)/3

has f(x) in the numerator, while

f_1(x)/3

does not have f_1(x) in the numerator.

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

Ah, but

f_a(x)/3

does have f_a(x) in the numerator. So I guess the rule has something to do with being followed by a letter?

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

In my opinion there's a bit too much "magic" in typst's parser. It makes it hard to predict.

@jgm
Copy link
Owner

jgm commented Nov 24, 2024

Interestingly f_alpha(x)/3 and f_"alpha"(x)/3 both pattern with f_a(x)/3.
So it's not quite "preceded by a letter."

@knuesel
Copy link

knuesel commented Nov 27, 2024

This is actually an issue with the parsing of subscripts. I think the current behavior was introduced in Typst 0.5 to allow typesetting function calls in subscripts/superscripts without extra parentheses. So f_a(x), f_alpha(x) and f_"alpha"(x) are all interpreted as a function call in subscript of f. Then naturally the fraction f_a(x)/3 is parsed such that f_a(x) is the numerator.

Meanwhile 1(x) is not treated as a function call, so f_1(x)/3 is parsed as f_1 (x)/3.

I don't think the exact rules are documented anywhere. I guess you can get close enough by treating as a subscript function call anything that looks like a variable name or "text" followed by parentheses.

(Many people are unhappy with the current rules and there's been a lot of discussions about a redesign but no decision yet as far as I know.)

@jgm
Copy link
Owner

jgm commented Nov 30, 2024

Many people are unhappy with the current rules and there's been a lot of discussions about a redesign but no decision yet as far as I know.

If you could link to some of those discussions, it would be useful.

@jgm jgm closed this as completed in f7c729d Dec 3, 2024
@jgm jgm reopened this Dec 3, 2024
@jgm
Copy link
Owner

jgm commented Dec 3, 2024

Reopening because we still don't get the original case quite right:

document(body: { math.equation(block: true, 
                               body: { math.frac(denom: text(body: [d]), 
                                                 num: { math.lr(body: ({ [(], 
                                                                         text(body: [b]), 
                                                                         [)] })), 
                                                        math.lr(body: ({ [(], 
                                                                         text(body: [c]), 
                                                                         [)] })) }), 
                                       text(body: [!]), 
                                       math.frac(denom: text(body: [b]), 
                                                 num: text(body: [a])), 
                                       linebreak(), 
                                       text(body: [!]), 
                                       math.frac(denom: text(body: [b]), 
                                                 num: text(body: [a])) }, 
                               numbering: none), 
                 parbreak() })

We have \frac{(b)(c)}{d} but it should be (b)\frac{c}{d}.

@jgm jgm closed this as completed in 5a50154 Dec 3, 2024
@jgm
Copy link
Owner

jgm commented Dec 3, 2024

OK I think I've got it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants