MathJax icon indicating copy to clipboard operation
MathJax copied to clipboard

sync MathML spacing with MathML Core

Open xworld21 opened this issue 9 months ago • 10 comments

Is your feature request related to a problem? Please describe. MathML Core has changed dictionary slightly as well as the form detection algorithm. I believe MathJax currently implements the old MathML rules (for instance: the infix/postfix/prefix detection should check all 'grouping elements' and mpadded, msqrt, but MathJax checks mrow only, and it should only look at 'in-flow' children).

This makes MathJax with MathML spacing slightly inconsistent with browser implementations, although I do not know how often that happens in practice.

I suspect the dictionary is also from an old version of the MathML (non-core) spec and might need updating too.

Describe the solution you'd like Follow new MathML Core spec more closely.

Describe alternatives you've considered I can override getMathMLSpacing in configuration. I'll post the code here when I can make it presentable.

Additional context Dictionary-based attributes (including how to determine the default forms): https://w3c.github.io/mathml-core/#dictionary-based-attributes New operator dictionary: https://w3c.github.io/mathml-core/#operator-tables

xworld21 avatar May 10 '25 10:05 xworld21

MathJax implements MathML3 (so you are right that it is an older spec than MathML-Core). MathML-Core does not include some features that are used by MathJax (e.g., mlabeledtr elements), and so MathJax is not going to implement the MathML-Core specification. MathML4 seems the next likely version that MathJax would work on, and it is current a FPWD (first public working draft), which is not yet far enough along for us to start making significant changes. While MathML-Core is supposed to be a subset of MathML4, I have found in the past that this isn't actually the case, as the two specifications didn't agree on some issues (though I'm afraid I no longer remember what that was), at least at the time I looked (the drafts may have changed since then). For now, MathJax is likely to stay at MathML3.

I'm not particularly concerned about not matching the browser MathML output exactly. MathML-Core does make much more explicit what the positioning should be for things like fractions, roots, and so on, and MathJax doesn't implement those at this point either (MathJax is over 15 years old, so its output long predates the MathJax-Core specification), as MathJax implements (to the best of its ability) the TeX layout for these constructs, even when MathML spacing is requested (which really only affects the horizontal spacing).

dpvc avatar May 19 '25 21:05 dpvc

While MathML-Core is supposed to be a subset of MathML4

You might see me going back and forth between different repositories about this. My understanding from the outside (and quite far out) is that MathML Core is the spec being actively developed and that browsers are aligning to it. Updates to MathML 4 seem to happen whenever some decision is made about stuff that goes beyond the scope of Core. I was assuming that MathML 4 would be brought back in sync once MathML Core 'level 1'(?) is stabilised.

At any rate: I will post a configuration that implements MathML Core spacing for MathJax, as it might be useful for people in my situation, and it is easy to tweak (for spec updates or e.g. to work around quirks of MathML authoring tools).

xworld21 avatar May 24 '25 20:05 xworld21

MathML-Core does not include some features that are used by MathJax (e.g., mlabeledtr elements),

Noteworthy, since MathML4 mlabeledtr can only be used in Legacy Schema.

CoelacanthusHex avatar Jul 12 '25 02:07 CoelacanthusHex

At any rate: I will post a configuration that implements MathML Core spacing for MathJax, as it might be useful for people in my situation, and it is easy to tweak (for spec updates or e.g. to work around quirks of MathML authoring tools).

@xworld21 do you have a link?

Context: I discovered today that MathJax does not support MathML-core (which is the subset of MathML supported by chrome). Thus, if one wants to create a page that has basic math support via MathML and better math support via MathJax, this is only possible when one generates MathML-full. This will lead to the fact that the page will fail the MathML core validation.

For example, mathml core does NOT support alignment. This is done via CSS. Thus, when generating MathML one has to add both the columnalign attribute and the CSS rules. Chrome would render the CSS and MathJax the columnalign attribute. This is not fully satisfactory.

physikerwelt avatar Aug 14 '25 12:08 physikerwelt

@xworld21 do you have a link?

Not yet... I only plan to implement the MathML Core dictionary, and that's big enough that I had to postpone for a while.

Tweaking MathJax is pretty easy, though, once you know where the hooks are. This is my current configuration: https://github.com/vlmantova/bookml/blob/v0.19.1/js/mathjax4.js It makes three changes: translate the class 'ltx_font_mathcaligraphic', emitted by LaTeXML, to a MathJax attribute for calligraphic script; recognise the few standard Unicode variation sequences, although only for single character identifiers; make operator spacing a bit closer to MathML.

xworld21 avatar Aug 15 '25 10:08 xworld21

@xworld21, thanks for the link. Nice work!

@physikerwelt, if the CSS is explicit in a style attribute for the tables, then it might be possible to use a MathML input jax post-filter to convert the style values to the corresponding attributes needed by MathJax. if you can give me some examples of the tables that you are using for MathML-Core, I can see how practical that would be. If the CSS is inherited from a style cheet, that makes things harder. MathJax could use getComputedStyle() to look up the styles, but that is expensive, and if the styling is on rows or cells, then it would have to be used on each element in the table, which is worse yet. It could be done, but would probably reduce the performance of the output.

dpvc avatar Aug 29 '25 11:08 dpvc

@dpvc, before we were using 'columnalign' => 'right left right left right left right left right left ... on the mtable element is now each table cell gets a CSS class mwe-math-columnalign-left or right. Is there a way to get the CSS classes?

physikerwelt avatar Aug 31 '25 12:08 physikerwelt

@physikerwelt, since your class names are explicit on the mtd elements, MathJax can use those to add the MathML3 attributes it needs.

Here is a MathJax configuration (for v4) that will convert your classes to columnalign attributes when MathJax is used:

window.MathJax = {
  mml: {
    postFilters: [
      ({data}) => {
        data.walkTree((node) => {
          if (node.isKind('mtd')) {
            for (const side of ['left', 'right']) {
              key = 'mwe-math-columnalign-' + side;
              const classes = node.attributes.get('class').split(/ /);
              if (classes.includes(key)) {
                classes.splice(classes.indexOf(key), 1);
                if (classes.length) {
                  node.attributes.set('class', classes.join(''));
                } else {
                  node.attributes.unset('class');
                }
                node.attributes.set('columnalign', side);
                break;
              }
            }
          }
        });
      }
    ]
  }
};

This walks through the MathJax's internal MathML looking for mtd elements and checks if they have either the mwe-math-columnalign-left or mwe-math-columnalign-right class, and if so, it removes the class and adds the corresponding columnalign attribute that MathJax needs. You could leave the class in place if you want, provided the CSS doesn't cause problems for the MathJax output (that will depend on how the CSS is defined).

If you have other classes that control things that used to be attributes in MathML3, then you could use something similar to convert those.

Hope that does the trick for you.

dpvc avatar Aug 31 '25 14:08 dpvc

Yeah, maybe it's wise to update to MathJax 4. We already added quite some preprocessing... https://github.com/wikimedia/mediawiki-extensions-Math/blob/master/modules/ext.math.mathjax.js

physikerwelt avatar Sep 11 '25 18:09 physikerwelt

I have just today made a PR that updates MathJax's operator dictionary with that of MathML4 (with some additions needed by MathJax). It uses the MathML spacing numbers from MathML4, so may be more to your liking. We'll see if it passes review.

dpvc avatar Sep 11 '25 18:09 dpvc