A Custom MathJax Build — MathJax 4.0 documentation (original) (raw)

It is possible to make a completely custom build of MathJax that is not based on other MathJax components at all. The following example shows how to make a custom build that provides a function for obtaining the speech string for a given TeX math string. This example is similar to one in the MathJax web demosrepository.

After downloading a copy of MathJax as described in the section onGetting Things Ready, create a directory called mathjax-speech andcd into it.


The Custom Build File

Create the custom MathJax file named mathjax-speech.js containing the following:

mathjax-speech.js

1// 2// Load the desired components 3// 4import {mathjax} from '@mathjax/src/js/mathjax.js'; // MathJax core 5import {TeX} from '@mathjax/src/js/input/tex.js'; // TeX input 6import {browserAdaptor} from '@mathjax/src/js/adaptors/browserAdaptor.js'; // browser DOM 7import {RegisterHTMLHandler} from '@mathjax/src/js/handlers/html.js'; // the HTML handler 8import {STATE} from '@mathjax/src/js/core/MathItem.js'; // the various states 9import {SerializedMmlVisitor} from '@mathjax/src/js/core/MmlTree/SerializedMmlVisitor.js'; 10import * as Sre from 'speech-rule-engine/js/common/system.js'; // Speech generation 11 12// 13// Load the needed TeX extensions 14// 15import '@mathjax/src/js/input/tex/ams/AmsConfiguration.js'; 16import '@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js'; 17 18// 19// Register the HTML handler with the browser adaptor 20// 21RegisterHTMLHandler(browserAdaptor()); 22 23// 24// Initialize mathjax with a blank DOM. 25// 26const html = mathjax.document('', { 27 InputJax: new TeX({ 28 packages: ['base', 'ams', 'newcommand'] 29 }) 30}); 31 32// 33// The visitor to produce serialized MathML 34// 35const visitor = new SerializedMmlVisitor(); 36 37// 38// The user's configuration object 39// 40const CONFIG = window.MathJax || {}; 41 42// 43// The global MathJax object 44// 45window.MathJax = { 46 version: mathjax.version, 47 html: html, 48 Sre: Sre, 49 50 // 51 // A function to serialize the internal MathML format 52 // 53 toMML(node) { 54 return visitor.visitTree(node, this.html); 55 }, 56 57 // 58 // A function to convert TeX/LaTeX to a speech string 59 // 60 tex2speech(tex, display = true) { 61 return this.Sre.engineReady().then(() => { 62 return mathjax.handleRetriesFor(() => 63 this.toMML(html.convert(tex, {format: 'TeX', end: STATE.COMPILED, display})) 64 ) 65 }).then((mml) => this.Sre.toSpeech(mml)); 66 } 67}; 68 69// 70// Setup SRE's engine 71// 72Sre.setupEngine({domain: 'clearspeak', ...(CONFIG.sre || {})}); 73 74// 75// Perform ready function, if there is one 76// 77if (CONFIG.ready) { 78 Sre.engineReady().then(CONFIG.ready); 79}

Unlike the component-based example in the Building a Custom Componentsection, this custom build calls on the MathJax source files directly. The import commands at the beginning of the file load the needed objects, and the rest of the code instructs MathJax to create aMathDocument object for handling the conversions that we will be doing (using a TeX input jax), and then defines a global MathJaxobject that has the tex2speech() function that our custom build offers.

Note

This file uses ES6 import commands to load the MathJax modules. It is possible to use ES5 require() calls instead, if you wish. For example,

import {mathjax} from '@mathjax/src/js/mathjax.js';

could be replaced by

const {mathjax} = require('@mathjax/src/js/mathjax.js');

and similarly for the other import commands. Note that the MathJax package.json file is set up to route@mathjax/src/js to the MathJax mjs directory when used in an import command, and to the cjs directory when used in arequire() statement, so you can use the same path in either case. Similarly @mathjax/src/components/js maps either to thecomponents/mjs or components/cjs directory based on whetherimport or require() is used.

The Custom Configuration File

Next, create a file config.json that includes the following:

config.json

{ "webpack": { "name": "mathjax-speech", "dist": "." } }

This file gives the name that will be used for this component (mathjax-speech in this case), and the directory where we want the final packaged build to go. ("." means the directory containing the config.json file). When the directory is the same as the one containing the control file, the packed build file will end in.min.js rather than just .js.

Most of the real work is done by the@mathjax/src/components/webpack.config.mjs file, which will be called automatically by the commands in the following section.

Building the Custom File

Once these two files are ready, you are ready to make your custom build. First, make sure that you have obtained the needed tools as described in Getting Things Ready above. Then you should be able to use the command

node ../node_modules/@mathjax/src/components/bin/makeAll

to process your custom build.

Note

If you have changed the import commands to require(), then you will need to use the command

node ../node_modules/@mathjax/src/components/bin/makeAll --cjs

in order to tell makeAll to use MathJax’swebpack.config.cjs file rather than the webpack.config.mjsone.

You should end up with a file mathjax-speech.min.js in the directory with the other files. it will contain just the parts of MathJax that are needed to implement the MathJax.tex2speech()command defined in the file above. Note that this is not enough to do normal typesetting (for example, no output jax has been included), so this is a minimal file for producing the speech strings from TeX input.

Using the File in a Web Page

If you put the mathjax-speech.min.js file on your web server, you can load it into your web pages in place of loading MathJax from a CDN. This file will include all that you need to use theMathJax.tex2speech() command in your pages, provided they don’t need any additional TeX extensions.

Note

If you do need additional extensions, you can add them into themathjax-speech.js file above. Add import commands for the extensions you need, and add them into the packages list in thenew TeX() command. Note that you can not use \require or autoload any extensions in this setup, since this is not a component-based implementation (it doesn’t have the loader andstartup modules needed for that), so every extension you plan to use must be loaded in advance.

To load your custom MathJax build, just add

to your page (adjust the URL to point to wherever you have placed themathjax-speech.min.js file). Then you can use javascript calls like

const speech = await MathJax.tex2speech('\sqrt{x^2+1}', true);

to obtain a text string that contains the speech text for the square root given in the TeX string.

Alternatively, you can use the then() and catch()methods of the promise that is returned byMathJax.tex2speech(), as in

MathJax.tex2speech('\sqrt{x^2+1}', true).then( (speech) => console.log(speech); }).catch((err) => console.error(err));

to produce and handle the speech.

Configuring the Speech Generation

The speech-generation software can produce strings in a variety of languages, or in Braille notation, and this custom build of MathJax allows you to specify which language to use, or set other parameters of the speech-rule engine (SRE). This is done by setting theMathJax variable to a configuration that includes an sre block with the properties you want to customize. For example:

MathJax = { sre: { locale: 'fr' } }

would tell the SRE to produce speech strings in the French language rather than English.

The complete list of options for the sre block can be found in theSpeech-Rule Engine documentation.

Here is a complete page that converts a math expression into Nemeth Beaille.

Use mathjax-speech to generate Braille

Of course, you could create a more sophisticated version that takes an expression typed by a user and processes that usingMathJax.tex2speech(), then displays the result in the web page. That is left as an exercise for the interested reader.

Performing Actions at Startup

If you load mathjax-speech.min.js with the defer attribute, then your own code would need to wait for mathjax-speech.js to load before it can call MathJax.tex2speech(). One way to do that is to use a script with type="module" that follows the script that loads mathjax-speech.js, as is done in the example above.

Another way is to use the ready() function in theMathjax, which will be run after the MathJax file has been loaded, and SRE has been initialized. For example

MathJax = { ready() { MathJax.tex2speech('\sqrt{x^2+1}').then((speech) => console.log(speech)); } }

could be used to perform the speech conversion after everything is ready.