Rendering Error Javascript Event

186 views
Skip to first unread message

Stephan Claus

unread,
May 11, 2012, 9:02:18 AM5/11/12
to mathja...@googlegroups.com
Hello,

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
stephan 

Davide P. Cervone

unread,
May 14, 2012, 8:18:08 PM5/14/12
to mathja...@googlegroups.com
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!

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

rasc...@gmail.com

unread,
May 19, 2012, 10:06:40 AM5/19/12
to mathja...@googlegroups.com
Hello, world !
Thanks for MathJax !

I need that too.
The method you proposed doesn't work for me, unfortunately.
The overriden method doesn't get called.

I solved it for me, using an ugly hack, of which I would be happy
to replace it, with the clean method you showed.

It goes along the lines of this (using YUI3 as my browser normalizer of choice [ http://yuilibrary ])
and makes use of the fact, that, in case of an error, an element with class merror, is generated.
It is easy to translate it to any other "Ajax"-library, or by using the DOM directly:

var tex = ...,       // some tex as a string out of a textarea or so
     html = ['<div>', tex, '</div>'].join(''),
     node = Y.Node.create(html);
MathJax.Hub.Queue(['Typeset', MathJax.Hub, n.getDOMNode()]);
MathJax.Hub.Queue(function () {
    if (n.all('.merror').size() > 1) {        // has at least one element a class of merror ?
       Y.log('boom');  // then handle the error yourself
    } else {
       Y.one('body').append(n);       // otherwise just show the node
    }
});

CAVE: That is a dirty hack.

Heinz.

raschedh

unread,
May 19, 2012, 10:10:26 AM5/19/12
to mathja...@googlegroups.com
I should add the relevant portition of my conf:

TeX: {
    noErrors: {
      disabled: true
    },
    noUndefined: {
      disabled: true
    }
}

and a nonbroken link:

raschedh

unread,
May 19, 2012, 10:51:06 AM5/19/12
to mathja...@googlegroups.com
Sorry for all the errors in my Code, folks !

Jetzt aber:

var tex = ...,       // some tex as a string out of a textarea or so
     html = ['<div>', tex, '</div>'].join(''),
     node = Y.Node.create(html);
MathJax.Hub.Queue(['Typeset', MathJax.Hub, node.getDOMNode()]);
MathJax.Hub.Queue(function () {
    if (node.all('.merror').size() > 0) {        // has at least one element a class of merror ?
       Y.log('boom');  // then handle the error yourself
    } else {
       Y.one('body').append(node);       // otherwise just show the node
    }
});

Davide P. Cervone

unread,
May 21, 2012, 9:55:54 AM5/21/12
to mathja...@googlegroups.com
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).
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


On May 19, 2012, at 10:06 AM, <rasc...@gmail.com>

raschedh

unread,
May 30, 2012, 8:11:19 AM5/30/12
to mathja...@googlegroups.com
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


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.

raschedh

unread,
May 30, 2012, 8:24:25 AM5/30/12
to mathja...@googlegroups.com
Just to clarify:

Well, what those two callbacks receive would, of  course, be a function of success and failure:
The failure callback would receive your data object for example.
The success callback maybe only  the node.

raschedh

unread,
May 30, 2012, 8:39:22 AM5/30/12
to mathja...@googlegroups.com
Ahrg ! When will I learn to post stuff ?:
Clarifying again and for the last time:

I do not want the second question to be concerned about the Tex-Errors for
the first question *and* I do not want a controller-like module, that dispatches
all TeX-Errors to the modules.

I like encapsulation and the event-based system of the browser a lot.

Davide P. Cervone

unread,
Jun 8, 2012, 7:06:00 AM6/8/12
to mathja...@googlegroups.com
> 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

Reply all
Reply to author
Forward
0 new messages