2

让 GitHub 识别定制的语言

GitHub 的语法高亮是通过 github/linguist 实现的, 实际上封装了 Pygments,
如果要让 GitHub 能对代码进行高亮, 就需要 Pygments 先支持这们语言,
然后, 在上述 repo 的 lib/linguist/languages.yml 文件里声明语言怎样识别,
一般是根据文件后缀进行区分, 有时也会进行更复杂的处理判断具体语言,

在 GitHub 声明语言的步骤并不难, 几行声明即可, 外加一些示例的文件
https://github.com/github/linguist/pull/906/files

langauges.yaml 里主要是这样一些选项:
https://github.com/github/linguist/blob/master/lib/linguist/languages....

yamltype              - data, programming, markup, or nil
lexer             -  lexer String (默认是语言名称)
aliases           - aliases (implicitly includes name.downcase)
ace_mode          - A String name of Ace Mode (if available)
wrap              - Boolean wrap to enable line wrapping (default: false)
extensions        - 相关的后缀名
interpreter       - An Array of associated interpreters
primary_extension - 唯一的语言后缀名
searchable        - Boolean flag to enable searching (defaults to true)
color             - 10 进制的颜色.

Pygments 告一段落了, 现在是 Ace 的问题, 需要编写对应的插件

文档

Ace 的文档一个是在官网比较详细: http://ace.c9.io/
此外在 GitHub Wiki 上还有一些: https://github.com/ajaxorg/ace/wiki/_pages
相对来说源码提供的帮助也非常大, 已有的例子比较清晰,

插件开发流程

添加插件大致是要修改下面几个地方,

添加语言到 modelist

lib/ace/ext/modelist.js 里需要按格式填入 Cirru 对应的后缀,
kitchen-sink/ 页面进行调试时会用到 modelist 的内容.

添加示例的代码

我添加的代码是在 demo/kitchen-sink/docs/cirru.cirru
kitchen-sink/ 里调试时会用到这边的代码, 通过请求加载到编辑器里,
make build 执行时似乎也会引入这部分代码...

mode 文件

主要的语言配置文件在 ace/lib/ace/mode/ 下, 比如 cirru.js 控制 Cirru 的行为
主要的配置有 Folding, Indent, 通过覆写一些方法对具体逻辑进行调整,
另外语法高亮也从这个文件引入, 如果是沿用已有的模版, 要注意修改相关变量名.

再有一个是 Worker 可能涉及到, 是通过 Web Worker 在后台处理语法的,
在编写 Cirru 插件时, 遇到后台跑的 JSON Worker 没有删除, 会给我报错.
我不清楚具体功能, Cirru 里用不到, 临时去掉了代码. 文档倒是有:
https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode...
https://github.com/ajaxorg/ace/wiki/Syntax-validation

Indent 是 Cirru 里没做的, 相关代码也去掉了.

Folding 实现略复杂, 不过, Ace 提供了机制可以使用已有的其他 Style,
比如 JSON 集成了 CStyle 的 Folding, Cirru 于是继承了 CoffeeStyle.

$rules 文件

cirru_highlight_rules.js 是这样一个文件专门高亮语法.
文件也放在 ace/lib/ace/mode/. 平级有时可能还有其他的文件...

关于高亮如何生成, 看一些 JSON 的例子会觉得比较清晰:
https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/json_highlight...

文档上例子讲得也比较清晰, 主要就是一些状态, 默认是 start:
http://ace.c9.io/#nav=higlighter

jsthis.$rules = {
    "start" : [ {
        token : "text",
        merge : true,
        regex : "<\\!\\[CDATA\\[",
        next : "cdata"
    },

    "cdata" : [ {
        token : "text",
        regex : "\\]\\]>",
        next : "start"
    }, {
        token : "text",
        merge : true,
        regex : "\\s+"
    }, {
        token : "text",
        merge : true,
        regex : ".+"
    } ]
};

每次匹配, 都会都数组里选取一条, 按 regex 进行匹配,
next 表示匹配当前项之后, 转到新的一个 state 去, 如此循环.

文档里没写, 但是源码里暗示 Ace 有 Pygments 类似的 pushpop,
https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/haskell_highli...

Ace 的 Token 是和 TextMate 保持一致的, 具体可看文档:
https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode...
因此考虑在 Theme 方面两者也有一些共通,, 还有 Sublime 也是..

具体可以看我 PR 上提交的修改. 也可能存在一些需要纠正的地方:
https://github.com/ajaxorg/ace/pull/1780

调试

关于 $rules 的调试在 Creator 里做基本可以完成了
http://ace.c9.io/tool/mode_creator.html
完了手动复制到文件里去, 注意一些变量名可能要更改到对应 Cirru

ace/kitchen-sink.html 可以直接加载文件运行, 简单的 Nginx 静态服务器即可,
当然这个是在几个应对的文件修改完成以后..

build

暂时没去研究 build 用途.. 主要是对文件进行和合并的样子:

npm install
make build

合并后, index.html 可以打开直接运行, build/ace/kitchen-sink.html 也是
kitchen-sink.html 里打开的话, 就是下面这个样子:


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


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者