mathjax / MathJax

Beautiful and accessible math in all browsers
http://www.mathjax.org/
Apache License 2.0
10.18k stars 1.16k forks source link

MJ4 mathjax-tex monospace double-quote much wider than MJ2's #3268

Open AlexEdgcomb opened 2 months ago

AlexEdgcomb commented 2 months ago

Issue Summary

MJ4 typesets a double-quote from MML monospace as much wider than MJ2. Ex:

<math display="block" overflow="scroll"><mrow><mo mathvariant="monospace">&quot;</mo></mrow></math>

Steps to Reproduce:

  1. Go to https://codepen.io/alexedgcomb/pen/YzoNdpO Observed: The double-quote is quite wide image

    Expected: More like MJ2's:

    image

Technical details:

I am using the following MathJax configuration:

window.MathJax = { output: { font: 'mathjax-tex' } };

and loading MathJax via

<script src="https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.7/tex-mml-svg.js"></script>

Supporting information:

Also reproduces in Chrome 127.0.6533.73

dpvc commented 2 months ago

Here's the situation for this. In MathML, the quotation mark is considered to be a "pseudo-script" as defined in the MathML specification section 7.2.2. In order to handle both the recommended usage such as <msup><mi>f</mi><mo>"</mo></msup> and the discouraged usage as <mi>f</mi><mo>"</mo>, MathJax needs to have the needed character in two different sizes: a smaller and raised version for the latter, and a larger, un-raised one for the former. The mathjax-tex font does not have both for " (or for most of the pseudo-scripts), but it does have both sizes for things like the prime symbols (U+2032, U+2033, etc.), so quote-like pseudo-scripts are converted to those, when possible. So the double-quote is converted to U+2033 when it appears in an <mo> (the quote as an operator is usually meant to indicate double-prime). The monospace variant doesn't have U+2033, so MathJax tries to use two copies of U+2032 to fake it. That is what is happening here. Since both are fixed width, they are somewhat widely spaced, as you have indicated.

This is not what happened in v2 because MathJax v2 didn't handle pseudo-scripts, whereas v4 does.

Of course, this substitution only occurs for <mo> elements, so if you want the actual " character from the monospace font, then you should use <mtext mathvariant="monospace">"</mtex> instead.

It is true that using two U+2032 to replace U+2033 is not very good for a monospace font. But even in v2, <mo mathvariant="monospace">&#x2033;</mo> would produce the wide spacing.

The MathJax font tools do have a means of building new characters by combining others, and it would be possible to make a close-spaced version of U+2033 and the other multiple-prime characters for the monospace font. The mathjax-tex font is supposed to be the same as the v2/v3 font, so I'm not sure if that should be done or not.

In any case, this is "expected behavior" in v4.

dpvc commented 2 months ago

I forgot to add that you can disable the translation of " to U+2033 in <mo> elements using the following configuration:

MathJax = {
  startup: {
    ready() {
      const {MmlMo} = MathJax._.core.MmlTree.MmlNodes.mo;
      MmlMo.remapPrimes[0x0022] = 0x0022;  // don't remap double quote
      MathJax.startup.defaultReady();
    }
  }
};
AlexEdgcomb commented 2 months ago

@dpvc , thank you for your thoughtful explanation: Incredibly helpful insights into causes, MML standards, and options for going forward!