@@ -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//
362362function 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//
380389function 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, "&" ) . replace ( / < / g, "<" ) . replace ( / > / g, ">" ) ;
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