diff --git a/components/mjs/output/util.js b/components/mjs/output/util.js index 31d964747..f422745e0 100644 --- a/components/mjs/output/util.js +++ b/components/mjs/output/util.js @@ -2,9 +2,29 @@ import {combineDefaults, combineWithMathJax} from '#js/components/global.js'; import {Package} from '#js/components/package.js'; import {hasWindow} from '#js/util/context.js'; -export const FONTPATH = hasWindow ? - 'https://cdn.jsdelivr.net/npm/@mathjax/%%FONT%%-font': - '@mathjax/%%FONT%%-font'; +export const FONTPATH = hasWindow + ? 'https://cdn.jsdelivr.net/npm/@mathjax/%%FONT%%-font' + : '@mathjax/%%FONT%%-font'; + +export function configFont(font, jax, config, extension = '') { + const path = (config.fontPath || (FONTPATH + extension)); + const name = (font.match(/^[a-z]+:/) ? (font.match(/[^/:\\]*$/) || [jax])[0] : font); + combineDefaults(MathJax.config.loader, 'paths', { + [name+extension]: (name === font ? path.replace(/%%FONT%%/g, font) : font) + }); + return `[${name}${extension}]`; +} + +export function configExtensions(jax, config) { + const extensions = []; + for (const name of (config.fontExtensions || [])) { + const font = configFont(name, jax, config, '-extension'); + const module = `${font}/${jax}` + extensions.push(module); + } + return extensions; +} + export const OutputUtil = { config(jax, jaxClass, defaultFont, fontClass) { @@ -20,15 +40,15 @@ export const OutputUtil = { } if (font.charAt(0) !== '[') { - const path = (config.fontPath || FONTPATH); - const name = (font.match(/^[a-z]+:/) ? (font.match(/[^/:\\]*$/) || [jax])[0] : font); - combineDefaults(MathJax.config.loader, 'paths', { - [name]: (name === font ? path.replace(/%%FONT%%/g, font) : font) - }); - font = `[${name}]`; + font = configFont(font, jax, config); } const name = font.substring(1, font.length - 1); + const extensions = configExtensions(jax, config); + if (extensions.length) { + MathJax.loader.addPackageData(`${font}/${jax}`, {extraLoads: extensions}); + } + if (name !== defaultFont || !fontClass) { MathJax.loader.addPackageData(`output/${jax}`, {extraLoads: [`${font}/${jax}`]}); diff --git a/ts/output/common.ts b/ts/output/common.ts index 23e04e865..e2a1f0496 100644 --- a/ts/output/common.ts +++ b/ts/output/common.ts @@ -144,6 +144,7 @@ export abstract class CommonOutputJax< LinebreakVisitor: null, // The LinebreakVisitor to use }, font: '', // the font component to load + fontExtensions: [], // the font extensions to load htmlHDW: 'auto', // 'use', 'force', or 'ignore' data-mjx-hdw attributes wrapperFactory: null, // The wrapper factory to use fontData: null, // The FontData object to use @@ -183,6 +184,15 @@ export abstract class CommonOutputJax< }, }; + /** + * The font to use for generic extensions + */ + public static genericFont: FontDataClass< + CharOptions, + VariantData, + DelimiterData + >; + /** * Used for collecting styles needed for the output jax */ @@ -305,6 +315,8 @@ export abstract class CommonOutputJax< this.styleJson = this.options.styleJson || new StyleJsonSheet(); this.font = font || new fontClass(fontOptions); this.font.setOptions({ mathmlSpacing: this.options.mathmlSpacing }); + /* prettier-ignore */ + (this.constructor as typeof CommonOutputJax).genericFont = fontClass; this.unknownCache = new Map(); const linebreaks = (this.options.linebreaks.LinebreakVisitor || LinebreakVisitor) as typeof Linebreaks; @@ -349,9 +361,14 @@ export abstract class CommonOutputJax< * @override */ public typeset(math: MathItem, html: MathDocument) { + /* prettier-ignore */ + const CLASS = (this.constructor as typeof CommonOutputJax); + const generic = CLASS.genericFont; + CLASS.genericFont = this.font.constructor as FontDataClass; this.setDocument(html); const node = this.createNode(); this.toDOM(math, node, html); + CLASS.genericFont = generic; return node; }