Await MathJax typeset before doing other actions

1,170 views
Skip to first unread message

gross...@gmail.com

unread,
Oct 31, 2019, 1:07:37 PM10/31/19
to MathJax Users
Hello,

I've read http://docs.mathjax.org/en/latest/advanced/synchronize.html and search this forum but I'm unable to wait until MathJax is done.
I'm using the following code:

<script type="text/javascript" src="mathjax/es5/tex-chtml-full.js"></script>
<script>
 
MathJax.startup.promise
   
.then(() => MathJax.typesetPromise())
   
.then(() => /* other actions once MathJax is done */)
</script>

And I get the following error:

Uncaught (in promise) TypeError: MathJax.typesetPromise is not a function

I've tried some variations but at this point I'm just trying random stuff :(
I'm pretty sure it should be straight forward but I can't figure it out.


Thanks for your help.
Guillaume

gross...@gmail.com

unread,
Nov 1, 2019, 7:59:00 AM11/1/19
to MathJax Users
For reference, we were using the following code:

// defer relayouting by 'Paged' until 'MathJax' rendering is complete
// otherwise formulas wouldn't be replaced and content height can't be calculated by 'Paged'
// 'MathJax' needs to be loaded before 'Paged' to make this work
window
.PagedConfig = {
  before
: () => {
   
return new Promise((resolve) => {
      window
.MathJax.Hub.Queue(resolve);
   
})
 
}
}


The before function from Paged expects a promise that will delay the layouting but we need to wait until MathJax rendering is completed.
I've found a "workaround" but I'm pretty sure that's not the right way to do it:

const mathJaxReadyPromise = new Promise((resolve) => {
  window
.MathJax = {
    tex
: {
      inlineMath
: [['\\\\(', '\\\\)']],
      displayMath
: [['\\\\[', '\\\\]']],
      processEscapes
: false,
      tags
: "${eqnumsValue}"
   
},
    options
: {
      ignoreHtmlClass
: 'nostem|noasciimath',
      renderActions
: {
        adjustDisplay
: [25, (doc) => {for (math of doc.math) {adjustDisplay(math, doc)}}, adjustDisplay]
     
}
   
},
    startup
: {
      ready
: () => {
       
MathJax.startup.defaultReady()
       
MathJax.startup.promise.then(() => resolve())
     
}
   
},
    asciimath
: {
      delimiters
: [['\\\\$', '\\\\$']]
   
},
    loader
: {load: ['input/asciimath', 'output/chtml', 'ui/menu']}
 
}
})

// defer relayouting by 'Paged' until 'MathJax' rendering is complete
// otherwise formulas wouldn't be replaced and content height can't be calculated by 'Paged'
// 'MathJax' needs to be loaded before 'Paged' to make this work
window
.PagedConfig = {
  before
: () => mathJaxReadyPromise
};



Guillaume

Davide Cervone

unread,
Nov 1, 2019, 10:49:30 PM11/1/19
to mathja...@googlegroups.com
I would say the following is perhaps the way to do it:

window.MathJax = {
    // your main configuration (with no startup block)
};

// defer relayouting by 'Paged' until 'MathJax' rendering is complete
// otherwise formulas wouldn't be replaced and content height can't be calculated by 'Paged' 
// 'MathJax' needs to be loaded before 'Paged' to make this work
window.PageConfig = {
  before: (() => {
    let pagedResolve;
    let pagedPromise = new Promise((resolve) => {pagedResolve = resolve});
    
    MathJax.startup = {
      ready: () => {
        MathJax.startup.defaultReady();
        MathJax.startup.promise.then(() => pagedResolve());
      }
    };
    
    return () => pagedPromise;
  })()
};

This sets up a promise (pagedPromise) and saves the resolve function (pagedResolve), which MathJax will call when it is finished processing the page.  The before() function is set to return the pagedPromise.  This doesn't require any additional globals, like your mathjaxReadyPromise.

See if that does the trick.

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 on the web visit https://groups.google.com/d/msgid/mathjax-users/6a5c5113-f7a9-4409-b1f5-312b368be142%40googlegroups.com.

gross...@gmail.com

unread,
Nov 3, 2019, 5:41:55 AM11/3/19
to MathJax Users
I think the PageConfig.before function is called after MathJax initialization so it's not working in my context.
I've ended up with the following:

// main configuration (without startup block)
window.MathJax = {
}

;(() => {

 
const mathJaxReadyPromise = new Promise((resolve) => {

   
MathJax.startup = {
      ready
: () => {
       
MathJax.startup.defaultReady()

       
MathJax.startup.promise.then(resolve)

     
}
   
}
 
})
 
 
// defer relayouting by 'Paged' until 'MathJax' rendering is complete
 
// otherwise formulas wouldn't be replaced and content height can't be calculated by 'Paged'
 
// 'MathJax' needs to be loaded before 'Paged' to make this work
  window
.PagedConfig = {
    before
: () => mathJaxReadyPromise
 
}
})()


Do you think it could be useful to add a reference to a promise which will be resolved when the startup and the initial typesetting is completed?
In this case the code would be:

window.PageConfig = {
  before
: () => MathJax.startup.initial
};

(ignore the naming)

If you do, I can open an issue https://github.com/Mathjax/MathJax-src and try to provide an implementation :)


Have a nice day,
Guillaume

Davide Cervone

unread,
Nov 4, 2019, 7:24:24 PM11/4/19
to mathja...@googlegroups.com
> I think the PageConfig.before function is called after MathJax initialization so it's not working in my context.


The code I gave should work whether PageCobnfig.before() is called before or after MathJax initialization (at least it does for me). So I'm not sure what went wrong for you.

Glad you found something that works.

> Do you think it could be useful to add a reference to a promise which will be resolved when the startup and the initial typesetting is completed?

I'm thinking that MathJax.startup.promise should be used for that (it doesn't currently work that way if you call it before initialization is complete). I'll think about how best to accomplish that.

Davide


Sava Maksimović

unread,
Sep 11, 2021, 6:53:48 PM9/11/21
to MathJax Users
If problem is "Do something after MatJax finished his job", the solution is
 window.MathJax = {
             startup: {
                ready: () => {
                    MathJax.startup.defaultReady();
                    MathJax.startup.promise.then(() => {
                        window.PagedPolyfill.preview(); /* do this for example*/
                    });
                }
            }
};

Reply all
Reply to author
Forward
0 new messages