mathjax / MathJax-node

MathJax for Node
Apache License 2.0
615 stars 97 forks source link

exports.start() accepts a callback to get MathJax #320

Closed beeplin closed 7 years ago

beeplin commented 7 years ago

(moved from #319, based on develop branch)

In #318 we discussed how to access the MathJax object in mathjax-node. I suggest using the existing start() api to do this:

//  E.g.
//     mjAPI.start(function (MathJax) {
//       MathJax.Hub.Register.StartupHook('XXX Ready', function () {
//         // something you need to run when XXX is ready
//       }
//     });
//
exports.start = function (callback) {
  RestartMathJax();
  exports.typeset({}, function () {
    callback && callback(window.MathJax);
  });
}

Currently the start() API is merely used in practice, because the first typeset() already does its job. Therefore I think it may be a reasonable design to make use of start() to access the MathJax object.

dpvc commented 7 years ago

It's an interesting idea. I would suggest this change, however:

exports.start = function (callback) {
  RestartMathJax();
  if (callback) {
    exports.typeset({}, function () {callback(MathJax)});
  }
}

so that you only make the typeset call when there actually is a callback. I also don't think you need the window. since there is a MathJax variable in the module that holds window.MathJax (though I admit I haven't actually tested my suggested change above).

I'm not sure about the timing for the callback, however, as it may be too late for some actions to be performed. In general, configuration should occur before MathJax processes any math (i.e., before the input and output jax are loaded), but this will be after the initial typeset pass that loads the jax.

It might be better to have something in the config object, similar to AuthorInit that MathJax node calls during its initialization (i.e., during its own AuthorInit call). That way, you are sure to be able to do all the configuration that is required before the jax are loaded.

For example, the AuthorInit call from the user's config object could be cached (and removed), and then called from the MathJax AuthorInit function. It would probably have to pass the MathJax variable, as you do.

pkra commented 7 years ago

As I wrote in the issue, I'd favor restricting such modifications to MathJax extensions.

dpvc commented 7 years ago

I'd favor restricting such modifications to MathJax extensions.

Agreed. That was going to be my suggestion there as well. You should even be able to use a file:// URL to load a local extension without having to put it into the MathJax folder hierarchy.

beeplin commented 7 years ago

@dpvc I agree that the timing of using typeset() might be too late. It could be like this to make it run earlier:

exports.start = function (callback) {
  RestartMathJax();
  if (!callback) return;
  oldInit = window.MathJax.AuthorInit.bind(window.MathJax)
  window.MathJax.AuthorInit = function () {
    oldInit();
    callback(window.MathJax);
  }
}

But anyway, I also agree with @pkra that the best way to do this is via a mathjax extension. Anyway, thanks guys for your wonderful job~