Javascript: How to correct indentation in HTML string? [closed]

Given a string like this:

' \n <div id="a">\n <span class="b">\n<span>Hello</span>\n\n\n</span> <input type="text">\n  \n</div>\n '

I'd like to format it like this:

<div id="a">
  <span class="b">
    <span>Hello</span>
  </span>
  <input type="text">
</div>

i.e. the result should be: (assume 2 spaces for indentation)

'<div id="a">\n  <span class="b">\n    <span>\n      Hello\n    </span>\n  </span>\n  <input type="text">\n</div>'

What's the most elegant way to achieve this? Are there any known libraries that do that?

Note:

  • I'm not looking for HTML syntax highlighting, just indentation correction
  • I'm not looking to support the whole HTML spec, correcting basic HTML like the example above would suffice

Answers:

Answer

Here is a simple recursive function I wrote, which I think might help you to achieve what you are after.

function process(str) {

    var div = document.createElement('div');
    div.innerHTML = str.trim();

    return format(div, 0).innerHTML;
}

function format(node, level) {

    var indentBefore = new Array(level++ + 1).join('  '),
        indentAfter  = new Array(level - 1).join('  '),
        textNode;

    for (var i = 0; i < node.children.length; i++) {

        textNode = document.createTextNode('\n' + indentBefore);
        node.insertBefore(textNode, node.children[i]);

        format(node.children[i], level);

        if (node.lastElementChild == node.children[i]) {
            textNode = document.createTextNode('\n' + indentAfter);
            node.appendChild(textNode);
        }
    }

    return node;
}

Then you would use it like this:

process(str);

Here is a demo:

var str = '<div id="a"><span class="b"><span>Hello</span></span><input type="text"><p><b>b <i>italic</i></b></p></div>';

function process(str) {
  var div = document.createElement('div');
  div.innerHTML = str.trim();

  return format(div, 0).innerHTML;
}

function format(node, level) {
  var indentBefore = new Array(level++ + 1).join('  '),
    indentAfter = new Array(level - 1).join('  '),
    textNode;

  for (var i = 0; i < node.children.length; i++) {
    textNode = document.createTextNode('\n' + indentBefore);
    node.insertBefore(textNode, node.children[i]);

    format(node.children[i], level);

    if (node.lastElementChild == node.children[i]) {
      textNode = document.createTextNode('\n' + indentAfter);
      node.appendChild(textNode);
    }
  }

  return node;
}

document.querySelector('#out').innerText = process(str);
<pre id="out"></pre>

Demo: http://jsfiddle.net/1gf07wap/

Answer

The js-beautify tool can work with html, and has an api. It's probably the easiest way to do what you want.

After installing it with node:

var beautify_html = require('js-beautify').html;

result = beautify_html(htmlstring);

To use it in a browser, you need to include all the beautify*.js scripts in this directory and use window.html_beautify.

DEMO

Answer

Since there are lots of complains about js-beautify, I'm posting this alternative:

GIT: https://github.com/maxogden/commonjs-html-prettyprinter

DEMO: http://requirebin.com/?gist=45056f6a9b306a14ea3d

CODE:

var htmlmodule = require('html');
var str = ' \n <div id="a">\n <span class="b"><span>Hello</span></span><input type="text">\n  \n</div>\n ';
var pretty = htmlmodule.prettyPrint(str);

IF this does not work as you intend to, I recommend parsing the HTML string... for this job you can use this xmldom parseFromString... it's really simple.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.