zoukankan      html  css  js  c++  java
  • 自己实现HTMLBeautify

    文章截图 - 更好的排版 

    源代码下载

    学习HTML-Beautify.js之后,我们发现使用JavaScript对HTML进行解析也并不神秘, 首先是逐字符进行分析,从中提取标记(Token),在HTML只存在两种类型的标记-标签和正文, 然后对这些Token进行语法分析,主要是缩进量是多少。
    在有这些基本概念后,今天我们就自己来实现这个小程序:
        // 我在Html Beautifier的一个简单尝试
        function HtmlBeautify(source, indent_value) {
            this.source = source;
            this.indent_value = indent_value;
            this.result = "";
            this.parse();
        }
        // 分析并产生输出到this.result
        HtmlBeautify.prototype.parse = function() {
            var that = this;
            // 当前分析到哪个字符,当前标记值,标记类型,输出数组,缩进级别
            var pos = 0, token_value = "", token_type = "",
            output = [], indent_level = 0;
            // 把这些标签作为Single Tag
            var single_token = "br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed".split(',');
            // 输出当前标记(换行+缩进量+标记值)
            function outputToken() {
                output.push("\n");
                for (var i = 0; i < indent_level; i++) {
                    output.push(that.indent_value);
                }
                output.push(token_value);
            }
            // 获取下一个标记(首先获取正文,如果正文为空则获取标签)
            function nextToken() {
                var token_value_array = [], val = "";
                // "<"之前的所有内容作为正文标签
                while ((val = that.source[pos]) !== "<") {
                    if (pos >= that.source.length) {
                        token_type = "END";
                        return;
                    }
                    token_value_array.push(val);
                    pos++;
                }
                token_value = $.trim(token_value_array.join(""));
                if (token_value === "") {
                    // 如果正文标记为空,则获取标签标记
                    nextTokenTag();
                } else {
                    token_type = "CONTENT";
                }
            }
            function nextTokenTag() {
                var token_value_array = [], val = "", tagName = "";
                // 获取标签标记,直到遇到">"
                do {
                    val = that.source[pos];
                    token_value_array.push(val);
                    pos++;
                } while (val !== ">");
                token_value = $.trim(token_value_array.join(""));
                // 当前标签的名称(小写)
                tagName = getTagName();
                if (token_value[1] === "/") {
                    // token_value以"</"开始,则认为是结束标签
                    token_type = "END_TAG";
                } else if (contains(tagName, single_token) || token_value[token_value.length - 2] === "/") {
                    // 如果标签在single_token或者token_value以"/>"结尾,则认为是独立标签
                    // 这种判断没有考虑这种情况:"<br></br>"
                    token_type = "SINGLE_TAG";
                } else {
                    token_type = "START_TAG";
                }
            }
            function getTagName() {
                var tagName = token_value.substr(1, token_value.length - 2);
                var spaceIndex = tagName.indexOf(" ");
                if (spaceIndex > 0) {
                    tagName = tagName.substr(0, spaceIndex);
                }
                return tagName.toLowerCase();
            }
            function contains(val, array) {
                for (var i = 0; i < array.length; i++) {
                    if (val === array[i]) {
                        return true;
                    }
                }
                return false;
            }
    
            // parse的主体函数,循环获取下一个Token
            while (true) {
                nextToken();
                
                // 当前Token为结束标记
                if (token_type === "END") {
                    break;
                }
                switch (token_type) {
                    case "START_TAG":
                        // 我们对缩进的控制非常简单,开始标签后缩进一个单位
                        outputToken();
                        indent_level++;
                        break;
                    case "END_TAG":
                        // 结束标签前减少一个单位缩进
                        indent_level--;
                        outputToken();
                        break;
                    case "SINGLE_TAG":
                    case "CONTENT":
                        outputToken();
                        break;
                }
            }
            // 去除最前面的"\n"
            this.result = output.join("").substr(1);
        };
    
        $(function() {
            $("#format").click(function() {
                // 实例化HtmlBeautify,传递需要解析的HTML片段和缩进字符串
                var beautify = new HtmlBeautify($("#content").val(), "    ");
                $("#content").val(beautify.result);
            });
        });
        
  • 相关阅读:
    Linux常用基本命令(cut)
    Linux常用基本命令(tail )
    Linux常用基本命令(head)
    Linux常用基本命令(less)
    Linux常用基本命令(more)
    Linux常用基本命令(cat)
    apache2.4.33伪静态配置入门教程(1)
    ubuntu16.04 linux 编译安装apache2.4.33
    安装apr-1.6.3报错[cannot remove `libtoolT’: No such file or directory]解决方法
    Linux常用基本命令(chmod)
  • 原文地址:https://www.cnblogs.com/sanshi/p/1530321.html
Copyright © 2011-2022 走看看