@@ -41,7 +41,7 @@ import {expandable} from '../../../util/Options.js';
4141const MJCONFIG = MathJax . config ;
4242
4343/**
44- * Add an extension to the configuration , and configure its user options
44+ * Load any dependencies for an extension , and add the extension to the input jax.
4545 *
4646 * @param {TeX } jax The TeX jax whose configuration is to be modified
4747 * @param {string } name The name of the extension being added (e.g., '[tex]/amscd')
@@ -53,36 +53,57 @@ function RegisterExtension(jax: TeX<any, any, any>, name: string) {
5353 if ( required . indexOf ( extension ) < 0 ) {
5454 required . push ( extension ) ;
5555 //
56- // Register any dependencies that were loaded to handle this one
56+ // Register any dependencies that were loaded to handle this one,
57+ // and save the retry promise, if any, for when the dependencies need
58+ // to restart the expression (due to preprocessors, see below).
5759 //
58- RegisterDependencies ( jax , LOADERCONFIG . dependencies [ name ] ) ;
60+ let retry = RegisterDependencies ( jax , LOADERCONFIG . dependencies [ name ] ) ;
5961 //
60- // If the required file loaded an extension...
62+ // If we need to restart the expression due to the dependencies,
63+ // Wait for the dependencies to load, process this extension, then retry,
64+ // Otherwise, process the extension now.
6165 //
62- const handler = ConfigurationHandler . get ( extension ) ;
63- if ( handler ) {
64- //
65- // Check if there are user-supplied options
66- // (place them in a block for the extension, if needed)
67- //
68- let options = MJCONFIG [ name ] || { } ;
69- if ( handler . options && Object . keys ( handler . options ) . length === 1 && handler . options [ extension ] ) {
70- options = { [ extension ] : options } ;
71- }
72- //
73- // Register the extension with the jax's configuration
74- //
75- ( jax as any ) . configuration . add ( extension , jax , options ) ;
76- //
77- // If there are preprocessors, restart so that they run
78- // (we don't have access to the document or MathItem needed to call
79- // the preprocessors from here)
80- //
81- const configured = jax . parseOptions . packageData . get ( 'require' ) . configured ;
82- if ( handler . preprocessors . length && ! configured . has ( extension ) ) {
83- configured . set ( extension , true ) ;
84- mathjax . retryAfter ( Promise . resolve ( ) ) ;
85- }
66+ if ( retry ) {
67+ mathjax . retryAfter ( retry . then ( ( ) => ProcessExtension ( jax , name , extension ) ) ) ;
68+ } else {
69+ ProcessExtension ( jax , name , extension ) ;
70+ }
71+ }
72+ }
73+
74+ /**
75+ * Add an extension to the configuration, and configure its user options
76+ *
77+ * @param {TeX } jax The TeX jax whose configuration is to be modified
78+ * @param {string } name The name of the extension being added (e.g., '[tex]/amscd')
79+ */
80+ function ProcessExtension ( jax : TeX < any , any , any > , name : string , extension : string ) {
81+ //
82+ // If the required file loaded an extension...
83+ //
84+ const handler = ConfigurationHandler . get ( extension ) ;
85+ if ( handler ) {
86+ //
87+ // Check if there are user-supplied options
88+ // (place them in a block for the extension, if needed)
89+ //
90+ let options = MJCONFIG [ name ] || { } ;
91+ if ( handler . options && Object . keys ( handler . options ) . length === 1 && handler . options [ extension ] ) {
92+ options = { [ extension ] : options } ;
93+ }
94+ //
95+ // Register the extension with the jax's configuration
96+ //
97+ ( jax as any ) . configuration . add ( extension , jax , options ) ;
98+ //
99+ // If there are preprocessors, restart the typesetting so that they run
100+ // (we don't have access to the document or MathItem needed to call
101+ // the preprocessors from here)
102+ //
103+ const configured = jax . parseOptions . packageData . get ( 'require' ) . configured ;
104+ if ( handler . preprocessors . length && ! configured . has ( extension ) ) {
105+ configured . set ( extension , true ) ;
106+ mathjax . retryAfter ( Promise . resolve ( ) ) ;
86107 }
87108 }
88109}
@@ -92,14 +113,23 @@ function RegisterExtension(jax: TeX<any, any, any>, name: string) {
92113 *
93114 * @param {TeX } jax The jax whose configuration is being modified
94115 * @param {string[] } names The names of the dependencies to register
116+ * @return {Promise<any> } A promise resolved when all dependency's retries
117+ * are complete (or null if no retries)
95118 */
96- function RegisterDependencies ( jax : TeX < any , any , any > , names : string [ ] = [ ] ) {
119+ function RegisterDependencies ( jax : TeX < any , any , any > , names : string [ ] = [ ] ) : Promise < any > {
97120 const prefix = jax . parseOptions . options . require . prefix ;
121+ const retries = [ ] ;
98122 for ( const name of names ) {
99123 if ( name . substring ( 0 , prefix . length ) === prefix ) {
100- RegisterExtension ( jax , name ) ;
124+ try {
125+ RegisterExtension ( jax , name ) ;
126+ } catch ( err ) {
127+ if ( ! err . retry ) throw err ;
128+ retries . push ( err . retry ) ;
129+ }
101130 }
102131 }
132+ return ( retries . length ? Promise . all ( retries ) : null ) ;
103133}
104134
105135/**
0 commit comments