All files / src/preprocessor loopExpander.ts

100% Statements 17/17
100% Branches 0/0
100% Functions 6/6
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33            1x 32x 32x   32x 49x   1x 1x   1x 2x 2x 2x     1x     32x 2x 1x     32x    
import { DOMParser, XMLSerializer } from 'xmldom'
 
/**
 * Expands the loop nodes in the XML document.
 * Returns the original document with the loops expanded.
 */
export const loopExpander = (xml: string): string => {
    const parser = new DOMParser()
    const dom = parser.parseFromString(xml, 'text/xml')
 
    const textNodes = Array.from(dom.getElementsByTagName('Text'))
        .filter((node) => node.getAttribute('repeat'))
        .map((node) => {
            const repeat = parseInt(node.getAttribute('repeat')!)
            const parent = node.parentNode!
 
            const nodes = Array.from({ length: repeat }, () => {
                const clone = node.cloneNode(true);
                (clone as Element).removeAttribute('repeat')
                return clone
            })
 
            return { parent, node, nodes }
        })
 
    textNodes.forEach(({ parent, node, nodes }) => {
        nodes.forEach((n) => parent.insertBefore(n, node))
        parent.removeChild(node)
    })
 
    return new XMLSerializer().serializeToString(dom)
}