Text::MicroTemplate(Perlのテンプレートエンジン)のシンタックスハイライトを作った話

はじめに

この記事はTech KAYAC Advent Calendar 2020の16日目の記事になります。

こんにちは。技術部の中山といいます。普段はぼくらの甲子園!ポケットチームでUnityとかGAS(Google Apps Script)を触ったりしています。

自分は使っていないのですが、チーム内でText::MicroTemplateというPerlのテンプレートエンジンが使われていて、「シンタックスハイライトがなくて書きにくい」みたいなことを言っている人がいたのでVSCodeのシンタックスハイライトを作りました。

VSCodeの拡張機能を検索する画面で「ext:mt」とか「MicroTemplate」とかで検索するか、 https://marketplace.visualstudio.com/items?itemName=quarter.vscode-microtemplate-syntax-highlight を開いて「Install」を押すとインストールできます。

f:id:nakayama-daisuke:20201215100926p:plain
こんな感じでハイライトされます。

コードはGitHubで公開しています。

techblog.kayac.com

以前こういう記事を書いたのですが、ここには書いていないことをいくつかやったので、この記事で紹介しようと思います。

作り方

次のような手順で作りました。

  1. ファイル全体にHTMLのハイライトの規則が適用されるようにする
  2. MicroTemplateの記法を見つけたらそこにPerlのハイライトの規則を適用する

以下で順番に説明していきます。

ファイル全体にHTMLのハイライトの規則が適用されるようにする

ターミナルで

npm i -g yo
npm i -g vsce
yo code

と入力して質問に答えるといろいろファイルが作られるのですが、その中の syntaxes/xxx.tmLanguage.json みたいな名前のファイルを開いて、 repository というキーを消して、 patterns

{
    "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
    "name": "MicroTemplate",
    "patterns": [{
        "include": "text.html.derivative"
    }],
    "scopeName": "source.microtemplate"
}

のようにすると、ファイル全体がHTMLとしてハイライトされるようになります。 text.html.derivative はHTMLファイルを開いたときに使われる規則の名前です。

↑の場合は scopeName というキーに source.microtemplate と書いてあるので、 source.microtemplate という規則が text.html.derivative という規則と同じ挙動をするようにしているということになります。

MicroTemplateの記法を見つけたらそこにPerlのハイライトの規則を適用する

プロジェクトを生成すると package.jsoncontributes.grammars は以下のようになっていると思うのですが、

[{
    "language": "microtemplate",
    "scopeName": "source.microtemplate",
    "path": "./syntaxes/microtemplate.tmLanguage.json"
}]

この配列に要素を足して次のようにします。

[{
    "language": "microtemplate",
    "scopeName": "source.microtemplate",
    "path": "./syntaxes/microtemplate.tmLanguage.json"
}, {
    "injectTo": ["source.microtemplate"],
    "scopeName": "source.microtemplate.embedded",
    "path": "./syntaxes/microtemplate.embedded.tmLanguage.json"
}]

直前の章で source.microtemplate という規則がHTMLファイルに適用される規則と同じになるように設定しましたが、そこに injectTo というキーを使って別の規則を注入するということをしています。

あとは、 path で指定したファイルに scopeName で指定した名前の規則を書けば完成です。

ファイルの中身は100行くらいありますが、↓のような規則が何個か書いてあるだけです1

f:id:nakayama-daisuke:20201215101039p:plain

ファイル全体が見たい方はここをご覧ください。

さいごに

ここではPerlのシンタックスハイライトの規則をVSCodeに初めから入ってるものを利用してて、たまたまそれっぽくハイライトされてるんですが、本当は ? とか <? ~ ?> とかで分断されてるコードをハイライトしてくれる保証はないはずなので自分で書いたものを使わないといけないと思います。

が、Perlの文法何も知らないのでとりあえずこのままにしておこうと思います。


  1. begin/endの動作はおそらく前に書いた記事のような感じになるので、ここで貼った画像の説明は正確じゃないと思うんですが、このくらいの小さいものを作るだけならこういう雑な理解で別にいいんじゃないかなと思ってます。