mathjax / mathjax/MathJax-src

Can't load .../svg/dynamic/math.js

Open
#1,458 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.4k
Forks
245
Avg merge
5d 2h
Merged PRs (30d)
2

Description

Hello,

I have a 2 part problem with the following maths: K^\perp which seems to lead to unexpected behaviour in mathjax.

Given the following minimal-as-possible demo where I statically load packages and use 2 fonts:

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

// TeX to MathML
import { liteAdaptor } from '@mathjax/src/js/adaptors/liteAdaptor.js';
import { STATE } from '@mathjax/src/js/core/MathItem.js';
import { SerializedMmlVisitor } from '@mathjax/src/js/core/MmlTree/SerializedMmlVisitor.js';
import { RegisterHTMLHandler } from '@mathjax/src/js/handlers/html.js';
import { TeX } from '@mathjax/src/js/input/tex.js';

import '@mathjax/src/js/input/tex/base/BaseConfiguration.js';

// MathML to SVG
import { MathML } from '@mathjax/src/js/input/mathml.js';
import { SVG } from '@mathjax/src/js/output/svg.js';

import { MathJaxNewcmFont } from '@mathjax/mathjax-newcm-font/js/svg.js';
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/math.js';

import { MathJaxFiraFont } from '@mathjax/mathjax-fira-font/js/svg.js';
// import '@mathjax/mathjax-fira-font/js/svg/dynamic/math.js';

// TeX to MathML ---------------------------------------

const adaptor = liteAdaptor();
const visitor = new SerializedMmlVisitor();
RegisterHTMLHandler(adaptor);

const packages: string[] = [
  'base',
];

const tex = new TeX({ packages });

const mmlDoc = mathjax.document('', {
  InputJax: tex,
});

function texToMathML(tex: string) {
  const mmlNode = mmlDoc.convert(tex, { end: STATE.CONVERT });
  return visitor.visitTree(mmlNode)
}

// MathML to SVG ----------------------------------

const adaptor2 = liteAdaptor();
RegisterHTMLHandler(adaptor2);

const htmlDoc = mathjax.document('', {
  InputJax: new MathML(),
});

const NewcmFont = new MathJaxNewcmFont();
const FiraFont = new MathJaxFiraFont();

const packages2: string[] = [
  // 'math',
];

packages2.forEach((name) => {
  // @ts-expect-error Property 'dynamicFiles' is protected
  MathJaxNewcmFont.dynamicFiles[name].setup(NewcmFont);
  // @ts-expect-error Property 'dynamicFiles' is protected
  MathJaxFiraFont.dynamicFiles[name].setup(FiraFont);
});

const fonts: Record<string, any> = {
  computerModern: new SVG({ fontData: NewcmFont }),
  fira: new SVG({ fontData: FiraFont }),
};

function mathMLToSvg(mml: string, font: string) {
  htmlDoc.outputJax = fonts[font];
  htmlDoc.outputJax.setAdaptor(htmlDoc.adaptor);
  const htmlNode = htmlDoc.convert(mml);
  const svg = htmlNode.children[0];
  return adaptor2.outerHTML(svg);
}

// Render -------------------------------------

const texMaths = String.raw`K^\perp`

// Browser ----------------------------------------

const element = document.querySelector<HTMLDivElement>('#app')

// initial render fails
try {
  const mml = texToMathML(texMaths)
  const svg = mathMLToSvg(mml, 'computerModern')
  element!.innerHTML = svg
} catch (err) {
  console.error(err)
}

// 2nd try works
const mml = texToMathML(texMaths)
const svg = mathMLToSvg(mml, 'computerModern')
element!.innerHTML = svg

// Node.js --------------------------------------

// // initial render fails
// try {
//   const mml = texToMathML(texMaths)
//   const svg = mathMLToSvg(mml, 'computerModern')
//   console.log(svg)
// } catch (err) {
//   console.error(err)
// }

// // 2nd try works
// const mml2 = texToMathML(texMaths)
// const svg2 = mathMLToSvg(mml2, 'computerModern')
// console.log(svg2)

To run the demo in the browser:

pnpm create vite mathjax-dynamic-maths-error --template vanilla-ts
pnpm i @mathjax/src @mathjax/mathjax-newcm-font @mathjax/mathjax-fira-font
# replace contents of main.ts with the code above
pnpm dev

With node:

# comment out the browser part and uncomment the node part
npx tsx src/main.ts
1. The Fira font doesn't have a math extension

I can resolve the error by preloading the math extension for the MathJaxNewcmFont, but no such extension exists for the MathJaxFiraFont.

2. The maths renders the 2nd time without the math extension preloaded

I noticed that the maths does successfully render on the 2nd try for both fonts, when the math extension is not preloaded.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the minimal TypeScript demo and compare the first and second calls to mathMLToSvg for the NewcmFont and FiraFont. Read the dynamic font setup through MathJaxNewcmFont.dynamicFiles and MathJaxFiraFont.dynamicFiles, including the referenced dynamic/math.js modules. Done means explaining or fixing why the initial K^\perp render fails and the subsequent render succeeds, including the missing Fira math extension.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.