zoukankan      html  css  js  c++  java
  • 前端代码编辑器ace 语法高亮

    代码编辑器codemirror和ace,都有接触过,主要是简单的api使用下。现在项目选用的ace。主要结合官网的文档,加入些自己的理解。官方原文链接https://ace.c9.io/#nav=higlighter

    配置mode

      在线调试语法高亮 https://ace.c9.io/tool/mode_creator.html,可以自己练手下
      在ace项目的lib/ace/mode文件夹中已经定义了很多mode.下面介绍配置一个新的mode,其中包括 语法高亮规则,缩进规则,代码折叠规则。

    语法高亮规则

    语法高亮的规则可以继承其他规则,通过oop.inherits(MyNewHighlightRules, TextHighlightRules),比如php代码里面可以写html,所以继承HtmlHighlightRules。
    ace高亮语法是一种状态机机制。每一个状态,里面可以包含多个 用正则表达式regex定义的token标记。token标记可以通过next属性决定下一个状态。

    1 this.$rules = {
    2     stateName: [{
    3         token: token, // String, Array, or Function: the CSS token to apply
    4         regex: regex, // String or RegExp: the regexp to match
    5         next: next // [Optional] String: next state to enter
    6     }]
    7 };            

    this.$rules对象用来定义状态机的规则。开始规则定义为start状态,按顺序检测start的token列表。
    当检测到regex匹配的时候,文本包裹成`<span class="ace_${token}">${文本}</span>`,在编辑器显示。

    1 token=='function' => class="ace_function"
    2 token=='support.function' => class="ace_support ace_function"

    定义regex

    regex属性可以是正则表达式,也可以是正则表达式的字符串,字符串需要注意转义

    1 {
    2     token : "constant.language.escape",
    3     regex : /$[wd]+/
    4     regex : “\$[\w\d]+5 }

    regex与token关系

    regex不存在捕获,token可以是String, Function返回字符串
    token函数也可以用来对regex匹配的内容,再进行细分

     1 {
     2     token: function(value) {
     3         if (colors.hasOwnProperty(value.toLowerCase())) {
     4             return "support.constant.color";
     5         } else if (fonts.hasOwnProperty(value.toLowerCase())) {
     6             return "support.constant.fonts";
     7         } else {
     8             return "text";
     9         }
    10     },
    11     regex: "\-?[a-zA-Z_][a-zA-Z0-9_\-]*"
    12 }

    regex存在捕获分组,token可以是String(所有分组都用一样的定义), Array(长度和分组数量相同,与分组结果11对应),或Function返回Array

     1 {
     2   token : "constant",
     3   regex : "INT_MAX|INT_MIN"
     4 } // INT_MAX -> constant(INT_MAX)
     5 
     6 {
     7   token : ["constant", "keyword"],
     8   regex : "^(#{1,6})(.+)$"
     9 } // ### Header -> constant(###), keyword( Header)
    10 
    11 {
    12   token : "constant",
    13   regex : "(a+)(b)(\1)"
    14 } // aabaa -> constant(aabaa) :: abaa -> constant(aba) + a
    15 
    16 {
    17   token : function (first, second) {
    18     if (first == "a") return ["constant", "keyword"];
    19     return ["keyword", "constant"];
    20   },
    21   regex: "(.)(world)"
    22 } // aworld -> constant(a), keyword(world) :: bworld -> keyword(a), constant(world)

    分组需要覆盖所有匹配结果,如果需要不匹配的话,请使用(?:), (hel)lo => (hel)(?:lo)

    定义状态

    语法高亮状态机,一般处于start状态,如果你定义了next,会流转到next指定的状态,一直流转下去。最后,应该回到start状态,对后面的文本继续进行检测。
    可以理解是一个词法分析的过程。

     1 this.$rules = {
     2     "start" : [{
     3         token : "text",
     4         regex : "<\!\[CDATA\[",
     5         next : "cdata"
     6     }],
     7     "cdata" : [{
     8         token : "text",
     9         regex : "\]\]>",
    10         next : "start"
    11     }, {
    12         defaultToken : "text"
    13     }]
    14 };

    上面示例中,当检测到"<![cdata["字符串,标记器从start状态移动到cdata状态,默认使用text标记,直到遇到关闭符号“]]>”,重新回到start状态继续检测。

    扩展高亮规则

    如果你的语法中间,可以通过(<?lua, <?php)标识符来嵌入其他语言块。Ace可以使用一些有用的函数来进行扩展

    getRules 获取存在的规则

    1 var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
    2 this.$rules = new HtmlHighlightRules().getRules();

    addRules 合并规则

     1 this.$rules = {
     2     "start": [ /* ... */ ]
     3 };
     4 
     5 var newRules = {
     6     "start": [ /* ... */ ]
     7 }
     8 
     9 this.addRules(newRules, "new-");
    10 
    11 /*
    12     this.$rules = {
    13         "start": [ ... ],
    14         "new-start": [ ... ]
    15     };
    16 */

    embedRules 扩展规则

     1 this.addRules(newRules, "new-") == embedRules(this.$rules, "new-", newRules);
     2 
     3 var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
     4 var LuaHighlightRules = require("./lua_highlight_rules").LuaHighlightRules;
     5 
     6 var LuaPageHighlightRules = function() {
     7     this.$rules = new HtmlHighlightRules().getRules();
     8 
     9     for (var i in this.$rules) {
    10         this.$rules[i].unshift({
    11             token: "keyword",
    12             regex: "<\%\=?",
    13             next: "lua-start"
    14         }, {
    15             token: "keyword",
    16             regex: "<\?lua\=?",
    17             next: "lua-start"
    18         });
    19     }
    20     this.embedRules(LuaHighlightRules, "lua-", [
    21         {
    22             token: "keyword",
    23             regex: "\%>",
    24             next: "start"
    25         },
    26         {
    27             token: "keyword",
    28             regex: "\?>",
    29             next: "start"
    30         }
    31     ]);
    32 }

    当遇到'<%='或‘<?lua=’,就到lua-start状态,就使用LuaHighlightRules去检测下面的文本,直到遇到"%>", "?>"回到原来的HtmlHighlightRules;
    上面例子会存在<%=?>的嵌套,存在些问题

  • 相关阅读:
    HDU 4460 Friend Chains 第37届ACM/ICPC杭州赛区题目 (bfs求最短路,求两两之间最短路的最大值)
    HDU 4445 Crazy Tank (简单物理题,枚举)
    HDU 4433 locker 第37届ACM/ICPC 天津赛区现场赛C题(DP)
    JQuery 3级级联,3级联动,3级连动
    C++异常处理
    C++ Template
    学会用core dump调试程序错误(转)
    C++命名规则
    vim实用配置(转)
    GDB多进程调试(转)
  • 原文地址:https://www.cnblogs.com/legu/p/8277197.html
Copyright © 2011-2022 走看看