Upgrading from v2 to v3 — MathJax 4.0 documentation (original) (raw)

MathJax v3 is a complete rewrite of MathJax from the ground up (seeWhat’s New in MathJax v3.0), and so its internal structure is quite different from that of version 2. That means MathJax v3 is not a drop-in replacement for MathJax v2, and upgrading to version 3 takes some adjustment to your web pages. The sections below describe the changes you will need to make, and the most important differences between v2 and v3.

Warning

If you are using the latest.js feature of MathJax v2 on a CDN, note that this will not update to version 3 automatically, since there are significant and potentially breaking changes in version 3. There is, however, a bug in latest.js in versions 2.7.5 and below; when the current version is 3.0 or higher,latest.js will not use the highest version of 2.x, but instead will use the version from which latest.js has been taken. For example, if you load latest.js from version 2.7.3, it currently is giving you version 2.7.5 as the latest version, when version 3 is released to the CDN, your pages will revert to using version 2.7.3 again. This behavior has been corrected in version 2.7.6, so if you change to loading latest.js from version 2.7.6, you should get the latest 2.x version regardless of the presence of version 3 on the CDN.

MathJax v3 is still a work in progress; not all features of version 2 have been converted to version 3 yet, and some may not be. MathJax v2 will continue to be maintained as we work to move more features into version 3, but MathJax v2 likely will not see much further development, just maintenance, once MathJax v3 is fully converted.


Configuration Changes

There are a number of changes in version 3 that affect how MathJax is configured. In version 2, there were several ways to provide configuration for MathJax; in MathJax 3, when you are usingMathJax components, there is now only one, which is to set the MathJax global to contain the configuration information prior to loading MathJax. In particular, you no longer call MathJax.Hub.Config(), and this function does not exist in MathJax v3. See the section The Configuration Variable for more details on how to configure MathJax.

In addition to requiring the use of the MathJax global variable for setting the configuration, the organization of the configuration options have been changed to accommodate the new internal structure of MathJax, and some of their names have changed as well. To help you convert your existing version 2 configurations to version 3, we provide a conversion toolthat you can use to obtain a version 3 configuration that is as close as possible to your current one.

Not all configuration parameters can be converted directly, however. For some of these, it is because the version 2 features have not yet been ported to version 3, but for others, the version 2 feature may simply not exist in the new architecture of version 3. For example, MathJax v2 updates the page in phases, first removing the math source expressions (e.g., the TeX code), then inserts a preview expression (fast to create, but not as accurately laid out), and then goes back and produces high-quality typeset versions, which it inserts in chunks between page updates. MathJax version 3 does not work that way (it does not change the page until the math is entirely typeset), and so the options that control the math preview and the chunking of the equations for display simply have no counterparts in version 3.

Finally, configurations that change the MathJax code via augmenting the existing MathJax objects, or that hook into MathJax’s processing pipeline via MathJax.Hub.Register.StartupHook() or one of the other hook mechanisms will not carry over to version 3. MathJax v3 does not use the queues, signals, and callbacks that are central to version 2, so code that relies on them will have to be updated. See the Configuring MathJax section for some approaches to these issues.


Changes in Loading MathJax

Just as there are changes in how MathJax is configured, there are also changes in how MathJax is loaded. With version 2, you loadMathJax.js and indicate a combined configuration file using?config= followed by the name of the configuration file. This always required at least two files to be loaded (and often more than that), and the second file was always loaded asynchronously, meaning MathJax always operated asynchronously.

In version 3, there is no longer a MathJax.js file, and you load a combined component file directly. E.g., you load tex-chtml.js to get TeX with CommonHTML output. This reduces the number of files that need to be requested, and improves performance. SeeLoading MathJax for more details.

Just as there is no need to use ?config= in version 3, the other parameters that could be set in this way also are absent from version 3. So, for example, you can’t set delayStartupUntil in the script that loads MathJax.

The startup sequence operates fundamentally differently in version 3 from how it did in version 2. In version 2, MathJax would begin its startup process immediately upon MathJax being loaded, queuing action to perform configuration blocks, load extensions and jax, do the initial typesetting, and so on. It was difficult to insert your own actions into this sequence, and timing issues could occur if you didn’t put your configuration in the right place.

In version 3, synchronization with MathJax is done through ES6 promises, rather than MathJax’s queues and signals, and MathJax’s startup process is more straight-forward. You can insert your own code into the startup process more easily, and can replace the default startup actions entirely, if you wish. The actions MathJax takes during startup are better separated so that you can pick and choose the ones you want to perform. See the Startup Actionssection for more details on how to accomplish this.


Changes in the MathJax API

Because the internals have been completely redesigned, its API has changed, and so if you have been calling MathJax functions, or have modified MathJax internals by augmenting the existing MathJax objects, that code will no longer work with version 3, and will have to be modified. Some of the more important changes are discussed below.


Changes in Input and Output Jax

The input and output processors (called “jax”) are core pieces of MathJax. All three input processors from version 2 are present in version 3, but the AsciiMath processor has not been fully ported to version 3, and currently consists of the legacy version 2 code patched onto the version 3 framework. This is larger and less efficient than a full version 3 port, which should be included in a future release.

In version 2, MathJax used preprocessors (tex2jax, mml2jax,asciimath2jax, and jsMath2jax) to locate the mathematics in the page and prepare it for the input jax. There was really no need to have these be separate pieces, so in version 3, these have been folded into their respective input jax. That means that you don’t load them separately, and the configuration options of the preprocessor and input jax have been combined. For example, the tex2jax andTeX options now both occur in the tex configuration block.

MathJax version 2 included six different output jax, which had been developed over time to serve different purposes. The original HTML-CSS output jax had the greatest browser coverage, but its output was browser-dependent, its font detection was fragile, and it was the slowest of the output processors. The CommonHTML output jax was a more modern remake of the HTML output that was both browser independent, and considerably faster. The SVG output jax produced SVG images rather than HTML DOM trees, and did not require web fonts in order to display the math, so the results could be made self-contained. MathJax version 3 includes the CommonHTML and SVG output jax, but has dropped the older, slower HTML-CSS output format.

MathJax 2 also included an output format that produced MathML for those browsers that support it. Since only Firefox and Safari currently implement MathML rendering (with no support in IE, Edge, or Chrome), and because MathJax can’t control the quality or coverage of the MathML support in the browser, MathJax version 3 has dropped the NativeMML output format for now. Should the browser situation improve in the future, it could be added again. See MathML Support for more on this, and for an example of how to implement MathML output yourself.

There are few changes within the supported input and output jax, as described below:

Input Changes

There are two changes in the TeX input jax that can affect backward compatibility with existing TeX content in your pages.

The first concerns the \color macro; in version 2, \color is a non-standard in that it takes two arguments (the color an the math to be shown in that color), while the authentic LaTeX version is a switch that changes the color of everything that follows it. The LaTeX-compatible one was available as an extension. In version 3, both versions are extensions (see ), with the LaTeX-compatible one being autoloaded when \color is first used. See thecolor and colorv2 extensions for more information, and how to configure MathJax to use the original version-2 \color macro.

The other incompatibility is that the names of some extensions have been changed in version 3. For example, AMScd in version 2 is nowamscd in version 3. This means that you need to use\require{amscd} rather than \require{AMScd} to load the CDenvironment. In order to support existing content that uses\require, you can use the code in theVersion 2 Compatibility Example section below.

Some other changes include:

Output Changes

There are several important changes to the output jax in version 3, and several things that aren’t yet implemented, but will be in a future version. One such feature is linebreaking, which hasn’t been ported to version 3 yet. Another is that only the MathJax TeX font is currently available in version 3. See Not Yet Ported to Version 3 for a list of features that are still being converted.

In addition, there a few other changes of importance:


No Longer Applies to Version 3

A number of version 2 features have been removed as part of the redesign of MathJax version 3. These are described below.


Not Yet Ported to Version 3

As MathJax 3 is still a work in progress, not all of the version 2 features have been converted to the new code base yet, though we hope to include them in version 3 in a future release. Among the most important ones are the following.


MathJax in Node

Version 2 of MathJax was designed to work in a browser, and relied heavily on the presence of the browser window, document, DOM, and other browser-specific objects. Using MathJax on a server to pre-process mathematics (e.g., to convert a TeX string to an SVG image, for example), was not easy in version 2. The mathjax-node https://github.com/mathjax/mathjax-node project made that possible, but required a completely different way of interacting with MathJax, and was not as easy to use or as reliable as we would have liked.

Version 3 has server-side use as an important use-case to support, and so it is possible to use MathJax in a node application in essentially the same way as in a browser, with only a few minor adjustments to the configuration to allow for that. This should make it much easier to use MathJax on a server, as it will work the same there as for your web-based applications. It is also possible to link to MathJax at a lower level and access the MathJax modules directly.


Version 2 Compatibility Example

The following example causes the \color macro to be the original one from version 2, and sets up the \require macro to translate the old package names into the new ones. This should make MathJax v3 handle existing content properly.

Be sure to convert your version-2 configuration to a version-3 one via the conversion toolthat we provide.

This uses the tex-chtml.js combined component, so change this to whichever one you want.

If your website uses the MathJax API to queue typeset calls via

MathJax.Hub.Queue(['Typeset', MathJax.Hub]);

for example, these calls will need to be converted to use the MathJax 3 API. You may be able to use the following code to patch into MathJax version 3, which provides implementations forMathJax.Hub.Typeset(), and MathJax.Hub.Queue(). It also flags usages of MathJax.Hub.Register.StartupHook() and the other hook-registering commands, and that you have converted yourMathJax.Hub.Config() and x-mathjax-config scripts to their version 3 counterparts (use the conversion tool).

Add the following lines right after the new CommandMap() call in the code above:

// // Add a replacement for MathJax.Callback command // MathJax.Callback = function (args) { if (Array.isArray(args)) { if (args.length === 1 && typeof(args[0]) === 'function') { return args[0]; } else if (typeof(args[0]) === 'string' && args[1] instanceof Object && typeof(args[1][args[0]]) === 'function') { return Function.bind.apply(args[1][args[0]], args.slice(1)); } else if (typeof(args[0]) === 'function') { return Function.bind.apply(args[0], [window].concat(args.slice(1))); } else if (typeof(args[1]) === 'function') { return Function.bind.apply(args[1], [args[0]].concat(args.slice(2))); } } else if (typeof(args) === 'function') { return args; } throw Error("Can't make callback from given data"); }; // // Add a replacement for MathJax.Hub commands // MathJax.Hub = { Queue: function () { for (var i = 0, m = arguments.length; i < m; i++) { var fn = MathJax.Callback(arguments[i]); MathJax.startup.promise = MathJax.startup.promise.then(fn); } return MathJax.startup.promise; }, Typeset: function (elements, callback) { var promise = MathJax.typesetPromise(elements); if (callback) { promise = promise.then(callback); } return promise; }, Register: { MessageHook: function () {console.log('MessageHooks are not supported in version 3')}, StartupHook: function () {console.log('StartupHooks are not supported in version 3')}, LoadHook: function () {console.log('LoadHooks are not supported in version 3')} }, Config: function () {console.log('MathJax configurations should be converted for version 3')} }; // // Warn about x-mathjax-config scripts // if (document.querySelector('script[type="text/x-mathjax-config"]')) { throw Error('x-mathjax-config scripts should be converted to MathJax global variable'); }

With this you may be able to get away with using your existing version 2 code to interact with version 3. But if not, either a more sophisticated compatibility module will be needed, or better yet, convert to the new version 3 API.