2121 * @author dpvc@mathjax.org (Davide Cervone)
2222 */
2323
24- import { MmlNode , AbstractMmlTokenNode , TextNode , AttributeList } from '../../core/MmlTree/MmlNode.js' ;
24+ import { MmlNode , AbstractMmlTokenNode , TextNode } from '../../core/MmlTree/MmlNode.js' ;
2525import { ComplexityVisitor } from './visitor.js' ;
2626
2727/*==========================================================================*/
@@ -106,7 +106,7 @@ export class Collapse {
106106 root : '\u221A' ,
107107 superscript : '\u25FD\u02D9' ,
108108 subscript : '\u25FD.' ,
109- subsup :'\u25FD:' ,
109+ subsup : '\u25FD:' ,
110110 vector : {
111111 binomial : '(:)' ,
112112 determinant : '|:|' ,
@@ -269,14 +269,28 @@ export class Collapse {
269269
270270 ] as [ string , CollapseFunction ] [ ] ) ;
271271
272+ /**
273+ * The highest id number used for mactions so far
274+ */
275+ private idCount = 0 ;
276+
272277 /**
273278 * @param {ComplexityVisitor } visitor The visitor for computing complexities
274279 */
275280 constructor ( visitor : ComplexityVisitor ) {
276281 this . complexity = visitor ;
277282 }
278283
279- public check ( node : MmlNode , complexity : number ) {
284+ /**
285+ * Check if a node should be collapsible and insert the
286+ * maction node to handle that. Return the updated
287+ * complexity.
288+ *
289+ * @param {MmlNode } node The node to check
290+ * @param {number } complexity The current complexity of the node
291+ * @return {number } The revised complexity
292+ */
293+ public check ( node : MmlNode , complexity : number ) : number {
280294 const type = node . attributes . get ( 'data-semantic-type' ) as string ;
281295 if ( this . collapse . has ( type ) ) {
282296 return this . collapse . get ( type ) . call ( this , node , complexity ) ;
@@ -287,25 +301,44 @@ export class Collapse {
287301 return complexity ;
288302 }
289303
290- protected defaultCheck ( node : MmlNode , complexity : number , type : string ) {
304+ /**
305+ * Check if the complexity exceeds the cutoff value for the type
306+ *
307+ * @param {MmlNode } node The node to check
308+ * @param {number } complexity The current complexity of the node
309+ * @param {string } type The semantic type of the node
310+ * @return {number } The revised complexity
311+ */
312+ protected defaultCheck ( node : MmlNode , complexity : number , type : string ) : number {
291313 const role = node . attributes . get ( 'data-semantic-role' ) as string ;
292314 const check = this . cutoff [ type ] ;
293315 const cutoff = ( typeof check === 'number' ? check : check [ role ] || check . value ) ;
294316 if ( complexity > cutoff ) {
295317 const marker = this . marker [ type ] || '??' ;
296318 const text = ( typeof marker === 'string' ? marker : marker [ role ] || marker . value ) ;
297- complexity = this . recordCollapse ( node , complexity , text )
319+ complexity = this . recordCollapse ( node , complexity , text ) ;
298320 }
299321 return complexity ;
300322 }
301323
302- protected recordCollapse ( node : MmlNode , complexity : number , text : string ) {
324+ /**
325+ * @param {MmlNode } node The node to check
326+ * @param {number } complexity The current complexity of the node
327+ * @param {string } text The text to use for the collapsed node
328+ * @return {number } The revised complexity for the collapsed node
329+ */
330+ protected recordCollapse ( node : MmlNode , complexity : number , text : string ) : number {
303331 text = '\u25C2' + text + '\u25B8' ;
304332 node . setProperty ( 'collapse-marker' , text ) ;
305333 node . setProperty ( 'collapse-complexity' , complexity ) ;
306334 return text . length * this . complexity . complexity . text ;
307335 }
308336
337+ /**
338+ * Remove collapse markers (to move them to a parent node)
339+ *
340+ * @param {MmlNode } node The node to uncollapse
341+ */
309342 protected unrecordCollapse ( node : MmlNode ) {
310343 const complexity = node . getProperty ( 'collapse-complexity' ) ;
311344 if ( complexity != null ) {
@@ -315,7 +348,13 @@ export class Collapse {
315348 }
316349 }
317350
318- protected canUncollapse ( node : MmlNode , n : number , m : number = 1 ) {
351+ /**
352+ * @param {MmlNode } node The node to check if its child is collapsable
353+ * @param {number } n The position of the child node to check
354+ * @param {number= } m The number of children node must have
355+ * @return {MmlNode|null } The child node that was collapsed (or null)
356+ */
357+ protected canUncollapse ( node : MmlNode , n : number , m : number = 1 ) : MmlNode | null {
319358 if ( this . splitAttribute ( node , 'children' ) . length === m ) {
320359 const mml = ( node . childNodes . length === 1 &&
321360 ( node . childNodes [ 0 ] as MmlNode ) . isInferred ? node . childNodes [ 0 ] as MmlNode : node ) ;
@@ -329,7 +368,14 @@ export class Collapse {
329368 return null ;
330369 }
331370
332- protected uncollapseChild ( complexity : number , node : MmlNode , n : number , m :number = 1 ) {
371+ /**
372+ * @param {number } complexity The current complexity
373+ * @param {MmlNode } node The node to check
374+ * @param {number } n The position of the child node to check
375+ * @param {number= } m The number of children the node must have
376+ * @return {number } The updated complexity
377+ */
378+ protected uncollapseChild ( complexity : number , node : MmlNode , n : number , m : number = 1 ) : number {
333379 const child = this . canUncollapse ( node , n , m ) ;
334380 if ( child ) {
335381 this . unrecordCollapse ( child ) ;
@@ -341,20 +387,39 @@ export class Collapse {
341387 return complexity ;
342388 }
343389
344- protected splitAttribute ( node : MmlNode , id : string ) {
390+ /**
391+ * @param {MmlNode } node The node whose attribute is to be split
392+ * @param {string } id The name of the data-semantic attribute to split
393+ * @return {string[] } Array of ids in the attribute split at commas
394+ */
395+ protected splitAttribute ( node : MmlNode , id : string ) : string [ ] {
345396 return ( node . attributes . get ( 'data-semantic-' + id ) as string || '' ) . split ( / , / ) ;
346397 }
347398
399+ /**
400+ * @param {MmlNode } node The node whose text content is needed
401+ * @return {string } The text of the node (and its children), combined
402+ */
348403 protected getText ( node : MmlNode ) : string {
349404 if ( node . isToken ) return ( node as AbstractMmlTokenNode ) . getText ( ) ;
350405 return node . childNodes . map ( ( n : MmlNode ) => this . getText ( n ) ) . join ( '' ) ;
351406 }
352407
353- protected findChildText ( node : MmlNode , id : string ) {
408+ /**
409+ * @param {MmlNode } node The node whose child text is needed
410+ * @param {string } id The (semantic) id of the child needed
411+ * @return {string } The text of the specified child node
412+ */
413+ protected findChildText ( node : MmlNode , id : string ) : string {
354414 const child = this . findChild ( node , id ) ;
355415 return this . getText ( child . coreMO ( ) || child ) ;
356416 }
357417
418+ /**
419+ * @param {MmlNode } node The node whose child is to be located
420+ * @param {string } id The (semantic) id of the child to be found
421+ * @return {MmlNode|null } The child node (or null if not found)
422+ */
358423 protected findChild ( node : MmlNode , id : string ) : MmlNode | null {
359424 if ( ! node || node . attributes . get ( 'data-semantic-id' ) === id ) return node ;
360425 if ( ! node . isToken ) {
@@ -366,6 +431,11 @@ export class Collapse {
366431 return null ;
367432 }
368433
434+ /**
435+ * Add maction nodes to the nodes in the tree that can collapse
436+ *
437+ * @paramn {MmlNode} node The root of the tree to check
438+ */
369439 public makeCollapse ( node : MmlNode ) {
370440 const nodes : MmlNode [ ] = [ ] ;
371441 node . walkTree ( ( child : MmlNode ) => {
@@ -376,20 +446,25 @@ export class Collapse {
376446 this . makeActions ( nodes ) ;
377447 }
378448
449+ /**
450+ * @param {MmlNode[] } nodes The lsit of nodes to replace by maction nodes
451+ */
379452 public makeActions ( nodes : MmlNode [ ] ) {
380453 for ( const node of nodes ) {
381454 this . makeAction ( node ) ;
382455 }
383456 }
384457
385- private idCount = 0 ;
386458 /**
387- * @return {string } A unique id string.
459+ * @return {string } A unique id string.
388460 */
389461 private makeId ( ) : string {
390462 return 'mjx-collapse-' + this . idCount ++ ;
391463 }
392464
465+ /**
466+ * @param {MmlNode } node The node to make collapsible by replacing with an maction
467+ */
393468 public makeAction ( node : MmlNode ) {
394469 if ( node . isKind ( 'math' ) ) {
395470 node = this . addMrow ( node ) ;
@@ -416,7 +491,14 @@ export class Collapse {
416491 maction . appendChild ( node ) ;
417492 }
418493
419- public addMrow ( node : MmlNode ) {
494+ /**
495+ * If the <math> node is to be collapsible, add an mrow to it instead so that we can wrap it
496+ * in an maction (can't put one around the <math> node).
497+ *
498+ * @param {MmlNode } node The math node to create an mrow for
499+ * @return {MmlNode } The newly created mrow
500+ */
501+ public addMrow ( node : MmlNode ) : MmlNode {
420502 const mrow = this . complexity . factory . create ( 'mrow' , null , node . childNodes [ 0 ] . childNodes as MmlNode [ ] ) ;
421503 node . childNodes [ 0 ] . setChildren ( [ mrow ] ) ;
422504
0 commit comments