export class MDNav { constructor(public root: any, public pos: number = 0) {} find(test: (element: any) => boolean = () => true, index: number = 0): MDNav { if (!this.root || !this.root.children) { return new MDNav(null); } let currIndex = 0; for (let i = this.pos; i < this.root.children.length; i++) { const child = this.root.children[i]; if (test(child)) { if (currIndex === index) { return new MDNav(this.root, i); } else { currIndex++; } } } return new MDNav(this.root, this.root.children.length); } findAll(test: (element: any) => boolean = () => true, index: number = 0): MDNav[] { if (!this.root || !this.root.children) { return []; } const result = []; let currIndex = 0; for (let i = this.pos; i < this.root.children.length; i++) { const child = this.root.children[i]; if (test(child)) { if (currIndex === index) { result.push(new MDNav(this.root, i)); } else { currIndex++; } } } return result; } emph(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'emphasis' && test(h); }, index); } heading(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'heading' && test(h); }, index); } headings(test: (element: any) => boolean = () => true, index: number = 0): MDNav[] { return this.findAll((h) => { return h.type === 'heading' && test(h); }, index); } html(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'html' && test(h); }, index); } link(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'link' && test(h); }, index); } links(test: (element: any) => boolean = () => true, index: number = 0): MDNav[] { return this.findAll((h) => { return h.type === 'link' && test(h); }, index); } list(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'list' && test(h); }, index); } listItem(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'listItem' && test(h); }, index); } listItems(test: (element: any) => boolean = () => true, index: number = 0): MDNav[] { return this.findAll((h) => { return h.type === 'listItem' && test(h); }, index); } paragraph(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'paragraph' && test(h); }, index); } strong(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'strong' && test(h); }, index); } table(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'table' && test(h); }, index); } tableRow(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'tableRow' && test(h); }, index); } tableCell(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'tableCell' && test(h); }, index); } text(test: (element: any) => boolean = () => true, index: number = 0): MDNav { return this.find((h) => { return h.type === 'text' && test(h); }, index); } get item(): any { if (!this.root || !this.root.children) { return undefined; } else { return this.root.children[this.pos]; } } get empty(): boolean { return !this.root || !this.root.children || (this.pos >= this.root.children.length); } get childNav(): MDNav { return new MDNav(this.item); } get value(): any { if (this.item && this.item['value']) { return this.item.value; } else { return ''; } } get textValue(): string { if (this.item) { if (this.item['value']) { return this.item.value; } else if ( this.item.children && (this.item.children.length > 0) && (this.item.children[0].type === 'text') ) { return this.item.children[0].value; } else { return ''; } } else { return ''; } } }