Skip to content

Upgrade MathJax support from v2/v3 to v3/v4#7898

Open
emilykl wants to merge 11 commits into
v4.0from
upgrade-mathjax-v3-v4-2
Open

Upgrade MathJax support from v2/v3 to v3/v4#7898
emilykl wants to merge 11 commits into
v4.0from
upgrade-mathjax-v3-v4-2

Conversation

@emilykl

@emilykl emilykl commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Update plotly.js to be compatible with MathJax v4, and drop support for MathJax v2.

Due to some logic improvements, this should also make MathJax rendering faster.

  • Modify svg_text_utils.js to use MathJax v3/v4 syntax to render math symbols
    • MathJax v3 and v4 use the same syntax, so we can get rid of the if/else cases we used to handle v2 and v3
    • MathJax v4 uses asynchronous rendering calls only, so a small amount of refactoring is required to handle the asynchronous renders
  • Improve performance by not calling MathJax.startup.defaultReady() on every individual render. This was very slow and also incorrect usage of the MathJax API
    • Instead, create a secondary MathJax document upfront that we can use for our purposes, without affecting the page's main MathJax document, and call MathDocument.convert(tex) rather than MathJax.typeset(tex)
    • This also means we no longer have to reset the config after rendering, since the config is applied only to our internal MathJax document
    • This approach does involve three places where we reference functions/objects in the MathJax._. namespace. While not officially documented, the pattern is used in a few places in the MathJax documentation for advanced configuration
      • The context is that the MathJax API is really intended for rendering entire documents/pages in one shot, so it doesn't directly expose functions for rendering individual expressions one-at-a-time. I feel fine about this workaround though, given that it works in both v3 and v4
    • As a nice side effect, this change should make MathJax rendering in plotly much faster
  • Update image baselines
    • There are visible differences, but no regressions; all the changes are minor typsetting differences in character spacing or line height, which makes sense for a new MathJax version
  • Update all testing infrastructure to use MathJax v3 and v4 rather than v2 and v3.
    • NOTE: I've done this by changing all references to v2 to v4. This means that v4 is now the "default" in the CI, unless v3 is explicitly specified

Steps for testing

  • Check out this branch
  • Run the test dashboard (npm start) which uses MathJax 4
  • Verify that every mock with mathjax in the name (and the other baselines changed here) looks OK and matches the new baselines on this branch
    • Note: The mathjax mock itself contains several strings of TeX which don't render due to syntax errors; this is not new, and it's deliberate, to test the fallback behavior
  • Visit the MathJax 3 test dashboard (http://localhost:3000/devtools/test_dashboard/index-mathjax3.html) and verify again that everything looks fine

@emilykl emilykl changed the base branch from master to v4.0 July 10, 2026 12:18
@emilykl emilykl force-pushed the upgrade-mathjax-v3-v4-2 branch from 656d638 to 9c0b33c Compare July 10, 2026 12:33
@emilykl emilykl force-pushed the upgrade-mathjax-v3-v4-2 branch from 9c0b33c to 83bb307 Compare July 10, 2026 12:51
@emilykl emilykl marked this pull request as ready for review July 10, 2026 13:46
@emilykl emilykl requested a review from camdecoster July 10, 2026 13:46
Comment thread src/lib/svg_text_utils.js

// Now that the MathJax render has finished, re-hide the source text.
// We hid it earlier, too, but since this callback runs async,
// another function may have made it visible again

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a TODO to investigate this further

Comment thread src/lib/svg_text_utils.js
// Strip $…$ delimiters and clean up escape charaters,
// then pass the result to MathDocument.convert() to get an SVG element back
const texMath = cleanEscapesForTex(_texString).replace(/^\$+|\$+$/g, '');
return MathJax._.mathjax.mathjax.handleRetriesFor(function() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this call to handleRetriesFor required?

Comment thread src/lib/svg_text_utils.js

resetRenderer3();
resetConfig3();
// Initialize, render MathJax, then call _callback()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Initialize, render MathJax, then call _callback()

Comment thread src/lib/svg_text_utils.js
MathJax.config.startup.output = 'svg';
var tmpDiv;

const initiateMathJax = function() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an async function?

Comment thread draftlogs/7898_change.md
@@ -0,0 +1 @@
- Add support for MathJax v4, and **drop support for v2** [[#7898](https://github.com/plotly/plotly.js/pull/7898)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Add support for MathJax v4, and **drop support for v2** [[#7898](https://github.com/plotly/plotly.js/pull/7898)]
- **Breaking:** Add support for MathJax v4, and **drop support for v2** [[#7898](https://github.com/plotly/plotly.js/pull/7898)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you now why the legend got smaller?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the MathJax specifier supposed to be showing up in the pie chart? Is this the fallback behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants