Eureka

Tech, or not

pyorgというパッケージを作りました

2016-12-13

この記事はEmacs Advent Calendar 2016の、13日目の記事で、執筆者は@nasa9084です。
前日はfujimisakariさんのプログラミングに役立つelisp10選でした。


org記法でブログを書きたい

全国のEmacsユーザの皆さん、org-modeは使っていますか?私は使っています。
普段Pythonを書く私にとって、#はコメントアウトのイメージで、#を見出しに使うmarkdownは(ダメってほどじゃないですけど)なんとなく好きになれません。Emacsユーザということもあり、細かいメモを取るときや、スライドを作るときはorg-modeを使っています。

そんなわけで、慣れ親しんだorg記法。ブログを書くときも使いたいと考えました。
しかし、マークダウンで書くことができるブログや、或いはorgで書いたものをwordpressにアップすることができるelispなんかも有りましたが、どうもしっくり来ません。
そんな折に運用していたWordPressが使えなくなり、このブログシステムを作りました。
Pythonで使えるorg記法パーサも探したのですが、どれもブログで使えるようなものではなく、自分で変換機構も作成することにしました。
最初はブログシステムの中にorgをHTMLに変換するフィルターを作ればいいかな、と思って書き出したのですが、コレがなかなかうまく行かず。最終的にパーサとしてパッケージ化したので、そのお話をさせていただこうと思います。


正規表現の置換だけで実装してみた

org記法を使いたいとは言っても、ブログ記事を書くのに使いたいだけなので、チェックボックスや時間に関する部分など、org-modeの大部分は必要ありません。文字の装飾部や見出し、リストが実装されれば十分です。
ですので、最初はわざわざ構文木などを作らずとも、単純に正規表現で置換すればいいのではと考えて実装を始めました。
しかしコレが大きな間違いだったのです。

リスト

問題の1つめは、ネストしたリストを使えないことでした。
単純に正規表現で行ごとに置換していく都合上、ネストしたリストを解析することができません。この段階で、ネストしたリストは使わないことにしよう、と考えました。
しかし、実際に実装してみてわかったのですが(気づくのが遅い)、問題はそれだけではありませんでした。
リストが始まったことや終わったことを判断できないのです。いま置換している行はリストの始めなのか(つまり<ul>が必要なのか)、真ん中なのか、終わりなのか、判断することができないのです。これは困りました。

スラッシュ

更に大きな問題が潜んでいました。斜体とリンクです。
ご存知のように、URLは区切り文字としてスラッシュを多用します。また、org-modeでは斜体をスラッシュで挟んだ形で表します。
このせいで、URLの一部が斜体としてマークアップされてしまう事態が発生しました。
これはちょっと困ったものです。とりあえず斜体を使わないこととしましたが、これには不満が残ります。


結局パーサとしてパッケージ化

更に、テーブルの実装ができないなど、org記法が使える!というには不満点が多すぎました。
そんなわけで、改めて外部モジュールとして、org記法のパーサを書きました。org記法で書かれたテキストを読み込み、解析し、抽象構文木を生成します。そこからHTMLを出力することも可能です。GitHub上でソースも公開しています(nasa9084/py-org)。
コレをブログシステムに組み込むことでorgでブログを書くことができるという寸法です。
また、当初予定してはいなかったのですが、gitのsubmoduleで管理するのはバージョンアップの際などいろいろと面倒なので、パッケージ化してPyPIへとアップしました(pyorg)。
現在はバージョン0.1.3として、見出し、リスト、テーブル、リンク、画像、引用、文字の強調を実装済みです。今後、少しずつ拡張予定ですが、当面はリファクタリングを進めようと思っています。

以上、pyorgのお話でした。