mathjax / MathJax

Beautiful and accessible math in all browsers
http://www.mathjax.org/
Apache License 2.0
10.2k stars 1.16k forks source link

MJ4: Enormous typesetting caused by confluence of assistive MML and lazy typesetting #3167

Open AlexEdgcomb opened 9 months ago

AlexEdgcomb commented 9 months ago

Issue Summary

Having both assistive MML and lazy typesetting causes enormous typesettings

Steps to Reproduce:

  1. Go to https://codepen.io/alexedgcomb/pen/MWxvONX?editors=1001 Observed: Typesetting is enormous (499px by 465px) image

    Expected: Typesetting is normal size

    image

Console warnings:

Unexpected value NaNex parsing width attribute.
Unexpected value NaNex parsing height attribute.
Unexpected value 0 -442 NaN NaN parsing viewBox attribute.

No console error.

Technical details:

I am using the following MathJax configuration:

MathJax = {
  loader: { load: [ 'ui/lazy' ] },
  options: {
    lazyAlwaysTypeset: '.disable-lazy-typesetting',
    menuOptions: { settings: { assistiveMml: true } },
  },
  output: { font: 'https://cdn.jsdelivr.net/npm/mathjax-tex-font@1.0.0-alpha.1/es5/output/fonts/mathjax-tex' },
  startup: { typeset: false },
};

and loading MathJax via

<script src="https://cdn.jsdelivr.net/npm/mathjax-full@4.0.0-alpha.1/es5/tex-mml-svg.js"></script>

Supporting information:

Also confirmed to reproduce in:

dpvc commented 9 months ago

I wasn't able to reproduce in Firefox, but did see it in Chrome and Safari.

It took a bit of digging, but it turns out that the typeset: false was also a significant part of the problem. It turns out that when the startup typeset is shipped, the metrics need for the typesetting (e.g., the ex and em sizes) aren't computed, and when the math is then processed by the lazy loader, the values for ex and em are not defined, and the results produce the NaN values you re seeing. That means the final SVG is not properly scaled. The AssistiveMml extension plays a role because it requires the speech-rule engine to be set up, and that is done in a promise, so some code runs before that is processed, and MathJax thinks the metrics have been obtained when they haven't.

This code will work around the problem for now:

MathJax = {
  loader: { load: [ 'ui/lazy' ] },
  options: {
    lazyAlwaysTypeset: '.disable-lazy-typesetting',
    menuOptions: { settings: { assistiveMml: true } },
  },
  output: { font: 'https://cdn.jsdelivr.net/npm/mathjax-tex-font@1.0.0-alpha.1/es5/output/fonts/mathjax-tex' },
  startup: { 
    typeset: false,
    ready() {
      const {AbstractMathItem, STATE} = MathJax._.core.MathItem;
      Object.assign(AbstractMathItem.prototype, {
        __state: AbstractMathItem.prototype.state,
        state(state, restore) {
          if (state === STATE.TYPESET - 1 && !this.metrics.hasOwnProperty('em')) {
            state = STATE.METRICS - 1;
          }
          return this.__state(state, restore);
        }
      });
      MathJax.startup.defaultReady();
    }
  },
};

but I will make a PR to fix the issue in the next release.

For me, Firefox doesn't process the math when typeset: false is in play, but Chrome and Safari do. I'm trying to decide what the proper behavior should be for the lazy loader, but all three browser should really do the same thing, I would think. The typeset: false really should prevent any typesetting until the first time MathJax.typeset or MathJax.typesetPromise() is called. I'm not sure why Safari and Chrome are doing the typesetting, and will have to look into that. It is probably the the IntersectionObserver fires in one case and not the other.

AlexEdgcomb commented 9 months ago

@dpvc , thank you for the explanation and fix!

dpvc commented 9 months ago

I'm not sure why Safari and Chrome are doing the typesetting

I missed the fact that you have the math in a div with class disable-lazy-typesetting, so it is always typeset.

Now I'm wondering how that should interact with typeset: false bing set. If typeset is false, no initial typesetting should occur, and that should include lazy typesetting, I would think. That means any lazy typesetting (of either kind) should wait until after the first MathJax.typeset() or MathJax.typesetPromise() call when typeset: false is set. So the always typesetting should wait until then as well.

Is there a reason you have typeset: false set?

AlexEdgcomb commented 9 months ago

@dpvc , fair question! I set typeset: false while seeking the simplest configuration to reproduce the enormous typesetting issue.

My production configuration [1] and use case [2] are quite complex, and reproducing the issue there is tricky [3].

I wanted to narrow down the issue before reporting: Maybe I'd find a solution myself, or even useful clues; or, at least, reduce the sleuthing on your end :) Took about 8 hours to come up with the configuration that I reported.

Of note, the workaround you provided resolves the issue in my production use case.

[1] Production configuration Note: MathJax2 is also loaded b/c some learning tools have pixel-perfect layouts that rely on the specific size dimensions of MJ2. The MJ4 files hosted on our site simply have references to "MathJax" changed to "MathJax4", such that `window.MathJax` is MJ2 and `window.MathJax4` is MJ4. ```js window.MathJax4 = { loader: { load: [ '[tex]/mathtools', 'ui/lazy' ] }, options: { ignoreHtmlClass: 'do-process-mathjax-2', lazyAlwaysTypeset: '.disable-lazy-typesetting', menuOptions: { settings: { assistiveMml: true, inTabOrder: false } }, }, output: { font: 'https://mathjax.zybooks.com/4.0.0-alpha.1-customized/mathjax-tex-font', linebreaks: { inline: false }, }, startup: { // MathJax 4.0.0-alpha.1 has a bug wherein MathJax.startup.promise resolves too early, causing ui/lazy to fail for autoloaded extensions. // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3161#issuecomment-1889305257 async pageReady() { const { output, startup } = window.MathJax4.config; // Wait for font to load if (startup.loadAllFontFiles && output.font) { await output.font.loadDynamicFiles(); } // Wait for initial typeset to finish let result = Promise.resolve; if (startup.typeset && window.MathJax4.typesetPromise) { result = () => window.MathJax4.startup.typesetPromise(startup.elements); } return result; }, ready() { // MathJax 4.0.0-alpha.1 has a bug wherein typesetting is centered when inline breaking is off, but should be left-aligned. // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3005#issuecomment-1474940701 // Fix in for next MathJax 4 update: https://github.com/mathjax/MathJax-src/pull/916 const { CommonWrapper } = window.MathJax4._.output.common.Wrapper; Object.assign(CommonWrapper.prototype, { _processIndent: CommonWrapper.prototype.processIndent, processIndent(indentalign, indentshift, align = '', shift = '', width = this.metrics.containerWidth) { return this.jax.math.display ? this._processIndent(indentalign, indentshift, align, shift, width) : [ 'left', 0 ]; }, }); // MathJax 4.0.0-alpha.1 has a bug wherein Chrome typesets unequal vertical spacing for some math, like: \( p ∧ q \) // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3005#issuecomment-1450758810 const { SvgMath } = window.MathJax4._.output.svg.Wrappers.math; Object.assign(SvgMath.styles, { 'mjx-break::after': { content: '" "', 'white-space': 'normal', 'line-height': 0, 'font-family': 'MJX-ZERO', }, 'mjx-break[size="1"]': { 'letter-spacing': '-.889em' }, 'mjx-break[size="2"]': { 'letter-spacing': '-.833em' }, 'mjx-break[size="3"]': { 'letter-spacing': '-.778em' }, 'mjx-break[size="4"]': { 'letter-spacing': '-.772em' }, 'mjx-break[size="5"]': { 'letter-spacing': '-.667em' }, }); delete SvgMath.styles['mjx-break']; // MathJax 4.0.0-alpha.1 has a bug wherein an overline in MML is placed too high, like: s // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3011#issuecomment-1452802224 const { defaultDelimiters } = window.MathJax4._.output.fonts['mathjax-tex'].svg_ts.MathJax4TexFont; const overline = 0x203E; const overlineAlias = 0xAF; defaultDelimiters[overline] = defaultDelimiters[overlineAlias]; // MathJax 4.0.0-alpha.1 has a bug wherein 's subscript and superscript are in the middle, not bottom/top. // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3049#issuecomment-1556152947 const SvgScriptbase = window.MathJax4._.output.svg.Wrappers.scriptbase.SvgScriptbase.prototype; SvgScriptbase.baseCharZero = function(number) { const notLarge = !this.baseCore.node.attributes.get('largeop'); const unsized = !(this.baseCore.node.isKind('mo') && this.baseCore.size); return (this.baseIsChar && notLarge && unsized && this.baseScale === 1) ? 0 : number; }; const SvgMo = window.MathJax4._.output.svg.Wrappers.mo.SvgMo.prototype; Object.assign(SvgMo, { _setDelimSize: SvgMo.setDelimSize, setDelimSize(character, index) { this._setDelimSize(character, index); this.childNodes[0].invalidateBBox(); }, }); // MathJax 4.0.0-alpha.1 has a bug wherein the typesetting can be enormous due to unloaded measurements. // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3167#issuecomment-1909010036 const { AbstractMathItem, STATE } = window.MathJax4._.core.MathItem; Object.assign(AbstractMathItem.prototype, { __state: AbstractMathItem.prototype.state, state(state, restore) { let newState = state; if (state === STATE.TYPESET - 1 && !this.metrics.hasOwnProperty('em')) { newState = STATE.METRICS - 1; } return this.__state(newState, restore); }, }); window.MathJax4.startup.defaultReady(); // MathJax 4.0.0-alpha.1's mathjax-tex font does not have a three dots above character. Nor a four dots above character. // Suggested solution by MathJax author is to use periods: https://github.com/mathjax/MathJax/issues/3051#issuecomment-1593556240 const threeDotsAbove = 0x20DB; const fourDotsAbove = 0x20DC; /* eslint-disable no-magic-numbers, id-length */ [ [ 3, threeDotsAbove ], [ 4, fourDotsAbove ] ].forEach(([ numDots, char ]) => { window.MathJax4.startup.document.outputJax.font.variant.normal.chars[char] = [ 0.12, 0, numDots * 0.278, { c: '.'.repeat(numDots) } ]; }); /* eslint-enable no-magic-numbers, id-length */ // MathJax 4.0.0-alpha.1's mathjax-tex font has a bug wherein an over character centers too far left // Suggested workaround by MathJax author: https://github.com/mathjax/MathJax/issues/3051#issuecomment-1566186737 const { font } = window.MathJax4.startup.document.outputJax; if (font.options.dynamicPrefix.match(/^\[mathjax-tex\]/u)) { // eslint-disable const mathjaxTexSkewData = { normal: { 0x2A: 0.148, 0x32: -0.01, 0x34: 0.103, 0x36: 0.068, 0x37: -0.147, 0x38: 0.011, 0x42: -0.098, 0x43: 0.146, 0x44: -0.139, 0x45: -0.025, 0x46: -0.018, 0x47: 0.115, 0x4A: 0.06, 0x4B: -0.011, 0x4C: -0.119, 0x50: -0.09, 0x52: -0.134, 0x53: 0.052, 0x58: -0.014, 0x5A: 0.011, 0x60: -0.031, 0x61: -0.036, 0x62: -0.178, 0x63: 0.027, 0x64: 0.099, 0x65: 0.014, 0x66: 0.071, 0x67: 0.082, 0x68: -0.174, 0x6B: -0.164, 0x6C: -0.034, 0x6D: -0.067, 0x6E: -0.067, 0x70: -0.076, 0x71: 0.054, 0x72: -0.015, 0x73: 0.035, 0x74: -0.034, 0x75: -0.033, 0x392: -0.068, 0x393: -0.015, 0x395: -0.022, 0x396: 0.011, 0x39A: -0.011, 0x3A1: -0.058, 0x3A3: -0.011, 0x3A7: -0.014, 0x20D7: -0.264, 0x210C: 0.062, 0x210E: -0.075, 0x2111: 0.06, 0x2113: 0.111, 0x2119: -0.072, 0x211C: 0.016, 0x211D: -0.072, 0x2128: -0.137, 0x212D: 0.19, 0x1D401: -0.109, 0x1D402: 0.165, 0x1D403: -0.158, 0x1D404: -0.028, 0x1D405: -0.02, 0x1D406: 0.127, 0x1D409: 0.051, 0x1D40A: -0.013, 0x1D40B: -0.114, 0x1D40F: -0.1, 0x1D411: -0.15, 0x1D412: 0.054, 0x1D417: -0.017, 0x1D419: 0.013, 0x1D41A: -0.049, 0x1D41B: -0.194, 0x1D41C: 0.043, 0x1D41D: 0.124, 0x1D41E: 0.018, 0x1D41F: 0.069, 0x1D420: 0.07, 0x1D421: -0.185, 0x1D423: 0.013, 0x1D424: -0.177, 0x1D425: -0.024, 0x1D426: -0.061, 0x1D427: -0.063, 0x1D429: -0.079, 0x1D42A: 0.066, 0x1D42B: -0.021, 0x1D42C: 0.038, 0x1D42D: -0.029, 0x1D42E: -0.024, 0x1D434: 0.175, 0x1D435: 0.041, 0x1D436: 0.205, 0x1D437: 0.013, 0x1D438: 0.095, 0x1D439: 0.074, 0x1D43A: 0.203, 0x1D43B: 0.089, 0x1D43C: 0.084, 0x1D43D: 0.151, 0x1D43E: 0.09, 0x1D43F: 0.019, 0x1D440: 0.085, 0x1D441: 0.082, 0x1D442: 0.114, 0x1D443: 0.011, 0x1D444: 0.1, 0x1D445: 0.018, 0x1D446: 0.168, 0x1D447: 0.016, 0x1D448: 0.022, 0x1D449: -0.018, 0x1D44B: 0.097, 0x1D44C: -0.027, 0x1D44D: 0.114, 0x1D44E: 0.022, 0x1D44F: -0.05, 0x1D450: 0.101, 0x1D451: 0.182, 0x1D452: 0.067, 0x1D453: 0.172, 0x1D454: 0.077, 0x1D456: 0.074, 0x1D457: 0.153, 0x1D458: -0.048, 0x1D459: 0.035, 0x1D45A: -0.035, 0x1D45B: -0.035, 0x1D45C: 0.072, 0x1D45E: 0.121, 0x1D45F: 0.021, 0x1D460: 0.061, 0x1D461: 0.044, 0x1D462: 0.019, 0x1D463: 0.051, 0x1D464: 0.047, 0x1D465: 0.043, 0x1D466: 0.059, 0x1D467: 0.102, 0x1D468: 0.173, 0x1D469: 0.044, 0x1D46A: 0.221, 0x1D46C: 0.099, 0x1D46D: 0.072, 0x1D46E: 0.214, 0x1D46F: 0.091, 0x1D470: 0.086, 0x1D471: 0.153, 0x1D472: 0.095, 0x1D473: 0.018, 0x1D474: 0.086, 0x1D475: 0.083, 0x1D476: 0.11, 0x1D477: 0.012, 0x1D478: 0.093, 0x1D479: 0.014, 0x1D47A: 0.199, 0x1D47B: 0.014, 0x1D47C: 0.015, 0x1D47D: -0.018, 0x1D47F: 0.106, 0x1D480: -0.028, 0x1D481: 0.122, 0x1D482: 0.019, 0x1D483: -0.035, 0x1D484: 0.108, 0x1D485: 0.207, 0x1D486: 0.063, 0x1D487: 0.189, 0x1D488: 0.067, 0x1D489: -0.106, 0x1D48A: 0.08, 0x1D48B: 0.163, 0x1D48C: -0.074, 0x1D48D: 0.022, 0x1D48E: -0.038, 0x1D48F: -0.038, 0x1D490: 0.074, 0x1D492: 0.138, 0x1D493: 0.018, 0x1D494: 0.059, 0x1D495: 0.046, 0x1D497: 0.049, 0x1D498: 0.044, 0x1D499: 0.029, 0x1D49A: 0.05, 0x1D49B: 0.102, 0x1D504: 0.085, 0x1D505: -0.01, 0x1D508: 0.193, 0x1D509: -0.059, 0x1D50A: 0.126, 0x1D50D: -0.054, 0x1D50E: 0.115, 0x1D50F: 0.104, 0x1D510: 0.042, 0x1D511: 0.037, 0x1D512: -0.074, 0x1D513: 0.025, 0x1D514: -0.076, 0x1D517: 0.332, 0x1D518: 0.053, 0x1D519: 0.019, 0x1D51A: 0.01, 0x1D51B: 0.049, 0x1D51C: -0.011, 0x1D51E: 0.079, 0x1D51F: -0.068, 0x1D520: 0.074, 0x1D521: -0.084, 0x1D522: 0.043, 0x1D523: 0.058, 0x1D524: 0.087, 0x1D525: -0.092, 0x1D527: -0.01, 0x1D528: -0.011, 0x1D529: 0.056, 0x1D52A: -0.046, 0x1D52B: -0.037, 0x1D52C: 0.014, 0x1D52D: -0.122, 0x1D52E: 0.088, 0x1D531: 0.051, 0x1D533: -0.121, 0x1D534: -0.26, 0x1D535: 0.01, 0x1D536: -0.121, 0x1D537: -0.01, 0x1D539: -0.072, 0x1D53B: -0.1, 0x1D53C: 0.029, 0x1D53D: 0.029, 0x1D541: 0.151, 0x1D542: 0.013, 0x1D543: -0.139, 0x1D54A: -0.015, 0x1D56C: 0.082, 0x1D56E: 0.218, 0x1D56F: -0.033, 0x1D570: 0.207, 0x1D571: -0.078, 0x1D572: 0.17, 0x1D573: 0.071, 0x1D574: 0.073, 0x1D575: -0.059, 0x1D576: 0.126, 0x1D577: 0.126, 0x1D578: 0.038, 0x1D579: 0.024, 0x1D57A: -0.087, 0x1D57B: 0.013, 0x1D57C: -0.087, 0x1D57D: 0.011, 0x1D57F: 0.153, 0x1D580: 0.104, 0x1D582: 0.022, 0x1D583: 0.064, 0x1D585: -0.169, 0x1D586: 0.087, 0x1D588: 0.081, 0x1D589: -0.105, 0x1D58A: 0.048, 0x1D58B: 0.072, 0x1D58C: 0.111, 0x1D58D: -0.097, 0x1D590: -0.017, 0x1D591: 0.125, 0x1D592: -0.056, 0x1D593: -0.071, 0x1D594: 0.029, 0x1D595: -0.124, 0x1D596: 0.112, 0x1D597: 0.013, 0x1D599: 0.085, 0x1D59A: 0.011, 0x1D59B: -0.142, 0x1D59C: -0.296, 0x1D59D: 0.026, 0x1D59E: -0.127, 0x1D5A1: -0.077, 0x1D5A2: 0.091, 0x1D5A3: -0.109, 0x1D5A4: 0.018, 0x1D5A5: 0.025, 0x1D5A6: 0.073, 0x1D5A9: 0.109, 0x1D5AA: 0.02, 0x1D5AB: -0.132, 0x1D5AF: -0.06, 0x1D5B1: -0.066, 0x1D5B2: 0.015, 0x1D5B7: -0.015, 0x1D5BA: -0.013, 0x1D5BB: -0.139, 0x1D5BC: 0.042, 0x1D5BD: 0.139, 0x1D5BE: 0.016, 0x1D5BF: 0.096, 0x1D5C0: 0.074, 0x1D5C1: -0.14, 0x1D5C4: -0.124, 0x1D5C6: -0.038, 0x1D5C7: -0.038, 0x1D5C9: -0.03, 0x1D5CA: 0.041, 0x1D5CB: 0.034, 0x1D5CC: 0.022, 0x1D5CD: -0.04, 0x1D5D5: -0.07, 0x1D5D6: 0.082, 0x1D5D7: -0.096, 0x1D5D8: 0.015, 0x1D5D9: 0.022, 0x1D5DA: 0.061, 0x1D5DD: 0.097, 0x1D5DE: 0.016, 0x1D5DF: -0.126, 0x1D5E3: -0.064, 0x1D5E5: -0.056, 0x1D5EB: -0.015, 0x1D5EF: -0.152, 0x1D5F0: 0.041, 0x1D5F1: 0.152, 0x1D5F2: 0.011, 0x1D5F3: 0.087, 0x1D5F4: 0.065, 0x1D5F5: -0.153, 0x1D5F8: -0.138, 0x1D5FA: -0.028, 0x1D5FB: -0.028, 0x1D5FD: -0.043, 0x1D5FE: 0.061, 0x1D5FF: 0.03, 0x1D600: 0.015, 0x1D601: -0.047, 0x1D608: 0.147, 0x1D609: 0.047, 0x1D60A: 0.18, 0x1D60B: 0.021, 0x1D60C: 0.098, 0x1D60D: 0.095, 0x1D60E: 0.174, 0x1D60F: 0.108, 0x1D610: 0.108, 0x1D611: 0.209, 0x1D612: 0.1, 0x1D613: 0.016, 0x1D614: 0.112, 0x1D615: 0.11, 0x1D616: 0.131, 0x1D617: 0.048, 0x1D618: 0.131, 0x1D619: 0.04, 0x1D61A: 0.126, 0x1D61B: 0.062, 0x1D61C: 0.106, 0x1D61D: 0.048, 0x1D61E: 0.048, 0x1D61F: 0.065, 0x1D620: 0.04, 0x1D621: 0.084, 0x1D622: 0.084, 0x1D624: 0.096, 0x1D625: 0.237, 0x1D626: 0.09, 0x1D627: 0.133, 0x1D628: 0.116, 0x1D62A: 0.09, 0x1D62B: 0.102, 0x1D62C: -0.017, 0x1D62D: 0.099, 0x1D62E: 0.057, 0x1D62F: 0.057, 0x1D630: 0.079, 0x1D631: 0.05, 0x1D632: 0.126, 0x1D633: 0.069, 0x1D634: 0.08, 0x1D635: 0.043, 0x1D636: 0.084, 0x1D637: 0.034, 0x1D638: 0.034, 0x1D639: 0.032, 0x1D63A: 0.034, 0x1D63B: 0.052, 0x1D671: -0.073, 0x1D672: 0.1, 0x1D673: -0.098, 0x1D676: 0.072, 0x1D679: 0.085, 0x1D67B: -0.11, 0x1D67F: -0.07, 0x1D681: -0.097, 0x1D682: 0.046, 0x1D68A: -0.048, 0x1D68B: -0.172, 0x1D68C: 0.043, 0x1D68D: 0.088, 0x1D68F: 0.077, 0x1D690: 0.07, 0x1D691: -0.172, 0x1D693: 0.057, 0x1D694: -0.169, 0x1D695: -0.085, 0x1D696: -0.052, 0x1D697: -0.071, 0x1D699: -0.074, 0x1D69A: 0.044, 0x1D69B: -0.018, 0x1D69C: 0.04, 0x1D69D: -0.074, 0x1D69E: -0.043, 0x1D6A9: -0.075, 0x1D6AA: -0.019, 0x1D6AC: -0.027, 0x1D6AD: 0.013, 0x1D6B1: -0.013, 0x1D6B8: -0.063, 0x1D6BA: -0.015, 0x1D6BE: -0.017, 0x1D6E2: 0.177, 0x1D6E3: 0.077, 0x1D6E4: 0.074, 0x1D6E5: 0.17, 0x1D6E6: 0.094, 0x1D6E7: 0.11, 0x1D6E8: 0.089, 0x1D6E9: 0.117, 0x1D6EA: 0.084, 0x1D6EB: 0.09, 0x1D6EC: 0.17, 0x1D6ED: 0.085, 0x1D6EE: 0.082, 0x1D6EF: 0.097, 0x1D6F0: 0.117, 0x1D6F1: 0.089, 0x1D6F2: 0.049, 0x1D6F4: 0.104, 0x1D6F5: 0.012, 0x1D6F7: 0.082, 0x1D6F8: 0.097, 0x1D6F9: 0.025, 0x1D6FA: 0.137, 0x1D6FC: 0.072, 0x1D6FD: 0.148, 0x1D6FE: -0.019, 0x1D6FF: 0.107, 0x1D700: 0.051, 0x1D701: 0.067, 0x1D702: 0.024, 0x1D703: 0.075, 0x1D705: 0.043, 0x1D706: -0.053, 0x1D707: 0.048, 0x1D708: 0.028, 0x1D709: 0.06, 0x1D70B: 0.043, 0x1D70C: 0.096, 0x1D70D: -0.034, 0x1D710: 0.036, 0x1D711: 0.028, 0x1D712: 0.018, 0x1D713: 0.143, 0x1D714: 0.034, 0x1D715: 0.069, 0x1D716: 0.066, 0x1D717: 0.116, 0x1D718: 0.053, 0x1D719: 0.125, 0x1D71A: 0.102, 0x1D71B: 0.039, 0x1D71C: 0.174, 0x1D71D: 0.069, 0x1D71E: 0.071, 0x1D71F: 0.168, 0x1D720: 0.098, 0x1D721: 0.117, 0x1D722: 0.09, 0x1D723: 0.108, 0x1D724: 0.085, 0x1D725: 0.093, 0x1D726: 0.167, 0x1D727: 0.085, 0x1D728: 0.082, 0x1D729: 0.104, 0x1D72A: 0.111, 0x1D72B: 0.09, 0x1D72C: 0.039, 0x1D72E: 0.11, 0x1D72F: 0.01, 0x1D731: 0.08, 0x1D732: 0.106, 0x1D733: 0.029, 0x1D734: 0.135, 0x1D736: 0.059, 0x1D737: 0.153, 0x1D738: -0.02, 0x1D739: 0.115, 0x1D73A: 0.058, 0x1D73B: 0.083, 0x1D73C: 0.019, 0x1D73D: 0.062, 0x1D73F: 0.025, 0x1D740: -0.072, 0x1D741: 0.042, 0x1D742: 0.028, 0x1D743: 0.061, 0x1D745: 0.046, 0x1D746: 0.1, 0x1D747: -0.029, 0x1D74A: 0.037, 0x1D74B: 0.033, 0x1D74C: 0.011, 0x1D74D: 0.151, 0x1D74E: 0.039, 0x1D74F: 0.079, 0x1D750: 0.074, 0x1D751: 0.119, 0x1D752: 0.053, 0x1D753: 0.126, 0x1D754: 0.094, 0x1D755: 0.043, 0x1D757: -0.04, 0x1D758: 0.022, 0x1D75A: 0.015, 0x1D75F: 0.012, 0x1D766: -0.034, 0x1D76C: -0.015, 0x1D7D0: -0.011, 0x1D7D2: 0.127, 0x1D7D4: 0.048, 0x1D7D5: -0.164, 0x1D7D6: 0.011, 0x1D7E3: 0.01, 0x1D7E6: 0.073, 0x1D7E8: 0.084, 0x1D7EE: -0.016, 0x1D7F0: 0.068, 0x1D7F2: 0.056, 0x1D7F5: -0.016, 0x1D7F7: 0.015, 0x1D7F8: -0.011, 0x1D7F9: -0.015, 0x1D7FA: 0.06, 0x1D7FC: 0.054, 0x1D7FD: -0.184 }, bold: { 0x20D7: -0.264 }, italic: { 0x237: 0.083 }, 'bold-italic': { 0x131: -0.012, 0x237: 0.063 }, fraktur: { 0x2A: 0.148, 0x32: -0.01, 0x34: 0.103, 0x36: 0.068, 0x37: -0.147, 0x38: 0.011 }, 'sans-serif': { 0x237: 0.013 }, 'bold-sans-serif': { 0x237: 0.015 }, 'sans-serif-italic': { 0x131: 0.083, 0x237: 0.097 }, '-tex-calligraphic': { 0x41: 0.274, 0x42: 0.09, 0x43: 0.135, 0x44: 0.06, 0x45: 0.143, 0x46: 0.266, 0x47: 0.164, 0x48: 0.163, 0x49: 0.159, 0x4A: 0.219, 0x4B: 0.173, 0x4C: 0.249, 0x4D: 0.128, 0x4E: 0.121, 0x4F: 0.166, 0x50: 0.099, 0x51: 0.124, 0x52: 0.123, 0x53: 0.139, 0x54: 0.112, 0x55: 0.06, 0x56: 0.042, 0x57: 0.035, 0x58: 0.121, 0x59: 0.083, 0x5A: 0.033 }, '-tex-bold-calligraphic': { 0x41: 0.283, 0x42: 0.101, 0x43: 0.15, 0x44: 0.045, 0x45: 0.151, 0x46: 0.151, 0x47: 0.177, 0x48: 0.178, 0x49: 0.199, 0x4A: 0.26, 0x4B: 0.196, 0x4C: 0.259, 0x4D: 0.115, 0x4E: 0.139, 0x4F: 0.183, 0x50: 0.126, 0x51: 0.138, 0x52: 0.133, 0x53: 0.141, 0x54: 0.144, 0x55: 0.07, 0x56: 0.035, 0x57: 0.057, 0x58: 0.125, 0x59: 0.079, 0x5A: 0.133, 0x131: -0.012, 0x237: 0.063 }, '-tex-oldstyle': { 0x42: -0.098, 0x43: 0.146, 0x44: -0.139, 0x45: -0.025, 0x46: -0.018, 0x47: 0.115, 0x4A: 0.06, 0x4B: -0.011, 0x4C: -0.119, 0x50: -0.09, 0x52: -0.134, 0x53: 0.052, 0x58: -0.014, 0x5A: 0.011 }, '-tex-variant': { 0x3F0: -0.015 } }; // eslint-enable for (const [ variant, charToSkew ] of Object.entries(mathjaxTexSkewData)) { const { chars } = font.variant[variant]; for (const [ char, skew ] of Object.entries(charToSkew)) { chars[char][3].sk = skew; // eslint-disable-line no-magic-numbers } } } }, }, tex: { packages: { '[+]': [ 'mathtools' ] }, processEscapes: false, }, }; ```
[2] Production use case Ember JS framework that loads many learning tools. One of the learning tools adds a `div` with class `disable-lazy-typesetting` containing latex, then request typesetting from a custom typesetting module, then awaits typesetting, then measures the height of the latex to figure out how tall to make that learning tool's container. The custom typesetting module loads MathJax when needed and then periodically typesets batched requests.
[3] Production repro steps Immediately leave a refreshed tab, wait a while (5-10 seconds?), then return to the tab. And that was only somewhat reliable in FF and Safari... not reliable at all in Chrome.
dpvc commented 9 months ago

OK, it does seem pretty complicated.

I see that you are still using the alpha.1 version, and I'm wondering if you have tried beta.4 yet. Some of your issues are fixed there, I believe, so that might simplify your configuration.

AlexEdgcomb commented 9 months ago

@dpvc , thank you! A dev on my team was pushing me to do so yesterday, too. So, I guess it's time to try beta.4!

dpvc commented 9 months ago

Oh, I meant to say that I was sorry you took 8 hours to come up with the version you sent, though I appreciate it, as it made understanding it much easier for me.

dpvc commented 9 months ago

OK, I figured out why the math was being typeset even though typeset: false is set. It turns out that by setting the menu option for the assistive MathML extension, that requires the menu to load that extension itself, and when the menu loads an extension, it also does a re-render action. That was causing the typeset to occur.

I have made a PR to improve the handling of extensions in the menu code, so the initial rendering will not occur of typeset: false is in effect.