Catching errors

139 views
Skip to first unread message

Michal Frackowiak

unread,
Jun 2, 2011, 8:06:44 AM6/2/11
to MathJax Users
Hi,

is there a way to catch parsing errors from processed TeX elements?
Our current usage is that we process each element of class "math-
equation" individually using jQuery and LiveQuery, something like:

$('.math-equation').livequery(function(){
var el = this;
MathJax.Hub.Queue(["Typeset", MathJax.Hub, el]);
}

At this point it would be great to know which elements failed, either
completely, or contain unsupported (red) TeX commands.

Thanks for help,
Michal

Davide P. Cervone

unread,
Jun 6, 2011, 12:05:31 PM6/6/11
to mathja...@googlegroups.com
> Is there a way to catch parsing errors from processed TeX elements?

You could hook into the same mechanisms that the noErrors and
noUndefined extensions use. I'm assuming that you are using one of
the predefined combined configuration files (e.g., TeX-AMS-
MML_HTMLorMML), which load noErrors and noUndefined for you. If not,
you might need to change the examples below slightly depending on your
configuration.

If you don't mind undefined macros showing an error message, then it
is pretty easy to do something like

<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook("TeX noUndefined Ready",function () {

var TEX = MathJax.InputJax.TeX;
var formatError = TEX.formatError;

TEX.Augment({
formatError: function (err,math,displaystyle,script) {
alert("Error in math: "+math+"\nMessage: "+err.message.replace(/
\n.*/,""));
return formatError.apply(this,arguments);
}
});

TEX.Parse.Augment({
csUndefined: function (name) {
TEX.Error("Undefined control sequence "+name);
}
});

});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML
"></script>

which hooks into the TeX input jax's error mechanisms. The
formatError routine is called when the TeX input jax traps an error,
and it is passed the error object (err), the TeX string that was being
processed (math), a true/false value indicating whether the math is in
displaystyle or not (displaystyle), and the script element in the DOM
that stores the math in the page (script).

In this example, we simply produce an alert using the data we
received, and then do the original formatError routine, so we have
essentially inserted the alert into the error processing. You can, of
course, do whatever it is you need to do instead of the alert. Note,
however, that at this point, the math (or the error message) has not
yet been displayed, and so if you need to do something that relies on
the math output being present, you might need to use MathJax.Hub.Queue
to synchronize your code with that output.

The csUndefined function is called when the TeX input jax sees a
control sequence that it doesn't recognize. In this case, we throw an
error, which eventially ends up in the formatError routine, so the
same alert handles both issues. But this also means that equations
containing undefined macros will show as errors rather than as typeset
math with red macro names.

If you want to have undefined macros continue to show as red macro
names and still trap those errors, you have to work a bit harder.
Here is one approach:

<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook("TeX noUndefined Ready",function () {

var TEX = MathJax.InputJax.TeX;

var csUndefined = TEX.Parse.prototype.csUndefined,
formatError = TEX.formatError,
prefilterMath = TEX.prefilterMath,
postfilterMath = TEX.postfilterMath;

var active, badMacros, badList;

TEX.Augment({
formatError: function (err,math,displaystyle,script) {
badList = []; // clear this so only one message is produced
alert("Error in math: "+math+"\nMessage: "+err.message.replace(/
\n.*/,""));
return formatError.apply(this,arguments);
},
prefilterMath: function (math,displaystyle,script) {
active = math; badMacros = {}; badList = [];
return prefilterMath.apply(this,arguments);
},
postfilterMath: function (math,displaystyle,script) {
if (badList.length)
{alert("Error in math: "+active+"\nUndefined macros:
"+badList.sort().join(", "))}
return postfilterMath.apply(this,arguments);
}
});

TEX.Parse.Augment({
csUndefined: function (name) {
if (!badMacros[name]) {badMacros[name] = true;
badList.push(name)}
return csUndefined.apply(this,arguments);
}
});

});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML
"></script>

Here, the csUndefined function keeps track of the names of undefined
macros, and we also hook into the TeX input jax's prefilter in order
to start with an empty list of bad macros (and save the initial TeX
string for use in the error message), and its postfilter to check if
bad macros were found and report an error in that case. This takes a
bit more machinery, but it has the advantage of reporting ALL the bad
macros in an equation rather than just the first one. Care is taken
not to report the same macro twice if it is used more than once in the
same equation, and if some TeX syntax error occurs, the bad-macro
values are cleared in order to generate only a single error message
from each equation.


> Our current usage is that we process each element of class "math-
> equation" individually using jQuery and LiveQuery, something like:
>
> $('.math-equation').livequery(function(){
> var el = this;
> MathJax.Hub.Queue(["Typeset", MathJax.Hub, el]);
> }

You should be able to do

$('.math-equation').livequery(function(){
MathJax.Hub.Queue(["Typeset", MathJax.Hub, this]);
};

without the need of the "el" variable.

Anyway, I hope one of these suggestions is what you are looking for.

Davide

Message has been deleted

racoon

unread,
Nov 27, 2015, 11:41:40 AM11/27/15
to MathJax Users
 Hi,

I just tried to use the scripts above (and nothing else). But I end up with a "SyntaxError: unterminated regular expression literal" java script error. Am I missing something?

Daniel

Davide P. Cervone

unread,
Dec 26, 2015, 6:28:48 PM12/26/15
to mathja...@googlegroups.com
It is probably the newline in the replace() call.  It should be 

alert("Error in math: "+math+"\nMessage: "+err.message.replace(/\n.*/,""));

with no newline in the regular expression.  Probably an artifact of a message being wrapped automatically somewhere along the line.

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.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages