Skip to content

Single file built

Peter Krautzberger edited this page Apr 21, 2014 · 5 revisions

This page documents an experiment to Improve loading behavior: building a single-file MathJax version.

Word of caution

  1. This is experimental. Of course, MathJax is its usual self but there might be other problems that have not shown up in testing yet.

  2. Strictly speaking, it is neither possible nor desirable to build a single-file version of MathJax. Not possible, because MathJax is not just JavaScript (but also fonts and images). Not desirable because it extremely unlikely that the reader will need to load all of MathJax -- all inputs, all outputs, all extensions, all fonts in all formats, all locales etc. That being said, there are situations where a developer might prefer a single file built (e.g. on mobile apps where the developer has tight control over the reader's options and wants to consciously limit them).

Tools

The MathJax-dev repository contains the combiner for combined configuration files. We will build on it so make sure you have a working copy on your system.

Single-file built

There are three problems we'll have to deal with.

First, the combiner only builds configuration files, i.e., we'd have at least 2 files to load. We need to merge the combined configuration file with MathJax.js (note: it cannot be simply appended).

Second, the combined configuration combiner does not check the order in which MathJax components are combined. However, certain components need to load before others. We need to put them in the correct order.

Third, the SVG font data files are not set up to be loaded out of sequence. We need to fix them after packing.

List for the MathJax-dev combiner

The following list file for the combiner includes MathJax components for

  • MML input
  • SVG output
  • Mathjax TeX "fonts"
  • extensions: ContentMathML and webfonts matching
  • misc. MathJax internals

Of course, these are listed in the right order.

Save the list shown below as a lis file in MathJax-dev/combiner/lists/ and run the combiner. The resulting configuration file will end up in the MathJax copy that you added to the combiner directory.

    jax/input/MathML/config.js
    jax/output/SVG/config.js
    extensions/mml2jax.js
    extensions/MathEvents.js
    extensions/MathZoom.js
    extensions/MathMenu.js
    jax/element/mml/jax.js
    extensions/toMathML.js
    jax/input/MathML/jax.js
    jax/output/SVG/jax.js
    jax/output/SVG/fonts/TeX/fontdata.js
    jax/output/SVG/fonts/TeX/fontdata-extra.js
    jax/output/SVG/autoload/mtable.js
    jax/output/SVG/autoload/mglyph.js
    jax/output/SVG/autoload/mmultiscripts.js
    jax/output/SVG/autoload/annotation-xml.js
    jax/output/SVG/autoload/maction.js
    jax/output/SVG/autoload/multiline.js
    jax/output/SVG/autoload/menclose.js
    jax/output/SVG/autoload/ms.js
    extensions/MathML/content-mathml.js
    jax/input/MathML/entities/scr.js
    jax/input/MathML/entities/opf.js
    jax/input/MathML/entities/z.js
    jax/input/MathML/entities/g.js
    jax/input/MathML/entities/r.js
    jax/input/MathML/entities/p.js
    jax/input/MathML/entities/m.js
    jax/input/MathML/entities/q.js
    jax/input/MathML/entities/t.js
    jax/input/MathML/entities/w.js
    jax/input/MathML/entities/f.js
    jax/input/MathML/entities/v.js
    jax/input/MathML/entities/e.js
    jax/input/MathML/entities/k.js
    jax/input/MathML/entities/x.js
    jax/input/MathML/entities/c.js
    jax/input/MathML/entities/n.js
    jax/input/MathML/entities/a.js
    jax/input/MathML/entities/j.js
    jax/input/MathML/entities/u.js
    jax/input/MathML/entities/b.js
    jax/input/MathML/entities/i.js
    jax/input/MathML/entities/l.js
    jax/input/MathML/entities/y.js
    jax/input/MathML/entities/fr.js
    jax/input/MathML/entities/o.js
    jax/input/MathML/entities/s.js
    jax/input/MathML/entities/d.js
    jax/input/MathML/entities/h.js
    jax/element/mml/optable/Arrows.js
    jax/element/mml/optable/MiscMathSymbolsA.js
    jax/element/mml/optable/Dingbats.js
    jax/element/mml/optable/GeneralPunctuation.js
    jax/element/mml/optable/SpacingModLetters.js
    jax/element/mml/optable/MiscTechnical.js
    jax/element/mml/optable/SupplementalArrowsA.js
    jax/element/mml/optable/GreekAndCoptic.js
    jax/element/mml/optable/LetterlikeSymbols.js
    jax/element/mml/optable/SupplementalArrowsB.js
    jax/element/mml/optable/BasicLatin.js
    jax/element/mml/optable/MiscSymbolsAndArrows.js
    jax/element/mml/optable/CombDiacritMarks.js
    jax/element/mml/optable/GeometricShapes.js
    jax/element/mml/optable/MathOperators.js
    jax/element/mml/optable/MiscMathSymbolsB.js
    jax/element/mml/optable/SuppMathOperators.js
    jax/element/mml/optable/CombDiactForSymbols.js
    jax/element/mml/optable/Latin1Supplement.js
    extensions/MatchWebFonts.js
    extensions/HelpDialog.js
    jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedA.js
    jax/output/SVG/fonts/TeX/Main/Regular/MiscSymbols.js
    jax/output/SVG/fonts/TeX/Main/Regular/SpacingModLetters.js
    jax/output/SVG/fonts/TeX/Main/Regular/GreekAndCoptic.js
    jax/output/SVG/fonts/TeX/Main/Regular/LetterlikeSymbols.js
    jax/output/SVG/fonts/TeX/Main/Regular/LatinExtendedB.js
    jax/output/SVG/fonts/TeX/Main/Regular/BasicLatin.js
    jax/output/SVG/fonts/TeX/Main/Regular/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/Main/Regular/GeometricShapes.js
    jax/output/SVG/fonts/TeX/Main/Regular/MathOperators.js
    jax/output/SVG/fonts/TeX/Main/Regular/SuppMathOperators.js
    jax/output/SVG/fonts/TeX/AMS/Regular/Main.js
    jax/output/SVG/fonts/TeX/AMS/Regular/Arrows.js
    jax/output/SVG/fonts/TeX/AMS/Regular/PUA.js
    jax/output/SVG/fonts/TeX/AMS/Regular/Dingbats.js
    jax/output/SVG/fonts/TeX/AMS/Regular/LatinExtendedA.js
    jax/output/SVG/fonts/TeX/AMS/Regular/GeneralPunctuation.js
    jax/output/SVG/fonts/TeX/AMS/Regular/MiscSymbols.js
    jax/output/SVG/fonts/TeX/AMS/Regular/SpacingModLetters.js
    jax/output/SVG/fonts/TeX/AMS/Regular/MiscTechnical.js
    jax/output/SVG/fonts/TeX/AMS/Regular/GreekAndCoptic.js
    jax/output/SVG/fonts/TeX/AMS/Regular/LetterlikeSymbols.js
    jax/output/SVG/fonts/TeX/AMS/Regular/BoxDrawing.js
    jax/output/SVG/fonts/TeX/AMS/Regular/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/AMS/Regular/GeometricShapes.js
    jax/output/SVG/fonts/TeX/AMS/Regular/MathOperators.js
    jax/output/SVG/fonts/TeX/AMS/Regular/MiscMathSymbolsB.js
    jax/output/SVG/fonts/TeX/AMS/Regular/SuppMathOperators.js
    jax/output/SVG/fonts/TeX/AMS/Regular/Latin1Supplement.js
    jax/output/SVG/fonts/TeX/AMS/Regular/EnclosedAlphanum.js
    jax/output/SVG/fonts/TeX/Typewriter/Regular/Main.js
    jax/output/SVG/fonts/TeX/Typewriter/Regular/Other.js
    jax/output/SVG/fonts/TeX/Typewriter/Regular/BasicLatin.js
    jax/output/SVG/fonts/TeX/Typewriter/Regular/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/Fraktur/Regular/Main.js
    jax/output/SVG/fonts/TeX/Fraktur/Regular/PUA.js
    jax/output/SVG/fonts/TeX/Fraktur/Regular/Other.js
    jax/output/SVG/fonts/TeX/Fraktur/Regular/BasicLatin.js
    jax/output/SVG/fonts/TeX/Fraktur/Bold/Main.js
    jax/output/SVG/fonts/TeX/Fraktur/Bold/PUA.js
    jax/output/SVG/fonts/TeX/Fraktur/Bold/Other.js
    jax/output/SVG/fonts/TeX/Fraktur/Bold/BasicLatin.js
    jax/output/SVG/fonts/TeX/Math/BoldItalic/Main.js
    jax/output/SVG/fonts/TeX/Caligraphic/Regular/Main.js
    jax/output/SVG/fonts/TeX/Caligraphic/Bold/Main.js
    jax/output/SVG/fonts/TeX/Main/Italic/Main.js
    jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedA.js
    jax/output/SVG/fonts/TeX/Main/Italic/GeneralPunctuation.js
    jax/output/SVG/fonts/TeX/Main/Italic/GreekAndCoptic.js
    jax/output/SVG/fonts/TeX/Main/Italic/LetterlikeSymbols.js
    jax/output/SVG/fonts/TeX/Main/Italic/LatinExtendedB.js
    jax/output/SVG/fonts/TeX/Main/Italic/BasicLatin.js
    jax/output/SVG/fonts/TeX/Main/Italic/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/Main/Italic/MathOperators.js
    jax/output/SVG/fonts/TeX/Main/Bold/Main.js
    jax/output/SVG/fonts/TeX/Main/Bold/Arrows.js
    jax/output/SVG/fonts/TeX/Main/Bold/MiscMathSymbolsA.js
    jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedA.js
    jax/output/SVG/fonts/TeX/Main/Bold/GeneralPunctuation.js
    jax/output/SVG/fonts/TeX/Main/Bold/MiscSymbols.js
    jax/output/SVG/fonts/TeX/Main/Bold/SpacingModLetters.js
    jax/output/SVG/fonts/TeX/Main/Bold/MiscTechnical.js
    jax/output/SVG/fonts/TeX/Main/Bold/SupplementalArrowsA.js
    jax/output/SVG/fonts/TeX/Main/Bold/GreekAndCoptic.js
    jax/output/SVG/fonts/TeX/Main/Bold/LetterlikeSymbols.js
    jax/output/SVG/fonts/TeX/Main/Bold/LatinExtendedB.js
    jax/output/SVG/fonts/TeX/Main/Bold/BasicLatin.js
    jax/output/SVG/fonts/TeX/Main/Bold/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/Main/Bold/GeometricShapes.js
    jax/output/SVG/fonts/TeX/Main/Bold/MathOperators.js
    jax/output/SVG/fonts/TeX/Main/Bold/SuppMathOperators.js
    jax/output/SVG/fonts/TeX/Main/Bold/CombDiactForSymbols.js
    jax/output/SVG/fonts/TeX/Main/Bold/Latin1Supplement.js
    jax/output/SVG/fonts/TeX/Size3/Regular/Main.js
    jax/output/SVG/fonts/TeX/Size2/Regular/Main.js
    jax/output/SVG/fonts/TeX/Script/Regular/Main.js
    jax/output/SVG/fonts/TeX/Script/Regular/BasicLatin.js
    jax/output/SVG/fonts/TeX/Size1/Regular/Main.js
    jax/output/SVG/fonts/TeX/SansSerif/Italic/Main.js
    jax/output/SVG/fonts/TeX/SansSerif/Italic/Other.js
    jax/output/SVG/fonts/TeX/SansSerif/Italic/BasicLatin.js
    jax/output/SVG/fonts/TeX/SansSerif/Italic/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/SansSerif/Regular/Main.js
    jax/output/SVG/fonts/TeX/SansSerif/Regular/Other.js
    jax/output/SVG/fonts/TeX/SansSerif/Regular/BasicLatin.js
    jax/output/SVG/fonts/TeX/SansSerif/Regular/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/SansSerif/Bold/Main.js
    jax/output/SVG/fonts/TeX/SansSerif/Bold/Other.js
    jax/output/SVG/fonts/TeX/SansSerif/Bold/BasicLatin.js
    jax/output/SVG/fonts/TeX/SansSerif/Bold/CombDiacritMarks.js
    jax/output/SVG/fonts/TeX/Size4/Regular/Main.js

Notes

  • SVG font file order. You need to load the Main.js file first, and then the others. For SVG you should NOT load Main.js for MathJax_Main-Regular or MathJax_Math-Italic, as these are already in the fontdata.js file.

Fixing SVG font data files

Background

The SVG font data files are not set up to be loaded out of sequence. The creation of the SVG.FONTDATA value is done inside a signal handler that isn't triggered immediately, but the adding of data to SVG.FONTDATA by the font data files is done immediately (since they usually aren't loaded until much later, after SVG.FONTDATA is ready). So the information about the font information is being overwritten when SVG sets up FONTDATA later on. So the SVG jax thinks it needs to load the data, so it tries to, but the file is already loaded, so it doesn't load it again, so SVG thinks it needs to load it, and tries to ... and so on. Infinite loop.

Solution.

One solution is to put

    MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {

before the first font data file -- it starts with

    MathJax.Hub.Insert(MathJax.OutputJax.SVG.FONTDATA.FONTS.MathJax_Main

and put

    });

just before the MathJax.Ajax.loadComplete call at the bottom of the file. This will cause the action of these files to be postponed until after the SVG jax has set up the FONTDATA. Note that these edits are in the resulting configuration file, not the combiner list file.

(The combiner doesn't have a means of inserting commands like this automatically (perhaps it should).)

Merging the combined configuration file with MathJax.js

Problem

The combined configuration file cannot be simply appended to MathJax.js.

Solution

Insert the content of the combined configuration file after

  HUB.Browser.Select(MathJax.Message.browsers);

and before

  if (BASE.AuthorConfig && typeof BASE.AuthorConfig.AuthorInit === "function") {BASE.AuthorConfig.AuthorInit()}

in MathJax.js.

You can find a ready-to-use built at https://github.com/pkra/MathJax-single-file

Clone this wiki locally