0

I needed to generate the HTML strings from a tree object with proper indentation. e.g.

{
  children: [
    { tag: 'div', children: [{ tag: 'span', children: ['bar1', 'bar2'] }] },
    { tag: 'div', children: ['baz'] },
  ],
  tag: 'body',
}

would become

<body>
    <div>
        <span>
            bar1
            bar2
        </span>
    </div>
    <div>
        baz
    </div>
</body>

Here is my attempt

function generateHTMLFrom(tree) {
  const recur = (node, depth = 0, indent = '  ') => {
    if (!node.children) return node
    return [
      `${indent.repeat(depth * 2)}`,
      `<${node.tag}>`,
      ...node.children.flatMap((child) => recur(child, depth + 1)),
      `${indent.repeat(depth * 2)}</${node.tag}>`,
    ]
  }

  return recur(tree).join('\n')
}

But the format is actually messed up because the indentation is all wrong

Can someone help me fix this?

1 Answer 1

1

You almost got it. I would recommend to take out complexity from your recursion to simplify it (no need, just for better readability).

Instead of multiplying depth * 2, you could initialize your argument with indent = ' '. And the first two lines of your returned array could combine in the way as you already did for the closing tag.

`${indent.repeat(depth)}<${node.tag}>`

And last but not least (your actual little mistake) the return value should not be node, it should be your node with an indentation:

return `${indent.repeat(depth)}${node}`;

You will end up with something like this:

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

function generateHTML (tree) {
  const recur = (node, depth=0, indent='    ') => {
    if (!node.children) {
      return `${indent.repeat(depth)}${node}`;
    }
    return [
      `${indent.repeat(depth)}<${node.tag}>`,
      ...node.children.flatMap((child) => recur(child, depth + 1)),
      `${indent.repeat(depth)}</${node.tag}>`
    ];
  };
  return recur(tree).join('\n');
}

console.log(generateHTML(tree));

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.