mathjax / MathJax

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

Extra left padding in underset content of a referenced equation #3266

Closed geoff-cox closed 3 months ago

geoff-cox commented 3 months ago

Description:

When using PreText, I'm experiencing an issue with MathJax (?) adding extra left padding to a referenced equation, which skews the display of the underscored content within the equation. Please take a look at the screenshots below.

Native Equation: MJX-Screenshot-1

Referenced Equation: MJX-Screenshot-2

Here is a live example as well. The referenced equation is on page 2.

Steps to Reproduce

  1. HTML Containing the Original Equation (./knowl/xref/lncc-order2-gen-soln-parts.html):
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="robots" content="noindex, nofollow">
</head>
<body class="ignore-math">
  <div class="displaymath process-math" data-contains-math-knowls="./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-general-equation.html ./knowl/xref/lncc-general-solution.html ./knowl/xref/lncc-general-solution.html ./knowl/xref/lncc-general-solution.html ./knowl/xref/lncc-general-solution.html">
  \begin{equation}
    \underset{\text{terms that cancel}}{\underbrace{a_2 y_h'' + a_1 y_h' + a_0 y_h}} + 
    \underset{\text{terms that account for } f(x)}{\underbrace{a_2 y_p'' + a_1 y_p' + a_0 y_p}} = f(x)\tag{3}
  \end{equation}
  </div>
  <span class="incontext"><a class="internal" href="main-5-4-4.html#lncc-order2-gen-soln-parts">in-context</a></span>
</body>
</html>
  1. HTML Snippet of the Referenced Equation (main-5-4-8-5.html):
<div class="para" id="main-5-4-8-5">
  <a href="main-5-4-4.html#lncc-order2-gen-soln-parts" class="xref" data-knowl="./knowl/xref/lncc-order2-gen-soln-parts.html" data-reveal-label="Reveal" data-close-label="Close" title="Equation 3">(3)</a>
</div>

Issue:

MathJax generates the following (abbreviated) HTML for the referenced equation:

<div class="knowl__content" style="" id="knowl-uid-2" aria-live="polite" open="">
    <div class="displaymath process-math" data-contains-math-knowls="./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-eqn1.html ./knowl/xref/lncc-general-equation.html ./knowl/xref/lncc-general-solution.html ./knowl/xref/lncc-general-solution.html ./knowl/xref/lncc-general-solution.html ./knowl/xref/lncc-general-solution.html">
        <mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" display="true" width="full" tabindex="0" ctxtmenu_counter="39"(17) style="font-size: 110.9%; min-width: 22.499em; position: relative;">
            <mjx-math width="full" display="true" class="MJX-TEX" aria-hidden="true">
                <mjx-mtable width="full" side="right" style="min-width: 22.499em;">
                    <mjx-table style="width: auto; min-width: 20.899em; margin: 0px 0.8em;">
                        <mjx-itable width="full">
                            <mjx-mlabeledtr>
                                <mjx-mtd>
                                    <mjx-munder>
                                        ...
                                        <mjx-row>
                                            <mjx-under style="padding-top: 0.062em; padding-left: 4.141em;">
                                                ...
                                            </mjx-under>
                                        </mjx-row>
                                    </mjx-munder>
                                    ...
                                </mjx-mtd>
                            </mjx-mlabeledtr>
                        </mjx-itable>
                    </mjx-table>
                    ...
                </mjx-mtable>
            </mjx-math>
            ...
        </mjx-container>
    </div>
    <span class="incontext"><a class="internal" href="main-5-4-4.html#lncc-order2-gen-soln-parts">in-context</a></span>
</div>

Problem:

The padding-left on the <mjx-under> tag is set to 4.141em in the referenced equation, while in the original equation, the left-padding on the same element is 1.825em. This results in an extra 2.316em left padding on the referenced equation, causing a misalignment of the underset content.

Expected Behavior:

The padding-left should be consistent between the original and referenced equations to ensure proper alignment of the underset content.

Environment:

davidfarmer commented 3 months ago

The problem is occurring when new material is added to the page (added in a knowl).

I think the cause is that MathJax does not know the correct font size when measuring, so the calculated padding is incorrect.

dpvc commented 3 months ago

David is right, here. When the button is clicked, the content of the knowl is loaded and inserted into the page, then MathJax is used to process it, then the knowl is revealed. When not yet revealed, the content has display: none, which means that the browser doesn't do any layout on it, and when MathJax tries to figure out the surrounding em- and ex-size, it fails to do so, because the browser is returning sizes of 0 for everything. This often doesn't matter, but in the case where MathJax is configured to use the surrounding font for text-mode material, the em-size is critical, as MathJax has to determine the size of the text by asking the browser to measure it. That doesn't work in a container with display: none, as in the un-revealed knowl.

One solution would be to set mtextInheritFont to false in the chtml section of the MathJax configuration so that MathJax will use its font (where it knows the sizes) for the text material. This can lead to slight baseline misalignment in some browsers (notably Safari), however.

A second solution would be to call MathJax.startup.document.rerender() after the knowl is opened. (You can type this in the browser console window to test that it resolves the problem). I haven't looked closely at the knowl code, so I don't know if there is a hook that you can use to tell when the reveal has been completed. This will cause visual jitter, however.

Alternatively, the knowl code could delay its MathJax.typesetPromise() call until after it has changed display: none to a visible display, but before it has unrolled the knowl. That should let the sizes be computed and the math typeset before the knowl is unrolled, but while the browser is actually computing the sizes of the contents, so that should make for a smooth reveal. But again, I have not looked closely at the knowl code to see how that should be implemented.

geoff-cox commented 3 months ago

Thanks for the reply and clarification. I am asking the pretext group (here) the best way to proceed.

dpvc commented 3 months ago

I have looked closer at the knowl code, and I think that the issue can be solved fairly easily by removing line 315 from the knowl.js file:

https://github.com/PreTeXtBook/pretext/blob/f1bee47ed06587a201f55a787e239c83fec64c4d/js_lib/knowl.js#L315

And replacing line 60

https://github.com/PreTeXtBook/pretext/blob/f1bee47ed06587a201f55a787e239c83fec64c4d/js_lib/knowl.js#L60

with

      MathJax.typesetPromise().then(() => window.requestAnimationFrame(() => this.toggle(true)));

(and fixing the comment above it). This implements my third approach above (the math is not typeset until the knowl is about to open, when MathJax can get the proper measurements).

geoff-cox commented 3 months ago

Thanks, @dpvc! Based on initial testing, your suggestion seemed to work. Thanks for taking the time to investigate and provide feedback.