Atomで特定の言語のために新しい文法 grammar を作る

# Atomで特定の言語のために新しい文法 grammar を作る

データ解析のソフトウェアSpike2が独自のスクリプト言語を持っていますが、Windowsでしか動作しないし、不自由なので、汎用的なAtomエディタで**構文ハイライト表示**（シンタックスハイライト）が出来ないものかとほぼ一年間ずっと方法を探していました。ちなみに、[BBEdit と TextWrangler のための.plistファイルは以前に作って公開](https://gist.github.com/kouichi-c-nakamura/e879b86e4760201be554)しています。

ところが、どういう奇跡か知りませんが、[How To Develop a Package for GitHub's Atom Code Editor — SitePoint](https://www.sitepoint.com/how-to-write-a-syntax-highlighting-package-for-atom/)という記事が見つかり、一挙に事態が進展を見ました。

希望の言語に対して、希望通りに構文ハイライト表示をするには、

1. grammar文法を作る
2. theme テーマを作る、もしくは、`styles.less`を手動で編集して簡便にCSSの色指定を行う

のふたつの工程が必要なようです。grammarとthemeはそれぞれパッケージと言う形で利用できるようになります。

今回は、`language-spike2`という名前の文法を作ることにしました。

後述するように、一応これでパッケージを公開するところまで行きましたが、**公開時にはエラーが続出し、その根本原因は不明のまま**です。以下の説明を参考にされる場合は、その点を了解済みの上で自己責任で行ってください。



完成したgrammarパッケージ

https://atom.io/packages/language-spike2



# 1. ローカルでgrammarを開発する

## 1-1. 開発用のpackageフォルダを作る

Atomの外部packageのすべては、

+ `C:\Users\<username>\.atom\packages\` (Windows)
+ `/Users/<usename>/.atom/Packages/` (macOS) 

に保存されています。

この直下に`language-spike2`というpackageフォルダを作ります。

+ `C:\Users\<username>\.atom\packages\language-spike2` (Windows)
+ `/Users/<usename>/.atom/Packages/language-spike2` (macOS) 

## 1-2. フォルダ構成

このフォルダの中身を以下のように構成する必要があります。

+ `package.json` 必須
+ `README.md` 説明書き用
+ `grammars`というサブフォルダの下に`language-spike2.cson`を配置します。



## 1-3. package.json

[こちら](https://www.sitepoint.com/how-to-write-a-syntax-highlighting-package-for-atom/)を参照のこと。

私の作った[実例](https://github.com/kouichi-c-nakamura/language-spike2/blob/master/package.json)はこの通り。

```json
{
  "name": "language-spike2",
  "version": "0.2.1",
  "description": "Spike2 script language support for Atom",
  "engines": {
    "atom": "*"
  },
  "dependencies": {},
  "repository": {
    "type": "git",
    "url": "https://github.com/kouichi-c-nakamura/language-spike2.git"
  },
  "keywords": [
    "Spike2",
    "CED Spike2"
  ],
  "readmeFilename": "README.md",
  "license": "MIT"
}
```

+ `version`は最初は`"0.0.0"`とするべき。

+ `engines`ではAtomのヴァージョンを指定しますが、省略。


+ `repository`は公開レポジトリを指定します。上記の例に倣って、urlの末尾に`.git`を付けました。他の例を見ても、皆これを付けているので必須の可能性が高いです。





## 1-4. language-spike2.cson

このファイルで、**正規表現**を使って、言語独自の文法要素に対して、**CSSのクラス名を指定**していきます。私の場合はとりあえず、シンタックスハイライトが目的なので、色を付けたい部分だけ拾うようにしました。

詳しく書くとあまりにも煩雑なので参考にした情報だけ挙げておきます。

やはり[こちら](https://www.sitepoint.com/how-to-write-a-syntax-highlighting-package-for-atom/)を参照。

[こちらにもテンプレート language-sampleGrammar.cson](https://gist.github.com/DamnedScholar/622926bcd222eb1ddc483d12103fd315#file-language-samplegrammar-cson)があります。

クラス名の命名法（ルール）は[こちら](http://manual.macromates.com/en/language_grammars.html#naming_conventions)。

この書法の原型となっているらしい[TextMateのチュートリアルはこちら](http://manual.macromates.com/en/language_grammars)。



## 1-5. Atomを再起動いて動作確認

`language-spike2.cson`の編集内容は、Atomを再起動すると反映されるようです。これでローカルで動作を確認します。

色を変更したい言語のファイルをAtomで開いて、色指定をしたい要素の文字にカーソルを置いて、`Ctrl + Alt + Shift + P` (Windows)、`⌘ + ⌥ + P` （macOS）を同時に押すと、**Scopes at Cursor**というバナーが右上に表示されます。同じことをメニューから行う場合は、`Packages > Command Palette > Toggle`　に続き,  出現したCommand Palette に`log cursor scope`と入力して、**Editor: Log Cursor Scope** を選びます。これによって、指定したクラス名が反映されているかどうかを確認できます。

より詳しく調べるためには、View > Developer > Toggle Developer Tools （Macでは `⌥` + `⌘` + `I`）で、Chromeと同じ形式のディベロッパーツールが表示されます。ツールの左上にある <img width="30" alt="Screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/109898/9fc5e76b-307e-222c-3284-b4d2f6d92801.png">ボタンをクリックすると、ポインタをかざした部分の要素が表示されるので、この情報を元に CSS スタイルを指定していきます。


## 2. grammarをパッケージとして公開publishする

## 2-1. GitHub

GitHubで公開レポジトリ`language-spike2`を作り、上で開発したファイルを加えてGitレポジトリとし、説明用のREADME.mdファイルも加えます。

## 2-2. apm install minorとエラー回避

1. Terminalで、レポジトリのフォルダまで移動し、
2. `apm install minor`とすれば、それだけでAtomのサイトへの公開完了、の筈でした

が、ここで、[エラーに遭遇](https://discuss.atom.io/t/cannot-use-apm-publish-minor-the-header-content-contains-invalid-characters/46283/14)。

```
$ apm install minor
Publishing language-spike2@v0.1.0 ✗
Creating new version failed: Git tag not found
```

右往左往しましたが、Atomのサイトへレポジトリが登録されているらしいことを確認。しかし、README.mdが表示されない、Atomからもアクセスできないなど、何か異常です。

そこで、この失敗した公開パッケージを削除することに。パスワードも聞かれませんでしたが、これって誰でも出来てしまうんですかね？ちょっと恐ろしい設計だ。

```
$ apm unpublish language-spike2
Are you sure you want to unpublish ALL VERSIONS of 'language-spike2'? This will remove it from the apm registry, including download counts and stars, and this action is irreversible. (no)yes
Unpublishing language-spike2 ✓
```

[この投稿](https://github.com/atom/apm/issues/147)を参考にして、ヴァージョンを指定してpublishを試みると、…公開できました。

```
$ apm publish --tag v0.2.1
Registering language-spike2 ✓
Publishing language-spike2@v0.2.1 ✓
Congrats on publishing a new package! 👍  📦  🎉
Check it out at https://atom.io/packages/language-spike2
```

未だに真の原因が不明ですが、もし分かった方がいたら教えてください。



## 3. styles.lessで色指定を行い見た目をカスタマイズ

[CSSクラス名の命名法](http://manual.macromates.com/en/language_grammars.html#naming_conventions)に従えば、上の方法で大体望むような結果が得られるはずですが、実際の色そのものはテーマの選択に依存します。自分でテーマも作ればよいのかもしれませんが、簡単に済ませるならば、`styles.less`の編集です。

1. メニュー **File** > **Stylesheet...** (Windows)または **Atom** > **Stylesheet…** (macOS)から`styles.less` ファイルを開きます。
2. 以下の内容を `styles.less` に加えます。

```less
// Spike2
atom-text-editor.editor {
  .syntax--source.syntax--spike2 {
    color: black;
    
    .syntax--comment {
      color: #008000;
      font-style: normal;
    }
    .syntax--string {
      color: red;
    }
    .syntax--keyword {
      color: blue;
      font-weight: normal;
    }
    .syntax--support.syntax--function {
      color: #000080;
    }
    .syntax--constant.syntax--numeric {
      color: red;
    }
  }
}
```



## スクリーンショット

Spike2の内蔵エディタの色を再現できました。

<img width="957" alt="Atomで新しい文法 grammar を作る.png" src="https://qiita-image-store.s3.amazonaws.com/0/109898/73b0214f-c069-45ff-cffc-e452193e6626.png">


# まとめ

分かっていれば、それほど難しくない（最後の公開部分を除けば調べ物も含めて1-2時間で大体の形ができました）割に、欲しい情報が一箇所になくて、どう進めばよいか分からないという感じでした。

`language-spike2.cson`の編集方法についての情報は前から得られていましたが、それがパッケージ全体とどう関係するのか、[決め手となる情報](https://www.sitepoint.com/how-to-write-a-syntax-highlighting-package-for-atom/)にたどり着くまでちっとも分かりませんでした。

読者の皆さんの役に立てば幸いです。