简体   繁体   English

如何在 JavaScript 中格式化/整理/美化

[英]How to format/tidy/beautify in JavaScript

How can I format/tidy/beautify HTML in JavaScript?如何在 JavaScript 中格式化/整理/美化 HTML? I have tried doing a search/replace for angle brackets ( < , > ) and indenting accordingly. 我试过搜索/替换尖括号( <> )并相应地缩进。 But of course it does not take into account when the is JS or CSS etc inside the HTML.但是当然它没有考虑 HTML 中的 JS 或 CSS 等。

The reason I want to do this is I have made a content editor (CMS) which has both WYSIWYG and source code views.我想这样做的原因是我制作了一个内容编辑器(CMS),它具有所见即所得和源代码视图。 The problem the code written by the WYSIWYG editor is normally a single line. WYSIWYG 编辑器编写的代码的问题通常是单行。 So I would like a JavaScript that could format this into a more readable form on demand.所以我想要一个可以根据需要将其格式化为更易读的形式的 JavaScript。

Here what I have so far:这是我到目前为止所拥有的:

function getIndent(level) {
    var result = '',
        i = level * 4;
    if (level < 0) {
        throw "Level is below 0";
    }
    while (i--) {
        result += ' ';
    }
    return result;
}

function style_html(html) {
    html = html.trim();
    var result = '',
        indentLevel = 0,
        tokens = html.split(/</);
    for (var i = 0, l = tokens.length; i < l; i++) {
        var parts = tokens[i].split(/>/);
        if (parts.length === 2) {
            if (tokens[i][0] === '/') {
                indentLevel--;
            }
            result += getIndent(indentLevel);
            if (tokens[i][0] !== '/') {
                indentLevel++;
            }

            if (i > 0) {
                result += '<';
            }

            result += parts[0].trim() + ">\n";
            if (parts[1].trim() !== '') {
                result += getIndent(indentLevel) + parts[1].trim().replace(/\s+/g, ' ') + "\n";
            }

            if (parts[0].match(/^(img|hr|br)/)) {
                indentLevel--;
            }
        } else {
            result += getIndent(indentLevel) + parts[0] + "\n";
        }
    }
    return result;
}

@lovasoa How to format/tidy/beautify in JavaScript is an excellent solution. @lovasoa 如何在 JavaScript 中格式化/整理/美化是一个很好的解决方案。
rock-solid, much better than vkBeautify or even CodeMirror (hard to use AMD) and VERY easy坚如磐石,比 vkBeautify 甚至 CodeMirror(难以使用 AMD)好得多,而且非常容易

<script src='http://lovasoa.github.io/tidy-html5/tidy.js'></script>
<script>
  options = {
  "indent":"auto",
  "indent-spaces":2,
  "wrap":80,
  "markup":true,
  "output-xml":false,
  "numeric-entities":true,
  "quote-marks":true,
  "quote-nbsp":false,
  "show-body-only":true,
  "quote-ampersand":false,
  "break-before-br":true,
  "uppercase-tags":false,
  "uppercase-attributes":false,
  "drop-font-tags":true,
  "tidy-mark":false
}

var html = document.querySelector("body").outerHTML;
var result = tidy_html5(html, options);
console.log(result);
</script>

I use this method to format HTML.我使用这种方法来格式化 HTML。 Simple, but does the job:简单,但可以完成工作:

function format(html) {
    var tab = '\t';
    var result = '';
    var indent= '';

    html.split(/>\s*</).forEach(function(element) {
        if (element.match( /^\/\w/ )) {
            indent = indent.substring(tab.length);
        }

        result += indent + '<' + element + '>\r\n';

        if (element.match( /^<?\w[^>]*[^\/]$/ ) && !element.startsWith("input")  ) { 
            indent += tab;              
        }
    });

    return result.substring(1, result.length-3);
}

I needed something similar and here is my solution, inspired by method provided by michal.jakubeczy.我需要类似的东西,这是我的解决方案,灵感来自 michal.jakubeczy 提供的方法。 It is slightly complicated in order to preserve formatting within <pre> tags.为了保留<pre>标签内的格式,它有点复杂。 Hope this will help someone.希望这会帮助某人。

function formatHTML(html) {
    var indent = '\n';
    var tab = '\t';
    var i = 0;
    var pre = [];

    html = html
        .replace(new RegExp('<pre>((.|\\t|\\n|\\r)+)?</pre>'), function (x) {
            pre.push({ indent: '', tag: x });
            return '<--TEMPPRE' + i++ + '/-->'
        })
        .replace(new RegExp('<[^<>]+>[^<]?', 'g'), function (x) {
            var ret;
            var tag = /<\/?([^\s/>]+)/.exec(x)[1];
            var p = new RegExp('<--TEMPPRE(\\d+)/-->').exec(x);

            if (p) 
                pre[p[1]].indent = indent;

            if (['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'].indexOf(tag) >= 0) // self closing tag
                ret = indent + x;
            else {
                if (x.indexOf('</') < 0) { //open tag
                    if (x.charAt(x.length - 1) !== '>')
                        ret = indent + x.substr(0, x.length - 1) + indent + tab + x.substr(x.length - 1, x.length);
                    else 
                        ret = indent + x;
                    !p && (indent += tab);
                }
                else {//close tag
                    indent = indent.substr(0, indent.length - 1);
                    if (x.charAt(x.length - 1) !== '>')
                        ret =  indent + x.substr(0, x.length - 1) + indent + x.substr(x.length - 1, x.length);
                    else
                        ret = indent + x;
                }
            }
            return ret;
        });

    for (i = pre.length; i--;) {
        html = html.replace('<--TEMPPRE' + i + '/-->', pre[i].tag.replace('<pre>', '<pre>\n').replace('</pre>', pre[i].indent + '</pre>'));
    }

    return html.charAt(0) === '\n' ? html.substr(1, html.length - 1) : html;
}

function unformatHTML(html) {
    var i = 0;
    var pre = [];

    html = html.replace(new RegExp('<pre>((.|\\t|\\n|\\r)+)?</pre>'), function (x) {
        pre.push(x);
        return '<--TEMPPRE' + i++ + '/-->'
    }).replace(/\n/g, '').replace(/\t/g, '');

    for (i = pre.length; i--;) {
        html = html.replace('<--TEMPPRE' + i + '/-->', pre[i]);
    }

    html = html.replace(new RegExp('<pre>\\n'), '<pre>').replace(new RegExp('\\n\\t*</pre>'), '</pre>');
    return html;
}

You can also use a command line tool if you have node.js install如果你安装了 node.js,你也可以使用命令行工具

run npm install -g uglify-js to install uglifyjs globally, check here for documentation.运行npm install -g uglify-js uglify npm install -g uglify-js全局安装 uglifyjs,查看这里的文档。

Then you can uglify index.min.js -b -o index.js然后你可以uglify index.min.js -b -o index.js

I find js-beautify far superior to any solution posted so far.我发现js-beautify远远优于迄今为止发布的任何解决方案。

Add the script to your lib folder:脚本添加到您的 lib 文件夹中:

Bring inside header as usual:像往常一样带入内部标题:

<script src="libs/beautify.js"></script>

Target code wherever it is on your page (eg pre or code tag) and use the js_beautify function to format as needed:定位页面上任何位置的代码(例如precode标记)并使用js_beautify函数根据需要进行格式化:

$(".my_class").text(js_beautify($(".my_class").text()))

This will format as needed.这将根据需要进行格式化。 All kinds of config options available on the repo.存储库上可用的各种配置选项。

jQuery creator John Resig wrote a fast and lightweight HTML parser in javascript . jQuery 创建者 John Resig用 javascript编写了一个快速且轻量级的HTML 解析器 If you're looking for a solution which you can add directly to your CMS then you could write a simple beautifier using this parser as a base.如果您正在寻找可以直接添加到 CMS 的解决方案,那么您可以使用此解析器作为基础编写一个简单的美化器。 All you'd need to do is reoutput the elements adding spaces and line breaks as you like, using the built in api:您需要做的就是使用内置 api 重新输出添加空格和换行符的元素:

HTMLParser(htmlString, {
  start: function(tag, attrs, unary) {},
  end: function(tag) {},
  chars: function(text) {},
  comment: function(text) {}
});

An added benefit of this approach is that you could use the same HTMLParser to read HTML back into your WYSIWYG, or otherwise interact with your user's HTML tree.这种方法的另一个好处是您可以使用相同的 HTMLParser 将 HTML 读回您的所见即所得,或者以其他方式与用户的 HTML 树交互。 HTMLParser also comes prebuilt with an HTMLtoDOM method. HTMLParser 还预先构建了一个 HTMLtoDOM 方法。

Writing the on one line would download faster to the browser, so I am not sure I would want it formatted.在一行上编写会更快地下载到浏览器,所以我不确定我是否想要格式化它。 Maybe an option for a formatted version or an optimized version.也许是格式化版本或优化版本的选项。

As for the question... you could do an call after so many actions and send the code to the server to be formatted and shown in a different box on the screen.至于问题......你可以在这么多操作后进行调用,并将代码发送到服务器进行格式化并显示在屏幕上的不同框中。 Basically it would be a real time version of this site, http://infohound.net/tidy/基本上它是这个网站的实时版本, http://infohound.net/tidy/

I believe that both chrome and firebug's debugging code display engines are written in JS.相信chrome和firebug的调试代码显示引擎都是JS写的。 That's probably heavier duty than you really want to be messing with though.不过,这可能比你真正想要搞砸的任务更重。

Resig's formatter fails with a very simple test case: Resig 的格式化程序因一个非常简单的测试用例而失败:

at http://ejohn.org/apps/htmlparser/http://ejohn.org/apps/htmlparser/

in the input box enter:在输入框中输入:

<script src="/files/htmlparser.js"></script>
<script>
var x = 1;
</script>

output box renders:输出框呈现:

<script src="/files/htmlparser.js"></script>
<script></script>
var x = 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM