sile-typesetter / sile

The SILE Typesetter — Simon’s Improved Layout Engine
https://sile-typesetter.org
MIT License
1.66k stars 98 forks source link

TeX-like math operator with sup-only part has the latter incorrectly place #2130

Open Omikhleia opened 1 week ago

Omikhleia commented 1 week ago

Input

Formula in TeX-like syntax:

\prod_{n=1}^{\infty}
\prod_{p\,\in\,ℙ}
\prod^{ℙ} 

I.e. large operator, with (1) both sup and sub elements, (2) only sub elements, (3) only sup elements.

Expected

As obtained on https://latexeditor.lagrida.com/ and also https://saxarona.github.io/mathjax-viewer/

image

Observed

image

= The last case does not have the sup part above the operator.

Analysis

The math package code is insane and poorly commented, sorry to say. Yet a line for the sup-only case (which differs from the sub-only case) looks dubious:

diff --git a/packages/math/texlike.lua b/packages/math/texlike.lua
index 5d1073fe..5abb03c6 100644
--- a/packages/math/texlike.lua
+++ b/packages/math/texlike.lua
@@ -328,7 +328,7 @@ local function compileToMathML_aux (_, arg_env, tree)
       tree.options = {}
    -- Translate TeX-like sub/superscripts to `munderover` or `msubsup`,
    -- depending on whether the base is a big operator
-   elseif tree.id == "sup" and tree[1].command == "mo" and tree[1].atom == atomType.bigOperator then
+   elseif tree.id == "sup" and tree[1].command == "mo" and symbolDefaults[tree[1][1]].atom == atomType.bigOperator then
       tree.command = "mover"
    elseif tree.id == "sub" and tree[1].command == "mo" and symbolDefaults[tree[1][1]].atom == atomType.bigOperator then
       tree.command = "munder"

And with the shown change, yay! (EDIT but see comment, I was a bit too naive here)

image

Dear math-aware friends, what do you think?

Omikhleia commented 1 week ago

Yet a line for the sup-only case (which differs from the sub-only case) looks dubious:

Seems both conditions are right, depending on whether the mo was defined via macro or not. OMG.