Javascript: How to fix indentation in HTML string?
For a line 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 would like to format it as follows:
<div id="a"> <span class="b"> <span>Hello</span> </span> <input type="text"> </div> i.e. the result should be: (suppose 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 is the most elegant way to achieve this? Are there any known libraries that do this?
Note:
- I'm not looking for HTML syntax highlighting, just padding
- I donβt want to support the whole HTML specification, fixing a basic HTML like the example above will suffice
Here is a simple recursive function that I wrote that I think will help you 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 will use it as follows:
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/
The js-beautify tool can work with html and has an api. This is probably the easiest way to do what you want.
After installation using node:
var beautify_html = require('js-beautify').html; result = beautify_html(htmlstring); To use it in a browser, you need to include all the beautiful * .js scripts in this directory and use window.html_beautify .
Since there are many complaints about js-beautify, I am 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, I recommend parsing the HTML string ... for this work you can use xmldom parseFromString ... it's really simple.