MathJax-src icon indicating copy to clipboard operation
MathJax-src copied to clipboard

New default font

Open dpvc opened this issue 3 years ago • 1 comments

This PR changes the default font from the old MathJax TeX font to the new MathJax-Modern version of Latin-Modern. This is stored in a separate npm pages (like the other new fonts), and so the mathjax-modern-font package has been added as a dependency. So you need to do npm install to make this work. Because that package refers to mathjax-full to get access to the MathJax objects, you also need to do

npm link
npm link mathjax-full

so that webpack can find the proper references when it builds the components that include the fonts. This needs to be done after the npm install, as that command will remove the link and you'll have to do the second command again.

This looks like a lot of files, but there are a lot of deleted files (the old font files in output/chtml/fonts, output/common/fonts and output/svg/fonts, as well as deleted preload.js files in the components/src directories.

Also, there are new component files for the -nofont versions of the combined components like tex-chtml (so there is now tex-chtml-nofont in addition). Also, all the original combined configuration files have been modified to allow them to load a user-specified font, and that touches a lot of files, but all in the same way, so you should not have to look at all of them. I've added a components/src/output/util.js file so that the chtml and svg output components can share common code, and that is really the heart of the changes, here. This is what allows the components to load user-specified fonts. I'll say more about the details of that in a minute. The utility file exports an object with config() and loadFont() methods, and the chtml and svg output components use these to set up the configurations they need, and export their own version of loadFont() that can be used by combined components to check for whether a font needs to be loaded or not. You may just want to view the components/src/output/chtml.js and components/src/output/svg.js files separately rather than try to figure the deletions and insertions, as most of what they used to do has been moved to the util.js file, and it is confusing to look at the diffs. Also, the chtml and svg nofont.js files have been overhauled to provide a generic (empty) font object.

The startup component's init.js has been modified to include an exported function that does the work that components/src/startup/startup.js used to do, so that the combined components can pass that to the loadFont() functions (see below for details). This also allows the loader.preLoad() calls to be moved out of a separate import from 'preload.js' to the body of the main component file (which is why the preload.js files have been deleted).

The webpack.common.js file has an added function that adds the remapping of the default font to the nofont.js file, since this is needed for all the *-nofont combined configurations. This simplifies the component definition files for the no-font components.

The chtml and svg output jax are modified to get their default font from a DefaultFont.js file rather than the old TeXFont that has been removed. The DefaultFont.js file loads and exports the node_module file for the font as well as the font name. I could not get this to work using a .ts file, as the font module references mathjax-full, and even with the link for mathjax-full above, typescript seemed to be confused about finding the .d.ts files for the mathjax-full references (if they were in place from a previous compile, it was OK, but on a fresh one, they either couldn't be found, or typescript wanted to overwrite them). The DefaultFont.js approach was the only thing I could get to work, and I ran out of time trying to work around it, so this is something we can look into fixing after the alpha release. I added DefaultFont.d.ts to give typescript the types, which seemed to avoid the problems. I took this file from the one created by compiling the font module, but changed the mathjax-full references to be relative paths instead (and cleaned up the file a bit). Again, this can be straightened out later.

The package.json file has the new dependency, and also a modified compile script so that some new DefaultFont.js files are moved to the js directory when the ts files are compiled so they can be found by webpack when it builds the components.

The contextual menu is modified to use handleRetriesFor() when changing the output renderer, since it may need to wait for a font to load before trying to re-render the page with the new output jax.

A new output configuration block is used to provide common configuration options for both svg and chtml output jax, so that you don't have to duplicate them in both configuration blocks. So, for example,

MathJax = {
  output: {
    font: "mathjax-asana"
  }
}

could be used to select the Asana font, and that would apply to both chtml and svg output (even if you changed via the contextual menu).

The main work of checking for and loading the fonts is in the components/src/output/util.js file. The font option used to be for a FontData class to use, but now it is a string that identifies the font to use (see below), and fontData is used for a FontData class to use. (For backward compatibility, if font isn't a string, it is moved to fontData, and font is set to the object's NAME.)

The font string can be one of three things: the name of a font, like mathjax-modern, a MathJax path identifier, like [mathjax-asana], or an absolute URL to a font component. For a bracketed path, MathJax assumes you have already set up the loader.paths value for the font, and will use that to load the font. Otherwise, it define a loader.paths path for the font. If it is an explicit URL, that is what will be used for the font; if it is a string, it will use the output jax's fontPath configuration to set up the path. The fontPath is a string where %%FONT%% will be replaced by the font name to create the URL for the font. When used in node application, it will be @mathjax/%%FONT%%-font/es5/output/fonts/%%FONT%%, and when used with a browser, it is https://cdn.jsdelivr.net/npm/%%FONT%%-font/es5/output/fonts/%%FONT%%, so that the font will be taken from jsdelivr (regardless of where MathJax itself was loaded). The the v3 lab, you could add

  output: {
    fontPath: 'mathjax3/node_modules/%%FONT%%-font/es5/output/fonts/%%FONT%%'
  },

to get a local copy of the font.

Once the path has been set up, MathJax will check to see if the font is the default font, and if not, it will set up a callback that has MathJax load the desired font using that path (e.g., as [mathjax-asana]/chtml). That font will set up the output jax configuration as needed (the fontData class, the prefix used for loading dynamic portions of the font, and for CHTML fonts, the fontURL for the woff files). If the font is the default font, since the component file for the font isn't being loaded, that configuration needs to be done by hand.

All of this is handled in the config() operation of the util.js file, which is called by the components/src/output/chtml/chtml.js or svg/svg.js files.

The loadFont() method of the util.js file is given the startup() function from startup/init.js along with the jax and font names, and marks the font as being preloaded (if requested). Then it checks if the font needs to be loaded (via the loaders checkReady() function for the jax that was set up in config() earlier), and loads the font if so, performing the startup() action when the font is loaded. If there is no font to load (the default is being used), then run the startup action immediately. Any errors are trapped and reported.

dpvc avatar Sep 21 '22 03:09 dpvc

I should have mentioned that I only have mathjax-modern and mathjax-tex as npm packages at the moment, but will make packages for the other fonts soon. But you can use mathjax-tex as a test of setting the font configuration option, and it shoddy give you the old MathJax TeX font (you can see the difference readily in the double-struck characters, for example).

dpvc avatar Sep 21 '22 03:09 dpvc

I've modified this branch to handle the default font better, and have updated the instructions above to correspond to the new setup.

dpvc avatar Jan 30 '23 20:01 dpvc