Search code examples
javascripthtmlalgorithmdepth-first-search

How can I add proper indentation to this HTML generator that I wrote in JavaScript


I wrote a function that takes in an object that represents the DOM tree and outputs HTML strings. I used a DFS approach to traverse the object.

const tree = {
  children: [
    { children: [{ children: ['bar'], tag: 'span' }], tag: 'div' },
    { children: ['baz'], tag: 'div' },
  ],
  tag: 'body',
}

function fromTreeToString(root) {
  if (!root.children) {
    return root
  }
  return (
    `<${root.tag}>` + '\n' +
    `${root.children.map((node) => fromTreeToString(node)).join('\n')}` + '\n' +
    `</${root.tag}>`
  )
}

fromTreeToString(tree)

The output is

<body> 
<div> 
<span> 
bar 
</span> 
</div> 
<div> 
baz 
</div> 
</body> 

I wonder how I can modify this function so that the output has a proper indentation to it. Ideally the output should look like

<body> 
  <div> 
    <span> 
      bar 
    </span> 
  </div> 
  <div> 
    baz 
  </div> 
</body> 

and ideally the user of this API can customize the indentation e.g. tabs vs. space


Solution

  • You could also first use recursion to return an array of lines, and only concatenate them at the end:

    function fromTreeToString(root, indent='\t') {
        const recur = root => root.children ? [
                `<${root.tag}>`, 
                ...root.children.flatMap(recur).map(s => indent + s),
                `</${root.tag}>`
            ] : root;
        return recur(root).join('\n');
    }
    
    const tree = {children: [{ children: [{ children: ['bar'], tag: 'span' }], tag: 'div' },{ children: ['baz'], tag: 'div' },],tag: 'body'}
    
    console.log(fromTreeToString(tree, '. '));