mathjax / MathJax-src

MathJax source code for version 3 and beyond
https://www.mathjax.org/
Apache License 2.0
2.05k stars 205 forks source link

Fix handling of _ and ^ followed by command that doesn't push content (mathjax/MathJax#3184) #1060

Closed dpvc closed 6 months ago

dpvc commented 7 months ago

This PR fixes an issue with how _ and ^ interact with macros that don't push any content (like \rm). In the past, something like a_\rm{b}c would not produce an error (as it should), but instead ended up with an a having an upright b subscript, followed by an upright c. This is because \rm doesn't push any nodes onto the parser stack, and so the checking for the _ is not performed until the next token, {, is pushed, and the b becomes the subscript. Because \rm set the normal variant, that affects both the b and the c (and any following characters). What should happen is an error message from the _ concerning missing braces.

In addition, a_\rm{b}c would thrown a math input error in the updateResult() function, since it was being called before the subscript was actually processed, but updateResult() tried to use the subscript, even though it is null.

We fix the latter issue by checking for null children before using them.

We fix the former problem by introducing a new NullItem stack item that is pushed by macros that would not otherwise push any content. That triggers the checkItem() calls for the current stack items (like the one for _) so that they will produce the proper error messages. I looked through all the TeX package methods and added pushing the null item for those that didn't have any other pushes (at least the ones I could see on a quick pass through) and that didn't check foreign inside a specific stack item type. That should introduce error messages if any of them are used with _, for example a_\tag{b}{c}, and so on.

View this without whitespace differences for an easier-to-read difference listing.

Resolves issue mathjax/MathJax#3184.

dpvc commented 6 months ago

Yes, I'm not positive I found them all, but any that I missed will just work as they always did, so no harm there, and we can fix them in the future if we find any.