mathjax/MathJax-src
 Watch   
 Star   
 Fork   
18 days ago
MathJax-src

MathJax v4.0.0-beta.6

This release includes a significant rewrite of the expression explorer and an update to the speech-rule engine (SRE) that underlies MathJax's assistive support. Accompanying this is a reorganization of the MathJax contextual menu that moves the assistive options to a more prominent position for easier access and better control. This release also includes several new font-based TeX packages (and the fonts to accompany them) that provide alternative double-struck character styles. In addition, we have moved from npm to pnpm as the package manager for the MathJax source repository. Finally, there are also a number of bug fixes since the beta.4 release.

We anticipate one more beta release before the official 4.0.0 release.

Explorer Updates

The MathJax expression explorer has been updated to seamlessly fit in with an accessible browsing experience. In particular, there is no longer a need to switch on accessibility support in the contextual menu (which can still be used to explicitly disable that support, as described in the next section). Once a formula is focused, exploration can immediately start by using the arrow keys. (For a full list of keyboard commands see here.) This allows you to dive into the details of the formula, including highlighting sub-expressions, and, if selected, magnification. Moreover, the explorer can now also be started by left-clicking elements within in the formula itself. That is, you can click on any character within the expression to start the explorer at that point in the expression. Communication with screen readers (if any is used) is achieved via aria-label and aria-braille-label elements instead of the live region as utilized previously. Alternatively, automatic voicing and synchronized highlighting can be used directly without a screen reader by switching on those options in the contextual menu.

Menu Updates

The MathJax contextual menu has been reorganized to make the accessibility features more easy to use. The top-level menu now includes an "Accessibility" section with four submenus — "Speech", "Braille", "Explorer", and "Options" — rather than an accessibility submenu as in previous versions. The Speech menu allows you to enable/disable speech generation and its associated visual output, and to turn on or off auto voicing. It also provides control over the speech rule-set to use, the verbosity of the set in use, and the language to use for the speech. Similarly, the Braille menu allows you to enable/disable Braille generation and display, as well as to select the type of Braille to generate.

The explorer controls for magnification and highlighting have been moved to the Explorer menu, and other accessibility options have been moved from the Math Settings and old Accessibility submenus to the Options menu. A new "Semantic Enrichment" option controls whether the accessibility features are available or not (unchecking disables speech and Braille generation and the explorer).

New TeX packages

This release of MathJax includes three new TeX packages that provide alternative double-struck (i.e., blackboard bold) character sets: dsfont, bbm, and bboldx. New font extensions for the mathjax-modern font are now available for these packages, and the font extensions are loaded automatically when the TeX package is loaded. Currently, these fonts are available only in combination with the mathjax-modern font, but in the next release, they will be able to be applied to any of the available fonts.

The dsfont package defines a macro \mathds that provides access to its double-struck characters. There is a configuration option that controls whether the sans-serif version of these fonts is used, or the roman versions:

MathJax = {
  tex: {
    dsfont: {
      sans: true   // default is false
    }
  }
}

The bbm package defines macros \mathbbm, '\mathmmbss, and \mathbbmttto generate its double-struck characters, as well as a\mathversionmacro that can be used to select the version of the double-struck fonts to use (this is a global setting). Here,\mathversion{bold}selects the bold versions of the double-struck characters, while any argument other thanbold` will select the normal versions of the fonts.

The bboldx package redefines \mathbb to use the bboldx double-struck characters, and adds \mathbfbb to access their bold-face versions, plus \imathbb, \jmathbb, \imathbfbb, and \jmathbfbb for dotless i and j characters in these fonts. In addition, there are macros for upper- and lower-case Greek letters, e.g., \bbGamma, \bfbbsigma, etc., and text-based versions of these for use in \text{}, e.g., \txtbbGamma. The bold delimiters \bbLparen, \bbRparen, \bbLbrack, \bbRbrack, \bbLangle, \bbRangle, and the bfbb versions of these, are defined, but do not yet work with \left and \right. That will be addressed in the next release.

Move from npm to pnpm

With this release, MathJax is switching to pnpm as our package manager rather than npm. This speeds up installation and improves script handling. Although you can still use npm, some of the scripts in package.json call pnpm, so you will need to have pnpm installed to use those scripts. Fortunately, this only affects those who are compiling and packaging MathJax, so unless you are working with the MathJax source files, you should not be affected by this change. If you are only using MathJax in web pages via a CDN, for example, you will not need to worry about pnpm (or npm).

To install pnpm you can use

npm install -g pnpm

The following sections indicate the bug fixes in this release:

TeX Input Fixes

  • Add dsfont, bbm, and bboldx TeX extensions (#1055, #1056, #1057, #1063, #1064, #1065, #1074, #1075, #1076)

  • Make textcomp package register with textmacros automatically. (#1073)

  • Fix problems with data-latex attribute generation (mathjax/MathJax#3184) (#1028, #1060)

  • Allow unknown characters to use operator table to determine class and node type. (mathjax/MathJax#3203) (#1070)

  • Handle primes in munderover as in msubsup. (mathjax/MathJax#3202) (#1069)

  • Make \symbf and \symsf handle Greek italics as in LaTeX. (#1061)

  • Add missing commands to textmacros package (#1071)

  • Make stretchy paired delimiters in math tools package not be class INNER. (mathjax/MathJax#3183) (#1059)

  • Fix \require to properly handle retries in dependencies. (mathjax/MathJax#3170) (#1050)

  • Move \divsymbol to physics package and add \divisionsymbol. (mathjax/MathJax#3173) (#1049)

  • Allow (embellished) operators in \underset, \overset, and \underoverset to specify accent="true" (#894)

  • Fix processing of \U{...} where two occurrences in \text{} would fail. (#1048)

  • Update handling of braket bars so that the enclosing braket can be more accurately found. (mathjax/MathJax#3164) (#1041)

  • Fix problem with \let using attributes of {} when they should be null (#1030)

  • Have \unicode check for illegal font name. (mathjax/MathJax#3129) (#1019)

Output Fixes

  • Add xmlns attribute for global cache svg element. (mathjax/MathJax-demos-node#58) (#1045)

  • Fix issues with line breaks and spacing in SVG output. (mathjax/MathJax#3166) (#1043)

  • Make sure math items have their metrics set before lazy typesetting. (mathjax/MathJax#3167) (#1042)

  • Don't descend into items that aren't broken when looking for the line-break node. (mathjax/MathJax#3135) (#1024)

  • Fix font extension handling of extra variants, and handle those variants in enrichment. (#1033)

  • Update CHTML longdiv output to not require clip-path. (#1025)

  • Better measuring of text that is in a native font rather than MathJax fonts (#1014)

User Interface Updates

  • Update accessibility menu items (#1068, #1082)

  • Update expression explorer (#987, #1035, #1040, #1053, #1058, #1078, #1079)

  • Fix problem with spurious white pixels from unused explorer regions (mathjax/MathJax#3001) (#1072)

  • Fix rendering of embedded HTML to work with scaling and mathsize changes. (mathjax/MathJax#3116) (#1012)

  • Add ability to not show latex attributes, and reorganize settings menu (#1017)

API Fixes

  • Proper handling of typesetPromise() in defaultPageReady(). (mathjax/MathJax#3130) (#1018)

  • Move from npm to pnpm (#1021, #1023, #1077)

  • Add missing Text.splitText() method to linkedom. (mathjax/MathJax#3134) (#1036)

  • Update LiteParser's serializeXML() method. (mathjax/MathJax-demos-node#58) (#1046)

  • Fix menu to not re-render if no typesetting has occurred. (mathjax/MathJax#3167) (#1044)

  • Fix keyvalOptions to process braces and backslashes better (#1031)

  • Update TeX input's keyvalOptions, and add GetBrackets() option to match brackets. (#1037)

  • Add ability to do typechecking and conversion on the values of key-value options (#1032)

  • Clear process bits for findMath and attach-speech, and remove safe bit that isn't needed. (#1034)

  • Refactor input/tex/ParseUtil.ts to remove namespace (#1022)

  • Add cssText() method to DOMadaptor and handle dynamic rules in HTML output. (#1027)

  • Make const enum DIRECTION into a regular object. (mathjax/MathJax#3114) (#1026)

  • Fix default option list to {} in constructors for output jax. (mathjax/MathJax#3128) (#1016)

  • Fix make-cjs-components script to work without mjs files being built first (#1013)

23 days ago
MathJax-src

MathJax v4.0.0-beta.5

This release includes a significant rewrite of the expression explorer and an update to the speech-rule engine (SRE) that underlies MathJax's assistive support. Accompanying this is a reorganization of the MathJax contextual menu that moves the assistive options to a more prominent position for easier access and better control. This release also includes several new font-based TeX packages (and the fonts to accompany them) that provide alternative double-struck character styles. In addition, we have moved from npm to pnpm as the package manager for the MathJax source repository. Finally, there are also a number of bug fixes since the beta.4 release.

We anticipate one more beta release before the official 4.0.0 release.

Explorer Updates

The MathJax expression explorer has been updated to seamlessly fit in with an accessible browsing experience. In particular, there is no longer a need to switch on accessibility support in the contextual menu (which can still be used to explicitly disable that support, as described in the next section). Once a formula is focused, exploration can immediately start by using the arrow keys. (For a full list of keyboard commands see here.) This allows you to dive into the details of the formula, including highlighting sub-expressions, and, if selected, magnification. Moreover, the explorer can now also be started by left-clicking elements within in the formula itself. That is, you can click on any character within the expression to start the explorer at that point in the expression. Communication with screen readers (if any is used) is achieved via aria-label and aria-braille-label elements instead of the live region as utilized previously. Alternatively, automatic voicing and synchronized highlighting can be used directly without a screen reader by switching on those options in the contextual menu.

Menu Updates

The MathJax contextual menu has been reorganized to make the accessibility features more easy to use. The top-level menu now includes an "Accessibility" section with four submenus — "Speech", "Braille", "Explorer", and "Options" — rather than an accessibility submenu as in previous versions. The Speech menu allows you to enable/disable speech generation and its associated visual output, and to turn on or off auto voicing. It also provides control over the speech rule-set to use, the verbosity of the set in use, and the language to use for the speech. Similarly, the Braille menu allows you to enable/disable Braille generation and display, as well as to select the type of Braille to generate.

The explorer controls for magnification and highlighting have been moved to the Explorer menu, and other accessibility options have been moved from the Math Settings and old Accessibility submenus to the Options menu. A new "Semantic Enrichment" option controls whether the accessibility features are available or not (unchecking disables speech and Braille generation and the explorer).

New TeX packages

This release of MathJax includes three new TeX packages that provide alternative double-struck (i.e., blackboard bold) character sets: dsfont, bbm, and bboldx. New font extensions for the mathjax-modern font are now available for these packages, and the font extensions are loaded automatically when the TeX package is loaded. Currently, these fonts are available only in combination with the mathjax-modern font, but in the next release, they will be able to be applied to any of the available fonts.

The dsfont package defines a macro \mathds that provides access to its double-struck characters. There is a configuration option that controls whether the sans-serif version of these fonts is used, or the roman versions:

MathJax = {
  tex: {
    dsfont: {
      sans: true   // default is false
    }
  }
}

The bbm package defines macros \mathbbm, '\mathmmbss, and \mathbbmttto generate its double-struck characters, as well as a\mathversionmacro that can be used to select the version of the double-struck fonts to use (this is a global setting). Here,\mathversion{bold}selects the bold versions of the double-struck characters, while any argument other thanbold` will select the normal versions of the fonts.

The bboldx package redefines \mathbb to use the bboldx double-struck characters, and adds \mathbfbb to access their bold-face versions, plus \imathbb, \jmathbb, \imathbfbb, and \jmathbfbb for dotless i and j characters in these fonts. In addition, there are macros for upper- and lower-case Greek letters, e.g., \bbGamma, \bfbbsigma, etc., and text-based versions of these for use in \text{}, e.g., \txtbbGamma. The bold delimiters \bbLparen, \bbRparen, \bbLbrack, \bbRbrack, \bbLangle, \bbRangle, and the bfbb versions of these, are defined, but do not yet work with \left and \right. That will be addressed in the next release.

Move from npm to pnpm

With this release, MathJax is switching to pnpm as our package manager rather than npm. This speeds up installation and improves script handling. Although you can still use npm, some of the scripts in package.json call pnpm, so you will need to have pnpm installed to use those scripts. Fortunately, this only affects those who are compiling and packaging MathJax, so unless you are working with the MathJax source files, you should not be affected by this change. If you are only using MathJax in web pages via a CDN, for example, you will not need to worry about pnpm (or npm).

To install pnpm you can use

npm install -g pnpm

The following sections indicate the bug fixes in this release:

TeX Input Fixes

  • Add dsfont, bbm, and bboldx TeX extensions (#1055, #1056, #1057, #1063, #1064, #1065, #1074, #1075, #1076)

  • Make textcomp package register with textmacros automatically. (#1073)

  • Fix problems with data-latex attribute generation (mathjax/MathJax#3184) (#1028, #1060)

  • Allow unknown characters to use operator table to determine class and node type. (mathjax/MathJax#3203) (#1070)

  • Handle primes in munderover as in msubsup. (mathjax/MathJax#3202) (#1069)

  • Make \symbf and \symsf handle Greek italics as in LaTeX. (#1061)

  • Add missing commands to textmacros package (#1071)

  • Make stretchy paired delimiters in math tools package not be class INNER. (mathjax/MathJax#3183) (#1059)

  • Fix \require to properly handle retries in dependencies. (mathjax/MathJax#3170) (#1050)

  • Move \divsymbol to physics package and add \divisionsymbol. (mathjax/MathJax#3173) (#1049)

  • Allow (embellished) operators in \underset, \overset, and \underoverset to specify accent="true" (#894)

  • Fix processing of \U{...} where two occurrences in \text{} would fail. (#1048)

  • Update handling of braket bars so that the enclosing braket can be more accurately found. (mathjax/MathJax#3164) (#1041)

  • Fix problem with \let using attributes of {} when they should be null (#1030)

  • Have \unicode check for illegal font name. (mathjax/MathJax#3129) (#1019)

Output Fixes

  • Add xmlns attribute for global cache svg element. (mathjax/MathJax-demos-node#58) (#1045)

  • Fix issues with line breaks and spacing in SVG output. (mathjax/MathJax#3166) (#1043)

  • Make sure math items have their metrics set before lazy typesetting. (mathjax/MathJax#3167) (#1042)

  • Don't descend into items that aren't broken when looking for the line-break node. (mathjax/MathJax#3135) (#1024)

  • Fix font extension handling of extra variants, and handle those variants in enrichment. (#1033)

  • Update CHTML longdiv output to not require clip-path. (#1025)

  • Better measuring of text that is in a native font rather than MathJax fonts (#1014)

User Interface Updates

  • Update accessibility menu items (#1068, #1082)

  • Update expression explorer (#987, #1035, #1040, #1053, #1058, #1078, #1079)

  • Fix problem with spurious white pixels from unused explorer regions (mathjax/MathJax#3001) (#1072)

  • Fix rendering of embedded HTML to work with scaling and mathsize changes. (mathjax/MathJax#3116) (#1012)

  • Add ability to not show latex attributes, and reorganize settings menu (#1017)

API Fixes

  • Proper handling of typesetPromise() in defaultPageReady(). (mathjax/MathJax#3130) (#1018)

  • Move from npm to pnpm (#1021, #1023, #1077)

  • Add missing Text.splitText() method to linkedom. (mathjax/MathJax#3134) (#1036)

  • Update LiteParser's serializeXML() method. (mathjax/MathJax-demos-node#58) (#1046)

  • Fix menu to not re-render if no typesetting has occurred. (mathjax/MathJax#3167) (#1044)

  • Fix keyvalOptions to process braces and backslashes better (#1031)

  • Update TeX input's keyvalOptions, and add GetBrackets() option to match brackets. (#1037)

  • Add ability to do typechecking and conversion on the values of key-value options (#1032)

  • Clear process bits for findMath and attach-speech, and remove safe bit that isn't needed. (#1034)

  • Refactor input/tex/ParseUtil.ts to remove namespace (#1022)

  • Add cssText() method to DOMadaptor and handle dynamic rules in HTML output. (#1027)

  • Make const enum DIRECTION into a regular object. (mathjax/MathJax#3114) (#1026)

  • Fix default option list to {} in constructors for output jax. (mathjax/MathJax#3128) (#1016)

  • Fix make-cjs-components script to work without mjs files being built first (#1013)

2023-10-03 22:58:53
MathJax-src

MathJax v4.0.0-beta.4

This is mainly a bug-fix release to resolve some errors reported with the recent beta.3 release. A summary of some of the most significant fixes are below, followed by a categorized list of the fixes with links to the original issues that reported them, and to the pull requests that fixed the problem. See those links for additional details on those issue.

Change Summary

  • The move to ESM modules and compiling to ES6 rather than ES5 lead to an issue with the webpacked versions of some component files that would cause errors when they are loaded. This has been resolved in this release. The source of the problem was due to the use of a custom Symbol class in MathJax's TeX input jax that conflicts with the native javascript Symbol object. This was not an issue in previous versions of MathJax, but due to differences between how webpack handles CommonJS and ESM modules, it now causes problems with some TeX extension packages that use the Symbol class. This has lead us to rename the custom Symbol class to Token, and rename the Symbol.ts and SymbolMap.ts files to Token.ts and TokenMap.ts. This is a potential breaking change to those who have created their own TeX extension packages that load one of these files.

  • There was an issue in v3 where MathJax would throw an error setting getter-only property "Package" during its configuration processing (particularly when there was no explicit MathJax configuration in the page), and the move to ESM modules exacerbated that problem. The issue has been resolved here.

  • The beta.3 version had an error where the equation, equation*, displaymath, and math LaTeX environments would produce an error about incorrectly nested environments, regardless of their content. That has been fixed.

  • The \text{} macro would produce an error message when the textmacros package is used in beta.3. This has been resolved.

  • Inline line breaks could occur in incorrect locations, sometimes producing blank lines the shouldn't be there. These extraneous breakpoints have been removed, so line breaking should work better for in-line mathematics.

  • The TeX input jax now attaches data-latex attributes to the MathML elements that it produces, indicating the TeX command from which the element originated. This information can be used by the assistive tools to produce Braille output of the original LaTeX, for example. Since data attributes are transferred to the CHTML and SVG output nodes, this information is available in MathJax's output in the page, not just the internal MathML notation.

  • Because the MathML specification indicates that any mtext element is "space-like", and since an operator in an mrow whose only other elements are space-like is considered to be an "embellished operator" that should be treated as an unbreakable unit, this can lead to unexpected results. When the operator is used for line breaking, the line break must occur before or after the embellished operator as a whole. That is, {\text{A} + \text{B}} produces <mrow><mtext>A</mtext><mo>+</mo><mtext>B</mtext></mrow>, making the <mo>+</mo> an embellished operator; if a linebreak is to occur at this +, it will be done before the A or after the B, not at the + itself. This is not what is usually intended for this LaTeX expression. Although the MathML specification is not clear about why mtext elements are space-like, it is likely because these are sometimes used to insert explicit spaces into the expression via space characters, but any mtext is considered space-like regardless of its content, leading to awkward situations like the one described above.

    In this release, MathJax has parted from the specification in making an mtext element be space-like only if its contents consists only of space characters or is empty and it doesn't have a mathbackground or style attribute. Similarly, an mspace element is considered space-like only if it does not have an explicit linebreak, height, depth, mathbackground or style attribute. With these changes, TeX expressions will not generate unexpected embellished operators that will affect their line breaking.


The categorized list of changes are in the subsections below:

TeX Input Fixes

  • Use proper spacing for initial relations in right-aligned columns of alignment tables. (mathjax/MathJax#3089) (#996)

  • Make sure \operatorname keeps TeX class OP after enrichment. (mathjax/MathJax#3084) (#989)

  • Remove incorrect frame from multline environment. (mathjax/MathJax#3083) (#988)

  • Fix bug with \text{} when textmacros package is used. (mathjax/MathJax#3082) (#983)

  • Fix error message with \vdotswithin{} from the mathtools package when it is used outside of a table. (mathjax/MathJax#3078) (#981)

  • Fix incorrect flagging of nested environments. (mathjax/MathJax#3070) (#975)

Output Fixes

  • Don't include extra line-break positions after an explicit break. (#1003)

  • Propery handle placement of scripts on \vcenter, \vbox, and \vtop. (mathjax/MathJax#3091) (#1000)

  • Fix spacing before \vcenter, \vtop, \vbox. (mathjax/MathJax#3085) (#990)

  • Fix placement of super- and subscripts when superscript has large depth. (mathjax/MathJax#3097) (#999)

  • Remove errant mjx-linestrut from SVG output. (mathjax/MathJax#3087) (#991)

Miscellaneous

  • Include default font configuration so that it will be loaded when input/chtml or input/svg is loaded in node-main. (#992)

  • Update check for spacelike MathML nodes to be more sensible. (mathjax/MathJax#3098) (#1002)

  • Prevent setting a property that has a getter during configuration processing. (mathjax/MathJax#3098) (#1001)

  • Set TeX class OP for multi-letter mo elements, as in v2. (mathjax/MathJax#3095) (#998)

  • Improve build tools for use with third-party extensions. (mathjax/MathJax#3086) (#997)

  • Prevent file system paths from being included in extensions and bundles. (#993)

  • Remove install script from package.json that is only needed for development. (#985)

  • Change Symbol to Token to avoid conflict with native Symbol in webpacked files. (mathjax/MathJax#3072) (#982)

New Features

  • Add support for *{n}{...} in array environment preamble. (mathjax/MathJax#3090) (#995)

  • Add data-latex attributes to MathML nodes from TeX input jax. (#986)

  • Add LaTeX Braille support to assistive tools. (#1004)

2023-07-20 02:04:01
MathJax-src

MathJax v4.0.0-beta.3

This release fixes a problem with determining the path used by MathJax in the webpacked node-main.js file, which is what is loaded when you require("mathjax-full") or import "mathjax-full". In addition, the commit that is tagged 4.0.0-beta.2 corresponding to the beta.2 release had the version number incorrectly set to 4.0.0-beta.1 in the MathJax object, though the npm package had it set correctly.

See the 4.0.0-beta.2 release notes for details about the changes in the v4.0-beta release, but (of course) use 4.0.0-beta.3 in place of 4.0.0-beta.2 in the URLs for accessing this version.

2023-07-18 00:43:30
MathJax-src

MathJax v4.0.0-beta.2

This is the second preliminary release of version 4, which we hope to be the last beta release before the official version becomes available. We include fixes for a number of issues reported with the alpha release, and add several new features and improvements as well. A significant one is that we now provide the MathJax JavaScript files as both ES modules as well as the older CommonJS format that we have been using in the past, and these newer ES modules are compiled into ES6 rather than the older ES5 used in earlier versions. This is discussed more fully below. There is a lot of information here, but you can use the links below to jump to the points that interest you.



New Features

This beta version of MathJax introduces the following significant new features in addition to those from the v4 alpha release.

ES6 Modules

When MathJax was first released, the current version of JavaScript was ES5, so when the code base was moved to Typescript for v3, it was down-compiled to produce ES5 code. Modern browsers support ES6, which include many new features, such as true object class creation and inheritance, proper import and export commands, Set and Map objects, promises, iterators, and many other features that make JavaScript programs faster and more reliable.

Along with new language features, ES6 introduced a new module structure that affects how individual javascript files obtain values from other files, and how they make their own definitions available to others. ES6 modules (which we will refer to as "MJS") use the new import and export commands to do this, while the older CommonJS module format (which we will call "CJS") used require() and the module.exports object to perform those functions.

MathJax v3 uses CommonJS modules with ES5 code (though this was not quite pure ES5, since one of its dependencies was actually ES6), but modern JavaScript applications are moving more and more to MJS format. Beginning with this beta version of v4, MathJax offers both MJS and CJS versions, with the MJS version being ES6, but the CJS version remaining ES5, as in past versions. The webpacked components for use in web pages are now based on the MJS versions.

Implications for MathJax in Web Pages

The webpacked MJS files are smaller than the earlier webpacked CJS files, so that should mean faster download and compile times, and the ES6 code is more efficient, so should run faster. But since this version is no longer ES5, the es5 directory that was part of the URLs for accessing MathJax from a CDN is no longer correct. The details of how the directories have been adjusted are given in the next section, but for use on the web, the only important difference introduced by the change to ES6 is that you simply remove the /es5 from the url. For example, you would use

https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.2/tex-mml-chtml.js

to load the tex-mml-chtml.js combined component.

Support for IE11 has been dropped with this version, as it does not support enough of the ES6 standards. (It is possible to webpack the CJS versions, so you can build your own ES5 version if that is necessary for you. This is described at the end of this section below.) In version 3, we recommended a link to polyfill.io in order to support IE11. This can now be removed since this version will not work with IE11 even with the polyfill.

If your only usage is in a web browser, you can skip to the section on line breaking.

New Directory Structure

MathJax's new dual distribution of both MJS and CJS modules requires a new directory structure in the mathjax/MathJax-src repository and its associated mathjax-full npm package in order to accommodate both versions. In the past, the compiled JavaScript code was found in the js directory, and the webpacked components were in the es5 directory. Now that there are both CommonJS and ES-module versions of the compiled code, these are stored in the cjs and mjs directories, respectively.

The webpacked components are now based on the new mjs files, hence they are ES6 files, and so the es5 directory has been removed, with the components now being placed in the new generically named bundle directory. That way, if there is a move to ES7 or higher, the directory name doesn't need to change again. The mathjax/MathJax repository and associated mathjax package have also eliminated the es5 directory, and the combined components and component directories are now at the top level of the repository. That means you can access them without the need for /es5 in the URL that was needed in v3. (See the Availability section below for more information on how to access v4.0.0-beta.2 in a browser.)

Existing node applications that use MathJax may have code that refers to mathjax-full/js (e.g., the examples in the MathJax-demos-node repository), and mathjax-full/es5 or mathjax/es5 directories, which no longer exist. To accommodate these, this beta release includes an exports section in its package.json file that maps these references to the proper new locations. In particular, references to mathjax-full/es5 are routed to mathjax-full/bundle automatically, and similarly, mathjax/es5 is routed to mathjax. For the mathjax-full/js directory, references will be routed to mathjax-full/mjs or mathjax-full/cjs depending on whether the reference is from an import statement or a require() call. That means that ES modules (using import) will get the mjs versions, while CommonJS modules (using require()) will get the cjs ones, and so you can continue to use mathjax-full/js, mathjax-full/es5 and mathjax/es5 as you have in the past.

The main package.json file now includes a "type": "module" line so that the .js files are considered to be MJS files automatically. The cjs directory (and other directories that need to be marked as CJS files), contain separate package.json files that set the type to commonjs so that the .js files they contain will be treated as CJS files.

Similar changes have been made to the font directories in the font packages. In particular, there are mjs and cjs directories, and the es5 directory has been removed. The bundled files for the fonts are now in the top-level directory, as they are in the mathjax npm package.

Changes to components/src

The files that are used to create the webpacked component files are ES6 modules, since they use import and export, and in previous versions of MathJax, you needed to use node -r esm to be able to require() these in your own programs (you can't use require() to load ES modules directly). Although you could load the webpacked versions of the component files in either MJS or CJS applications, the fact that the source component files are MJS modules made it difficult to use the source versions of the components in CJS applications.

Now that MathJax provides both MJS and CJS versions, we wanted to allow the source component files to be available in both forms as well. Originally, the component files were found in components/src; with this beta version, those are now in components/mjs, since they are ES modules.

Prior to this version, MathJax used Babel to convert these to ES5 during the webpack process, but since the webpacked versions are now ES6, that is no longer necessary, and Babel is no longer needed as a dependency for MathJax. Instead, for those who wish to use the components from source in a CommonJS node application, we use Typescript to down-compile the components/mjs files into the components/cjs directory as CJS modules of ES5 code.

In previous versions, require('mathjax-full') would load components/src/node-main/node-main.js, which would load the components from source rather than the webpacked versions. With the mathjax package, which only includes the webpacked versions, require('mathjax') would get es5/node-main.js, the webpacked version. In this beta version, the two have been standardized so that they both load the webpacked version. When used with require(), you will get bundle/node-main.cjs, while import will load bundle/node-main.mjs. This is accomplished via the exports section of the package.json file.

In order to get the source versions in mathjax-full, use require('mathjax-full/source').init(...) or import {init} from 'mathjax-full/source' and then call init(...). These load components/mjs/node-main/node-main.mjs or components/cjs/node-main/node-main.cjs, respectively.

For those who have been using components/src to load individual components from source, we map components/src to components/mjs when included via an import command, and to components/cjs when included via require().

The end result is that you should always get an appropriate version for your situation, whether you are importing MathJax into an MJS application or requiring it into a CJS one.

More MJS/CJS Issues

Since MathJax now needs to produce javascript files in two different formats, we use different typescript configuration files for the different setups. These are stored in the tsconfig directory. The MJS files are produced using tsconfig/mjs.json and the CJS one use tsconfig/cjs.json. Both of these call in tsconfig/common.json to set the parameters that are common to both, and then specify the target and module values to be correct for the desired JavaScript version and module format. The main tsconfig.json file simply calls in tsconfig/mjs.def and is there as a convenience for tools that expect a tsconfig.json file in the main directory.

In order to support both MJS and CJS versions, MathJax's dependencies also must provide both versions. The speech-rule-engine, mj-context-menu, and mhchemparser packages all now include both module formats using dual directories similar to MathJax itself. This means that the imports used by MathJax for these packages need to change depending on which module version is being created. In order to accomplish this, the references to those packages are handled using pseudo-package references that are remapped to the correct locations via the tsconfig.json and package.json files.

To this end, MathJax now uses the #sre, #menu, and #mhchem pseudo-package names to refer to these packages. The main package.json file uses the imports section to map these to the actual package directories that contain their MJS JavaScript files. E.g., #mhchem/* is mapped to mhchemparser/esm/*, to obtain the ES module versions of the parser. Conversely, the package.json file that is placed in the cjs directory maps #mhchem/* to mhchemparser/js/* to obtain the CommonJS versions. Similar mappings are done for the other two packages.

In addition to the mappings in the package.json file to let node (and webpack) know which directory to use, Typescript must also be told where to look for the .d.ts files for these packages. This is accomplished through the tsconfig json files via the paths array.

MathJax takes its default font from one of the MathJax font packages, and that also has separate MJS and CJS directories, so the MathJax code uses a pseudo-package, #default-font, to link to the proper mjs or cjs directory in the font package. This also provides a means of specifying what the default font is (mathjax-modern by default), as changing the mappings in the package.json files and the tsconfig files would change the default font.

For the most part, MathJax's typescript source code can be used to produce either ES modules or CommonJS modules without alteration. But there are a few differences between MJS and CJS code that do need to be taken into account. For example, CommonJS code provides __dirname for the location of the file being compiled, but this is not available in MJS modules; meanwhile, MJS files must use new URL(import.meta.url).pathname to get that data, and import is not available in CJS modules. That means there is no common method that can be used for this in both cases, and so MathJax has some module-specific files to handle the few instances where module-specific code is needed.

To accommodate this, we introduce additional pseudo-package names that can be used to select between MJS and CJS files that export the needed data using the module-specific mechanisms. The #root and #mml3 pseudo-package names are used for these two situations in the Typescript code, and #js and #source are used in the components/mjs definitions to link to the mjs or cjs JavaScript code and to module-specific code for obtaining the directory name. These are mapped to the proper locations in the package.json files and the tsconfig files. The module-specific code that these link to are stored in mjs and cjs directories where they are needed, so that #root/root.js gets mapped to ts/components/mjs/root.js when MJS files are being produced, but to ts/components/cjs/root.js for CJS files. The tsconfig files exclude the directories for the other format so that they are not compiled when not needed.

Finally, since modern browsers can import MJS files, it is possible to load the MathJax files into a browser directly via a <script type="module"> tag. To do so, however, you need to include a <script type="importmap"> tag that tells the browser how to find the pseudo-packages described above. Something like

<script type="importmap">
{
  "imports": {
    "#js/": "./node_modules/mathjax-full/mjs/",
    "#source/source.cjs": "./node_modules/mathjax-full/components/mjs/source-lab.js",
    "#root/": "./node_modules/mathjax-full/mjs/components/mjs/",
    "#mml3/": "./node_modules/mathjax-full/mjs/input/mathml/mml3/mjs/",
    "#default-font/": "./node_modules/mathjax-modern-font/mjs/",
    "#sre/": "./node_modules/speech-rule-engine/js/",
    "#menu/": "./node_modules/mj-context-menu/js/",
    "#mhchem/": "./node_modules/mhchemparser/esm/",
    "mathjax-full/components/src/a11y/util.js": "./node_modules/mathjax-full/components/src/a11y/util-lab.js",
    "mathjax-full/components/src/": "./node_modules/mathjax-full/components/mjs/",
    "mathjax-full/js/": "./node_modules/mathjax-full/mjs/",
    "mathjax-full/": "./node_modules/mathjax-full/"
  }
}
</script>

should do the trick. Then you can set up your MathJax configuration in a file mathjax-config.js as in

import {source} from 'mathjax-full/components/src/source.js';

window.MathJax = {
  loader: {
    load: ['input/tex', 'output/chtml'],
    source: source
  }
};

and then use

<script type="module">
  import './mathjax-config.js';
  import 'mathjax-full/components/src/startup/startup.js';
</script>

to load MathJax components via their source code rather than webpacked files.

This is useful for testing changes to MathJax, but should not be used in production, as the number of files that will be loaded can be quite large, and each file will need to be retrieved separately, making for unneeded network overhead.

Component JSON files

In past versions of MathJax, the components/src directory contained files that control the production of the webpacked component files in the es5 directory. Each component had a subdirectory that contained files that told the MathJax build tools how to construct the component. These included at least one .js file that imported the needed MathJax modules and did any setup needed for the component, along with one or more of build.json, copy.json, and webpack.config.js that contain the data needed for the build tools to process the component.

In this version, these three .json files have been combined into a single config.json file that contains sections for each of the three original ones. The build property of config.json contains the data that used to be in build.json, the copy property holds what was in copy.json, and the webpack property holds the data needed to pack the component.

The webpack data primarily consists of the data that used to be passed to the PACKAGE() function in webpack.config.js, but as named properties, and only those that differ from the defaults need to be included (unlike the calls to PACKAGE() where all arguments were needed). The defaults are set up so that most properties don't need to be specified, just the name of the component and the libs array, in most cases. There are some additional properties that control whether the default font should be included in the packed file, or whether a function from an external file should be called to modify the default webpack configuration after it has been constructed. See the config.json files in the various components/mjs subdirectories for examples.

Building MJS and CJS versions

There are a large number of new package scripts used for building the files used by MathJax. The main changes are that there are separate commands for building the MJS and CJS files, along with new commands to make everything all in one step, and for making single components individually.

The npm run -s compile and npm run -s make-components scripts perform these steps for the MJS versions, and there is a new

npm run -s build

command that does both of these at once. The command

npm run -s build-all

not only compiles and packs the MJS versions, but also compiles the CJS versions.

Additional commands and details are given in the section on Changes to the Build Tools section below.

Reproducing the Old ES5 Webpack Files

The new webpacked components in the bundle directory are based on the MJS files, which are ES6 JavaScript files. In contrast, the earlier versions of MathJax had CJS versions of ES5 code. If you need to support an ES5 environment (like IE11), it is possible to build that using

npm run -s compile-cjs
npm run -s make-cjs-components

which will create a bundle-cjs directory that contains ES5 versions of the webpacked components, comparable to the old es5 directory.

The tsconfig.json file has the settings for the MJS versions of the JavaScript files, and if you use an editor like emacs, the typescript editing mode automatically compiles the .ts files based on tsconfig.json into the mjs directory. If you need to make modifications to the typescript files and your application links to the CJS versions of the compiled files, it may be convenient to switch the tsconfig.json file to produce the CJS versions instead. To do that, use

npm run -s use-cjs

which will point the tsconfig.json file to the parameters for compiling into the cjs directory instead. When you are done,

npm run -s use-mjs

will set things back to the original arrangement.

Improvements to Line Breaking

The v4 alpha release was the first to include MathJax's new line-breaking algorithm, and while it has been received well by those who have used it, some issues did arise.

First, there were situations in which the line-breaking could lead to an internal error; these have been resolved in this beta release.

Second, the spacing at potential breakpoints for in-line math was not always correct. This turned out to be due to some browsers' minimum font size limitations, and so this beta version uses a different approach to providing that space to avoid that problem.

Third, there was an issue when using the contextual menu to switch from SVG to CHTML output that would cause unwanted breaks for in-line expressions; that has been resolved here.

Finally, the TeX \allowbreak and related macros originally used mo elements for inserting the potential breakpoints; but this could lead to the mo being treated as an embellished operator, making the breakpoint appear in the wrong location. So this beta version now uses mspace elements instead, as they can't form embellished operators.

A subtler problem occurs within tables when breaks are needed in multiple columns. By default, the baseline of a cell that contains breakpoints is the baseline of the top line of the cell, and since the default row alignment is on the cell's baseline, this means that the rows align on the top lines' baselines. In the situation where the table is from an alignment environment, such as \begin{align}...\end{align}, if the first column requires breaks and the second has an equal sign at the beginning of it, then the equal sign appears to be after the top line of the first column, as shown below:

bad-align

which can cause confusing results. This beta version introduces additional controls for how cells containing line breaks should be aligned, and sets the defaults for environments like align so that the first column aligns on its bottom line while the second is on the top line, producing more effective results:

good-align

In addition, it introduces a new non-standard \breakAlign macro that can be used to set the vertical alignment for the various cells, rows, or columns in the alignment. The format is \breakAlign{type}{align}, where type is one of c, r, or t, indicating whether the alignment is for the single cell in which it occurs, the row in which it occurs, or for the entire table, and align is one of t, c, m, b, for top, center, middle, or bottom. The difference between c and m is that c always centers the cell regardless of line breaks, while m only centers if there are line breaks, and otherwise aligns on the cell baseline. When type is r or t, then align can be a sequence of these letters giving the alignments to use in each entry in the row, with the last one being repeated if there are more columns than letters. When type is t the alignments are applied as row alignments to each row in the table.

For example, \breakAlign{t}{bt} could be used at the beginning of an alignment to make the baseline of the bottom row of the first column align with that of the top row of the second column, as in the diagram above.

The same can be accomplished in MathML input using the new data-break-align attribute on the mtable, mtr, or mlabeledtr elements, or the data-vertial-align attribute for mtd elements. These can have values of top, center, middle, or bottom (repeated and space-separated for tables and rows).

The data-vertical-align attribute can be used on msqrt, mroot, and mrow elements as well to adjust how they are aligned when they contain line breaks. The default for roots is bottom, so that if line-breaks occur within a root, the root will align on its bottom line:

root-break

In TeX there is no direct control over this attribute within roots.

Improvements to Assistive Support

The following are the major improvements of a11y support in MathJax:

  • New Korean locale for speech output.
  • Explorer adaptation to support the exploration of line-broken elements.
  • New text heuristics that distinguishes genuine text elements from expressions that only use text to enforce font changes to roman or mathvariant=normal.
  • Improved speech output for tensor expressions.
  • Better support of self-voicing and synchronised highlighting via automatic marking of elements in SRE's SSML renderer. This also removes the old step renderer as it is no longer necessary.

Some changes that are available in this beta release, but that are still in an experimental stage:

  • Option aria allows the generation of enriched expression that provide compatibility support for the ARIA tree role.
  • Generation of LaTeX snippets for subexpression, which are included in the MathJax data structure. This supports SRE's Euro Braille output also for sub-expressions. Note, that the Euro Braille option still needs to be set manually.
  • Improvements in alphabet generation and symbol translations reduces the size of the locale files in the distribution.

Changes To SRE's Code Structure

  • Updated build process to use ES modules instead of CommonJS modules. For compatibility reasons, CommonJS versions are still created, and both ES module and CommonJS sources are distributed.
    • New package structure: js contains JavaScript files in ES module format, cjs contains JavaScript files in CommonJS format.
  • XML handling in node now based on the latest @xmldom/xmldom library, making xmldom-sre obsolete.
  • Computation of Clearspeak moved to the MathJax code base.

Fixes

  • Correctly marks all newly created elements during the enrichment process by adding an added attribute.
  • Initialization bug in tree colorer.
  • Solves Firefox-related Xpath issue in tree colorer.
  • Correct treatment of all maction elements with toggle attribute.

The following are fixes related to libraries used in node:

  • Security fix due to xmldom vulnerability.
  • Fixes for Xpath problems due to incomplete implementation in xmldom-sre.

New TeX Features

This update includes several new features for the TeX input jax, including updated Unicode positions for some macros, new macros for characters that are now available in the fonts, updates to some TeX extensions packages, new configuration parameters, and a new macro for controlling vertical alignment of blocks with line breaks. More details are given below.

The Unicode characters produced by \vdash, \models, and \backslash have been adjusted to produce better results. The \iddots, \dddot, \ddddot, \oiint, \oiiint, \ointop, and \AA macros have been added, as have the displaymath, math, and darray environments.

The non-standard \bbFont and \scr macros have been removed, and the \frak macro has been made compatible with its usual LaTeX version.

The \underline, \llap, \rlap, \phantom, \vphantom, \hphantom, \smash, \mmlToken macros have been added to the textmacros package for use in text mode.

The \char macro is now available for inserting characters by their Unicode character positions. It produces an internal mn, mi, mo, or mtext element depending on the character specified. E.g., \char"61 produces <mi>a</mi> internally.

A new non-standard macro \U is now available for inserting a Unicode character into the TeX input string to be processed as though it had been in the input stream originally. It takes on argument, which is the Unicode code point in hexadeciaml notation. For example, \U{229E} would produce the character U+229E, a plus sign in a square. Note in particular that these macros can be used in the second argument to \mmlToken, as in \mmlToken{mi}{\U{213C}}.

A new non-standard macro \breakAlign has been added to control the vertical alignment of blocks that contain line breaks. This is discussed in the previous section on line breaks.

The units package has been added, which makes the \units, \unitfrac, and \nicefrac macros available. There are new tex.units.loose and tex.units.ugly configuration options. Both are boolean values, and the first controls how large the space is before units (true is a large space, false a smaller one), while the second determines whether \nicefrac produces bevelled fractions (false) or stacked fractions (true).

The configmacros package now allows you to create active characters that are bound to macros, so that

MathJax = {
  tex: {
    active: {
      'x': '\\mmlToken{mi}[mathvariant="bold"]{x}'
    }
  }
}

defined x to always produce a boldface x.

Note that you need to take care not to cause a loop by using the character you are making active in its own definition. In the example above, since the argument to \mmlToken is not further processed as TeX commands (except for instances of \U), that is not the case here.

A new formatRef configuration option has been added to the tagformat package that allows you to specify how \eqref is formatted. It should be a function that takes one argument, the tag associated with the specified label, and returns the string that should be used in place of the \eqref. The default is to use the result of formatTag, which is the string that will be used for the equation number on the equation itself. The returned string will be used as the link text for the link that targets the specified expression.

A new tex.tagAlign configuration option is now available that specifies how tags should be vertically aligned compared to their equations. The default is to align on the baseline, but you can specify top, center, bottom, baseline, or axis. One use case for this is when the equation is likely to have automatic line breaks inserted, in which case the baseline will be the baseline of the top line of the equation (in most cases), but you may want to have the alignment be the center of the broken equation rather than the baseline of the top line. Setting tagAlign to center would make sense in this case, without harming the usual placement for most equations.

A new tex.mathStyle configuration parameter has been added to control the italicization of variables in TeX expressions, as can be done in LaTeX via the math-style document setting. This can be set to one of TeX, ISO, French, or upright. The setting affects how upper- and lower-case Latin and Greek letters are italicized. TeX uses italics for all but upper-case Greek, whereas ISO makes everything italic, upright makes them all upright, and French makes everything upright except lower-case Latin letters.

When converting TeX to MathJax's internal MathML format, the TeX input jax will put multi-letter sequences into a single mi element when they appear inside \mathrm, \mathbf, and related macros. What constitutes a "letter" in this setting is now configurable via the tex.identifierPattern configuration option, which is a regular expression that indicates what characters should be combined into one identifier. The default value is /^[a-zA-Z]+/, but it can be extended to include other characters (e.g., numbers or accented characters) via this configuration option. Note that the pattern must begin with ^ to tie it to the beginning of the string.

Similarly, there is now a configuration option tex.ams.operatornamePattern to specify what should be put into a single mi within the argument to \operatorname. Because LaTeX treats - and * as text characters (rather than mathematical operators) within \operatorname, the default for this pattern is /^[-*a-zA-Z]+/. Again, the pattern should always begin with ^.

In the past, if an array environment had lines around the outside of the array, and there were mixed solid and dotted lines used, then MathJax might change some of them so that they are all the same style. This has been fixed in this version, so the boundary lines should now have the correct style in all cases.

Finally, the checking for proper nesting of AMS environments has been improved. This may affect existing expressions that are improperly nested but were not flagged by MathJax in the past. Previously, there was no check that these environments appeared at the top level of the expression, so an align environment could be used inside an array, for example; this now generates an error. On the other hand, gather should be allowed within align (but not another gather), but was being flagged as erroneous nesting; this is now allowed.

See the TeX Updates section for additional bugs that have been fixed.

New Output Features

The SVG output jax has two new configuration options. The first is svg.blacker, which is a number that indicates the stroke width (in thousandths of an em) to use for the character paths. Because some parts of some characters are very thin, the default is 3 in an attempt to help prevent those sections from disappearing at small sizes. Some page authors may wish to increase or decrease this in order to help the weight of the MathJax fonts better match the surrounding text font.

The second is svg.useXlink, which is either true or false, and specifies whether the SVG elements should use xlink namespaces for their href attributes. In HTML5, the xlink namespace is no longer necessary, but older systems may still require it, so the option is available.

In addition, the SVG output jax now groups characters that are not in the MathJax fonts into a single <text> element. That allows combining characters to combine, so that languages and emojis that use multiple characters to form a single glyph will be handled properly. So use \text{} around such characters to allow them to combine properly.

An improvement has been made in a long-standing issue with WebKit-based browsers, like Safari, where characters (particularly in runs of text) would not line up on the baseline properly. This is a bug in WebKit, but this version of MathJax includes a work-around that should help with the alignment in \text{}, \mathrm{} and similar macros, and other situations where the character are grouped into a single MathML element.

In the past, the hidden MathML that is produced by the assistive-mml extension could be rendered by the browser larger than the math typeset by MathJax, which could interfere with the size of the container for the expression. This version includes additional CSS to resolve this problem.

There are a number of improvements to the handling of accents and stretchy characters. In particular, there was an issue with some accents in some of the fonts where they could be offset too far to the left in some browsers (due to differences in how browsers treat combining characters whose width is not set to zero); this version includes a work-around for those differences. There are also improvements to the placement of accents, as well as for the handling of italic correction for super- and subscripts when the base is in \it or \mathit. In the alpha version, the skew data needed for proper accent placement was missing from the mathjax-tex font; that data is now included in this version.

Finally, data for additional stretchy characters was added to all the fonts for consistency so that they all now can stretch at least the ones that were stretchable in the original MathJax TeX font. The font npm packages have been updated to new versions that contain this data.

User-Interface Updates

Several new items have been added to the Show Math As and Copy to Clipboard submenus of the MathJax contextual menu. These include:

  • SpeechText, which is the generated speech string for the mathematical expression.
  • SVG Image, which is a serialized SVG object representing the expression, which can be pasted into a stand-alone image file for use elsewhere.
  • Error Message, which is the full error message when there is a TeX or MathML input error, or an internal MathJax error. In particular, when the TeX noerrors extension is used (so that error messages are not displayed within the page), this can give you the actual error message for an expression that doesn't typeset.

Note that SpeechText is only available when the assistive tools are available (as is the case for the default combined components). Similarly, SVG Image is only available when the SVG output jax is available (either in a configuration that loads it, or if the user changes to SVG output in the contextual menu).

There is also a new Filter semantic annotations entry in the Math Settings submenu that controls whether the MathML versions produced by the Show Math As and Copy to Clipboard menus will include the attributes that have been added by the semantic enhancement. There are a lot of these, and they can make the MathML hard to read, and generally are not necessary for use outside of MathJax, so the default is to filter these attributes, but you can uncheck that item if you want to include them in the MathML output.

API Changes

There are several API changes in this release, though most should not be breaking changes, as described below.

In the past, promise-based functions, like MathJax.typesetPromise(), MathJax.tex2chtmlPromise(), etc., could not be called while another one was currently in effect. That is, you needed to use the promise from one such call to tell when you could do the next call, and the documentation encouraged you to use MathJax.startup.promise to help chain these calls together. In this release, these functions now use MathJax.startup.promise internally to prevent more than one from running concurrently. In particular, you should no longer use MathJax.startup.promise yourself to serialize your calls to these functions.

In earlier versions, the MathDocument's inputJax array included any input jax that you have loaded. E.g., in the tex-mml-svg.js combined component, it would contain entries for both the TeX and MathML input jax. Because this is an array, it was not obvious which of the two entries was which (you would need to check each entry's name property to see if it is the one you want). In this release, the inputJax array also includes properties that point to the input jax by name. That is, inputJax.tex will point to the TeX input jax, if any, and similarly for inputJax.mathml.

As mentioned above, the fact that the webpacked components are now ES6 files means that MathJax will no longer run in IE11, so there is no need to include the polyfill.io script that was recommended in the documentation for IE11 support.

Also as mentioned earlier, the es5 directory has been removed from the MathJax distribution, so the /es5 should be removed from the URL used to access MathJax's components. Similarly, the font packages no longer need es5 in their URLs, so if you have set the output.fontPath or chtml.fontURL configuration options, you may need to remove the /es5 from them.

The tex.skipHtmlTags configuration property now includes select and option tags, since pop-up menu items can only contain textual content, not other HTML tags.

In addition to the new configuration options discussed the other sections above, there are two additional options available in this release:

  • options.menuOptions.settings.filterSRE, which controls whether to remove the data attributes generated by the speech-rule-engine from MathML output in the "Show Math As" and "Copy to Clipboard" menus.

  • mathml.verify.checkMathvariants, which controls whether the MathML input jax will check that mathvariant attribute values are valid math variants and report an error if not. Invalid mathvariant values can cause MathJax to crash under some circumstances, so the default value of this option is true, but this may cause current expressions with invalid math variant values that used to render to now show those nodes as having errors.

The lineWidth property of the Metrics object, used to store information about the font metrics of the container surrounding an expression, has been removed, as the line-breaking algorithm ended up using the containerWidth property directly. That affects functions that accept metric data as their inputs (such as MathDocument.convert() and MathJax.tex2chtml()), as these will no longer accept lineWidth in the options passed to them.

Some backward-compatibility code in v3 has been removed; e.g., when the tex.multlineWidth configuration option was moved to tex.ams.multlineWidth in an earlier version, there was code to move the old value to the new location, but that code has been removed in v4.

Changes to the Build Tools

The tools used for creating the webpacked component files have been significantly updated for this beta release. Partly this is to accommodate the changes needed for the production of the dual MJS/CJS files, and partly in order to make it easier to do individual steps of the build process in isolation. There are now package scripts for performing most of the development tasks that you might need to do if you are modifying MathJax or building your own components.

In the past, to compile the typescript files into javascript, you would use npm run -s compile, and to build the webpacked component files, you did npm run -s make-components. These commands are still available, but there is a new

npm run -s build

command that does both at once.

Because we now make both MJS and CJS versions of the MathJax files, there are commands to make each type. The commands above make the MJS versions, but there are also module-specific commands that make the MJS and CJS versions separately.

npm run -s compile-cjs
npm run -s compile-mjs

npm run -s make-cjs-components
npm run -s make-mjs-components

npm run -s build-cjs
npm run -s build-mjs

The generic versions are just aliases for the MJS-specific ones. Note that because the webpacked versions use the MJS JavaScript files, the make-cjs-components script is never run, but if you want to make ES5-based versions of the webpacked files,

npm run -s compile-cjs
npm run -s make-cjs-components

will create a bundle-cjs directory containing the ES5 webpacked files comparable to the ones that used to be in the es5 directory.

There is also

npm run -s build-all

that does both the build-mjs and build-cjs actions, creating all the files in the mjs, cjs, bundle and components/cjs directories.

Because the make-components action webpacks all the components, a time consuming process, there is a make-one script that webpacks only one component. The format for this is

npm run -s make-one <component> <module-type>

where <component> is the name of the directory in components/mjs that defines the component, and <module-type> is either mjs or cjs. For example

npm run -s make-one input/tex mjs

would pack only the TeX input component.

These commands all rely on the components/bin/makeAll script, which has been enhanced for this version. It now has a number of command-line options to control its functions, including:

  • --no-subdirs to prevent it from processing all the subdirectories of the given directory
  • --cjs to process using CJS rules
  • --mjs to process using MJS rules (the default)
  • --terse to only print the main headings rather than the file details like the files included in a webpacked version
  • --build to only perform the build steps (i.e., creating the lib directories used for shared imports)
  • --copy to only perform the copy steps (e.g., copying the CHTML woff files into place)
  • --pack to only do the webpack steps
  • --bundle-cjs to webpack into the bundle-cjs directory rather than the bundle directory

These can also be passed to npm run -s -- make-one if you want to restrict the steps performed (it already uses --no-subdirs and one of --cjs or --mjs).

These changes mean you only need to use makeAll, since it handles calling components/bin/build, components/bin/copy and components/bin/pack itself. The arguments for these sub-programs have changed in this version, particularly for components/bin/pack, so you should not call these by hand yourself unless you have looked at the internals of them carefully.

If you use a checked-out copy of this repository for your development, then there needs to be a symbolic link from node_modules/mathjax-full to this repository directory. That should be created automatically when you do npm install, but if you need to install other npm packages, that link will be removed by npm, so you will need to recreate the link. To do so, you can use

npm run -s link:full

which should produce the proper link for you.


Updates and Issues Resolved

This section lists the issues that are fixed and pull requests that are included in this release. Many of these include more details about the changes in the pull request associated with the issue, so be sure to look at both.

TeX Updates

  • Properly handle italic correction for \mathit, and for subscripts with multi-character bases. (#961)

  • Properly place super- and subscripts for stretched operators. (mathjax/MathJax#3049) (#962)

  • Make vertical spacing for horizontal stretchy characters more like TeX. (#960)

  • Handle dash during font-change in \operatorname. (mathjax/MathJax#3038) (#958)

  • Handle multiple spaces in \text{} as in LaTeX. (#937)

  • Properly handle arrays with dashed frame borders. (mathjax/MathJax#2972) (#932)

  • Add nulldelimiterspace for null delimiters. (mathjax/MathJax#985) (#391)

  • Don't treat \overrightarrow as a mathaccent. (mathjax/MathJax#3010) (#929)

  • Add a number of requested macros and environments now that we can support them: \AA, \iddots, \oiint and \oiiint, \dddot and \ddddot, \ointop, and the darray, math, and displaymath environments. (#923)

  • Make un-delimited in-line environments possible. (#923)

  • The Unicode value for \backslash has been changed to U+005C. (#923)

  • Implement \char and add \U for raw unicode characters. (#921)

  • Better checking of improperly nested AMS environments. (mathjax/MathJax#1892) (#915)

  • Add the latex units package. (#881)

  • Make \frak consistent with LaTeX, and remove non-standard \scr and \bbFont. (mathjax/MathJax#1780) (#917)

  • Add ability to define active characters as macros. (math/MathJax#2967) (#914)

  • Allow separate formatting for \eqref{}. (mathjax/MathJax#2736)

  • Make vertical bar have the correct TeX class. (mathjax/MathJax#2938) (#907)

  • Provide an option for placement of equation numbers in TeX input. (mathjax/MathJax#2977) (#904)

  • Allow \columncolor in the array preamble. (mathjax/MathJax#2955) (#902)

  • Allow (embellished) operators in \underset, \overset, and \underoverset to specify accent="true". (#894)

  • Handle newlines as spaces in text mode. (mathjax/MathJax#2993) (#898)

  • Add \underline and several other macros to textmacros package. (mathjax/MathJax#2969) (#897)

  • Map \models to correct Unicode point, and don't use variant form for \vDash (mathjax/MathJax#2543) (#895)

  • Better handling of multiple children from \operatorname{} (mathjax/MathJax#2991) (#888)

  • Fix parsing of vertical bar delimiters in physics package (mathjax/MathJax#2973) (#876)

  • Properly handle \over within braket and physics packages. (mathjax/MathJax#3000) (#906)

  • Fix infinite loop when <tex-html> is used more than once (mathjax/MathJax#2948) (#875)

  • Fix memory leak in textmacros package. (mathjax/MathJax#3061) (#968)

  • Handle \operatorname{} like named functions. (mathjax/MathJax#2899) (#860)

MathML Updates

  • Fix problem with MML3 extension when MathML includes &nbsp;. (mathjax/MathJax#3030) (#949)

  • Add checks for valid mathvariant attributes. (#940)

  • Add a tooltip for MathML verification short errors that shows the full error. (#939)

  • Verify that <math> elements are not nested. (#938)

  • Add <html>, <head>, and <body> tags to MathML when parsing a MathML expression as HTML. (#880)

Output Updates

  • Allow inline-breaking within top-level nodes added by SRE (#971)

  • Honor the rule_thickness and surd_height font parameters. (#948)

  • Work around WebKit bug that causes baseline alignment problems. (mathjax/MathJax#2866) (#957)

  • Remove forced breaks that SVG inserted when switching to CHTML. (#956)

  • More reliable handling of stretchy assemblies. (#952)

  • Use <mspace> for \allowbreak, etc., and fix issues with <mspace> breaking. (#935)

  • Move handling of overflow scrolling to CSS and allow tagged expressions to scroll. (#945)

  • Remove Safari hack that is not needed with v4. (mathjax/MathJax#3023) (#933)

  • Better control over breaking in tables, and over vertical alignment of nodes containing breaks. (#927)

  • Handle <mrow> with class INNER as a unit to get spacing after it correct. (mathjax/MathJax#3018) (#930)

  • Fix issue with size of spaces for potential in-line break points, and improve line spacing when a breakpoint occurs. (mathjax/MathJax#3005) (#919)

  • Combine unknown characters into a common <text> element in SVG output. (mathjax/MathJax#2672) (#903)

  • Allow space for labels when deciding on a table's width for line breaking its columns. (#926)

  • Fix potential crash with line breaks. (mathjax/MathJax#3015) (#925)

  • Use left alignment and no indent for forced inline breaks when inline breaking is off. (mathjax/MathJax#3005) (#919)

  • Provide option to control how <mi> is italicized. (mathjax/MathJax#2570) (#900)

  • Add option to not use xlink namespace in serialized SVG output. (mathjax/MathJax#2929) (#910)

  • Allow SVG character stroke-width to be specified. (mathjax/MathJax#2859) (#909)

  • Better handling of scriptminsize. (mathjax/MathJax#2975) (#901)

  • Allow borders to inherit surrounding color in SVG. (mathjax/MathJax#2939) (#896)

  • Fix problems with size of horizontal stretchy characters in some cases. (mathjax/MathJax#2981)

  • Fix CHTML so that depth is correct for empty <mpadded> elements that have depth specified. (#891)

  • Improve vertical separation for x-arrows (#mathjax/MathJax#2981) (#887)

  • Work around combining characters being handled as 0-width automatically by some browsers. (#885)

  • Use proper scaling factors for placement of top and bottom of <munderover> when the construct is scaled (mathjax/MathJax#2983) (#898)

  • Update use of skew values from accents to allow better placement. (mathjax/MathJax#3051) (#966)

  • Don't remap U+0060 to U+2035 so \grave works properly. (#967)

User Interface Updates

  • Add SVG Image and Speech Text to Show As and Copy As menu items. (#942)

  • Better handling of dynamic submenus in the MathJax contextual menu. (#872)

  • Fix longstanding issues with the assistive explorer, and add autovoicing. (#857)

  • Update CSS used by assistive-mml so its size matches that of the typeset math. (mathjax/MathJax#2936) (#920)

  • Fix scaling of tooltips when text font is inherited. (mathjax/MathJax#2957) (#908)

API Updates

  • Make it easier to find a specific input jax by name. (#959)

  • Use promises when changing the renderer so that dynamic files can be loaded properly. (#950)

  • Make promise-based calls use MathJax.startup.promise to avoid concurrency. (#941)

  • Remove lineWidth from the Metrics object, since it is never used. (#936)

  • Remove backward-compatibility code from previous version. (#934)

  • Make sure math in multiple container elements are typeset in order. (mathjax/MathJax#2999) (#912)

  • Don't typeset within <select> or <option> nodes by default. (mathjax/MathJax#3006) (#911)

  • Allow semantic-enrich to enrich HTML-in-MML. (#890)

  • Only activate explorer if in a browser. (#878)


Availability of v4.0.0-beta

The MathJax 4.0.0-beta.2 version can be accessed via CDN as

https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.2/tex-mml-chtml.js

or using one of the other combined configuration files:

  • tex-html.js
  • tex-svg.js
  • tex-mml-chtml.js
  • tex-mml-svg.js
  • mml-html.js
  • mml-svg.js

Each of these includes the mathjax-modern font, but also comes in a version ending in -nofont.js (e.g., tex-mml-chtml-nofont.js) that does not include it, where you are expected to specify the font using the output.font configuration option. This saves your readers from having to download the data for the mathjax-modern font that is not going to be used.

Note that the es5 directory is no longer needed in the URL when you are using mathjax@4.0.0-beta.2, as all the combined configuration files are now at the top level of the mathjax npm package that is used by CDNs to deliver MathJax.

The source code for MathJax v4 is available in the mathjax-full@4.0.0-beta.2 npm package, or in the v4.0.0-beta branch of the MathJax-src repository on GitHub.

The fonts are each in their own npm package, e.g., mathjax-modern-font, mathjax-stix2-font, etc., which you can install in your own node applications as needed. In a browser, MathJax should access the fonts from cdn.jsdelivr.com automatically. These font packages also include combined configuration files that are like tex-mml-chtml.js and tex-mml-svg.js, but that include that package's font rather than mathjax-modern. For example, the mathjax-stix2-font package include tex-mml-chtml-mathjax-stix2.js and tex-mml-svg-mathjax-stix2.js, so you can use

https://cdn.jsdelivr.net/npm/mathjax-stix2-font/tex-mml-chtml-mathjax-stix2.js

in order to get a single-file MathJax component that includes the mathjax-stix2 font rather than mathjax-modern. In particular, you can get the equivalent of the tex-mml-html.js file with the original MathJax TeX font all-in-one file using

https://cdn.jsdelivr.net/npm/mathjax-tex-font/tex-mml-chtml-mathjax-tex.js

This font does not have dynamic ranges (all the font data is in one file), so it should operate much the same as MathJax v3 in that respect, but it does have a more limited character coverage than the other fonts.

2023-07-17 23:58:29
MathJax-src

MathJax v4.0.0-beta.1

This is the second preliminary release of version 4, which we hope to be the last beta release before the official version becomes available. We include fixes for a number of issues reported with the alpha release, and add several new features and improvements as well. A significant one is that we now provide the MathJax JavaScript files as both ES modules as well as the older CommonJS format that we have been using in the past, and these newer ES modules are compiled into ES6 rather than the older ES5 used in earlier versions. This is discussed more fully below. There is a lot of information here, but you can use the links below to jump to the points that interest you.



New Features

This beta version of MathJax introduces the following significant new features in addition to those from the v4 alpha release.

ES6 Modules

When MathJax was first released, the current version of JavaScript was ES5, so when the code base was moved to Typescript for v3, it was down-compiled to produce ES5 code. Modern browsers support ES6, which include many new features, such as true object class creation and inheritance, proper import and export commands, Set and Map objects, promises, iterators, and many other features that make JavaScript programs faster and more reliable.

Along with new language features, ES6 introduced a new module structure that affects how individual javascript files obtain values from other files, and how they make their own definitions available to others. ES6 modules (which we will refer to as "MJS") use the new import and export commands to do this, while the older CommonJS module format (which we will call "CJS") used require() and the module.exports object to perform those functions.

MathJax v3 uses CommonJS modules with ES5 code (though this was not quite pure ES5, since one of its dependencies was actually ES6), but modern JavaScript applications are moving more and more to MJS format. Beginning with this beta version of v4, MathJax offers both MJS and CJS versions, with the MJS version being ES6, but the CJS version remaining ES5, as in past versions. The webpacked components for use in web pages are now based on the MJS versions.

Implications for MathJax in Web Pages

The webpacked MJS files are smaller than the earlier webpacked CJS files, so that should mean faster download and compile times, and the ES6 code is more efficient, so should run faster. But since this version is no longer ES5, the es5 directory that was part of the URLs for accessing MathJax from a CDN is no longer correct. The details of how the directories have been adjusted are given in the next section, but for use on the web, the only important difference introduced by the change to ES6 is that you simply remove the /es5 from the url. For example, you would use

https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.1/tex-mml-chtml.js

to load the tex-mml-chtml.js combined component.

Support for IE11 has been dropped with this version, as it does not support enough of the ES6 standards. (It is possible to webpack the CJS versions, so you can build your own ES5 version if that is necessary for you. This is described at the end of this section below.) In version 3, we recommended a link to polyfill.io in order to support IE11. This can now be removed since this version will not work with IE11 even with the polyfill.

If your only usage is in a web browser, you can skip to the section on line breaking.

New Directory Structure

MathJax's new dual distribution of both MJS and CJS modules requires a new directory structure in the mathjax/MathJax-src repository and its associated mathjax-full npm package in order to accommodate both versions. In the past, the compiled JavaScript code was found in the js directory, and the webpacked components were in the es5 directory. Now that there are both CommonJS and ES-module versions of the compiled code, these are stored in the cjs and mjs directories, respectively.

The webpacked components are now based on the new mjs files, hence they are ES6 files, and so the es5 directory has been removed, with the components now being placed in the new generically named bundle directory. That way, if there is a move to ES7 or higher, the directory name doesn't need to change again. The mathjax/MathJax repository and associated mathjax package have also eliminated the es5 directory, and the combined components and component directories are now at the top level of the repository. That means you can access them without the need for /es5 in the URL that was needed in v3. (See the Availability section below for more information on how to access v4.0.0-beta.1 in a browser.)

Existing node applications that use MathJax may have code that refers to mathjax-full/js (e.g., the examples in the MathJax-demos-node repository), and mathjax-full/es5 or mathjax/es5 directories, which no longer exist. To accommodate these, this beta release includes an exports section in its package.json file that maps these references to the proper new locations. In particular, references to mathjax-full/es5 are routed to mathjax-full/bundle automatically, and similarly, mathjax/es5 is routed to mathjax. For the mathjax-full/js directory, references will be routed to mathjax-full/mjs or mathjax-full/cjs depending on whether the reference is from an import statement or a require() call. That means that ES modules (using import) will get the mjs versions, while CommonJS modules (using require()) will get the cjs ones, and so you can continue to use mathjax-full/js, mathjax-full/es5 and mathjax/es5 as you have in the past.

The main package.json file now includes a "type": "module" line so that the .js files are considered to be MJS files automatically. The cjs directory (and other directories that need to be marked as CJS files), contain separate package.json files that set the type to commonjs so that the .js files they contain will be treated as CJS files.

Similar changes have been made to the font directories in the font packages. In particular, there are mjs and cjs directories, and the es5 directory has been removed. The bundled files for the fonts are now in the top-level directory, as they are in the mathjax npm package.

Changes to components/src

The files that are used to create the webpacked component files are ES6 modules, since they use import and export, and in previous versions of MathJax, you needed to use node -r esm to be able to require() these in your own programs (you can't use require() to load ES modules directly). Although you could load the webpacked versions of the component files in either MJS or CJS applications, the fact that the source component files are MJS modules made it difficult to use the source versions of the components in CJS applications.

Now that MathJax provides both MJS and CJS versions, we wanted to allow the source component files to be available in both forms as well. Originally, the component files were found in components/src; with this beta version, those are now in components/mjs, since they are ES modules.

Prior to this version, MathJax used Babel to convert these to ES5 during the webpack process, but since the webpacked versions are now ES6, that is no longer necessary, and Babel is no longer needed as a dependency for MathJax. Instead, for those who wish to use the components from source in a CommonJS node application, we use Typescript to down-compile the components/mjs files into the components/cjs directory as CJS modules of ES5 code.

In previous versions, require('mathjax-full') would load components/src/node-main/node-main.js, which would load the components from source rather than the webpacked versions. With the mathjax package, which only includes the webpacked versions, require('mathjax') would get es5/node-main.js, the webpacked version. In this beta version, the two have been standardized so that they both load the webpacked version. When used with require(), you will get bundle/node-main.cjs, while import will load bundle/node-main.mjs. This is accomplished via the exports section of the package.json file.

In order to get the source versions in mathjax-full, use require('mathjax-full/source').init(...) or import {init} from 'mathjax-full/source' and then call init(...). These load components/mjs/node-main/node-main.mjs or components/cjs/node-main/node-main.cjs, respectively.

For those who have been using components/src to load individual components from source, we map components/src to components/mjs when included via an import command, and to components/cjs when included via require().

The end result is that you should always get an appropriate version for your situation, whether you are importing MathJax into an MJS application or requiring it into a CJS one.

More MJS/CJS Issues

Since MathJax now needs to produce javascript files in two different formats, we use different typescript configuration files for the different setups. These are stored in the tsconfig directory. The MJS files are produced using tsconfig/mjs.json and the CJS one use tsconfig/cjs.json. Both of these call in tsconfig/common.json to set the parameters that are common to both, and then specify the target and module values to be correct for the desired JavaScript version and module format. The main tsconfig.json file simply calls in tsconfig/mjs.def and is there as a convenience for tools that expect a tsconfig.json file in the main directory.

In order to support both MJS and CJS versions, MathJax's dependencies also must provide both versions. The speech-rule-engine, mj-context-menu, and mhchemparser packages all now include both module formats using dual directories similar to MathJax itself. This means that the imports used by MathJax for these packages need to change depending on which module version is being created. In order to accomplish this, the references to those packages are handled using pseudo-package references that are remapped to the correct locations via the tsconfig.json and package.json files.

To this end, MathJax now uses the #sre, #menu, and #mhchem pseudo-package names to refer to these packages. The main package.json file uses the imports section to map these to the actual package directories that contain their MJS JavaScript files. E.g., #mhchem/* is mapped to mhchemparser/esm/*, to obtain the ES module versions of the parser. Conversely, the package.json file that is placed in the cjs directory maps #mhchem/* to mhchemparser/js/* to obtain the CommonJS versions. Similar mappings are done for the other two packages.

In addition to the mappings in the package.json file to let node (and webpack) know which directory to use, Typescript must also be told where to look for the .d.ts files for these packages. This is accomplished through the tsconfig json files via the paths array.

MathJax takes its default font from one of the MathJax font packages, and that also has separate MJS and CJS directories, so the MathJax code uses a pseudo-package, #default-font, to link to the proper mjs or cjs directory in the font package. This also provides a means of specifying what the default font is (mathjax-modern by default), as changing the mappings in the package.json files and the tsconfig files would change the default font.

For the most part, MathJax's typescript source code can be used to produce either ES modules or CommonJS modules without alteration. But there are a few differences between MJS and CJS code that do need to be taken into account. For example, CommonJS code provides __dirname for the location of the file being compiled, but this is not available in MJS modules; meanwhile, MJS files must use new URL(import.meta.url).pathname to get that data, and import is not available in CJS modules. That means there is no common method that can be used for this in both cases, and so MathJax has some module-specific files to handle the few instances where module-specific code is needed.

To accommodate this, we introduce additional pseudo-package names that can be used to select between MJS and CJS files that export the needed data using the module-specific mechanisms. The #root and #mml3 pseudo-package names are used for these two situations in the Typescript code, and #js and #source are used in the components/mjs definitions to link to the mjs or cjs JavaScript code and to module-specific code for obtaining the directory name. These are mapped to the proper locations in the package.json files and the tsconfig files. The module-specific code that these link to are stored in mjs and cjs directories where they are needed, so that #root/root.js gets mapped to ts/components/mjs/root.js when MJS files are being produced, but to ts/components/cjs/root.js for CJS files. The tsconfig files exclude the directories for the other format so that they are not compiled when not needed.

Finally, since modern browsers can import MJS files, it is possible to load the MathJax files into a browser directly via a <script type="module"> tag. To do so, however, you need to include a <script type="importmap"> tag that tells the browser how to find the pseudo-packages described above. Something like

<script type="importmap">
{
  "imports": {
    "#js/": "./node_modules/mathjax-full/mjs/",
    "#source/source.cjs": "./node_modules/mathjax-full/components/mjs/source-lab.js",
    "#root/": "./node_modules/mathjax-full/mjs/components/mjs/",
    "#mml3/": "./node_modules/mathjax-full/mjs/input/mathml/mml3/mjs/",
    "#default-font/": "./node_modules/mathjax-modern-font/mjs/",
    "#sre/": "./node_modules/speech-rule-engine/js/",
    "#menu/": "./node_modules/mj-context-menu/js/",
    "#mhchem/": "./node_modules/mhchemparser/esm/",
    "mathjax-full/components/src/a11y/util.js": "./node_modules/mathjax-full/components/src/a11y/util-lab.js",
    "mathjax-full/components/src/": "./node_modules/mathjax-full/components/mjs/",
    "mathjax-full/js/": "./node_modules/mathjax-full/mjs/",
    "mathjax-full/": "./node_modules/mathjax-full/"
  }
}
</script>

should do the trick. Then you can set up your MathJax configuration in a file mathjax-config.js as in

import {source} from 'mathjax-full/components/src/source.js';

window.MathJax = {
  loader: {
    load: ['input/tex', 'output/chtml'],
    source: source
  }
};

and then use

<script type="module">
  import './mathjax-config.js';
  import 'mathjax-full/components/src/startup/startup.js';
</script>

to load MathJax components via their source code rather than webpacked files.

This is useful for testing changes to MathJax, but should not be used in production, as the number of files that will be loaded can be quite large, and each file will need to be retrieved separately, making for unneeded network overhead.

Component JSON files

In past versions of MathJax, the components/src directory contained files that control the production of the webpacked component files in the es5 directory. Each component had a subdirectory that contained files that told the MathJax build tools how to construct the component. These included at least one .js file that imported the needed MathJax modules and did any setup needed for the component, along with one or more of build.json, copy.json, and webpack.config.js that contain the data needed for the build tools to process the component.

In this version, these three .json files have been combined into a single config.json file that contains sections for each of the three original ones. The build property of config.json contains the data that used to be in build.json, the copy property holds what was in copy.json, and the webpack property holds the data needed to pack the component.

The webpack data primarily consists of the data that used to be passed to the PACKAGE() function in webpack.config.js, but as named properties, and only those that differ from the defaults need to be included (unlike the calls to PACKAGE() where all arguments were needed). The defaults are set up so that most properties don't need to be specified, just the name of the component and the libs array, in most cases. There are some additional properties that control whether the default font should be included in the packed file, or whether a function from an external file should be called to modify the default webpack configuration after it has been constructed. See the config.json files in the various components/mjs subdirectories for examples.

Building MJS and CJS versions

There are a large number of new package scripts used for building the files used by MathJax. The main changes are that there are separate commands for building the MJS and CJS files, along with new commands to make everything all in one step, and for making single components individually.

The npm run -s compile and npm run -s make-components scripts perform these steps for the MJS versions, and there is a new

npm run -s build

command that does both of these at once. The command

npm run -s build-all

not only compiles and packs the MJS versions, but also compiles the CJS versions.

Additional commands and details are given in the section on Changes to the Build Tools section below.

Reproducing the Old ES5 Webpack Files

The new webpacked components in the bundle directory are based on the MJS files, which are ES6 JavaScript files. In contrast, the earlier versions of MathJax had CJS versions of ES5 code. If you need to support an ES5 environment (like IE11), it is possible to build that using

npm run -s compile-cjs
npm run -s make-cjs-components

which will create a bundle-cjs directory that contains ES5 versions of the webpacked components, comparable to the old es5 directory.

The tsconfig.json file has the settings for the MJS versions of the JavaScript files, and if you use an editor like emacs, the typescript editing mode automatically compiles the .ts files based on tsconfig.json into the mjs directory. If you need to make modifications to the typescript files and your application links to the CJS versions of the compiled files, it may be convenient to switch the tsconfig.json file to produce the CJS versions instead. To do that, use

npm run -s use-cjs

which will point the tsconfig.json file to the parameters for compiling into the cjs directory instead. When you are done,

npm run -s use-mjs

will set things back to the original arrangement.

Improvements to Line Breaking

The v4 alpha release was the first to include MathJax's new line-breaking algorithm, and while it has been received well by those who have used it, some issues did arise.

First, there were situations in which the line-breaking could lead to an internal error; these have been resolved in this beta release.

Second, the spacing at potential breakpoints for in-line math was not always correct. This turned out to be due to some browsers' minimum font size limitations, and so this beta version uses a different approach to providing that space to avoid that problem.

Third, there was an issue when using the contextual menu to switch from SVG to CHTML output that would cause unwanted breaks for in-line expressions; that has been resolved here.

Finally, the TeX \allowbreak and related macros originally used mo elements for inserting the potential breakpoints; but this could lead to the mo being treated as an embellished operator, making the breakpoint appear in the wrong location. So this beta version now uses mspace elements instead, as they can't form embellished operators.

A subtler problem occurs within tables when breaks are needed in multiple columns. By default, the baseline of a cell that contains breakpoints is the baseline of the top line of the cell, and since the default row alignment is on the cell's baseline, this means that the rows align on the top lines' baselines. In the situation where the table is from an alignment environment, such as \begin{align}...\end{align}, if the first column requires breaks and the second has an equal sign at the beginning of it, then the equal sign appears to be after the top line of the first column, as shown below:

bad-align

which can cause confusing results. This beta version introduces additional controls for how cells containing line breaks should be aligned, and sets the defaults for environments like align so that the first column aligns on its bottom line while the second is on the top line, producing more effective results:

good-align

In addition, it introduces a new non-standard \breakAlign macro that can be used to set the vertical alignment for the various cells, rows, or columns in the alignment. The format is \breakAlign{type}{align}, where type is one of c, r, or t, indicating whether the alignment is for the single cell in which it occurs, the row in which it occurs, or for the entire table, and align is one of t, c, m, b, for top, center, middle, or bottom. The difference between c and m is that c always centers the cell regardless of line breaks, while m only centers if there are line breaks, and otherwise aligns on the cell baseline. When type is r or t, then align can be a sequence of these letters giving the alignments to use in each entry in the row, with the last one being repeated if there are more columns than letters. When type is t the alignments are applied as row alignments to each row in the table.

For example, \breakAlign{t}{bt} could be used at the beginning of an alignment to make the baseline of the bottom row of the first column align with that of the top row of the second column, as in the diagram above.

The same can be accomplished in MathML input using the new data-break-align attribute on the mtable, mtr, or mlabeledtr elements, or the data-vertial-align attribute for mtd elements. These can have values of top, center, middle, or bottom (repeated and space-separated for tables and rows).

The data-vertical-align attribute can be used on msqrt, mroot, and mrow elements as well to adjust how they are aligned when they contain line breaks. The default for roots is bottom, so that if line-breaks occur within a root, the root will align on its bottom line:

root-break

In TeX there is no direct control over this attribute within roots.

Improvements to Assistive Support

The following are the major improvements of a11y support in MathJax:

  • New Korean locale for speech output.
  • Explorer adaptation to support the exploration of line-broken elements.
  • New text heuristics that distinguishes genuine text elements from expressions that only use text to enforce font changes to roman or mathvariant=normal.
  • Improved speech output for tensor expressions.
  • Better support of self-voicing and synchronised highlighting via automatic marking of elements in SRE's SSML renderer. This also removes the old step renderer as it is no longer necessary.

Some changes that are available in this beta release, but that are still in an experimental stage:

  • Option aria allows the generation of enriched expression that provide compatibility support for the ARIA tree role.
  • Generation of LaTeX snippets for subexpression, which are included in the MathJax data structure. This supports SRE's Euro Braille output also for sub-expressions. Note, that the Euro Braille option still needs to be set manually.
  • Improvements in alphabet generation and symbol translations reduces the size of the locale files in the distribution.

Changes To SRE's Code Structure

  • Updated build process to use ES modules instead of CommonJS modules. For compatibility reasons, CommonJS versions are still created, and both ES module and CommonJS sources are distributed.
    • New package structure: js contains JavaScript files in ES module format, cjs contains JavaScript files in CommonJS format.
  • XML handling in node now based on the latest @xmldom/xmldom library, making xmldom-sre obsolete.
  • Computation of Clearspeak moved to the MathJax code base.

Fixes

  • Correctly marks all newly created elements during the enrichment process by adding an added attribute.
  • Initialization bug in tree colorer.
  • Solves Firefox-related Xpath issue in tree colorer.
  • Correct treatment of all maction elements with toggle attribute.

The following are fixes related to libraries used in node:

  • Security fix due to xmldom vulnerability.
  • Fixes for Xpath problems due to incomplete implementation in xmldom-sre.

New TeX Features

This update includes several new features for the TeX input jax, including updated Unicode positions for some macros, new macros for characters that are now available in the fonts, updates to some TeX extensions packages, new configuration parameters, and a new macro for controlling vertical alignment of blocks with line breaks. More details are given below.

The Unicode characters produced by \vdash, \models, and \backslash have been adjusted to produce better results. The \iddots, \dddot, \ddddot, \oiint, \oiiint, \ointop, and \AA macros have been added, as have the displaymath, math, and darray environments.

The non-standard \bbFont and \scr macros have been removed, and the \frak macro has been made compatible with its usual LaTeX version.

The \underline, \llap, \rlap, \phantom, \vphantom, \hphantom, \smash, \mmlToken macros have been added to the textmacros package for use in text mode.

The \char macro is now available for inserting characters by their Unicode character positions. It produces an internal mn, mi, mo, or mtext element depending on the character specified. E.g., \char"61 produces <mi>a</mi> internally.

A new non-standard macro \U is now available for inserting a Unicode character into the TeX input string to be processed as though it had been in the input stream originally. It takes on argument, which is the Unicode code point in hexadeciaml notation. For example, \U{229E} would produce the character U+229E, a plus sign in a square. Note in particular that these macros can be used in the second argument to \mmlToken, as in \mmlToken{mi}{\U{213C}}.

A new non-standard macro \breakAlign has been added to control the vertical alignment of blocks that contain line breaks. This is discussed in the previous section on line breaks.

The units package has been added, which makes the \units, \unitfrac, and \nicefrac macros available. There are new tex.units.loose and tex.units.ugly configuration options. Both are boolean values, and the first controls how large the space is before units (true is a large space, false a smaller one), while the second determines whether \nicefrac produces bevelled fractions (false) or stacked fractions (true).

The configmacros package now allows you to create active characters that are bound to macros, so that

MathJax = {
  tex: {
    active: {
      'x': '\\mmlToken{mi}[mathvariant="bold"]{x}'
    }
  }
}

defined x to always produce a boldface x.

Note that you need to take care not to cause a loop by using the character you are making active in its own definition. In the example above, since the argument to \mmlToken is not further processed as TeX commands (except for instances of \U), that is not the case here.

A new formatRef configuration option has been added to the tagformat package that allows you to specify how \eqref is formatted. It should be a function that takes one argument, the tag associated with the specified label, and returns the string that should be used in place of the \eqref. The default is to use the result of formatTag, which is the string that will be used for the equation number on the equation itself. The returned string will be used as the link text for the link that targets the specified expression.

A new tex.tagAlign configuration option is now available that specifies how tags should be vertically aligned compared to their equations. The default is to align on the baseline, but you can specify top, center, bottom, baseline, or axis. One use case for this is when the equation is likely to have automatic line breaks inserted, in which case the baseline will be the baseline of the top line of the equation (in most cases), but you may want to have the alignment be the center of the broken equation rather than the baseline of the top line. Setting tagAlign to center would make sense in this case, without harming the usual placement for most equations.

A new tex.mathStyle configuration parameter has been added to control the italicization of variables in TeX expressions, as can be done in LaTeX via the math-style document setting. This can be set to one of TeX, ISO, French, or upright. The setting affects how upper- and lower-case Latin and Greek letters are italicized. TeX uses italics for all but upper-case Greek, whereas ISO makes everything italic, upright makes them all upright, and French makes everything upright except lower-case Latin letters.

When converting TeX to MathJax's internal MathML format, the TeX input jax will put multi-letter sequences into a single mi element when they appear inside \mathrm, \mathbf, and related macros. What constitutes a "letter" in this setting is now configurable via the tex.identifierPattern configuration option, which is a regular expression that indicates what characters should be combined into one identifier. The default value is /^[a-zA-Z]+/, but it can be extended to include other characters (e.g., numbers or accented characters) via this configuration option. Note that the pattern must begin with ^ to tie it to the beginning of the string.

Similarly, there is now a configuration option tex.ams.operatornamePattern to specify what should be put into a single mi within the argument to \operatorname. Because LaTeX treats - and * as text characters (rather than mathematical operators) within \operatorname, the default for this pattern is /^[-*a-zA-Z]+/. Again, the pattern should always begin with ^.

In the past, if an array environment had lines around the outside of the array, and there were mixed solid and dotted lines used, then MathJax might change some of them so that they are all the same style. This has been fixed in this version, so the boundary lines should now have the correct style in all cases.

Finally, the checking for proper nesting of AMS environments has been improved. This may affect existing expressions that are improperly nested but were not flagged by MathJax in the past. Previously, there was no check that these environments appeared at the top level of the expression, so an align environment could be used inside an array, for example; this now generates an error. On the other hand, gather should be allowed within align (but not another gather), but was being flagged as erroneous nesting; this is now allowed.

See the TeX Updates section for additional bugs that have been fixed.

New Output Features

The SVG output jax has two new configuration options. The first is svg.blacker, which is a number that indicates the stroke width (in thousandths of an em) to use for the character paths. Because some parts of some characters are very thin, the default is 3 in an attempt to help prevent those sections from disappearing at small sizes. Some page authors may wish to increase or decrease this in order to help the weight of the MathJax fonts better match the surrounding text font.

The second is svg.useXlink, which is either true or false, and specifies whether the SVG elements should use xlink namespaces for their href attributes. In HTML5, the xlink namespace is no longer necessary, but older systems may still require it, so the option is available.

In addition, the SVG output jax now groups characters that are not in the MathJax fonts into a single <text> element. That allows combining characters to combine, so that languages and emojis that use multiple characters to form a single glyph will be handled properly. So use \text{} around such characters to allow them to combine properly.

An improvement has been made in a long-standing issue with WebKit-based browsers, like Safari, where characters (particularly in runs of text) would not line up on the baseline properly. This is a bug in WebKit, but this version of MathJax includes a work-around that should help with the alignment in \text{}, \mathrm{} and similar macros, and other situations where the character are grouped into a single MathML element.

In the past, the hidden MathML that is produced by the assistive-mml extension could be rendered by the browser larger than the math typeset by MathJax, which could interfere with the size of the container for the expression. This version includes additional CSS to resolve this problem.

There are a number of improvements to the handling of accents and stretchy characters. In particular, there was an issue with some accents in some of the fonts where they could be offset too far to the left in some browsers (due to differences in how browsers treat combining characters whose width is not set to zero); this version includes a work-around for those differences. There are also improvements to the placement of accents, as well as for the handling of italic correction for super- and subscripts when the base is in \it or \mathit. In the alpha version, the skew data needed for proper accent placement was missing from the mathjax-tex font; that data is now included in this version.

Finally, data for additional stretchy characters was added to all the fonts for consistency so that they all now can stretch at least the ones that were stretchable in the original MathJax TeX font. The font npm packages have been updated to new versions that contain this data.

User-Interface Updates

Several new items have been added to the Show Math As and Copy to Clipboard submenus of the MathJax contextual menu. These include:

  • SpeechText, which is the generated speech string for the mathematical expression.
  • SVG Image, which is a serialized SVG object representing the expression, which can be pasted into a stand-alone image file for use elsewhere.
  • Error Message, which is the full error message when there is a TeX or MathML input error, or an internal MathJax error. In particular, when the TeX noerrors extension is used (so that error messages are not displayed within the page), this can give you the actual error message for an expression that doesn't typeset.

Note that SpeechText is only available when the assistive tools are available (as is the case for the default combined components). Similarly, SVG Image is only available when the SVG output jax is available (either in a configuration that loads it, or if the user changes to SVG output in the contextual menu).

There is also a new Filter semantic annotations entry in the Math Settings submenu that controls whether the MathML versions produced by the Show Math As and Copy to Clipboard menus will include the attributes that have been added by the semantic enhancement. There are a lot of these, and they can make the MathML hard to read, and generally are not necessary for use outside of MathJax, so the default is to filter these attributes, but you can uncheck that item if you want to include them in the MathML output.

API Changes

There are several API changes in this release, though most should not be breaking changes, as described below.

In the past, promise-based functions, like MathJax.typesetPromise(), MathJax.tex2chtmlPromise(), etc., could not be called while another one was currently in effect. That is, you needed to use the promise from one such call to tell when you could do the next call, and the documentation encouraged you to use MathJax.startup.promise to help chain these calls together. In this release, these functions now use MathJax.startup.promise internally to prevent more than one from running concurrently. In particular, you should no longer use MathJax.startup.promise yourself to serialize your calls to these functions.

In earlier versions, the MathDocument's inputJax array included any input jax that you have loaded. E.g., in the tex-mml-svg.js combined component, it would contain entries for both the TeX and MathML input jax. Because this is an array, it was not obvious which of the two entries was which (you would need to check each entry's name property to see if it is the one you want). In this release, the inputJax array also includes properties that point to the input jax by name. That is, inputJax.tex will point to the TeX input jax, if any, and similarly for inputJax.mathml.

As mentioned above, the fact that the webpacked components are now ES6 files means that MathJax will no longer run in IE11, so there is no need to include the polyfill.io script that was recommended in the documentation for IE11 support.

Also as mentioned earlier, the es5 directory has been removed from the MathJax distribution, so the /es5 should be removed from the URL used to access MathJax's components. Similarly, the font packages no longer need es5 in their URLs, so if you have set the output.fontPath or chtml.fontURL configuration options, you may need to remove the /es5 from them.

The tex.skipHtmlTags configuration property now includes select and option tags, since pop-up menu items can only contain textual content, not other HTML tags.

In addition to the new configuration options discussed the other sections above, there are two additional options available in this release:

  • options.menuOptions.settings.filterSRE, which controls whether to remove the data attributes generated by the speech-rule-engine from MathML output in the "Show Math As" and "Copy to Clipboard" menus.

  • mathml.verify.checkMathvariants, which controls whether the MathML input jax will check that mathvariant attribute values are valid math variants and report an error if not. Invalid mathvariant values can cause MathJax to crash under some circumstances, so the default value of this option is true, but this may cause current expressions with invalid math variant values that used to render to now show those nodes as having errors.

The lineWidth property of the Metrics object, used to store information about the font metrics of the container surrounding an expression, has been removed, as the line-breaking algorithm ended up using the containerWidth property directly. That affects functions that accept metric data as their inputs (such as MathDocument.convert() and MathJax.tex2chtml()), as these will no longer accept lineWidth in the options passed to them.

Some backward-compatibility code in v3 has been removed; e.g., when the tex.multlineWidth configuration option was moved to tex.ams.multlineWidth in an earlier version, there was code to move the old value to the new location, but that code has been removed in v4.

Changes to the Build Tools

The tools used for creating the webpacked component files have been significantly updated for this beta release. Partly this is to accommodate the changes needed for the production of the dual MJS/CJS files, and partly in order to make it easier to do individual steps of the build process in isolation. There are now package scripts for performing most of the development tasks that you might need to do if you are modifying MathJax or building your own components.

In the past, to compile the typescript files into javascript, you would use npm run -s compile, and to build the webpacked component files, you did npm run -s make-components. These commands are still available, but there is a new

npm run -s build

command that does both at once.

Because we now make both MJS and CJS versions of the MathJax files, there are commands to make each type. The commands above make the MJS versions, but there are also module-specific commands that make the MJS and CJS versions separately.

npm run -s compile-cjs
npm run -s compile-mjs

npm run -s make-cjs-components
npm run -s make-mjs-components

npm run -s build-cjs
npm run -s build-mjs

The generic versions are just aliases for the MJS-specific ones. Note that because the webpacked versions use the MJS JavaScript files, the make-cjs-components script is never run, but if you want to make ES5-based versions of the webpacked files,

npm run -s compile-cjs
npm run -s make-cjs-components

will create a bundle-cjs directory containing the ES5 webpacked files comparable to the ones that used to be in the es5 directory.

There is also

npm run -s build-all

that does both the build-mjs and build-cjs actions, creating all the files in the mjs, cjs, bundle and components/cjs directories.

Because the make-components action webpacks all the components, a time consuming process, there is a make-one script that webpacks only one component. The format for this is

npm run -s make-one <component> <module-type>

where <component> is the name of the directory in components/mjs that defines the component, and <module-type> is either mjs or cjs. For example

npm run -s make-one input/tex mjs

would pack only the TeX input component.

These commands all rely on the components/bin/makeAll script, which has been enhanced for this version. It now has a number of command-line options to control its functions, including:

  • --no-subdirs to prevent it from processing all the subdirectories of the given directory
  • --cjs to process using CJS rules
  • --mjs to process using MJS rules (the default)
  • --terse to only print the main headings rather than the file details like the files included in a webpacked version
  • --build to only perform the build steps (i.e., creating the lib directories used for shared imports)
  • --copy to only perform the copy steps (e.g., copying the CHTML woff files into place)
  • --pack to only do the webpack steps
  • --bundle-cjs to webpack into the bundle-cjs directory rather than the bundle directory

These can also be passed to npm run -s -- make-one if you want to restrict the steps performed (it already uses --no-subdirs and one of --cjs or --mjs).

These changes mean you only need to use makeAll, since it handles calling components/bin/build, components/bin/copy and components/bin/pack itself. The arguments for these sub-programs have changed in this version, particularly for components/bin/pack, so you should not call these by hand yourself unless you have looked at the internals of them carefully.

If you use a checked-out copy of this repository for your development, then there needs to be a symbolic link from node_modules/mathjax-full to this repository directory. That should be created automatically when you do npm install, but if you need to install other npm packages, that link will be removed by npm, so you will need to recreate the link. To do so, you can use

npm run -s link:full

which should produce the proper link for you.


Updates and Issues Resolved

This section lists the issues that are fixed and pull requests that are included in this release. Many of these include more details about the changes in the pull request associated with the issue, so be sure to look at both.

TeX Updates

  • Properly handle italic correction for \mathit, and for subscripts with multi-character bases. (#961)

  • Properly place super- and subscripts for stretched operators. (mathjax/MathJax#3049) (#962)

  • Make vertical spacing for horizontal stretchy characters more like TeX. (#960)

  • Handle dash during font-change in \operatorname. (mathjax/MathJax#3038) (#958)

  • Handle multiple spaces in \text{} as in LaTeX. (#937)

  • Properly handle arrays with dashed frame borders. (mathjax/MathJax#2972) (#932)

  • Add nulldelimiterspace for null delimiters. (mathjax/MathJax#985) (#391)

  • Don't treat \overrightarrow as a mathaccent. (mathjax/MathJax#3010) (#929)

  • Add a number of requested macros and environments now that we can support them: \AA, \iddots, \oiint and \oiiint, \dddot and \ddddot, \ointop, and the darray, math, and displaymath environments. (#923)

  • Make un-delimited in-line environments possible. (#923)

  • The Unicode value for \backslash has been changed to U+005C. (#923)

  • Implement \char and add \U for raw unicode characters. (#921)

  • Better checking of improperly nested AMS environments. (mathjax/MathJax#1892) (#915)

  • Add the latex units package. (#881)

  • Make \frak consistent with LaTeX, and remove non-standard \scr and \bbFont. (mathjax/MathJax#1780) (#917)

  • Add ability to define active characters as macros. (math/MathJax#2967) (#914)

  • Allow separate formatting for \eqref{}. (mathjax/MathJax#2736)

  • Make vertical bar have the correct TeX class. (mathjax/MathJax#2938) (#907)

  • Provide an option for placement of equation numbers in TeX input. (mathjax/MathJax#2977) (#904)

  • Allow \columncolor in the array preamble. (mathjax/MathJax#2955) (#902)

  • Allow (embellished) operators in \underset, \overset, and \underoverset to specify accent="true". (#894)

  • Handle newlines as spaces in text mode. (mathjax/MathJax#2993) (#898)

  • Add \underline and several other macros to textmacros package. (mathjax/MathJax#2969) (#897)

  • Map \models to correct Unicode point, and don't use variant form for \vDash (mathjax/MathJax#2543) (#895)

  • Better handling of multiple children from \operatorname{} (mathjax/MathJax#2991) (#888)

  • Fix parsing of vertical bar delimiters in physics package (mathjax/MathJax#2973) (#876)

  • Properly handle \over within braket and physics packages. (mathjax/MathJax#3000) (#906)

  • Fix infinite loop when <tex-html> is used more than once (mathjax/MathJax#2948) (#875)

  • Fix memory leak in textmacros package. (mathjax/MathJax#3061) (#968)

  • Handle \operatorname{} like named functions. (mathjax/MathJax#2899) (#860)

MathML Updates

  • Fix problem with MML3 extension when MathML includes &nbsp;. (mathjax/MathJax#3030) (#949)

  • Add checks for valid mathvariant attributes. (#940)

  • Add a tooltip for MathML verification short errors that shows the full error. (#939)

  • Verify that <math> elements are not nested. (#938)

  • Add <html>, <head>, and <body> tags to MathML when parsing a MathML expression as HTML. (#880)

Output Updates

  • Allow inline-breaking within top-level nodes added by SRE (#971)

  • Honor the rule_thickness and surd_height font parameters. (#948)

  • Work around WebKit bug that causes baseline alignment problems. (mathjax/MathJax#2866) (#957)

  • Remove forced breaks that SVG inserted when switching to CHTML. (#956)

  • More reliable handling of stretchy assemblies. (#952)

  • Use <mspace> for \allowbreak, etc., and fix issues with <mspace> breaking. (#935)

  • Move handling of overflow scrolling to CSS and allow tagged expressions to scroll. (#945)

  • Remove Safari hack that is not needed with v4. (mathjax/MathJax#3023) (#933)

  • Better control over breaking in tables, and over vertical alignment of nodes containing breaks. (#927)

  • Handle <mrow> with class INNER as a unit to get spacing after it correct. (mathjax/MathJax#3018) (#930)

  • Fix issue with size of spaces for potential in-line break points, and improve line spacing when a breakpoint occurs. (mathjax/MathJax#3005) (#919)

  • Combine unknown characters into a common <text> element in SVG output. (mathjax/MathJax#2672) (#903)

  • Allow space for labels when deciding on a table's width for line breaking its columns. (#926)

  • Fix potential crash with line breaks. (mathjax/MathJax#3015) (#925)

  • Use left alignment and no indent for forced inline breaks when inline breaking is off. (mathjax/MathJax#3005) (#919)

  • Provide option to control how <mi> is italicized. (mathjax/MathJax#2570) (#900)

  • Add option to not use xlink namespace in serialized SVG output. (mathjax/MathJax#2929) (#910)

  • Allow SVG character stroke-width to be specified. (mathjax/MathJax#2859) (#909)

  • Better handling of scriptminsize. (mathjax/MathJax#2975) (#901)

  • Allow borders to inherit surrounding color in SVG. (mathjax/MathJax#2939) (#896)

  • Fix problems with size of horizontal stretchy characters in some cases. (mathjax/MathJax#2981)

  • Fix CHTML so that depth is correct for empty <mpadded> elements that have depth specified. (#891)

  • Improve vertical separation for x-arrows (#mathjax/MathJax#2981) (#887)

  • Work around combining characters being handled as 0-width automatically by some browsers. (#885)

  • Use proper scaling factors for placement of top and bottom of <munderover> when the construct is scaled (mathjax/MathJax#2983) (#898)

  • Update use of skew values from accents to allow better placement. (mathjax/MathJax#3051) (#966)

  • Don't remap U+0060 to U+2035 so \grave works properly. (#967)

User Interface Updates

  • Add SVG Image and Speech Text to Show As and Copy As menu items. (#942)

  • Better handling of dynamic submenus in the MathJax contextual menu. (#872)

  • Fix longstanding issues with the assistive explorer, and add autovoicing. (#857)

  • Update CSS used by assistive-mml so its size matches that of the typeset math. (mathjax/MathJax#2936) (#920)

  • Fix scaling of tooltips when text font is inherited. (mathjax/MathJax#2957) (#908)

API Updates

  • Make it easier to find a specific input jax by name. (#959)

  • Use promises when changing the renderer so that dynamic files can be loaded properly. (#950)

  • Make promise-based calls use MathJax.startup.promise to avoid concurrency. (#941)

  • Remove lineWidth from the Metrics object, since it is never used. (#936)

  • Remove backward-compatibility code from previous version. (#934)

  • Make sure math in multiple container elements are typeset in order. (mathjax/MathJax#2999) (#912)

  • Don't typeset within <select> or <option> nodes by default. (mathjax/MathJax#3006) (#911)

  • Allow semantic-enrich to enrich HTML-in-MML. (#890)

  • Only activate explorer if in a browser. (#878)


Availability of v4.0.0-beta

The MathJax 4.0.0-beta.1 version can be accessed via CDN as

https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.1/tex-mml-chtml.js

or using one of the other combined configuration files:

  • tex-html.js
  • tex-svg.js
  • tex-mml-chtml.js
  • tex-mml-svg.js
  • mml-html.js
  • mml-svg.js

Each of these includes the mathjax-modern font, but also comes in a version ending in -nofont.js (e.g., tex-mml-chtml-nofont.js) that does not include it, where you are expected to specify the font using the output.font configuration option. This saves your readers from having to download the data for the mathjax-modern font that is not going to be used.

Note that the es5 directory is no longer needed in the URL when you are using mathjax@4.0.0-beta.1, as all the combined configuration files are now at the top level of the mathjax npm package that is used by CDNs to deliver MathJax.

The source code for MathJax v4 is available in the mathjax-full@4.0.0-beta.1 npm package, or in the v4.0.0-beta branch of the MathJax-src repository on GitHub.

The fonts are each in their own npm package, e.g., mathjax-modern-font, mathjax-stix2-font, etc., which you can install in your own node applications as needed. In a browser, MathJax should access the fonts from cdn.jsdelivr.com automatically. These font packages also include combined configuration files that are like tex-mml-chtml.js and tex-mml-svg.js, but that include that package's font rather than mathjax-modern. For example, the mathjax-stix2-font package include tex-mml-chtml-mathjax-stix2.js and tex-mml-svg-mathjax-stix2.js, so you can use

https://cdn.jsdelivr.net/npm/mathjax-stix2-font/tex-mml-chtml-mathjax-stix2.js

in order to get a single-file MathJax component that includes the mathjax-stix2 font rather than mathjax-modern. In particular, you can get the equivalent of the tex-mml-html.js file with the original MathJax TeX font all-in-one file using

https://cdn.jsdelivr.net/npm/mathjax-tex-font/tex-mml-chtml-mathjax-tex.js

This font does not have dynamic ranges (all the font data is in one file), so it should operate much the same as MathJax v3 in that respect, but it does have a more limited character coverage than the other fonts.

2022-10-02 21:52:05
MathJax-src

MathJax v4.0.0-alpha.1

This is the first alpha release of a major update to MathJax, adding a number of new features and enhancements. As this includes significant changes that involve potentially breaking changes, in order to not have these changes affect existing web sites, this release increments the major version number so that sites using the mathjax@3 URLs will be protected from these changes until they update to version 4 explicitly. That is, this new release is an opt-in update.



Major New Features

Version 4 of MathJax introduces the following significant new features. It also fixes some outstanding bugs, adds some new TeX macros, and improves support for some others.

Extended Font Support

This version includes support for a number of new font sets for MathJax, and changes the default font to one based on the Latin-Modern fonts; it offers support for a much larger range of characters than MathJax's original TeX font set, but is consistent with the look-and-feel of the original MathJax TeX fonts. The new set is slightly lighter, so will not seem so bold and will fit in better on Windows machines, without losing too much on linux, Mac OS, and iOS displays. The original MathJax TeX font set is also available as an option, for those who are unwilling to part with it.

There are 11 fonts available for MathJax v4:

Font Name Original Source
mathjax-modern A version of Latin-Modern (the new default font in MathJax)
mathjax-asana A version of the Asana-Math font
mathjax-bonum A version of the Gyre Bonum font
mathjax-dejavu A version of the Gyre DejaVu font
mathjax-pagella A version of the Gyre Pagella font
mathjax-schola A version of the Gyre Schola font
mathjax-termes A version of the Gyre Termes font
mathjax-stix2 A version of the STIX2 font
mathjax-fira A version of the Fira and Fira-Math fonts
mathjax-euler A version of the Neo Euler font as an extension to mathjax-modern
mathjax-tex The original MathJax TeX font

You can specify the font you want to use by setting the font option in the new output block of your MathJax configuration (where options common to both output renders can be placed). For example,

MathJax = {
  output: {
    font: 'mathjax-stix2'
  }
};

will select the mathjax-stix2 font. For in-browser use, this will obtain the font and its data from cdn.jsdelivr.net and no other configuration is necessary. For node applications, first install the font via

npm install mathjax-stix2-font

(add -font to the name of whichever font you want and install that); MathJax should find the font in your node_modules folder. It is also possible to configure the path to the fonts using the fontPath option of the output block. This should be set to a string that indicates where the font can be found; that string should include %%FONT%% in any part of the path where the font name needs to appear. For example,

MathJax = {
  output: {
    fontPath: './node_modules/%%FONT%%-font/es5/output/fonts/%%FONT%%'
  }
};

is the default path in node applications.

It is also possible to specify an explicit URL as the font name in the configuration:

MathJax = {
  output: {
     font: 'https://cdn.jsdelivr.net/npm/mathjax-stix2-font/es5/output/fonts/mathjax-stix2'
  }
};

For those who wish to use the original MathJax font as it appears in version 3, specify the font as mathjax-tex.

The combined component files, like tex-chtml.js and mml-svg.js, include the new mathjax-modern font as part of the component so that only one file needs to be downloaded. But if you want to use a different font, you probably don't want to download mathjax-modern first and then the font you actually want to use. Instead, you should use a component ending in -nofont.js, for example, tex-chtml-nofont.js, so that the initial download is smaller, as it doesn't include mathjax-modern. See the section on MathJax v4.0 and Promises for more details concerning the proper handling of typesetting with the new fonts.

The tools for building the data needed by MathJax for your own font will be made available after version 4 is officially released. They were used to create these new fonts, but are not yet ready for public release, as they need cleaning up and documentation. But in the future, you will be able to generate an extension to an existing font (for example, to replace the letters and numbers with a different font while leaving all the rest of the characters unchanged), or a completely new font. So look for that functionality in the future.

Line-breaking Support

Version 4 include the long-awaited support for automatic and explicit line breaking of math expressions. The support in v4 is an improvement over that in v2 in a number of ways. In particular, version 4 includes the option of breaking in-line expressions so that long expressions near the end of a line will automatically break and wrap to the next line. This is accomplished by allowing the browser to break the expressions where it needs to (following TeX's rules for what constitutes a valid in-line breakpoint). For display equations, version 4 provides support not only for automatic line breaking, but also for several other options for handling wide equations, including scaling the equation (to fit the container size), and scrolling if it is too wide. The page author can set the default, but there is also a new menu item where the viewer can switch the overflow handling to match their preferences. Version 4 also implements line-breaking of <mtext> elements (which are created by \text{} and other text-mode macros) , so long textual material can be broken automatically; this was not possible in version 2.

As part of the line-breaking support, a number of new TeX macros have been made available to control line breaks (to make them more or less desirable, or force or prevent them entirely). Also, support has been added for additional array environment template patterns that can be used to control the width of and automatic line breaking within table cells, as well as insert text before or after every cell in a column, or adjust the spacing between columns. New macros for creating boxes of specific widths in which line breaking will occur are also available, and there are options for controlling justification and indentation of the text. Such boxes are also available in MathML via additional options for the mpadded element.

Finally, version 4 now attempts to break cells within tables based on the size of table as a whole (whereas v2 broke cells only if they individually were too wide for the container, and broke them to the container width regardless of the size of the rest of the table).

Display breaking

The algorithm used in version 4 for breaking displayed equations is based on the one from version 2, but is not identical to it. Unlike version 2, the results should be nearly identical between the CHTML and SVG output renders, and the code is set up so that the algorithm can be updated or even replaced much easier than in v2. We do have plans for improvements that we hope to make in the future.

The page author can control how long expressions are handled using the new displayOverflow output jax configuration option, which can be set to overflow, scale, scroll, truncate, linebreak, or elide, though the latter is not yet implemented. The reader can override that default using the MathJax contextual menu, which has a new item in the "Math Settings" submenu for handling "Wide Expressions". For MathML input, MathJax version 4 now honors the overflow attribute of the math element, so you can mark a single long expression for line breaking, or for scrolling, for example.

Note that there is now a new output configuration block that can be used to provide options that are common to both CHTML and SVG output, so that you may have set for your default output jax will stay in effect when the user changes renderers via the contextual menu.

When displayOverflow is set to linebreak, the breaking is controlled by the settings in the linebreaks sub-block of the output (or chtml or svg) block. The default settings are

    linebreaks: {                  // options for when overflow is linebreak
      inline: true,                   // true for browser-based breaking of inline equations
      width: '100%',                  // a fixed size or a percentage of the container width
      lineleading: .2,                // the default lineleading in em units
      LinebreakVisitor: null,         // The LinebreakVisitor to use
    },

The last option is used to replace the line-breaking algorithm with a new one, so is a developer option, but the others are author-level settings that control things like how wide the lines are allowed to be, and how much extra space to put between lines.

In-line breaking

In version 4, in-line expressions can be allowed to break automatically by the browser. This is controlled via the inline option of the linebreaks block described above. When true (the default), MathJax will arrange for in-line expressions to be broken into pieces so that the browser can move parts of the equation onto the next line, if they would otherwise extend beyond the width of the expression's container. (In version 2, in-line expressions are only broken when the expression by itself would be wider than the container, and in that case, the expression would essentially act like it was inside a <div> element, so it badly disrupts the flow of the paragraph, and could cause misleading wrapping of text around the broken expression).

Note, however, that in order to do this, MathJax must make several separate elements containing math, and for SVG output in particular, several separate top-level <svg> elements. For this reason, node applications that are trying to create single svg images for the mathematics would want to set linebreaks.inline to false to avoid that.

Finally, because the browser is doing the actual determination of the locations for in-line breaks, these breaks are chosen purely by how much of the expression can fit at the end of the line before the break. That is, the parameters that mark breakpoints as good or bad (described below) are not taken into effect; however, forced breaks and no-break markers are respected.

New TeX Array Preamble Options

To help support line breaking within cells of wide tables, MathJax v4 includes support for the preamble column declarations defined in the array TeX package. These include the traditional c, l, and r for alignment of the contents of the cell (centered, left, or right), but adds support for p{width}, m{width}, and b{width} for vertical alignment of a fixed-width column in which line-breaking will occur at the given width, as well as w{align}{width} and W{align}{width}. There is also new support for >{...} and <{...} for adding content that is put before or after every entry in a column, as well as @{...} for replacing the inter-column space with the given content, and !{...} for replacing inter-column rules. Support for | and the non-standard : are improved so multiple copies of | and : now produce multiple rules that are close together. Finally, non-standard P{...}, M{...}, and B{...} are defined that produce math-mode versions of their corresponding lower-case counterparts. The \newcolumntype macro for declaring new column specifications is also available.

Note that for p, m, b, w, W, P, M, and B columns, line-breaking will occur to the given column with if line-breaking is the active overflow setting. Otherwise, wide content will overflow the width, as in actual LaTeX.

Line-breaking macros in TeX

In MathML, <mo> and <mspace> items can be marked as either good or bad breakpoint options via the linebreak="goodbreak" or linebreak="badbreak" options, or linebreaks can be prevented via linebreak="nobreak" or forced with linebreak="newline". In TeX, these can be controlled via the \goodbreak, \badbreak, \nobreak, and \break (or \\) macros. These will try to mark the operator that follows (or in some case precedes) the macro using the appropriate linebreak attribute. If there is no operator, then one will be introduced into the expression at that location. There is also \allowbreak that inserts a breakpoint that can be used if one is needed.

The \parbox[align]{width}{text} macro has been added in v4 to provide a line-breaking context of a given width and vertical alignment (t, b, c for top, bottom, center (the default), with m allowed as an alias for c) for text-mode material. Previous versions of MathJax include \vcenter{} for vertical centering, and v4 adds \vtop{} and \vbox{} for material to be aligned on the top line or bottom line of the contents. In LaTeX, their content is text-mode, but in MathJax, they are in math mode (since MathJax mainly does math-mode, and for backward compatibility with the original \vcenter{} implementation). The width of these boxes can be controlled using \hsize=<dimen> within the box, so \vtop{\hsize=10em ...} would make a box that is 10em wide whose content is line broken and aligned on the baseline of the first line. Finally, the \makebox[width][align]{text} macro can also be used to produce a line-breaking text box of a given width and vertical alignment. (This complements the \mathmathbox[width][align]{math} macro already in the mathtools package.)

While the new array preamble options allow you to control the cell widths in an array, they aren't available for other environments, like align. When line-breaking is enabled, you may want to have more control over how long lines of an alignment are broken. You can use \hbox or \mbox to avoid line breaks, but when you do allow breaks, you may want more control over indenting and alignment in such settings. For this reason, MathJax v4 introduces a non-standard indentalign environment that can be used within a cell of a table (or in any line-breaking context) to adjust the indentation amount and the horizontal alignment of any wrapped lines:

\begin{indentalign}[first][middle][last]{align}
   (long line of math)
\end{indentalign}

where first, middle, and last are optional dimensions that specify how much indentation to use for the first, middle, and last lines (where middle is any but the first or last lines). If only first and middle are provided, last will be the same as middle, and if only first is given, all three will use the same value. The align argument is one to three letters, each being one of l, c, or r, and these represent the alignments for the first, middle, and last lines. So

\begin{indentalign}[0em][1em]{l}
   (long line of math)
\end{indentalign}

would left align all lines, and indent the second and subsequent lines by 1em, when used in a context where line-breaking is in effect.

Options for <mpadded> elements

The various line-breaking boxes described above are implemented via the MathML <mpadded> element. In order to facility that, MathJax v4 adds two non-standard attributes to the mpadded element: data-overflow and data-align. When data-overflow="linebreak" is used, the contents performs line-breaking to the width specified in the element's width attribute. (No other value for data-linebreak is implemented). The data-align attribute value can be left, center or right, to get the contents (line-broken or not) aligned to the left, center, or right of the specified width. You can use an <mstyle> element within the <mpadded> element in order to set the indentshift, indentalign, and similar attributes (for first and last lines) of the content, or can specify those attributes on the individual <mo> or <mspace> elements within the <mpadded> container.

Support for HTML in MathML and TeX

HTML in MathML

The HTML5 specification allows for mixing HTML nodes inside MathML token nodes, and it is a long-standing request for MathJax to implement that as well. Version 4 finally does so. You can now use HTML nodes as children of token nodes, such as <mtext>. Thus

<mtext>a button <input type="button" value="Push Me"> to press</mtext>

is allowed, and would produce an <mtext> element containing a button surrounded by some plain text.

Because the HTML is not currently sanitized (something that could be added to the safe extension), allowing HTML in token elements would be a security issue for sites that allow user-entered MathML. For this reason, the MathML input jax has a new option allowHtmlInTokenNodes to control whether to allow it, and it is false by default, so you have to opt into this new feature if you want to use it on your site.

HTML in TeX

HTML is now allowed in TeX and LaTeX input as well. This is handled through the special <tex-html> node, which (unlike most HTML nodes) can be included within the math delimiters. So, for example

$$3 + <tex-html><input type="text" id="answer" size="10"></tex-html> = 10$$

would present an expression with an input box where a student could fill in an answer. This feature is implemented via the texhtml extension package for the TeX input jax, so you would use a configuration like

MathJax = {
  loader: {load: ['[tex]/texhtml']}},
  tex: {
      allowTexHTML: true,
      packages: {'[+]': ['texhtml']}
  }
};

to load it, add it to the packages to use, and enable it.

In its usual use case in the browser, the HTML will come from the DOM already, and so MathJax doesn't include HTML sanitization in this extension. Because of this, however, the texhtml extension does represent a security risk on sites that allow user content, if they don't sanitize the user input themselves. For this reason, there is an allowTexHTML option for the TeX input jax that must be enabled in order for the <tex-html> elements to be used. Note that \require{} is configured not to load the texhtml package, so unless you explicitly load it yourself, there should be no security issue.

Specifying the size of the HTML

In a browser, MathJax can measure the size of the HTML so that it can provide the proper amount of space for it within the equation, but in node applications, that is not possible, so MathJax provides a method for you to specify the size of the HTML explicitly. To specify the dimensions, add data-mjx-hdw="H D W" to the top-level HTML element inside the MathML token element, where H, D, and W are the height, depth, and width of the HTML. They can be in any units, but em units will work best.

How this attribute is used is handled via a new option to the output jax, htmlHDW, which can be set to 'auto' (the default), 'ignore', 'use', or 'force'. When set to ignore, the data-mjx-hdw attribute is ignored, and MathJax will try to measure the size of the HTML directly. This works well in the browser, but not in the liteDOM, jsdom, linkedom, or other non-browser adaptors. The force option means that MathJax will use the data-mjx-hdw values and will surround the HTML with additional nodes that force the HTML to have the given dimensions. This would make the browser and node both have the same representation, not relying on the browser measurements. The value use means that MathJax will assume the data-mjx-hdw values are correct and will use them without forcing the HTML to have the given dimensions. Finally, auto means that MathJax will determine which to use; this will be ignore when in the browser and force when in node applications.

Having accurate values for the data-mjx-hdw attribute is crucial to the quality of the output. To that end, the following HTML file computes the needed values. These values depend on the surrounding font, so there is a place to enter that, as well. You can also specify the font in the MathML token element that holds the HTML, as in <mtext fontfamily="Arial"><div>...</div></mtext> or <mo style="font-family: arial"><div>...</div></mo>. Otherwise, MathJax will use the surrounding font. The page below gives you a place to enter the HTML you want to measure and the font to use. Press the "Compute HDW" and the HTML is shown below together with modified HTML source that includes the needed data-mjx-hdw attribute. You can copy that and replace the original HTML will it.


<!DOCTYPE html>
<html>
<head>
<title>Compute HDW values for HTML in Token nodes</title>
<script>
function GetHDW() {
  const html = document.querySelector('mjx-html');
  const content = html.getBoundingClientRect();
  const baseline = document.querySelector('mjx-baseline').getBoundingClientRect();
  const em = parseFloat(window.getComputedStyle(html).fontSize);
  const h = baseline.top - content.top;
  const d = content.bottom - baseline.top;
  const w = content.right - content.left;
  return [h, d, w].map(x => (x / em).toFixed(3).replace(/\.?0+$/, '') + 'em').join(' ');
}
function ShowHDW() {
  const html = document.querySelector('#html').value;
  const content = document.querySelector('mjx-html');
  content.style.fontFamily = document.querySelector('#family').value;
  content.innerHTML = html
  const output = document.querySelector('#output');
  content.firstChild.setAttribute('data-mjx-hdw', GetHDW());
  output.innerHTML = content.innerHTML.replace(/</g, '&lt;');
}
</script>
<style>
mjx-measure {
  display: inline-block;
  border-left: 2px solid red;
  border-right: 2px solid red;
}
mjx-baseline {
  display: inline-block;
  height: 0;
  width: 0;
}
mjx-html {
  display: inline-block;
}
mjx-line {
  display: inline-block;
  height: 0;
  width: 1em;
  border-top: 1px solid blue;
}
#input {
  display: inline-block;
}
#input textarea {
  margin-bottom: 3px;
}
#input input[type="button"] {
  float: right;
}
</style>
</head>
<body>

<h1>Compute HDW values for HTML in Token nodes</h1>

<p id="input">
<textarea id="html" cols="80" rows="10">
<div>HTML</div>
</textarea><br>
Font family: <input type="text" id="family">
<input type="button" value="Compute HDW" onclick="ShowHDW()">
</p>
<h2>The HTML:</h2>
<p>
<mjx-line></mjx-line><mjx-measure><mjx-baseline></mjx-baseline><mjx-html>
&#xA0;
</mjx-html></mjx-measure><mjx-line></mjx-line>
</p>
<h2>The HTML with the HDW attribute:</h2>
<p id="output">
</p>

</body>
</html>

Of course, you can use this as a basis for automating the process using something like puppeteer, if you wish.

Expression Explorer Included in Combined Components

In version 3 of MathJax, the expression explorer was not active by default, and so those with assistive needs had to turn it on explicitly, and it was loaded dynamically at that time. In its place, the assistive-MathML extension was used to generate a hidden MathML expression that could be read by those screen readers that can process MathML. This was a stop-gap measure that was both clunky and somewhat fragile, and changes in screen readers often rendered it ineffective (e.g., the current VoiceOver version doesn't read the mathematics and skips it entirely).

Because of these problems, and because the Speech Rule Engine (SRE) that underlies MathJax's assistive support has been substantially rewritten, we are now packaging the expression explorer and SRE as part of all the combined configuration files, and the assistive MathML extension has been removed from them (though it can still be turned on in the Accessibility sub-menu of the MathJax contextual menu). The SRE generates speech automatically for the expressions in your page and makes these speech strings available to screen readers using ARIA labels and live regions, a technology that has far better support in screen readers than the hidden MathML. This is a substantial change, however, and there are many screen-reader/browser/operating-system combinations, so some issues may arise. Please report problems that you encounter to our issue tracker.

While basic speech is provided for expression via an aria-label attribute, so that a screen reader can read the math naturally as part of the page, it is still possible to interactively explore expressions. This features is available by default in version 4, but interaction with the expressions is now achieved using the ARIA tree view paradigm, moving away from the previously used application role. This should provide smoother interaction with screen readers on all platforms. Speech during exploration is still exposed via a live region; however, we are still experimenting with a number of alternative methods before the final v4.0 release.

In addition, MathJax now provides optional auto-voicing of expressions together with step-by-step highlighting of expression while a formula is spoken. This feature is primarily aimed at users who do not normally utilize a screen reader, and in particular as support for dyslexic readers. It currently has to be switched on explicitly, either in the speech sub-item of the explorer sub-menu of the MathJax contextual menu, or using the voicing option in the a11y sub-block of the options configuration block. Speech is generated by providing SSML annotations to the browser's speechSynthesis API. While this makes use of the full range of prosody annotations available in SRE's speech rules, the feature is only available in browsers that come with an implementation of the speechSynthesis API and with built in voices.

MathJax v4.0 and Promises

Because the new MathJax fonts include more extensive character coverage, meaning much more data is required, the fonts have been broken down into smaller pieces that can be loaded dynamically, rather than being one big data file, as was the case with version 3. This allows the initial download of MathJax to be smaller, while still accommodating rarely used glyphs for those who need them.

As a result, however, when the data for one of these ranges is needed, MathJax will pause and wait for the data to arrive from the CDN. That means that producing MathJax output is now potentially an asynchronous process, which was not the case in v3. So in the past, as long as you pre-loaded all the TeX extensions that you needed (e.g., with one of the -full components), you could use synchronous calls to MathJax.tex2svg() or the other similar functions. With the new (larger) dynamic fonts, that is no longer guaranteed. That means you should instead use the promise-based versions of these calls, like MathJax.tex2svgPromise(), in order to properly handle the potential for dynamically loaded font data. Without this, you may get errors indicating a "retry" error, which is what MathJax uses to mediate its asynchronous loading actions.

If you can not avoid using synchronous calls, then you may need to load all the font dynamic data up front using a single promise-based call before you start using MathJax synchronously. This can be done using

MathJax.startup.document.outputJax.font.loadDynamicFiles();

to load all the font dynamic data. This function returns a promise, and you should wait for it to resolve before calling any MathJax conversion functions. Note, however, that there can be a lot of font data, and these fonts may include many characters that will never get used, so only do this if you absolutely have to. It is better to use the promise-based conversion functions if you can.

For node applications, you can use

MathJax.startup.document.outputJax.font.loadDynamicFilesSync();

to load the font data synchronously, provided you have defined the MathJax loading mechanism by importing mathjax-full/js/util/asyncLoad/node.ts before hand.

Availability of v4.0.0-alpha

The MathJax 4.0.0-alpha.1 version can be accessed via CDN as

https://cdn.jsdelivr.net/npm/mathjax@4.0.0-alpha.1/es5/tex-mml-chtml.js

or using one of the other combined configuration files:

  • tex-html.js
  • tex-svg.js
  • tex-mml-chtml.js
  • tex-mml-svg.js
  • mml-html.js
  • mml-svg.js

Each of these includes the mathjax-modern font, but also comes in a version ending in -nofont.js (e.g., tex-mml-chtml-nofont.js) that does not include it, where you are expected to specify the font using the output.font configuration option. This saves your readers from having to download the mathjax-modern font that is not going to be used. The other combined configurations have been removed, as they were either redundant (now that the explorer is already included in all combined components), or where the ones that included tex-full. The latter have been removed because you will need to use the promise-based calls anyway, and that will handle the autoloading of extensions as well, and since the all-packages extension doesn't include the newer packages, and so isn't really "all" packages anyway.

The source code for MathJax v4 is available in the mathjax-full@4.0.0-alpha.1 npm package, or in the v4.0.0-alpha branch of the MathJax-src repository on GitHub.

The fonts are each in their own npm package, e.g., mathjax-modern-font, mathjax-stix2-font, etc., which you can install in your own node applications as needed. In a browser, MathJax should access the fonts from jsdelivr automatically. These font packages also include combined configuration files that are like tex-mml-chtml.js and tex-mml-svg.js, but that include that package's font rather than mathjax-modern. For example, the mathjax-stix2-font package include tex-mml-chtml-mathjax-stix2.js and tex-mml-svg-mathjax-stix2.js, so you can use

https://cdn.jsdelivr.net/npm/mathjax-stix2-font/ex5/tex-mml-chtml-mathjax-stix2.js

in order to get a single-file MathJax component that includes the mathjax-stix2 font rather than mathjax-modern. In particular, you can get the equivalent of the tex-mml-html.js file with the original MathJax TeX font all in one file using

https://cdn.jsdelivr.net/npm/mathjax-tex-font/ex5/tex-mml-chtml-mathjax-tex.js

This font does not have dynamic ranges (all the font data is in one file), so it should operate much the same as MathJax v3 in that respect.

2022-06-09 01:21:12
MathJax-src

MathJax v3.2.2

This is a hot-fix release to correct three issues in the recent 3.2.1 release. These are listed below:

  • Prevent lazy typesetting from re-typeset expressions unnecessarily, which can cause duplicate-label error messages in the output, and degrade performance. (mathjax/MathJax#2873)

  • Improve method for obtaining the <math> element from mml3 conversion, allowing it to work better in an XHTML setting. (mathjax/MathJax#2879)

  • Make version.ts use a constant and create the file during the build process rather than dynamically determining the version. This allows easier packaging of MathJax into other applications. (#824)

2022-05-20 04:36:10
MathJax-src

MathJax v3.2.1

This is mostly a bug-fix release, resolving various display and input bugs and other issues. See the individual bugs linked below for more details, and the 3.2.1 milestone for the pull requests involved in this release.


New Features in this Release

Speech-Rule Engine

MathJax now integrates version 4 of Speech Rule Engine (SRE). (#800)

  • SRE v4 is a full port to ES6 using TypeScript providing transpiled JavaScript for easier integration into third party projects via its npm package.
  • Uses webpack as the primary bundler to offer a single bundle file for both node and browser.
  • Major rewrite of rule handling and provision of locales.
    • Smaller locale files and memory footprint in the index structure.
    • Hierarchical locale setup that allows inheritance within rule sets.
    • Uses ES6 promises to handle locale loading and engine setup.
  • A number of new locales for Swedish, Norwegian (Bokmal and Nynorks), Danish (MathSpeak only), and Catalan (MathSpeak only)
  • Locale files are now served with a .json extension. (https://github.com/mathjax/MathJax/issues/2403)

For more details and a full list of all changes and additions see the SRE release notes.

MathJax makes use of SRE v4 new features in the following ways:

  • Source integration
    • Integrates SRE directly via importing the relevant library files into its code and webpacks them into its components and bundles.
    • Replaces the timeout-driven SRE loading promise with SRE's new native promises.
    • The sre.ts module now imports and exports exclusively API methods necessary for SRE's use in MathJax
    • A new mathmaps.ts module provides a map for directly integrating and bundling locales (see more below).
  • Components integration
    • The sre component under components/src/sre now simply handles copying the locale files in the mathmaps directory.
    • The a11y/sre component under components/src/sre contains a configuration file sre_config.js that sets up the basic SRE configuration for MathJax, especially the correct path to the mathmaps folder (online or in the npm distribution).
    • Components can webpack SRE's locale files into bundles. See the components/src/tex-chtml-full-speech component as an example.
  • MathJax Configuration
    • The sre path in MathJax is now used exclusively for pointing to a directory containing the locale files.

Most of these changes are internal and should remain unnoticeable. However, there are a couple of points to note when using SRE via MathJax:

  • Previously, MathJax would load SRE as a single library file, but now webpacks its source files, which, as a side-effect, closes several convenient loopholes you could have exploited in the past:
    • OLD: SRE's functionality was available to a developer as if running SRE standalone. That is, in both node and browser, all of SRE's API methods where available in the SRE namespace, and additionally, the full functionality was reachable in the browser through the sre namespace. NEW: Now only the explicitly exported API methods are available to import via the a11y/sre component. * OLD: You could easily change the version of SRE MathJax would use by:
      1. In the browser, pointing to an alternative copy of sre_browser.js using the sre path in the MathJax configuration, and
      2. In node, replacing the speech-rule-engine package with a different version in the node_modules folder. NEW: This is no longer possible.
  • The sreReady method is still exported but deprecated. In the future, you should use the corresponding method in the API bundle Sre.sreReady().
  • By default SRE comes without rules (or locales) preloaded, and pulls those in only when necessary. That is, it loads the relevant .json files via XML-HTTP-request in the browser, or via file loading in the node module. However, it is now possible to pre-bundle (some) locales directly into a custom distribution using webpack, which is particularly useful if you want to run MathJax offline while still using the full power of is assistive technology extension. See the tex-chtml-full-speech component as an example.

Output Improvements

  • Properly handle border and padding CSS in CHTML and SVG output. (#799)

Lazy Typesetting

  • Have lazy typesetter typeset all remaining math before printing. (#777)
  • Have lazy typesetting specify a (configurable) distance around the viewport for triggering typesetting. (#777)
  • Allow containers to be marked so that they are always typeset by the lazy typesetter. (#777)

Bugs Addressed in this Release

Output Bug Fixes

  • Update svg output to properly handle token elements with multiple child nodes. (mathjax/MathJax#2836)

  • Include CSS to reset border-collapse in CHTML output. (mathjax/MathJax#2861)

  • Prevent CHTML adaptive CSS from adding character CSS multiple times. (#796)

  • Make sure all character data is included when adaptiveCSS is false. (mathjax/MathJax#2724)

  • Place super- and subscripts properly around \vcenter elements. (#787)

  • Add a minimum height for accented characters. (mathjax/MathJax#2766)

  • Take relative scaling into account for CHTML output of non-MathJax fonts. (mathjax/MathJax#2818)

  • Fix placement of surd when root extends above the top of the root. (mathjax/MathJax#2764)

  • Fix problem with msubsup when subscript is blank (mathjax/MathJax#2765)

TeX Input Fixes

  • Add \textup and \textnormal to macros allowed by textmacros. (mathjax/MathJax#2846)

  • Update \operatorname to work more like in LaTeX. (mathjax/MathJax#2830)

  • Have physics package match nested parentheses, fix spacing issues. (mathjax/MathJax#2760, mathjax/MathJax#2831)

  • Re-implement \sideset using mmultiscripts. (mathjax/MathJax#1217)

  • Fix problem where errors during mhchem argument collection are not properly handled. (mathjax/MathJax#2835)

  • Update XSLT to produce better results in mml3 extension. (#785)

  • Add ability for TeX input to force normal variant for CJK input. (mathjax/MathJax#2744)

  • Make sure math-in-text forms an ORD atom within textmacros. (mathjax/MathJax#2828)

  • Make sure explicit attributes added by \mmlToken are not removed. (mathjax/MathJax#2806)

  • Fix typo in \DeclarePairedDelimiter macros, and substitute arguments in pre and post sections. (mathjax/MathJax#2816, mathjax/MathJax#2758)

  • Mark mo as not an accent if used in \overset and friends. (mathjax/MathJax#2800)

MathML Input Fixes

  • Fix problems with verification and repair of malformed mtables. (#779)

  • Add support for mglyph use of fontfamily/index. (mathjax/MathJax#2298)

  • Trim MathML string before parsing it. (mathjax/MathJax#2805)

  • Only process MJX-TeXAtom classes on mrow elements. (mathjax/MathJax#2822)

  • Move mml3 filter to an mmlFilter so that forceReparse isn't needed. (mathjax/MathJax#2718)

  • Make U+2061 through U+2064 have TeX class NONE so they don't affect spacing. (#806)

Miscenaleous

  • Handle documents better when created by parsing in XHTML. (mathjax/MathJax#2788)

  • Add version numbers to component files and check them when loaded. (#738)

  • Fix problem where some menu settings weren't sticky (mathjax/MathJax#2786)

  • Add a linkedom adaptor (mathjax/MathJax#2833)

  • Refactor usage of all-packages to reduce redundant code in components. (#784)

  • Make variables local in legacy AsciiMath code. (mathjax/MathJax#2748)

  • Make safe extension properly handle scriptlevel of 0. (mathjax/MathJax#2745)

  • Update webpack files for empheq and cases. (mathjax/MathJax#2762)

  • Update build tools to work with extensions better. (#737)

  • Add defaultPageReady() to MathJaxObject interface. (#746)

2021-06-17 22:32:33
MathJax-src

MathJax v3.2.0

This release includes a number of new features, along with several bug fixes. The new features include a lazy-typesetting extension, better handling of adaptive CSS in the CommonHTML output, several new TeX extensions, a port of the MML3 extension from v2, and the addition of the Hindi language to the speech generation. These are described more fully below.

There are several several potentially breaking changes in this release. See the second section below for more details.

Finally, a number of bug fixes are also included in this release, as described in the last section below.



New Features in this Release

Lazy Typesetting

Although MathJax version 3 is already an order of magnitude faster than version 2, with version 3.2 we offer a new extension that is designed to make pages with large numbers of equations perform even better. It implements a "lazy typesetting" approach that only typesets an expression when it comes into view, which means that expressions will not be typeset when they are not visible. Your readers will not have to wait for the entire document to typeset, which can speed up their initial view of the page. Furthermore, any expressions that are never seen will not be typeset. This also helps with the situation where you may link to a particular location in your page (via a URL with a hash); in version 2, typesetting the material above that point can cause the browser to change the scroll position, and so the user may not end up at the proper location in the page. With the lazy extension, the material above that point is not typeset until the user scrolls upwards, and so there is no position change.

Lazy typesetting works best with SVG output, but changes (discussed below) with the way the CommonHTML output handles its stylesheet updates make the CHTML output nearly as fast. With TeX input, the lazy extension makes sure that previous expressions are processed by TeX (though not output to the page) so that any macro definitions or automatic equation numbers are in place when the visible expressions are processed. Currently, documents that contain \ref or \eqref links may not yet work properly, since target equations may not have been typeset, and so the link location may not be marked in the document. In particular, forward references are unlikely to work, and backward references will work only if the target expression has already been typeset. We hope to improve this situation in a future release.

See the lazy extension documentation for information on how to configure MathJax to use this new feature.

CSS Updates

MathJax's CHTML output handles the characters that appear in the math on the page by storing information about their bounding boxes and text content in a CSS stylesheet. When additional math is typeset, this stylesheet may need to be updated, and in previous versions, MathJax would replace the entire stylesheet with a new one. This can cause visual flashing, and can be expensive as the browser must re-evaluate all the rules and apply them again. In version 3.2, the CHTML output now adds rules to the stylesheet individually, so the older rules are not replaced, and only the new rules must be evaluated and applied. This makes updates must faster, and is of particular benefit to the lazy-typesetting extension described above, as the page can be updated many times as equations scroll into view. This change makes the CHTML output work almost as smoothly as SVG output with the lazy extension.

New TeX Packages

Version 3.2 includes nine new TeX extension packages:

  • cases — provides environments for individually numbered cases.
  • centernot — implements a centered \not command (and a non-standard \centerOver that places one symbol centered on top of another).
  • colortbl — provides macros for coloring cells of an array or alignment.
  • empheq — an environment for placing material to the left or right of an alignment that has individual equation numbers.
  • gensymb — provides macros for some specific units.
  • mathtools — offers a range of macros and environments for advanced mathematical typesetting.
  • setoptions — provides the ability to change some TeX input jax options from within an expression (e.g., to change the tag side).
  • textcomp — provides a range of macros for specifying various text characters.
  • upgreek — provides macros for upright Greek characters.

These are all included in the components that end in -full (and include the TeX input jax), and you can load individual ones as you would other tex packages. Note, however, that none of these are autoloaded, though you can configure the autoload extension to do so, if you wish. See the autoload documentation for details.

In addition to these new packages, some of the older packages have been updated:

  • The ams package now includes flalign, xalign, and xxalign environments. In addition, the multline extension has been made more compatible with actual LaTeX. In the past, multline was set to be 85% of the container width, but now it is set to 100%, but with a 1em indent on both sides; when there is a tag, the indent on the tag side is increased by the width of the tag, as is the case in LaTeX. The width was stored in the multlineWidth configuration option in the tex configuration block. That has now been moved to the ams block in the tex configuration, and there is a new multlineIndent value. These are set to 100% and 1em respectively. To obtain the old behavior, set them to 85% and 0. Currently, if multlineWidth is found in the main tex option block, it will be moved to the ams block, but that backward-compatibility code will be removed in a future release.

  • The physics package now implements all macros, even those that are not officially documented, but are nevertheless available in LaTeX. In addition, it now implements the italicdiff and arrowdel options.

  • The following macros have been added to the indicated package:

    • \overunderset (ams) — a combination of \overset and \underset.
    • \stackbin (ams) — similar to \stackrel but produces a symbol with the spacing of a binary operator.
    • \nonscript (base) — apply the following spacing only when in display and text styles.
    • \boxed (base) — puts a frame around an expression.
    • \framebox (base) — puts a frame around a text argument.
    • \ip, \Bqty, \qsince, \Residue (physics) — originally missing from the physics package.

MathML Extensions

The MML3 extension from version 2 has been ported to version 3 and is available to be included when you load the MathML input jax. This extension implements the MathML3 elementary math tags (like <mstack> and <mlongdiv>) using an XSLT transform to convert these tags into other presentation MathML tags that MathJax has implemented. This does a reasonable job for some constructs, and a poorer job for others, but it does make it possible to process elementary math within MathJax v3. This is an experimental extension as a stop-gap measure until these tags are fully implemented within core MathJax.

See the mml3 extension documentation for information on how to configure MathJax to use this new feature.

Explorer Update

The Speech-Rule Engine (SRE) that underlies MathJax's assistive technology support has been updated to the most recent version (3.3.3). This includes support for the Hindi language, so that the expression explorer can generate speech in Hindi (as well as its other languages: English, French, German, Italian, Spanish, together with Braille support in Nemeth).

See the SRE release notes for details.

This release also ports the remaining missing features for the explorer to v3. This includes summarising expressions and navigation of tabular expressions, like matrices or equation systems. See the explorer keyboard commands for details.

Other New Features

In addition to the major features listed above, there are some minor new features as well:

  • Packages can now be specified for the textmacros extension to the TeX input jax. This allows you to configure additional macros that can be processed within text mode. See the textmacros documentation for details.

  • Processing of raw Unicode characters in TeX input has been improved. In the past, nearly all non-ASCII characters would be placed within an <mo> element, which is not always the best tag to use. In version 3.2, processing of raw Unicode characters is more nuanced, so that letters are placed in <mi> elements and other symbols in <mo>. For example, a literal Greek alpha (U+03B1) will produce <mi>&#x03B1;</mi> (which is what is generated by \alpha) rather than <mo>&#x03B1;</mo> as in earlier versions. This should provide better results, though perhaps still not perfect in all cases.

  • In the past, errors in the MathJax configuration options (such as an unknown option) would produce a fatal error and MathJax would not run. In version 3.2, such errors now produce non-fatal warnings instead, and MathJax will continue to process the remaining options (and then typeset the page). This means that changes to the options (like those described in the breaking changes below) will not cause your pages to fail outright (though the old options will have no effect). You can configure MathJax to make such errors fatal again, if you wish, and you can provide a function that will be called when there is an option error so that you can more easily trap such errors and handle them yourself. See the startup options for more details.

  • The component loader uses a set of filters to convert a component specification (like [tex]/physics) to the full URL for loading the extension. In the past, it was difficult to hook into that filtering mechanism, but in version 3.2, you can now configure additional filters for the loader. See the loader documentation for more details.

Breaking Changes in this Release

Some of the changes made to the options to accommodate the updated speech-rule engine are potentially breaking changes, in that the previous options (enrichSpeech, a11y.locale, a11y.speechRules) are no longer valid options. Version 3.1.4 includes code to transfer the old options to their new locations, but that code has been removed in version 3.2. As errors in options are no longer fatal (unless you configure them to be), this change will no longer cause MathJax to fail, but will cause warning messages in the browser console, so look there for such error reports.

Similarly, the code that automatically renames the older TeX package names to their current all-lower-case versions (e.g., configMacros to configmacros and colorV2 to colorv2) has been removed from version 3.2. If you are using old package names, you will need to update your configuration. This applies to \require{} macros that refer to the older names as well as their names in the loader section, the tex.packages array, and the tex.autoload block.

Version 3.2 removes the matchFontHeight option for the SVG output jax, since it only applies to the CommonHTML output, but was previously allowed in the svg configuration block, while doing nothing.

Version 3.2 removes of the toArray() method from the LinkedList class (and its subclasses), so any custom code that uses that should switch to using Array.from(...) around the list instead.

Finally, the Box.ts and CssStyles.ts (and their associated .js files) have been moved from the output directories to the util directory. Compatibility files were placed in the original locations so that older code would continue to work, but these have been removed in v3.2, so you should modify any custom code that loads these files to obtain them from the util directory instead.

Bugs Addressed in this Release

Output Bug Fixes

  • Work around long-standing WebKit bug with CHTML characters. (mathjax/MathJax#2435)
  • Fix error where a second use of \| delim causes the wrong size to be used. (#700)
  • Fixed problem with vertical centering of tables (#697)
  • Reset cramped style for explicit style changes, and in tables (#697)
  • Force setting of width of text with an explicit font (work around Safari bug) (#699)
  • Add support for shifting combining-character accents into place (#695)

Input Bug Fixes

  • Fix \overset and similar macros to now convert over-under to sub-sup in text mode. (mathjax/MathJax#2709)
  • Fixed problem with converting under-over to sub-sup when one script is missing. (mathjax/MathJax#2691)
  • Trim delimiter for \big and friends (mathjax/MathJax#2688, mathjax/MathJax#2689)
  • Wrap results of \mathbf and similar macros so they are treated as a unit(mathjax/MathJax#2688, mathjax/MathJax#2689)
  • Fix several bugs in the physics package (mathjax/MathJax#2449)
  • Remove heuristic for U+2061 forcing previous item to be TeX class OP (#719)

Miscellaneous

  • Update node-main for webpack 5 (#696)
  • Fix problem with detecting whether the ex-height can be computed, and work around jsdom problems (#691)
  • Clear the stylesheet when used in a new MathDocument. (mathjax/MathJax#2678)
  • Only return a DOCTYPE if there is one (#692)
  • Go back to mhchemparser package, now that it is es5 (#714)