import getMeta from '../../utils/meta' let mathJaxPromise: Promise export const loadMathJax = async (options?: { enableMenu?: boolean numbering?: string singleDollar?: boolean useLabelIds?: boolean }) => { if (!mathJaxPromise) { mathJaxPromise = new Promise((resolve, reject) => { options = { enableMenu: false, singleDollar: true, useLabelIds: false, ...options, } const inlineMath = [['\\(', '\\)']] if (options.singleDollar) { inlineMath.push(['$', '$']) } // https://docs.mathjax.org/en/v3.2-latest/upgrading/v2.html window.MathJax = { // https://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block tex: { macros: { // Implements support for the \bm command from the bm package. It bolds the argument in math mode. // https://github.com/mathjax/MathJax/issues/1219#issuecomment-341059843 bm: ['\\boldsymbol{#1}', 1], }, inlineMath, displayMath: [ ['\\[', '\\]'], ['$$', '$$'], ], packages: { '[-]': [ 'html', // avoid creating HTML elements/attributes 'require', // prevent loading disabled packages ], }, processEscapes: true, processEnvironments: true, useLabelIds: options.useLabelIds, tags: options.numbering, }, loader: { load: [ 'ui/safe', // https://docs.mathjax.org/en/latest/options/safe.html ], }, options: { enableMenu: options.enableMenu, // https://docs.mathjax.org/en/latest/options/menu.html }, startup: { typeset: false, pageReady() { // disable the "Math Renderer" option in the context menu, // as only SVG is available window.MathJax.startup.document.menu.menu .findID('Renderer') .disable() }, ready() { window.MathJax.startup.defaultReady() // remove anything from the "font-family" attribute after a semicolon // so it's not added to the style attribute // https://github.com/mathjax/MathJax/issues/3129#issuecomment-1807225345 const { safe } = window.MathJax.startup.document safe.filterAttributes.set('fontfamily', 'filterFontFamily') safe.filterMethods.filterFontFamily = ( _safe: any, family: string ) => family.split(/;/)[0] }, }, } const script = document.createElement('script') const path = getMeta('ol-mathJaxPath') if (!path) { reject(new Error('No MathJax path found')) return } script.src = path script.addEventListener('load', async () => { await window.MathJax.startup.promise document.head.appendChild(window.MathJax.svgStylesheet()) resolve(window.MathJax) }) script.addEventListener('error', reject) document.head.append(script) }) } return mathJaxPromise }