Typesetting Mathematics

There are two main uses for MathJax:

  • Typesetting all the mathematics within a web page, and

  • Converting a string containing mathematics into another form.

In version 2, MathJax could perform the first function very well, but it was much harder to do the second. The current version of MathJax makes both easy to do. Typesetting math is described below, while converting math is described in the next section.

Typesetting Math in a Web Page

MathJax makes it easy to typeset all the math in a web page, and in fact it will do this automatically when it is first loaded unless you configure it not to. So this is one of the easiest actions to perform in MathJax; if your page is static, there is nothing to do but load MathJax.

If your page is dynamic, and you may be adding math after the page is loaded, then you will need to tell MathJax to typeset the mathematics once it has been inserted into the page. There are two methods for doing that: MathJax.typeset() and MathJax.typesetPromise().

The first of these, MathJax.typeset(), typesets the page, and does so immediately and synchronously, so when the call finishes, the page will have been typeset. Note, however, that if the math includes actions that require additional files to be loaded (e.g., TeX input that uses \require, or that includes autoloaded extensions), then a retry error will be thrown. In that case, you should use the MathJax.typesetPromise() instead, as described below. This will make your typesetting asynchronous, however, and you may need to take that into account in the rest of your code. See also The “MathJax Retry” Error section for more details.

Warning

In MathJax v4, with the introduction of new fonts that include many more characters than the original MathJax TeX fonts did, the fonts have been broken into smaller pieces so that your readers don’t have to download the entire font and its data for characters that may never be used. That means that typesetting mathematics may need to operate asynchronously even if the TeX doesn’t include \require or any auto-loaded extensions, as the output itself could need extra font data files to be loaded. Thus in version 4, it is always best to use the promise-based commands, as described below.

The second method, MathJax.typesetPromise(), performs the typesetting asynchronously, and returns a promise that is resolved when the typesetting is complete. This properly handles loading of external files, so if you are expecting to process TeX input that can include \require or autoloaded extensions, you should use this form of typesetting. Note that it can be used with await as part of a larger async function. If you are getting a retry error while calling MathJax.typeset(), you should switch to using MathJax.typesetPromise() instead.

Each of these functions take an optional argument, which is an array of elements whose content should be processed. An element can be either an actual DOM element, or a CSS selector string for one or more DOM elements. Supplying an array of elements will restrict the typesetting to the contents of those elements only.

MathJax.typeset([elements])
Arguments:
  • elements ((string|HTMLElement)[]()) – An optional array of DOM elements or CSS selector strings that restricts the typesetting to the contents of the specified container elements.

MathJax.typesetPromise([elements])
Arguments:
  • elements ((string|HTMLElement)[]()) – An optional array of DOM elements or CSS selector strings that restricts the typesetting to the contents of the specified container elements.

Returns Promise:

A promise that resolves when the typesetting is complete.


Handling Asynchronous Typesetting

It is not recommended to perform multiple asynchronous typesetting calls simultaneously, as these can interfere with one another while they are waiting for files to load. For this reason, MathJax chains the promises returned by the MathJax.typesetPromise() function to make sure any previous typeset calls are complete before starting the new one. So if you do

MathJax.typesetPromise(["#container1"]);
MathJax.typesetPromise(["#container2"]);

the second typeset operation will wait for the first one to complete before it starts. This applies as well to the promise-based conversion functions described in the next section, which also use the promise chain to coordinate with other typesetting and conversion operations.

Warning

This automatic use of promises to serialize the typeset and conversion calls is new in version 4. In version 3, you were expected to handle chaining of the typeset calls yourself, but most coders failed to do this, so MathJax v4 now does that for you.

The version 3 documentation recommended using and setting MathJax.startup.promise yourself to make sure typeset calls were serialized; if you included that code pattern in your v3 work-flow, you should remove it, as it is no longer necessary.

Because MathJax.typesetPromise() returns a promise, you can use that promise to synchronize the rest of your code with the actions of MathJax. For example,

MathJax.typesetPromise().then(() => {
  for (const eqn of MathJax.startup.document.math) {
    console.log(eqn.math);
  }
});

would typeset the math on the page and then print the original TeX code to the console for each of the expressions on the page.

It is also possible to use the await command to wait for the promise to be resolved. For example

async function reportMath() {
  await MathJax.typesetPromise();
  for (const eqn of MathJax.startup.document.math) {
    console.log(eqn.math);
  }
}

would define an asynchronous function reportMath() that typesets the page and then reports the original TeX for each expression, similarly to the previous code example.

As an alternative approach, it is also possible to hook into the promise chain used by MathJax.typesetPromise() and the promise-based conversion functions if you have actions that need to be coordinated with MathJax’s typesetting. To do this use the command

MathJax.whenReady(action)
Arguments:
  • action (()=>any()) – A function to be performed when MathJax has finished any pending typesetting or conversion actions.

Returns:

A promise that resolves when your action has completed.

and pass it a function that does the actions you want to have symchronized with MathJax’s typesetting. This will perform your function when MathJax is finished with any pending typeset or conversion actions. It also returns a promise that resolves when your action is complete, just like the promise-based typeset functions do. If your action creates a promise, be sure you function returns that promise so that MathJax.whenReady() will wait for it to complete before its own promise is resolved.

Using this function, the previous examples could be implemented

MathJax.typesetPromise();
MathJax.whenReady(() => {
  for (const eqn of MathJax.startup.document.math) {
    console.log(eqn.math);
  }
});

The MathJax.whenReady() function is analogous to the MathJax.Hub.Queue() command in v2.


Resetting Automatic Equation Numbering

The TeX input jax allows you to automatically number equations. When modifying a page, this can lead to problems as numbered equations may be removed and added; most commonly, duplicate labels lead to issues.

You can reset equation numbering using the command

MathJax.texReset([start])
Arguments:
  • start (number()) – An optional number at which to start the equation numbering. The default is 1.

This can be used to start the equation numbering at a particular number, or reset it to the default starting number of 1.


Updating Previously Typeset Content

MathJax keeps track of all the math that it has typeset within your page. This is so that if you change the output renderer (using the MathJax contextual menu), it can be changed to use the new format, for example; or if you change the accessibility settings, say to enable Braille output, all the math can be updated to include the Braille strings that it generates. If you modify the page to include new mathematics and call MathJax.typeset() or MathJax.typesetPromise(), the newly typeset mathematics will be added to the list of already typeset mathematics, as you would expect.

If you modify the page to remove content that contains typeset mathematics, you will need to tell MathJax about that so that it knows the typeset math that you are removing is no longer on the page. You do this by using the following command:

MathJax.typesetClear([elements])
Arguments:
  • elements ((string|HTMLElement)[]()) – An optional array of DOM elements or CSS selector strings that restricts the typesetting to the contents of the specified container elements.

When called with no arguments, MathJax.typesetClear() tells MathJax to forget about all the math that has been typeset so far. Note that the math will remain in the page as typeset math, but MathJax will no longer know anything about it. For example, that means that changes to the output renderer or accessibility settings will not affect any of the math that was typeset previously.

If you remove math from only a portion of the page, you can call MathJax.typesetClear() passing it an array of container elements that will be removed, or CSS selector strings for them, and MathJax will forget about the math that is within those containers, while remembering the rest of the math on the page. Note that you should call this function before you change the contents of the containers.

For example, if you have an element with id="has-math" that you have previously typeset, and you are planning to replace the contents of this element with new content (stored in a variable new_html) that needs to be typeset, you might use something like:

MathJax.typesetClear([node]);
node.innerHTML = new_html;
MathJax.typesetPromise([node]).then(() => {
  // the new content has been typeset
});

The argument passed to MathJax.typesetClear() can be an actual DOM element, as in the example above, or a CSS selector string (e.g., '#has-math'), or an array of these. The selector can specify more than one container element (e.g., via a class selector).

If you are using automatic equation numbers and insert new content in the middle of the page, that may require the equation numbers to be adjusted throughout the page. In that case, you can do

MathJax.startup.document.state(0);
MathJax.texReset();
MathJax.typesetPromise();

to force MathJax to reset the page to the state it was before MathJax processed it (i.e., remove its typeset math), reset the TeX automatic line numbering and labels, and then re-typeset the contents of the page from scratch.


Looking up the Math on the Page

MathJax saves its information about a particular expression that it has typeset in an object called a MathItem; each typeset expression has an associated MathItem. You can look up the MathItems using the following command:

MathJax.startup.document.getMathItemsWithin(elements)
Arguments:
  • elements ((string|HTMLElement)[]()) – An array of DOM elements or CSS selector strings that restricts the typesetting to the contents of the specified container elements.

Return MathItem[]:

The list of MathItem objects for the expressions within the specified containers.

You pass this a container element (or a CSS selector for an element or collection of elements, or an array of containers or selectors) and it will return an array of the MathItems that are within those containers. E.g.,

MathJax.startup.document.getMathItemsWithin(document.body);

will return an array of all the MathItems for the typeset math on the page. See the MathItem definition for details on the contents of the MathItem structure. The MathItem is the replacement for the v2 ElementJax object, and MathJax.startup.document.getMathItemsWithin() performs a similar function to the v2 function MathJax.Hub.getAllJax().


Typesetting User-Supplied Content

Mathematics formats like LaTeX and MathML allow a powerful range of layout options, including access to hyperlinks, CSS styles, font selection and sizing, spacing, and so on. Such features give you a great deal of flexibility in producing the mathematics for your pages; but if your readers are allowed to enter mathematics into your pages (e.g., for a question-and-answer site, or in comments on a blog), these features can be abused to cause problems for other readers and pose a potential security risk to them. For example, the TeX \href command can be used to insert javascript: links into the page, while the \style macro could be used to disrupt the user interface or layout of your pages.

In order to limit the potential interference that could be caused by the mathematics entered by your readers, MathJax provides the ui/safe extension. This extension filters the mathematics on the page in order to try to remove problematic attributes, like javascript links, or font sizes that are too large or too small, or style settings that would be disruptive to the page layout. If your page allows your readers to post content that includes mathematics processed by MathJax, you should strongly consider using the ui/safe extension.

See the Safe Extension Options section for details of how to load and configure the ui/safe extension.