MathJax.tex2mmlPromise in pageReady()

7 views
Skip to first unread message

Alex Jordan

unread,
Dec 21, 2025, 1:11:10 AM12/21/25
to MathJax Users
At this sample page:

I have taken PreTeXt's sample article and I'm trying to adjust it to load math macros in a different way than what PreTeXt has always done (which is to load them inside math delimiters somewhere early in the page). There's a lot going on in this page for all that PreTeXt does, and the only part I have modified is that I've inserted lines 93-107:

MathJax.tex2mmlPromise(String.raw`
...a bunch of tex commands defining macros...
`);

I'm getting an error in the console:
Uncaught (in promise) TypeError: l.item.renderMath is not a function

and the page is clearly not succeeding to load the macros being defined here. This is with MathJax3. But also PreTeXt has a flag to try using MathJax4, and when I try that with the same changes, I get a similar error, just with a different name on some indexed variable:
Uncaught (in promise) TypeError: i.item.renderMath is not a function

Is it easy to see what I'm doing wrong here?

Davide Cervone

unread,
Jan 3, 2026, 9:51:49 AM (9 days ago) Jan 3
to mathja...@googlegroups.com
Alex:

Sorry to have left this so long.  I had forgotten about it and only now just saw it again.

In your MathJax configuration, you have specified render actions:

             "renderActions": {
                "findScript": [
                10,
                function(doc) {
                    document.querySelectorAll('script[type^="math/tex"]').forEach(function(node) {
                        var display = !!node.type.match(/; *mode=display/);
                        var math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
                        var text = document.createTextNode('');
                        node.parentNode.replaceChild(text, node);
                        math.start = {
                            node: text,
                            delim: '',
                            n: 0
                        };
                        math.end = {
                            node: text,
                            delim: '',
                            n: 0
                        };
                        doc.math.push(math);
                    });
                },
                ""
                ]
            }

Change the empty ring before the close square bracket to () => {} instead and I think that will take care of it.

Davide


--
You received this message because you are subscribed to the Google Groups "MathJax Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mathjax-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mathjax-users/CA%2BR-jrdsY5GhDAaCOuhX%2BswA9iepVyPba1NqoTORvgrC2j758g%40mail.gmail.com.

Alex Jordan

unread,
Jan 7, 2026, 1:21:22 AM (5 days ago) Jan 7
to mathja...@googlegroups.com
Thanks Davide, I've got it working! Actually I now believe that in several earlier stages of our discussion about this (including off-list) it would have been working. But I was testing with a block of code to run at startup that happened to include `\require{cancel}` and `require{extpfeil}`. As things were not working and I tried to minimize the situation, once I removed those from the startup code, it all started working. Should I not be surprised about this? Using `\require{...}` does special things, is that right?

Davide Cervone

unread,
7:23 AM (5 hours ago) 7:23 AM
to mathja...@googlegroups.com
I'm glad you got it working.  Yes, \require does do special things.  In particular, it has to load the require extension, and that is an asynchronous action, which is where the "Promise" part of "tex2mmlPromise()" comes in. Because this function returns a promise, you need to be sure to wait for that promise before allowing MathJax to typeset the page (otherwise the definitions won't be in place when the page is rendered).  It looks like your page (linked in your original page below) has the order reversed:  you wait for the initial typesetting before defining the macros.  That is, you have

pageReady() {
                return MathJax.startup.defaultPageReady().then(function() {
                    MathJax.tex2mmlPromise(String.raw`
...
    `)
});
}

The defaultPageReady() function does the initial typesetting, and since you wait for that before the tex2mmlPromise(), that is the wrong order.  It should be

return MathJax.tex2mmlPromise(
  String.raw`
    ...
  `
).then(MathJax.startup.defaultPageReady)
 .then(rsMathReady);

so that the definitions are in place before the startup typesetting is performed.

Note also that your code doesn't wait for the tex2mmlPromise to resolve (the function that calls it would have had to return the promise in order for the .then() to have waited for it), so the .then() will resolve before tex2mmlPromise() executes.  Because the tex2mmlPromise commands include \require{cancel}, that will guarantee that other code will run before the definitions are processed.

I think if you handle the promises correctly, you should be able to use \require within your definitions.

Davide


Reply all
Reply to author
Forward
0 new messages