Skip to content

Commit 884c8b2

Browse files
committed
Merge branch 'refactor'
2 parents bdb4b62 + eb9a5fa commit 884c8b2

File tree

1 file changed

+104
-70
lines changed

1 file changed

+104
-70
lines changed

lib/mj-single.js

Lines changed: 104 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var defaults = {
6060
speakRuleset: "mathspeak", // set speech ruleset (default (chromevox rules), mathspeak)
6161
speakStyle: "default", // set speech style (mathspeak: default, brief, sbrief)
6262

63-
timeout: 5 * 1000, // 5 second timeout before restarting MathJax
63+
timeout: 10 * 1000, // 10 second timeout before restarting MathJax
6464
};
6565

6666
//
@@ -361,21 +361,30 @@ function AddError(message,nopush) {
361361
//
362362
function GetMML(result) {
363363
if (!data.mml && !data.speakText) return;
364-
var mml, jax = MathJax.Hub.getAllJax()[0];
364+
var jax = MathJax.Hub.getAllJax()[0];
365365
try {result.mml = jax.root.toMathML('',jax)} catch(err) {
366366
if (!err.restart) {throw err;} // an actual error
367367
return MathJax.Callback.After(window.Array(GetMML,result),err.restart);
368368
}
369-
if (data.speakText) {
370-
speech.setupEngine({semantics: true, domain: data.speakRuleset, style: data.speakStyle});
371-
jax.root.alttext = result.speakText = speech.processExpression(result.mml);
369+
}
370+
371+
//
372+
// Creates the speech string and updates the MathML to include it, if needed
373+
//
374+
function GetSpeech(result) {
375+
if (!data.speakText) return;
376+
speech.setupEngine({semantics: true, domain: data.speakRuleset, style: data.speakStyle});
377+
result.speakText = speech.processExpression(result.mml);
378+
if (data.mml) {
379+
var jax = MathJax.Hub.getAllJax()[0];
380+
jax.root.alttext = result.speakText;
372381
if (jax.root.attrNames) {jax.root.attrNames.push("alttext")}
373382
result.mml = jax.root.toMathML('',jax);
374383
}
375384
}
376385

377386
//
378-
// Create SVG output and PNG output, if requested
387+
// Create SVG output and IMG output, if requested
379388
//
380389
function GetSVG(result) {
381390
if (!data.svg && !data.png && !data.img) return;
@@ -389,12 +398,11 @@ function GetSVG(result) {
389398
//
390399
if (data.speakText) {
391400
ID++; var id = "MathJax-SVG-"+ID;
392-
var speak = result.speakText;
393401
svg.setAttribute("role","math");
394402
svg.setAttribute("aria-labelledby",id+"-Title "+id+"-Desc");
395403
for (var i=0, m=svg.childNodes.length; i < m; i++)
396-
{svg.childNodes[i].setAttribute("aria-hidden",true);}
397-
var node = MathJax.HTML.Element("desc",{id:id+"-Desc"},[speak]);
404+
svg.childNodes[i].setAttribute("aria-hidden",true);
405+
var node = MathJax.HTML.Element("desc",{id:id+"-Desc"},[result.speakText]);
398406
svg.insertBefore(node,svg.firstChild);
399407
node = MathJax.HTML.Element("title",{id:id+"-Title"},["Equation"]);
400408
svg.insertBefore(node,svg.firstChild);
@@ -420,56 +428,41 @@ function GetSVG(result) {
420428
//
421429
// Add the requested data to the results
422430
//
423-
if (data.svg) {result.svg = svgdata}
431+
if (data.svg) result.svg = svgdata;
432+
if (data.png) result.svgfile = svgfile;
424433
if (data.img) {
425434
if (data.svg) result.svg = svgfile;
426435
result.img = '<img src="file.svg" style="'+svg.style.cssText+
427436
" width:"+svg.getAttribute("width")+"; height:"+svg.getAttribute("height")+';">';
428437
}
438+
}
439+
440+
//
441+
// Create the PNG file asynchronously, reporting errors.
442+
//
443+
function GetPNG(result) {
444+
var svgfile = result.svgfile; delete result.svgfile;
429445
if (data.png) {
430-
var callback = MathJax.Callback(function () {}); // for synchronization with MathJax
431-
fs.writeFileSync(tmpfile+".svg",svgfile);
432446
var batikCommand = fmt("java -jar %s -dpi %d '%s.svg'",BatikRasterizerPath,data.dpi,tmpfile);
433-
exec(batikCommand, function (err,stdout,stderr) {
434-
if (err) {AddError(err)} else {
435-
var buffer = fs.readFileSync(tmpfile+".png");
436-
result.png = "data:image/png;base64," + buffer.toString('base64');
437-
fs.unlinkSync(tmpfile+".svg"); fs.unlinkSync(tmpfile+".png");
438-
callback();
439-
}
447+
var synch = MathJax.Callback(function () {}); // for synchronization with MathJax
448+
var check = function (err) {if (err) {AddError(err.message); synch(); return true}}
449+
var tmpSVG = tmpfile+".svg", tmpPNG = tmpfile+".png";
450+
fs.writeFile(tmpSVG,svgfile,function (err) {
451+
if (check(err)) return;
452+
exec(batikCommand, function (err,stdout,stderr) {
453+
if (check(err)) {fs.unlinkSync(tmpSVG); return}
454+
fs.readFile(tmpPNG,null,function (err,buffer) {
455+
result.png = "data:image/png;base64,"+(buffer||"").toString('base64');
456+
fs.unlinkSync(tmpSVG); fs.unlinkSync(tmpPNG);
457+
check(err); synch();
458+
});
459+
});
440460
});
441-
return callback; // This keeps the queue from continuing until the exec() is complete
461+
return synch; // This keeps the queue from continuing until the readFile() is complete
442462
}
443463
}
444464

445-
//
446-
// When the expression is typeset,
447-
// clear the timeout timer, if any,
448-
// update the MathJax state,
449-
// return the result object, and
450-
// do the next queued expression
451-
//
452-
function TypesetDone(result) {
453-
if (timer) {clearTimeout(timer); timer = null}
454-
html.removeAttribute("xmlns:"+data.xmlns);
455-
var state = data.state;
456-
if (state) {
457-
var AMS = MathJax.Extension["TeX/AMSmath"];
458-
var GLYPH = MathJax.OutputJax.SVG.BBOX.GLYPH;
459-
state.AMS.startNumber = AMS.startNumber;
460-
state.AMS.labels = AMS.labels;
461-
state.AMS.IDs = AMS.IDs;
462-
state.mmlID = MathJax.ElementJax.mml.SUPER.ID;
463-
state.glyphs = GLYPH.glyphs;
464-
state.defs = GLYPH.defs;
465-
state.n = GLYPH.n;
466-
state.ID = ID;
467-
}
468-
if (errors.length) {result.errors = errors}
469-
callback(result);
470-
serverState = STATE.READY;
471-
StartQueue();
472-
}
465+
/********************************************************************/
473466

474467
//
475468
// Start typesetting the queued expressions
@@ -490,9 +483,8 @@ function StartQueue() {
490483
data = item[0]; callback = item[1];
491484
var delim = delimiters[data.format];
492485
var math = data.math;
493-
if (data.format !== "MathML") {
486+
if (data.format !== "MathML")
494487
math = math.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
495-
}
496488
content.innerHTML = delim[0]+math+delim[1];
497489
html.setAttribute("xmlns:"+data.xmlns,"http://www.w3.org/1998/Math/MathML");
498490

@@ -502,10 +494,7 @@ function StartQueue() {
502494
//
503495
var SVG = MathJax.OutputJax.SVG,
504496
TEX = MathJax.InputJax.TeX,
505-
MML = MathJax.ElementJax.mml,
506-
AMS = MathJax.Extension["TeX/AMSmath"],
507-
HUB = MathJax.Hub, HTML = MathJax.HTML,
508-
GLYPH = SVG.BBOX.GLYPH;
497+
HUB = MathJax.Hub;
509498

510499
SVG.defaultEx = data.ex;
511500
SVG.defaultWidth = data.width;
@@ -516,10 +505,38 @@ function StartQueue() {
516505
TEX.config.equationNumbers.autoNumber = data.equationNumbers;
517506

518507
//
519-
// Update the MathJax values from the state,
520-
// or clear them if there is no state.
521-
//
522-
var state = data.state;
508+
// Set the state from data.state or clear it
509+
//
510+
GetState(data.state);
511+
512+
//
513+
// Set up a timeout timer to restart MathJax if it runs too long,
514+
// Then push the Typeset call, the MathML, speech, SVG, and PNG calls,
515+
// and our TypesetDone routine
516+
//
517+
timer = setTimeout(RestartMathJax,data.timeout);
518+
HUB.Queue(
519+
$$("Typeset",HUB),
520+
$$(GetMML,result),
521+
$$(GetSpeech,result),
522+
$$(GetSVG,result),
523+
$$(GetPNG,result),
524+
$$(TypesetDone,result)
525+
);
526+
}
527+
528+
//
529+
// Update the MathJax values from the state,
530+
// or clear them if there is no state.
531+
//
532+
function GetState(state) {
533+
var SVG = MathJax.OutputJax.SVG,
534+
TEX = MathJax.InputJax.TeX,
535+
MML = MathJax.ElementJax.mml,
536+
AMS = MathJax.Extension["TeX/AMSmath"],
537+
HUB = MathJax.Hub, HTML = MathJax.HTML,
538+
GLYPH = SVG.BBOX.GLYPH;
539+
523540
if (state && state.AMS) {
524541
AMS.startNumber = state.AMS.startNumber;
525542
AMS.labels = state.AMS.labels;
@@ -540,21 +557,38 @@ function StartQueue() {
540557
TEX.resetEquationNumbers();
541558
MML.SUPER.ID = ID = 0;
542559
}
560+
}
543561

544-
//
545-
// Set up a timeout timer to restart MathJax if it runs too long,
546-
// Then push the Typeset call, the MathML and SVG calls, and our
547-
// TypesetDone routine
548-
//
549-
timer = setTimeout(RestartMathJax,data.timeout);
550-
HUB.Queue(
551-
$$("Typeset",HUB),
552-
$$(GetMML,result),
553-
$$(GetSVG,result),
554-
$$(TypesetDone,result)
555-
);
562+
//
563+
// When the expression is typeset,
564+
// clear the timeout timer, if any,
565+
// update the MathJax state,
566+
// return the result object, and
567+
// do the next queued expression
568+
//
569+
function TypesetDone(result) {
570+
if (timer) {clearTimeout(timer); timer = null}
571+
html.removeAttribute("xmlns:"+data.xmlns);
572+
var state = data.state;
573+
if (state) {
574+
var AMS = MathJax.Extension["TeX/AMSmath"];
575+
var GLYPH = MathJax.OutputJax.SVG.BBOX.GLYPH;
576+
state.AMS.startNumber = AMS.startNumber;
577+
state.AMS.labels = AMS.labels;
578+
state.AMS.IDs = AMS.IDs;
579+
state.mmlID = MathJax.ElementJax.mml.SUPER.ID;
580+
state.glyphs = GLYPH.glyphs;
581+
state.defs = GLYPH.defs;
582+
state.n = GLYPH.n;
583+
state.ID = ID;
584+
}
585+
if (errors.length) {result.errors = errors}
586+
callback(result);
587+
serverState = STATE.READY;
588+
StartQueue();
556589
}
557590

591+
558592
/********************************************************************/
559593

560594
//

0 commit comments

Comments
 (0)