写 Highlight.js 插件的一些尝试

发布时间:2019-08-06 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了写 Highlight.js 插件的一些尝试脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

我想写 Cirru 的语法高亮, 实际上我失败了, 或者说花的心思不够多吧.
Highlight.js 的文档和代码示例还是比较不错的, 只是..
写 CodeMirror 和 Pygments 的插件时, 全局传递的状态非常有用,
CoderMirror 只有一个状态, 而 Pygments 和 Lexer 类似有状态的数组,
然而, 比如 Sublime 就没有状态传递的方式, Highlight.js 更糟糕.

开发流程

Fork 的成本并不高, 我把文档页面上的步骤大概翻译一下:
http://highlightjs.readthedocs.org/en/latest/contribution.html

  • 首先 gIT clone 代码, 确认已经安装 python3
  • src/langauges/ 下创建文件, 比如我是 cirru.js
  • cirru.js 文件头部写如一些语言相关的信息, 比如
/*
Language: Cirru
Author: Jiyin Yiyong <jiyinyiyong@gmail.COM>
Contributors: Jiyin Yiyong <jiyinyiyong@gmail.com>
Description: Cirru is an indentation-based grammar for programming languages. See http://cirru.org/
*/

测试环境

其实测试比较麻烦, 每次修改文件以后都需要进行编译, 或者说合并

tools/ 目录下运行命令将 JS 打包, 然后可以浏览器打开 src/test.html 测试:

python3 build.py

或者如果只是打包一种或者几种语言, 通过参数指定:

python3 build.py -n cirru

测试的语言下, 会有对应的一些数字, 这是 Highlight.js 在用多种语言检测代码,
比如这里是 Scala 和 CoffeeSript 代码示例中的匹配结果:

写 Highlight.js 插件的一些尝试

如果其他语言的匹配结果过高, 会提示测试失败.. 不过调试过程中不大看这个.

高亮语法

直接用 JSON 的例子来说明问题吧:

/*
Language: JSON
Author: Ivan Sagalaev <;maniac@Softwaremaniacs.org>
*/

function(hljs) {
  var LITERALS = {literal: 'true false null'};
  var TYPES = [
    hljs.QUOTE_STRING_MODE,
    hljs.C_NUMBER_MODE
  ];
  var VALUE_CONTAINER = {
    className: 'value',
    end: ',', endsWithParent: true, excludeEnd: true,
    contains: TYPES,
    keywords: LITERALS
  };
  var OBJECT = {
    begin: '{', end: '}',
    contains: [
      {
        className: 'attribute',
        begin: '\s*"', end: '"\s*:\s*', excludeBegin: true, excludeEnd: true,
        contains: [hljs.BACKSLASH_ESCAPE],
        illegal: '\n',
        starts: VALUE_CONTAINER
      }
    ],
    illegal: '\S'
  };
  var ARRAY = {
    begin: '\[', end: '\]',
    contains: [hljs.inherit(VALUE_CONTAINER, {className: null})], // inherit is also a workaround for a bug that makes shared modes with endsWithParent compile only the ending of one of the parents
    illegal: '\S'
  };
  TYPES.splice(TYPES.length, 0, OBJECT, ARRAY);
  return {
    contains: TYPES,
    keywords: LITERALS,
    illegal: '\S'
  };
}

首先, 关键字通过声明可以自动高亮, 不用太多问题了.
然后是 contains 里增加可以被高亮出来的模式,
其中 begin end 标记模式的开始和结尾, 比如 [] 的效果,
cantains 可以进行嵌套, 定义比如 "escape" 之类的语法.

一些技巧:

  • 只有 begin 没有 end 时, begin 的内容就是匹配字符串内容,
  • 虽然例子上都是字符串表示的正则, 但内部实现来说, 直接写正则更方便,
  • 文档上有 starts 属性, 表示在当前模式结束后立即进行对应模式,
  • hljs.BACKSLASH_ESCAPE 这些内置模式可以加快书写

更多细节请参考文档, 或者 src/languages/ 下丰富的例子:

结果

我尝试改了几个小时, 结果不理想, 没有想到好的方案:
https://github.com/Cirru/highlight.js/commit/428f198c285319cb4a06381f2...
主要是开头说过的问题, Highlight.js 没有状态的概念,
而 Cirru 将表达式第一个标识符作为函数处理, 就很不方便,
在 Sublime 里我做的处理比较 tricky, 也许未来还是要换..
暂时就这些了.


返回博客首页: http://blog.tiye.me

脚本宝典总结

以上是脚本宝典为你收集整理的写 Highlight.js 插件的一些尝试全部内容,希望文章能够帮你解决写 Highlight.js 插件的一些尝试所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。