MathJax v4.0.0-beta.7
This release is primarily a bug-fix release. In particular, the redesign of the way speech is computed and attached to MathJax’s output that was part of the beta.6 release introduced a performance degradation that needed to be addressed. The main purpose of the beta.7 release is to fix that performance problem. In addition, there are also fixes to allow table columns to shrink when their contents have line-breaks, and to allow in-line breaking to work properly in Safari. The computations for the bounding boxes of the layouts in the bussproofs
TeX package have been improved. A security issue involving the potential for users being able to insert CSS styles into MathJax equations was identified by the GitHub security team, and is addressed here. The all-packages
extension and corresponding AllPackages.ts
file and the tex-full
component that used them have been removed. Finally, font extension can now be generic extensions so that they work with any base font, and the bbm
, bboldx
, and dsfonts
packages have been rebuilt to be generic font extensions.
The changes made to the speech computations in v4.0.0-beta.6 caused a performance degradation that causes pages to typeset visibly slower than earlier versions. In particular, the lazy-typesetting extension was noticeably affected. In order to address this, MathJax v4.0.0-beta.7 puts off doing the speech computation until after the visual mathematics has been displayed, which restores the original performance. To do this, the speech is computed and attached a few equations at a time, with slight delays in between in order to allow the browser to perform screen updates and scrolling for other user interaction. There are new configuration parameters that control the timing of this operation:
MathJax = {
options: {
speechTiming: {
asynchronous: true, // true to allow screen updates while adding speech, false to not
initial: 100, // initial delay (in milliseconds) until starting to add speech
threshold: 250, // time (in milliseconds) to process speech before letting screen update
intermediate: 10 // delay (in milliseconds) after processing speech reaches the threshold
}
}
};
When the options.speechTiming.asynchronous
value is true, speech will be added a little at a time. The options.speechTiming.initial
value is the delay (in milliseconds) to wait before starting to add speech, the threshold
value indicates how long MathJax should work on speech before allowing the screen to update again, and intermediate
is how long to wait after that before starting to compute speech again.
If options.speechTiming.asynchronous
value is false, then speech is added to the expressions immediately when they are typeset. This can be useful for node applications that run on the server, and don't need to wait for screen updates (as there is no screen to update).
The AllPackages.ts
file was intended as a means of loading most of the TeX extensions up front so that you did not need to worry about asynchronous loading of extensions via the autoload
package. But now that MathJax's output is also asynchronous, using AllPackages
is no longer sufficient to allow for synchronous processing. As more extensions have been created, they have not all been added to AllPackages.ts
, and as the library of extensions, both core and third-party, grows, it is impractical to keep all of them in one package. So in this release, these files have been removed. For those using MathJax in node applications, you can use
import {source} from 'mathjax-full/components/src/source.js';
const AllPackages = Object.keys(source).filter((name) => name.substring(0,6) === '[tex]/').sort();
to get a list of the main TeX packages. For use on the web, you could use
<script type="importmap">
{
"imports": {
"#source/source.cjs": "https://cdn.jsdelivr.net/npm/mathjax-full@4.0.0-beta.6/components/mjs/source-lab.js"
}
}
</script>
<script type="module">
import {source} from 'https://cdn.jsdelivr.net/npm/mathjax-full@4.0.0-beta.6/components/mjs/source.js';
const load = Object.keys(source).filter((name) => name.substring(0,6) === '[tex]/').sort();
const packages = ['base'].concat(load.map((name) => name.substring(6)));
window.MathJax = {
loader: {load},
tex: {packages}
};
</script>
to load all the extensions. Add any other configuration options that you need to the window.MathJax
variable.
-
Better validation of style values (mathjax/MathJax-src#1121)
-
Create explorer regions only when needed (mathjax/MathJax-src#1119)
-
Fix inline breaking in Safari. (mathjax/MathJax#3252) (mathjax/MathJax-src#1117)
-
Compute proper left and right adjustments for tables in
bussproof
TeX extension. (mathjax/MathJax#3251) (mathjax/MathJax-src#1115) -
Fix bounding box computation for some embellished operators. (mathjax/MathJax#3250) (mathjax/MathJax-src#1114)
-
Remove the
AllPackages
file, theall-packages
TeX extension and thetex-full
component (mathjax/MathJax-src#1110) -
Update the asyncLoad implementations to be more consistent, and update tests. (mathjax/MathJax-src#1109)
-
Improve speech performance, especially for lazy typesetting (mathjax/MathJax-src#1107)
-
Improve performance by detaching speech computation (mathjax/MathJax-src#1103)
-
Allow columns to shrink during line breaking. (mathjax/MathJax#3235) (mathjax/MathJax-src#1102)
-
Fix regression from #1069 (mathjax/MathJax#3233, mathjax/MathJax#3234) (mathjax/MathJax-src#1101)
-
Refactors the treatment of namespaces for methods of TeX packages (mathjax/MathJax-src#1097)
-
Refactors and simplifies macro mappings (mathjax/MathJax-src#1096)
-
Update handling of math accents to round-trip through SRE (mathjax/MathJax-src#1093)
-
Use XML serialization not HTML serialization for SVG images. (mathjax/MathJax#3226) (mathjax/MathJax-src#1090)
-
Fix handling of unknown characters in SVG output. (mathjax/MathJax#3224) (mathjax/MathJax-src#1089)
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.
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.
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).
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 than
bold` 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.
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:
-
Add
dsfont
,bbm
, andbboldx
TeX extensions (#1055, #1056, #1057, #1063, #1064, #1065, #1074, #1075, #1076) -
Make
textcomp
package register withtextmacros
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 inmsubsup
. (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
tophysics
package and add\divisionsymbol
. (mathjax/MathJax#3173) (#1049) -
Allow (embellished) operators in
\underset
,\overset
, and\underoverset
to specifyaccent="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 benull
(#1030) -
Have
\unicode
check for illegal font name. (mathjax/MathJax#3129) (#1019)
-
Add
xmlns
attribute for global cachesvg
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 requireclip-path
. (#1025) -
Better measuring of text that is in a native font rather than MathJax fonts (#1014)
-
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)
-
Proper handling of
typesetPromise()
indefaultPageReady()
. (mathjax/MathJax#3130) (#1018) -
Move from
npm
topnpm
(#1021, #1023, #1077) -
Add missing
Text.splitText()
method tolinkedom
. (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 addGetBrackets()
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 removenamespace
(#1022) -
Add
cssText()
method toDOMadaptor
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 withoutmjs
files being built first (#1013)
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.
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.
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).
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 than
bold` 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.
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:
-
Add
dsfont
,bbm
, andbboldx
TeX extensions (#1055, #1056, #1057, #1063, #1064, #1065, #1074, #1075, #1076) -
Make
textcomp
package register withtextmacros
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 inmsubsup
. (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
tophysics
package and add\divisionsymbol
. (mathjax/MathJax#3173) (#1049) -
Allow (embellished) operators in
\underset
,\overset
, and\underoverset
to specifyaccent="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 benull
(#1030) -
Have
\unicode
check for illegal font name. (mathjax/MathJax#3129) (#1019)
-
Add
xmlns
attribute for global cachesvg
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 requireclip-path
. (#1025) -
Better measuring of text that is in a native font rather than MathJax fonts (#1014)
-
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)
-
Proper handling of
typesetPromise()
indefaultPageReady()
. (mathjax/MathJax#3130) (#1018) -
Move from
npm
topnpm
(#1021, #1023, #1077) -
Add missing
Text.splitText()
method tolinkedom
. (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 addGetBrackets()
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 removenamespace
(#1022) -
Add
cssText()
method toDOMadaptor
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 withoutmjs
files being built first (#1013)
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 javascriptSymbol
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 theSymbol
class. This has lead us to rename the customSymbol
class toToken
, and rename theSymbol.ts
andSymbolMap.ts
files toToken.ts
andTokenMap.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
, andmath
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 thetextmacros
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. Sincedata
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 anmrow
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 theA
or after theB
, not at the+
itself. This is not what is usually intended for this LaTeX expression. Although the MathML specification is not clear about whymtext
elements are space-like, it is likely because these are sometimes used to insert explicit spaces into the expression via space characters, but anymtext
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 amathbackground
orstyle
attribute. Similarly, anmspace
element is considered space-like only if it does not have an explicitlinebreak
,height
,depth
,mathbackground
orstyle
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{}
whentextmacros
package is used. (mathjax/MathJax#3082) (#983) -
Fix error message with
\vdotswithin{}
from themathtools
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
orinput/svg
is loaded innode-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 frompackage.json
that is only needed for development. (#985) -
Change
Symbol
toToken
to avoid conflict with nativeSymbol
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)
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.
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.
components/src
Changes to 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:
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:
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:
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
ormathvariant=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.
- New package structure:
- XML handling in node now based on the latest
@xmldom/xmldom
library, makingxmldom-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 withtoggle
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 TeXnoerrors
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 thatmathvariant
attribute values are valid math variants and report an error if not. Invalidmathvariant
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 thelib
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 thebundle-cjs
directory rather than thebundle
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 thedarray
,math
, anddisplaymath
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 specifyaccent="true"
. (#894) -
Handle newlines as spaces in text mode. (mathjax/MathJax#2993) (#898)
-
Add
\underline
and several other macros totextmacros
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
withinbraket
andphysics
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
. (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
andsurd_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 classINNER
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
andSpeech Text
toShow As
andCopy 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.
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.
components/src
Changes to 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:
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:
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:
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
ormathvariant=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.
- New package structure:
- XML handling in node now based on the latest
@xmldom/xmldom
library, makingxmldom-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 withtoggle
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 TeXnoerrors
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 thatmathvariant
attribute values are valid math variants and report an error if not. Invalidmathvariant
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 thelib
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 thebundle-cjs
directory rather than thebundle
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 thedarray
,math
, anddisplaymath
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 specifyaccent="true"
. (#894) -
Handle newlines as spaces in text mode. (mathjax/MathJax#2993) (#898)
-
Add
\underline
and several other macros totextmacros
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
withinbraket
andphysics
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
. (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
andsurd_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 classINNER
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
andSpeech Text
toShow As
andCopy 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.
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
- MathJax v4.0 and Promises
- Availability of v4.0.0-alpha
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.
<mpadded>
elements
Options for 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, '<');
}
</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>
 
</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.
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 frommml3
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)
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 undercomponents/src/sre
now simply handles copying the locale files in themathmaps
directory. - The
a11y/sre
component undercomponents/src/sre
contains a configuration filesre_config.js
that sets up the basic SRE configuration for MathJax, especially the correct path to themathmaps
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.
- The
- MathJax Configuration
- The
sre
path in MathJax is now used exclusively for pointing to a directory containing the locale files.
- The
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 thesre
namespace. NEW: Now only the explicitly exported API methods are available to import via thea11y/sre
component. * OLD: You could easily change the version of SRE MathJax would use by:- In the browser, pointing to an alternative copy of
sre_browser.js
using thesre
path in the MathJax configuration, and - In node, replacing the
speech-rule-engine
package with a different version in thenode_modules
folder. NEW: This is no longer possible.
- In the browser, pointing to an alternative copy of
- 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
- The
sreReady
method is still exported but deprecated. In the future, you should use the corresponding method in the API bundleSre.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 thetex-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 bytextmacros
. (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
usingmmultiscripts
. (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 offontfamily
/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 anmmlFilter
so thatforceReparse
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()
toMathJaxObject
interface. (#746)