Skip to content

Rendering Error Javascript Event

Davide P. Cervone edited this page May 28, 2013 · 3 revisions

From https://groups.google.com/d/msg/mathjax-users/ct4drdifuyI/qPJBqdG6aFQJ


I have the following problem:

When visiting a site with math content from a mobile device i sometimes get a Math Rendering Error for all included math content.

I could not reproduce this error when using a desktop pc, so I think it has something to do with the rendering time or something like a max script time of the device.

Now I want to provide a "Load again" button only if this error occured - is there a Javascript Event which I could use for this idea? I just found the preferences to show different styled text when this error occurs, but not if some event is fired.

Thanks for your help and best regards


I included a lot of new signals for error conditions in v2.0 of MathJax, but apparently didn't think to include one for the Math Processing Error! Argh!

Edit: There is a "Math Processing Error" signal in v2.1 and later, so there is no need for the following example any longer. Simply register an MessageHook for "Math Processing Error".

But there is still a way to do this. You could add

<script type="text/x-mathjax-config">
(function () {
  var FORMATERROR = MathJax.Hub.formatError;
  MathJax.Hub.formatError = function () {
    ... your code here ...
    return FORMATERROR.apply(this,arguments);
  }
})();
</script>

to have some action performed when the [Math Processing Error] is generated. If you want it to occur only once, then use

<script type="text/x-mathjax-config">
(function () {
  var FORMATERROR = MathJax.Hub.formatError;
  MathJax.Hub.formatError = function () {
    ... your code here ...
    this.formatError = FORMATERROR;
    return FORMATERROR.apply(this,arguments);
  }
})();
</script>

so that the second and subsequent calls will go to the original code again.

Hope that helps.

Davide


And later for TeX processing error messages


Heinz:

I think you may be looking to trap a different type of error from what Stephan was asking about. He was trapping the "[Math Processing Error]", but your code seems to be after the cases where there are TeX error messages. Those are not the same: the TeX error messages are properly reporting syntax errors in the page's TeX code, while the Math Processing Error is indicating a failure of the MathJax code itself. The Math Processing Errors do not produce merror elements, so that's why I think your code is after the TeX errors.

If you are after the TeX errors, then there is a better way to get access to them, as MathJax produces a signal when there is a TeX error (it should produce one for Math Processing Error as well, but apparently that was left out -- I will add it in the next version [note: it is in v2.1 and later]). So you can use

<script type="text/x-mathjax-config">
MathJax.Hub.Register.MessageHook("TeX Jax - parse error", function (data) {
  ... your code to handle the error ...
});
</script>

somewhere before the script that loads MathJax.js itself. This will set up a function that is called whenever there is a TeX parsing error, and pass you data about the error. In this case, data[0] will be the "TeX Jax - parse error" string, data[1] will be the actual error message, data[2] will be the TeX code that has the parsing error, data[3] will be true/false depending on whether the math is a display or in-line math formula, and data[4] will be the DOM script element that holds this math expression.

Perhaps that will be what you need.


Davide,

You're right: I want to know, when there is a TeX-error, indeed. I misinterpreted the api-docs for formatError at http://www.mathjax.org/docs/2.0/api/hub.html Thank you for clarifying !

Your solution works. Thank for you that. On the other hand, I have difficulties with it and apologize in advance if I didn't read the apidocs carefully enough.

The thing is: Your solution forces me to have one global handler for TeX-errors. I need to dispatch manually than to the part of the program that is responsible for that. I could, for example, dispatch on the node.

An example for my problem would be a page with multiple areas to type TeX in, like in this page.

I do not want the module for the second question be bothered with the tex errors of the first.

What I would really like, is an API that makes the Typesetting feel like an ordinary HTTP request, and so it would feel natural to any frontend-building person.

What I mean is, that I would not only pass the node to be typeset to MathJax.Hub.Typeset and a callback, but an object that has two callbacks, one that is called in case of success, the other in case of failure and those callbacks receive the data object from your solution. So I could encapsulate better.

Sorry again, if that is all there, already! I am on a tight schedule, here...

Thanks for your help,

Heinz.


What I would really like, is an API that makes the Typesetting feel like an ordinary HTTP request, and so it would feel natural to any frontend-building person.

What I mean is, that I would not only pass the node to be typeset to MathJax.Hub.Typeset and a callback, but an object that has two callbacks, one that is called in case of success, the other in case of failure > and those callbacks receive the data object from your solution. So I could encapsulate better.

Here are two different approaches to doing that. The first simply checks the typeset math to see if it is an error after it is typeset:

<!DOCTYPE html>
<html>
<head>
<title>Encapsulate Trapping of TeX errors -- Method I</title>
<script type="text/x-mathjax-config">
//
//  Turn off noErrors extension
//
MathJax.Hub.Config({
  TeX: {noErrors: {disabled: true}}
});
//
//  Call this to typeset the contents of the node, with success() being called
//  if the math typeset properly, and failure() being called if there was a
//  TeX error during the typeset
//
function EncapsulatedTypeset (node,success,failure) {
  var HUB = MathJax.Hub;
  return HUB.Typeset(node,function () {
    var math = HUB.getAllJax(node)[0];
    if (!math.texError) {success(node,math)}
      else {failure(node,math,math.root.HTMLspanElement().textContent)}
  });
}
//
//  Service routines to set the math, report success, and report failure
//
function SetMath(TeX) {document.getElementById("output").innerHTML = TeX}
function Success(node,math) {alert("Math OK!")}
function Failure(node,math,msg) {alert("TeX Error: "+msg)}
//
//  Queue some actions that set the math and typeset with success/failure messages
//
MathJax.Hub.Queue(
  [SetMath,"$$x+1\\\\over {1-x$$"],  // has an error
  [EncapsulatedTypeset,"output",Success,Failure],
  [SetMath,"$$x+1\\\\over 1-x$$"],  // no error
  [EncapsulatedTypeset,"output",Success,Failure]
);
</script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<p id="output"></p>
</body>
</html>

Note that we turn off the noErrors extension, since otherwise the error message returned would be the original TeX code.

The second uses the signal handler to record the error message for later use:

<!DOCTYPE html>
<html>
<head>
<title>Encapsulate Trapping of TeX errors -- Method II</title>

<script type="text/x-mathjax-config">
(function () {
  var texError = "";       // stores the tex error
  var HUB = MathJax.Hub;   // shorthand for MathJax.Hub
  //
  //  Register a hook that records the tex error message for later
  //
  HUB.Register.MessageHook("TeX Jax - parse error", function (data) {texError = data[1]});
  //
  //  Call this to typeset the contents of the node, with success() being called
  //  if the math typeset properly, and failure() being called if there was a
  //  TeX error during the typeset
  //
  window.EncapsulatedTypeset = function (node,success,failure) {
    texError = "";
    return HUB.Typeset(node,function () {
      var math = HUB.getAllJax(node)[0];
      if (texError == "") {success(node,math)} else {failure(node,math,texError)}
    });
  }
})();
//
//  Service routines to set the math, report success, and report failure
//
function SetMath(TeX) {document.getElementById("output").innerHTML = TeX}
function Success(node,math) {alert("Math OK!")}
function Failure(node,math,msg) {alert("TeX Error: "+msg)}
//
//  Queue some actions that set the math and typeset with success/failure messages
//
MathJax.Hub.Queue(
  [SetMath,"$$x+1\\\\over {1-x$$"],  // has an error
  [EncapsulatedTypeset,"output",Success,Failure],
  [SetMath,"$$x+1\\\\over 1-x$$"],  // no error
  [EncapsulatedTypeset,"output",Success,Failure]
);
</script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<p id="output"></p>
</body>
</html>

Note that both methods assume there is only one math expression within the given node. If that is not the case, I'm not sure exactly how the success and failure should be handled (do you want success/failure called for each expression, or is it for the node as a whole?), so I'll let you work out the details in that case. You can loop through all the jax returned by MathJax.Hub.getAllJax(node) and call the succes/failure as appropriate in the first case, but would potentially have to record multiple error messages in the second case.

Davide

Clone this wiki locally