import * as _ from 'lodash' ; import { LiteElement , LiteNode } from 'mathjax-full/js/adaptors/lite/Element' ; export type TreeWalkerCallback < N , T > = ( node : N , level : number , accum : T [ ] , quit : ( ) => void ) => T ; export type Child < T = { } > = { parent ? : Child < T > ; } & T ; export type Parent < T = { } > = { children ? : Parent < T > [ ] ; } & T ; param node param callback returns export function walkUp < N extends Child | LiteElement = LiteElement , T = LiteElement > ( node , callback ) { let n = node ; let i = 0 ; let _break = false ; const quit = ( ) => { _break = true ; } ; const accum = [ ] ; while ( n . parent && ! _break ) { accum . push ( callback ( n , i , accum , quit ) ) ; i ++ ; n = n . parent ; } return accum ; } param node param callback returns export function walkDown < N extends Parent | LiteElement = LiteElement , T = LiteElement > ( node , callback ) { let stack = [ ] as N [ ] ; let n = node ; let i = 0 ; let _break = false ; const quit = ( ) => { _break = true ; } ; const accum = [ ] ; let children ; while ( n ) { i = _ . get ( n , 'attributes.pLevel' , 0 ) ; accum . push ( callback ( n , i , accum , quit ) ) ; children = _ . get ( n , 'children' , [ ] ) as N [ ] ; if ( _ . size ( children ) > 0 ) { children = _ . map ( children , ( child ) => _ . set ( child , 'attributes.pLevel' , i + 1 ) ) ; stack = _ . concat ( children , stack ) ; } n = stack . shift ( ) ; } return accum ; } export function reject ( node ) { return node . kind === '#text' || node . kind === '#comment' ; }