@@ -90,6 +90,8 @@ var queue = []; // queue of typesetting requests of the form [data,callbac
9090var data , callback , originalData ; // the current queue item
9191var errors = [ ] ; // errors collected durring the typesetting
9292var ID = 0 ; // id for this SVG element
93+ var userMacros = { } ; // tracks user-defined macros during typesetting
94+ var userEnvironment = { } ; // tracks user-defined environments during typesetting
9395
9496//
9597// The delimiters used for each of the input formats
@@ -425,6 +427,27 @@ function ConfigureMathJax() {
425427
426428 } ) ;
427429
430+ //
431+ // Track user-defined macros and environment
432+ //
433+ MathJax . Hub . Register . StartupHook ( "TeX newcommand Ready" , function ( ) {
434+ var TEX = MathJax . InputJax . TeX ,
435+ TEXDEF = TEX . Definitions ;
436+
437+ var originalSetDef = TEX . Parse . prototype . setDef ;
438+ var originalSetEnv = TEX . Parse . prototype . setEnv ;
439+ TEX . Parse . Augment ( {
440+ setDef : function ( name , value ) {
441+ userMacros [ name ] = value ;
442+ return originalSetDef . apply ( this , arguments ) ;
443+ } ,
444+ setEnv : function ( name , value ) {
445+ userEnvironment [ name ] = value ;
446+ return originalSetEnv . apply ( this , arguments ) ;
447+ } ,
448+ } ) ;
449+ } ) ;
450+
428451 //
429452 // Reset the color extension after `autoload-all`
430453 //
@@ -724,6 +747,7 @@ function StartQueue() {
724747function GetState ( state ) {
725748 var SVG = MathJax . OutputJax . SVG ,
726749 TEX = MathJax . InputJax . TeX ,
750+ TEXDEF = TEX . Definitions ,
727751 MML = MathJax . ElementJax . mml ,
728752 AMS = MathJax . Extension [ "TeX/AMSmath" ] ,
729753 HUB = MathJax . Hub , HTML = MathJax . HTML ,
@@ -750,6 +774,38 @@ function GetState(state) {
750774 MML . SUPER . ID = ID = 0 ;
751775 MathJax . OutputJax . CommonHTML . ID = 0 ;
752776 }
777+
778+ // Clear any existing user-defined macros and environment, then load them from state
779+ for ( var name in userMacros ) {
780+ if ( userMacros . hasOwnProperty ( name ) ) {
781+ delete TEXDEF . macros [ name ] ;
782+ }
783+ }
784+ userMacros = { } ;
785+ if ( state && state . macros ) {
786+ for ( var name in state . macros ) {
787+ if ( state . macros . hasOwnProperty ( name ) ) {
788+ userMacros [ name ] = TEXDEF . macros [ name ] = state . macros [ name ] ;
789+ // Set isUser on array, in case the state has been serialized and the property has been lost.
790+ TEXDEF . macros [ name ] . isUser = true ;
791+ }
792+ }
793+ }
794+ for ( var name in userEnvironment ) {
795+ if ( userEnvironment . hasOwnProperty ( name ) ) {
796+ delete TEXDEF . environment [ name ] ;
797+ }
798+ }
799+ userEnvironment = { } ;
800+ if ( state && state . environment ) {
801+ for ( var name in state . environment ) {
802+ if ( state . environment . hasOwnProperty ( name ) ) {
803+ userEnvironment [ name ] = TEXDEF . environment [ name ] = state . environment [ name ] ;
804+ // Set isUser on array, in case the state has been serialized and the property has been lost.
805+ TEXDEF . environment [ name ] . isUser = true ;
806+ }
807+ }
808+ }
753809}
754810
755811//
@@ -774,6 +830,7 @@ function ReturnResult(result) {
774830 if ( state ) {
775831 var AMS = MathJax . Extension [ "TeX/AMSmath" ] ;
776832 var GLYPH = MathJax . OutputJax . SVG . BBOX . GLYPH ;
833+ var TEX = MathJax . InputJax . TeX ;
777834 state . AMS . startNumber = AMS . startNumber ;
778835 state . AMS . labels = AMS . labels ;
779836 state . AMS . IDs = AMS . IDs ;
@@ -782,6 +839,8 @@ function ReturnResult(result) {
782839 state . defs = GLYPH . defs ;
783840 state . n = GLYPH . n ;
784841 state . ID = ID ;
842+ state . macros = userMacros ;
843+ state . environment = userEnvironment ;
785844 }
786845 serverState = STATE . READY ;
787846 callback ( result , originalData ) ;
0 commit comments