今回は、.md
ファイルにMarkdown形式で文章を書いておき、それをApache httpdやnginxでホストし、ブラウザからアクセスするとHTMLに変換されて表示されるMarkdownコンバータモジュールをmrubyで書く方法を紹介したいと思います。
Markdownのテキスト形式で保存しているファイルを適当にApache上で配信すれば、ブラウザ上でHTMLで綺麗に閲覧できるといったよくあるアレをWebサーバを拡張して実装してみようという話です。自分の開発環境やローカル環境のメモ置き場にも良いかもしれません。
Apacheモジュールやnginxモジュールで幾つかそういった機能を提供するモジュールはあると思うのですが、もう少し独自で改良したかったり、C言語で実装せずにもっと簡単に自分で書いてみたい、といった要求に本エントリを読むと答えられると思います。
もちろんそれらの機能の実装は、僕が開発しているApacheはmod_mrubyを、nginxはngx_mrubyを使って実装してみましょう。
ApacheでMarkdownコンバータモジュールをmrubyで実装
では早速実装してみましょう。
まずは、httpd.conf
やconf.d/markdown.conf
のような設定ファイルに以下のようにApacheモジュール代わりにフックするRubyスクリプトのパスを書きます。
<FilesMatch "^.*\.md$"> AddType text/html .md SetOutputFilter mruby mrubyOutputFilter /path/to/filter.rb </FilesMatch>
続いて、そのRubyスクリプト/path/to/filter.rb
に以下のようにMarkdown変換処理を書きます。
# このスクリプトが動くミドルウェアのチェック if server_name == "NGINX" Server = Nginx elsif server_name == "Apache" Server = Apache end f = Server::Filter.new # Markdown変換の準備、スタイルの読込等 css = "https://gist.github.com/andyferra/2554919/raw/2e66cabdafe1c9a7f354aa2ebf5bc38265e638e5/github.css" title = "markdown" md = Discount.new css, title # MarkdownからHTMLに変換したデータをレスポンスデータに上書き f.body = md.md2html f.body
コードの内容は説明するまでもないでしょう。これだけで、Markdownコンバータモジュールが作成できました。例えば、以下のようなMarkdownファイルにアクセスすると、
# Section ## aaa - hoge - foo ## bbb __code__ a = 1 b = a + 1
以下のように表示されます。
簡単ですね。C言語で書く場合と比べるとコードの量も大幅に少ない事がわかります。
nginxでもMarkdownコンバータモジュールをmrubyで実装してみる
続いてnginxでも同様の機能を実装してみましょう。
nginxでは、mod_mrubyのかわりにngx_mrubyを使いましょう。インストール方法等はGitHubのWikiを御覧ください。また、Dockerfileを使った簡単なインストール方法もWikiに書いているので、ざっと試すにはそれらを使うのが良いかもしれません。
まずは、以下のような設定をnginx.conf
に書きます。
location ~ \.md$ {
mruby_output_filter /path/to/filter.rb;
}
続いて、mod_mrubyと同様に/path/to/filter.rb
にコンバートの処理を実装します。
# このスクリプトが動くミドルウェアのチェック if server_name == "NGINX" Server = Nginx elsif server_name == "Apache" Server = Apache end f = Server::Filter.new # Markdown変換の準備、スタイルの読込等 css = "https://gist.github.com/andyferra/2554919/raw/2e66cabdafe1c9a7f354aa2ebf5bc38265e638e5/github.css" title = "markdown" md = Discount.new css, title # MarkdownからHTMLに変換したデータをレスポンスデータに上書き f.body = md.md2html f.body
おや?mod_mrubyの時のmrubyの実装と全く同じですね。
そうなんです。このように、mod_mrubyとngx_mrubyはある程度クラスやメソッドの実装の互換性を持たせつつ並行して開発していますので、こういった実装が可能になります。このように開発していくことで、mod_mrubyで学んだメソッドや実装のコツといった資産は、もう一方のngx_mrubyでもある程度活かせる、という特徴があります。
当然、この.md
ファイルにアクセスすると、以下のように表示されます。
mod_mrubyの時と同様ですね。
ApacheモジュールやnginxモジュールをC言語で書く事なくこんなに簡単にかけました。
まとめ
以上のように、今回はApacheとnginxのMarkdownコンバータモジュールをC言語で実装するのではなく、mod_mrubyとngx_mrubyを使ってmrubyで実装してみました。
C言語でそれぞれを実装した事がある人は、この実装の簡単さにびっくりしたのではないでしょうか。
このように、mod_mrubyやngx_mrubyを使えば、Apacheやnginxのモジュールという敷居の高かった開発が、非常に簡単にできるようになります。また、mod_mrubyとngx_mrubyは、mrubyの軽量な特徴をいかして、スクリプト言語による実装にも関わらずかなり高速に動作するように実装しているので、生産性と性能のバランスが取りやすいのではないでしょうか。
非常に簡単にWebサーバの拡張が書けますので、まずは自身のローカルサーバや検証環境等で、自分用の便利なApache(nginx)モジュールをmrubyで開発して遊んでみると、色々捗るのではないかと思います!
例えば今回のMarkdownコンバータの実装に、追加で実装して遊んでみるのも楽しいと思います。休みの日とかサーバ弄って遊んでみよっかなーみたいな日に是非是非色々遊んでみてください!
言い忘れていましたが、mod_mrubyやngx_mrubyのビルドの際に、build_config.rb上でmruby-discountをリンクする設定をコメントで書いているのでそのコメントを外してビルドして下さいね!