読者です 読者をやめる 読者になる 読者になる
月 の 上

Atomのはてな記法モードを作ったよ!!

https://cloud.githubusercontent.com/assets/1403842/23390963/93f9712a-fdb4-11e6-82c3-67798c57e2f6.png

atom.io

はてなブログはてなグループ、増田に投稿する時に便利です。
どうぞご利用ください。

もくじ

機能

はてな記法シンタックスハイライトしてくれる

こんな感じ

https://cloud.githubusercontent.com/assets/1403842/23390963/93f9712a-fdb4-11e6-82c3-67798c57e2f6.png

Markdown文字列をはてな記法に変換できる

md2hatenaを利用した変換機能です。

language-hatena をインストールすると、Language Hatena: Convert Markdown To Hatena Syntax というコマンドが使えるようになります。
文字列を選択し、Cmd + P でコマンドパレットを表示して、 hatena とか打ち込んだら出てきます。
何も選択されていないときはファイル全体を変換します。

https://cloud.githubusercontent.com/assets/1403842/23490546/8d97a4bc-ff3c-11e6-8514-20af7e062710.gif

便利〜〜〜〜!!!!

スニペット使える

よく使うスニペットをいくつか定義しています。

f:id:amagitakayosi:20170304095644g:plain

現在使えるスニペットは以下のとおり。

  • code: スーパーpre記法
  • inlineCode: <code></code> を出力する。文中にコードを書きたい時に。
  • table: 表組み記法
  • image: [(画像URL):image] を出力する (http記法) 。
  • comment: <!-- --> を出力する

インストール方法

AtomのInstall Packages画面で検索してインストールしましょう。

f:id:amagitakayosi:20170304095022p:plain

もちろん apm でもインストールできます。

apm install language-atom

Atomで新しい言語のモードを作る方法

ここからは、Atomで新言語に対応するパッケージを開発する方法を解説します!

基礎知識

Atomlanguage-*** の作り方、公式ドキュメントにはまとまった情報がありません。
今回得た情報を要約するとこんな感じです。

言語モードはAtomのpackageとして開発する

Atomでは、ほぼ全ての機能がpackageとして実装されています。
言語の解釈は language-*** といった名前のpackageで行ないます。
これを language package と呼びます。

言語のパースは正規表現で行なう

language packageは正規表現を羅列した Grammar ファイルを持ちます。
これはTextmateで使われていたGrammarファイルと似た形式になっています。

TextmatemacOS向けのテキストエディタです。
日本では殆ど使われていませんが、英語圏ではGUIでつかえる入門向けエディターとして、かつて人気を博していました。

github.com

Textmateでは、言語のパースは正規表現で行われていました。
Grammarファイルに記法ごとの正規表現を記述し、文字列を keywordstring といったトークンに分解していました。

Atomでは、Textmateとよく似たGrammarファイルを利用して言語のパースを行ないます。
TextmateのGrammarファイルは XML 形式でしたが、Atomでは CSON 形式で記述します。

また、Atomのパッケージ管理ツール apm には、TextmateのGrammarファイルをAtomの形式に変換する機能が存在します。
Atomのlanguage packageの多くは、この変換機能を利用して作成されたようです。

Converting from TextMate

というわけで、language packageは正規表現をこねくり回して作ることになります。

実際の手順

今回の開発は、次の手順で行ないました。

  • apm init -l で雛形を作る
  • apm link して手元のAtomにインストール
  • grammars/ にGrammarファイルを書く
  • snippets/スニペットを追加
  • settings/ を編集
  • apm publish

色々と適当ですが、順番に解説していきます。

apm init -l で雛形を作る

apmAtomのパッケージ管理ツールですが、新たにパッケージを開発するためのテンプレート機能が存在します。
apm init --language (または-l) を実行すると、language packageの雛形が作成されます。

$ apm init -l hatena
$ tree language-hatena
language-hatena
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── grammars
│   └── hatena.cson
├── package.json
├── settings
│   └── language-hatena.cson
└── snippets
    └── language-hatena.cson

3 directories, 7 files

apm link を実行すると、開発中のパッケージを手元のAtomにインストールできます(apm unlink で解除)。

$ cd language-hatena
$ apm link
/Users/amagitakayosi/.atom/packages/language-hatena -> /Users/amagitakayosi/language-hatena

Window: Reload コマンドでAtomをリロードすると、選択できる言語のリストに新しい言語が追加されたのが確認できるはずです。

grammars/ にGrammarファイルを書く

早速Grammarファイルを書いていきます。

Grammarファイルの書き方は複雑なので、いきなりまっさらな状態から書き始めるのはオススメしません。
既存のlanguage packageからよく似た言語をのGrammarファイルを元に書くことをオススメします。
はてな記法の構造はMarkdownとよく似ているため、今回は laguage-gfm のGrammarファイルを参考にしました。

Grammarファイルは以下のように書きます。

'scopeName': 'source.hatena'  # 言語の識別子
'name': 'Hatena Syntax'  # 言語の名前。言語セレクターとかで出てくる
'fileTypes': [  # 拡張子
  'hatena'
  'h'
]
'patterns': [  # 記法/トークンに対応する正規表現を書いていく
  {
    'match': '^[\\+\\-]+'  # 正規表現
    'name': 'markup.list.hatena'  # クラス
  }
]

patternsには、記法/トークンに対応するパターンオブジェクトを書いていきます。
ここでは リスト記法 に対応するパターンを記述しました。
name には、 match正規表現にマッチした文字列にあてるクラス名を指定します。

ご存知のとおり、Atomではエディター内のすべての要素がHTMLとCSSで出来ています。
シンタックスハイライト機能は、language packageがHTML要素にクラスを与え、テーマのpackageがスタイルを当てる、という仕組みで実現されています。
name で指定した文字列は . で分割され、コードを表現するHTML要素のクラスに設定されます。

今回の場合だと、以下の文字列は

- foo
- bar

次のようなHTMLに変換されます(簡略化してあります)。

<span class="markup list hatena">-</span> foo
<span class="markup list hatena">-</span> bar

パターンオブジェクトには、 match name の他にも begin end captures などのプロパティを指定できます。
それらの使い方については、実際のGrammerファイルを見たほうが速いでしょう。
https://github.com/atom/language-gfm/blob/master/grammars/gfm.cson

Grammarファイルの開発は、次のような手順で進めました。

1. patternsにパターンを一つ追加する
2. Window: Reload コマンド(Cmd + Alt + Shift + L)でAtomをリロード
3. おかしい所を直す
4. 2.3.を繰り返して、直ったら git commit

snippets/ にスニペットを追加

スニペットの追加は、普段 ~/.atom/snippets.cson を書くのと全く同じ方法で行えます。
めっちゃ簡単だし日本語情報も沢山あるので割愛。

Snippets

settings/ を編集

Atomでは Cmd + / で文字列をコメントアウトできますが、そのためには settings にコメントの記法を追加する必要があります。
language-hatena の場合はこんな感じ。

'.source.hatena':
  'editor':
    'softWrap': true
    'commentStart': '<!-- '
    'commentEnd': ' -->'
GitHubにpush

Atomパッケージを公開するには、GitHubにレポジトリを公開する必要があります。
レポジトリを作成したら git push して、 package.jsonrepository フィールドを追加してください。

{
  "name": "language-hatena",
  "version": "0.0.0",
  "description": "Syntax highlighting and snippets for Hatena Syntax (?????).",
  "repository": "https://github.com/fand/language-hatena",
  "license": "MIT",
  "engines": { "atom": ">=1.0.0 <2.0.0" }
}
apm publish

いよいよ公開です!
apm publish するとパッケージが atom.io に登録され、パッケージマネージャーからインストールできるようになります。

f:id:amagitakayosi:20170304095119p:plain

公開成功です!!!!

apm publish [更新の単位] を実行すると、パッケージのバージョン更新、gitのタグ作成、Atomへの公開まで apm が自動でやってくれます。
今回は更新の単位に minor を指定したので、バージョンは 0.0.0 から 0.1.0 に更新されました。

公開したら、実際にインストールできるか試してみましょう。
apm unlink で手元のパッケージをアンインストールし、Atomをリロードします。
Install Packages画面で検索すると、公開したパッケージが見つかるはずです。

f:id:amagitakayosi:20170304095022p:plain

お疲れ様でした!!!!🎉🎉🎉🎉🎉

参考リンク