diff --git a/packages/rehype-mathjax/lib/chtml.js b/packages/rehype-mathjax/lib/chtml.js
index 71c4b88..fe869f7 100644
--- a/packages/rehype-mathjax/lib/chtml.js
+++ b/packages/rehype-mathjax/lib/chtml.js
@@ -1,4 +1,19 @@
-import {CHTML as Chtml} from 'mathjax-full/js/output/chtml.js'
+// CHTML font metric data — side-effect imports register metrics on the font
+// class. Only math-essential files (~113 KB). See lib/svg.js for rationale.
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/accents.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/arrows.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/calligraphic.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/double-struck.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/fraktur.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/marrows.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/math.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/mshapes.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/script.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/shapes.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/symbols.js'
+import '@mathjax/mathjax-newcm-font/js/chtml/dynamic/variants.js'
+
+import {CHTML as Chtml} from '@mathjax/src/js/output/chtml.js'
import {createPlugin} from './create-plugin.js'
import {createRenderer} from './create-renderer.js'
diff --git a/packages/rehype-mathjax/lib/create-plugin.js b/packages/rehype-mathjax/lib/create-plugin.js
index d3702ed..5369ec6 100644
--- a/packages/rehype-mathjax/lib/create-plugin.js
+++ b/packages/rehype-mathjax/lib/create-plugin.js
@@ -79,7 +79,7 @@
* // …
* .use(rehypeMathjaxChtml, {
* chtml: {
- * fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2'
+ * fontURL: 'https://cdn.jsdelivr.net/npm/@mathjax/mathjax-newcm-font/chtml/woff2'
* }
* })
* // …
diff --git a/packages/rehype-mathjax/lib/create-renderer.js b/packages/rehype-mathjax/lib/create-renderer.js
index 9e1aa30..a5cd971 100644
--- a/packages/rehype-mathjax/lib/create-renderer.js
+++ b/packages/rehype-mathjax/lib/create-renderer.js
@@ -1,20 +1,24 @@
/**
* @import {Element, Text} from 'hast'
- * @import {LiteDocument} from 'mathjax-full/js/adaptors/lite/Document.js'
- * @import {LiteElement} from 'mathjax-full/js/adaptors/lite/Element.js'
- * @import {LiteText} from 'mathjax-full/js/adaptors/lite/Text.js'
- * @import {MathDocument} from 'mathjax-full/js/core/MathDocument.js'
- * @import {OutputJax} from 'mathjax-full/js/core/OutputJax.js'
- * @import {HTMLHandler as HtmlHandler} from 'mathjax-full/js/handlers/html/HTMLHandler.js'
+ * @import {LiteDocument} from '@mathjax/src/js/adaptors/lite/Document.js'
+ * @import {LiteElement} from '@mathjax/src/js/adaptors/lite/Element.js'
+ * @import {LiteText} from '@mathjax/src/js/adaptors/lite/Text.js'
+ * @import {MathDocument} from '@mathjax/src/js/core/MathDocument.js'
+ * @import {OutputJax} from '@mathjax/src/js/core/OutputJax.js'
+ * @import {HTMLHandler as HtmlHandler} from '@mathjax/src/js/handlers/html/HTMLHandler.js'
* @import {Options, Renderer} from './create-plugin.js'
*/
import {h} from 'hastscript'
-import {liteAdaptor as liteAdapter} from 'mathjax-full/js/adaptors/liteAdaptor.js'
-import {RegisterHTMLHandler as registerHtmlHandler} from 'mathjax-full/js/handlers/html.js'
-import {AllPackages as allPackages} from 'mathjax-full/js/input/tex/AllPackages.js'
-import {TeX as Tex} from 'mathjax-full/js/input/tex.js'
-import {mathjax} from 'mathjax-full/js/mathjax.js'
+import {liteAdaptor as liteAdapter} from '@mathjax/src/js/adaptors/liteAdaptor.js'
+import {RegisterHTMLHandler as registerHtmlHandler} from '@mathjax/src/js/handlers/html.js'
+import {TeX as Tex} from '@mathjax/src/js/input/tex.js'
+import {mathjax} from '@mathjax/src/js/mathjax.js'
+import {allPackages} from './tex-packages.js'
+// No-op async loader: all font data is pre-loaded via static imports
+// in the entry points (svg.js, chtml.js). This prevents MathJax from
+// attempting dynamic loading at runtime.
+mathjax.asyncLoad = () => Promise.resolve()
/**
* Create a renderer.
@@ -38,6 +42,21 @@ export function createRenderer(options, output) {
const adapter = liteAdapter()
handler = registerHtmlHandler(adapter)
document = mathjax.document('', {InputJax: input, OutputJax: output})
+ // Apply pre-loaded dynamic font data to this output instance.
+ // The font side-effect imports in svg.js / chtml.js registered
+ // setup() functions on the font class via dynamicSetup(). We must
+ // call them on each new font instance because loadDynamicFiles()
+ // has a class-level `if (!df.promise)` guard that skips setup for
+ // instances created after the first.
+ const font = /** @type {any} */ (output).font
+ if (font) {
+ const dynamicFiles = font.constructor.dynamicFiles
+ for (const name of Object.keys(dynamicFiles)) {
+ const df = dynamicFiles[name]
+ df.promise ??= Promise.resolve()
+ df.setup(font)
+ }
+ }
},
render(value, options) {
// Cast as this practically results in an element instead of an `MmlNode`.
diff --git a/packages/rehype-mathjax/lib/svg.js b/packages/rehype-mathjax/lib/svg.js
index d3c73ae..cb26be4 100644
--- a/packages/rehype-mathjax/lib/svg.js
+++ b/packages/rehype-mathjax/lib/svg.js
@@ -1,4 +1,32 @@
-import {SVG as Svg} from 'mathjax-full/js/output/svg.js'
+// SVG font glyph data — side-effect imports register SVG path strings on the
+// font class for character ranges beyond the static base font.
+//
+// Only math-essential files are imported (~1.1 MB). Extended scripts (Cyrillic,
+// Arabic, Hebrew, Braille, Cherokee, Devanagari, etc.) and extra font variants
+// (sans-serif, monospace, phonetics, etc.) are omitted to keep the bundle close
+// to v3's ~1 MB. Users needing those ranges can add them via a custom plugin.
+//
+// Full list of available files (40 total, ~9.9 MB):
+// PUA, accents, accents-b-i, arabic, arrows, braille, braille-d,
+// calligraphic, cherokee, cyrillic, cyrillic-ss, devanagari, double-struck,
+// fraktur, greek, greek-ss, hebrew, latin, latin-b, latin-bi, latin-i,
+// marrows, math, monospace, monospace-ex, monospace-l, mshapes, phonetics,
+// phonetics-ss, sans-serif, sans-serif-b, sans-serif-bi, sans-serif-ex,
+// sans-serif-i, sans-serif-r, script, shapes, symbols, symbols-b-i, variants
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/accents.js' // 72 KB — accented math characters
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/arrows.js' // 229 KB — extended arrows
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/calligraphic.js' // 40 KB — \mathcal
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/double-struck.js' // 42 KB — \mathbb (ℝ, ℂ, ℤ)
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/fraktur.js' // 77 KB — \mathfrak
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/marrows.js' // 43 KB — more arrow shapes
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/math.js' // 199 KB — extra math symbols
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/mshapes.js' // 45 KB — math shapes
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/script.js' // 71 KB — \mathscr
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/shapes.js' // 111 KB — shapes and delimiters
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/symbols.js' // 178 KB — extra symbols
+import '@mathjax/mathjax-newcm-font/js/svg/dynamic/variants.js' // 17 KB — TeX variant characters
+
+import {SVG as Svg} from '@mathjax/src/js/output/svg.js'
import {createPlugin} from './create-plugin.js'
import {createRenderer} from './create-renderer.js'
diff --git a/packages/rehype-mathjax/lib/tex-packages.js b/packages/rehype-mathjax/lib/tex-packages.js
new file mode 100644
index 0000000..d65a5e2
--- /dev/null
+++ b/packages/rehype-mathjax/lib/tex-packages.js
@@ -0,0 +1,94 @@
+// TeX extension side-effect imports (registers each package with MathJax).
+// Includes all v4 packages except autoload (requires async asyncLoad) and
+// bboldx (requires font variant not in NCM).
+import '@mathjax/src/js/input/tex/action/ActionConfiguration.js'
+import '@mathjax/src/js/input/tex/ams/AmsConfiguration.js'
+import '@mathjax/src/js/input/tex/amscd/AmsCdConfiguration.js'
+import '@mathjax/src/js/input/tex/base/BaseConfiguration.js'
+import '@mathjax/src/js/input/tex/bbm/BbmConfiguration.js'
+// bboldx omitted — requires -bboldx font variant not in the NCM font package.
+import '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js'
+import '@mathjax/src/js/input/tex/begingroup/BegingroupConfiguration.js'
+import '@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js'
+import '@mathjax/src/js/input/tex/braket/BraketConfiguration.js'
+import '@mathjax/src/js/input/tex/bussproofs/BussproofsConfiguration.js'
+import '@mathjax/src/js/input/tex/cancel/CancelConfiguration.js'
+import '@mathjax/src/js/input/tex/cases/CasesConfiguration.js'
+import '@mathjax/src/js/input/tex/centernot/CenternotConfiguration.js'
+import '@mathjax/src/js/input/tex/color/ColorConfiguration.js'
+import '@mathjax/src/js/input/tex/colortbl/ColortblConfiguration.js'
+import '@mathjax/src/js/input/tex/colorv2/ColorV2Configuration.js'
+import '@mathjax/src/js/input/tex/configmacros/ConfigMacrosConfiguration.js'
+import '@mathjax/src/js/input/tex/dsfont/DsfontConfiguration.js'
+import '@mathjax/src/js/input/tex/empheq/EmpheqConfiguration.js'
+import '@mathjax/src/js/input/tex/enclose/EncloseConfiguration.js'
+import '@mathjax/src/js/input/tex/extpfeil/ExtpfeilConfiguration.js'
+import '@mathjax/src/js/input/tex/gensymb/GensymbConfiguration.js'
+import '@mathjax/src/js/input/tex/html/HtmlConfiguration.js'
+import '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js'
+import '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js'
+import '@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js'
+import '@mathjax/src/js/input/tex/noerrors/NoErrorsConfiguration.js'
+import '@mathjax/src/js/input/tex/noundefined/NoUndefinedConfiguration.js'
+import '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js'
+import '@mathjax/src/js/input/tex/require/RequireConfiguration.js'
+import '@mathjax/src/js/input/tex/setoptions/SetOptionsConfiguration.js'
+import '@mathjax/src/js/input/tex/tagformat/TagFormatConfiguration.js'
+import '@mathjax/src/js/input/tex/texhtml/TexHtmlConfiguration.js'
+import '@mathjax/src/js/input/tex/textcomp/TextcompConfiguration.js'
+import '@mathjax/src/js/input/tex/textmacros/TextMacrosConfiguration.js'
+import '@mathjax/src/js/input/tex/unicode/UnicodeConfiguration.js'
+import '@mathjax/src/js/input/tex/units/UnitsConfiguration.js'
+import '@mathjax/src/js/input/tex/upgreek/UpgreekConfiguration.js'
+import '@mathjax/src/js/input/tex/verb/VerbConfiguration.js'
+
+/**
+ * All TeX packages (all v4 extensions minus autoload and bboldx).
+ *
+ * Note: `physics` redefines `\div`, `\Re`, `\Im`, and trig/log functions.
+ * `colorv2` overrides `\color` from the `color` package.
+ * Both are included to match v3's AllPackages behavior.
+ *
+ * @type {ReadonlyArray}
+ */
+export const allPackages = [
+ 'action',
+ 'ams',
+ 'amscd',
+ 'base',
+ 'bbm',
+ 'bbox',
+ 'begingroup',
+ 'boldsymbol',
+ 'braket',
+ 'bussproofs',
+ 'cancel',
+ 'cases',
+ 'centernot',
+ 'color',
+ 'colortbl',
+ 'colorv2',
+ 'configmacros',
+ 'dsfont',
+ 'empheq',
+ 'enclose',
+ 'extpfeil',
+ 'gensymb',
+ 'html',
+ 'mathtools',
+ 'mhchem',
+ 'newcommand',
+ 'noerrors',
+ 'noundefined',
+ 'physics',
+ 'require',
+ 'setoptions',
+ 'tagformat',
+ 'texhtml',
+ 'textcomp',
+ 'textmacros',
+ 'unicode',
+ 'units',
+ 'upgreek',
+ 'verb'
+]
diff --git a/packages/rehype-mathjax/package.json b/packages/rehype-mathjax/package.json
index 0dc120f..15681fd 100644
--- a/packages/rehype-mathjax/package.json
+++ b/packages/rehype-mathjax/package.json
@@ -7,10 +7,10 @@
],
"dependencies": {
"@types/hast": "^3.0.0",
- "@types/mathjax": "^0.0.40",
"hast-util-to-text": "^4.0.0",
"hastscript": "^9.0.0",
- "mathjax-full": "^3.0.0",
+ "@mathjax/mathjax-newcm-font": "^4.0.0",
+ "@mathjax/src": "^4.0.0",
"unified": "^11.0.0",
"unist-util-visit-parents": "^6.0.0",
"vfile": "^6.0.0"
@@ -60,12 +60,18 @@
"test-api": "node --conditions development test/index.js",
"test": "npm run build && npm run test-api"
},
- "sideEffects": false,
+ "sideEffects": [
+ "./lib/svg.js",
+ "./lib/chtml.js",
+ "./lib/tex-packages.js",
+ "./lib/create-renderer.js"
+ ],
"type": "module",
"version": "7.1.0",
"xo": {
"prettier": true,
"rules": {
+ "import/no-unassigned-import": "off",
"unicorn/prefer-at": "off"
}
}
diff --git a/packages/rehype-mathjax/readme.md b/packages/rehype-mathjax/readme.md
index 3b9c5e2..28ca94d 100644
--- a/packages/rehype-mathjax/readme.md
+++ b/packages/rehype-mathjax/readme.md
@@ -181,7 +181,7 @@ For example:
// …
.use(rehypeMathjaxChtml, {
chtml: {
- fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2'
+ fontURL: 'https://cdn.jsdelivr.net/npm/@mathjax/mathjax-newcm-font/chtml/woff2'
}
})
// …
diff --git a/packages/rehype-mathjax/test/fixture/document-svg.html b/packages/rehype-mathjax/test/fixture/document-svg.html
index 765aa2f..b621cad 100644
--- a/packages/rehype-mathjax/test/fixture/document-svg.html
+++ b/packages/rehype-mathjax/test/fixture/document-svg.html
@@ -3,8 +3,41 @@
Math!
-Hello, !
+Hello, !
-