Rails で Markdown をレンダリングするとき、Qiita みたいにコードブロックにファイル名をつけられるようにしたいな。と思って拡張を書き始めましたが、よく考えたら Qiita::Markdown そのものが公開されているので、それを使わせてもらうのが一番よさそうじゃん!というお話です。
Rails のバージョンは現時点で一番新しかった 4.2.0rc2
を使いました。
事前に準備しておかないと、とか考えてるからお前はいつまでたってもそこから動けないんだよ
Python が必要だからインストールしたいって?その節穴の目をいますぐ潰したほうがいいんじゃないか?よく見ろ、もう入ってるだろ?
Qiita::Markdown はコードのシンタックスハイライトに pygments.rb を使っているので、Python のツールである Pygments をインストールする必要がある、と思うのですが、ちょっといきなりここは明確ではありません。
私の場合、元々 Python 2.7.8 と Pygments をインストールした環境だったのですが、試しに Pygments をアンインストールしても Qiita::Markdown でシンタックスハイライトが効いていました。
Yosemite であれば Python 2.7 系がデフォルトで入っているので、ここは何もせずに次に進んでみてもよいかもしれません。というか、誰か試していただけると嬉しいです。
もし動作しない場合は、以下の手順でシステムの Python をいじらずに Homebrew でインストールした Python に Pygments をインストールすることをおすすめします。
$ brew install python
$ type python
python is /usr/local/bin/python
$ pip install pygments
なるほど、また Rails アプリケーションを作成したいのか。何回やっても無理だよ。お前には早い。一生早い
でた!Rails new!ほんとお前好きだよな Rails new!またどうせいつもと同じで、new して何も中身を作れず終わるんだろ?まるでお前の人生みたいだな
それでは Rails のアプリケーションを作るところからはじめます。
ここでは、例として qiita_markdown_example
という名前で作ることにします。
$ rails new qiita_markdown_example
bundle install が nokogiri でこけたって?今度は rugged でこけたって?仕方ないな。続きは俺がやっておくから、お前はもう田舎に帰って bundle install のことは忘れろ
Gemfile
に Qiita::Markdown を追加して、bundle install
します。
$ cd qiita_markdown_example/
...
gem 'qiita-markdown'
...
$ bundle install
もし Native Extension のビルドに失敗したら、以下の記事などを参考にインストールを完了させてください。
Qiita::Markdownを使う on Yosemite
お前がメールで emoji 使うのがキモイ、ってあの子がこないだ言ってから emoji 使うのやめたんだって?さっき聞いたら、emoji なくてもやっぱキモイってよ
Qiita::Markdown は emoji を使うので、emoji 用の画像をアプリケーションにインストールしておく必要があります。
ただ、emoji を利用しないのであれば、ここの手順は飛ばしても構いません。
任意のディレクトリ (ここでは例として ~/Desktop
) に gemoji を clone して、用意されている Rake タスクを利用してアプリケーションにコピーします。
$ cd ~/Desktop
$ git clone git@github.com:github/gemoji.git
$ cd path/to/qiita_markdown_example
$ bundle exec rake -f ~/Desktop/gemoji/lib/tasks/emoji.rake emoji
これを実行すると、public/images/emoji/
以下に画像がインストールされます。
scaffold って聞くたびにスキャットマンの真似するの、悪いけど本当につまらないからやめてくれるか?
ここでは、scaffold を使って、Page という、Markdown をレンダリングするためのアプリケーションの雛形を作成することにします。
$ bundle exec rails g scaffold Page body:text
$ bundle exec rake db:migrate
あと、renderer って聞くたびにスマップの真似するの、あれはちょっと面白いから俺がもらうわ。お前は2度とやるなよ
Qiita::Markdown で文字列をレンダリングするためのヘルパーを定義します。
module ApplicationHelper
def qiita_markdown(markdown)
processor = Qiita::Markdown::Processor.new
processor.call(markdown)[:output].to_s.html_safe
end
end
結果を表示するためにビューを編集します。
<p id="notice"><%= notice %></p>
<p>
<strong>Body:</strong>
<%= qiita_markdown(@page.body) %>
</p>
<%= link_to 'Edit', edit_page_path(@page) %> |
<%= link_to 'Back', pages_path %>
ハイライト結果が見に見えないと寂しいので、とりあえず以下の CSS を追加しておきます。
.code-frame {
background-color: #eee;
.code-lang {
span {
padding: .5em;
color: #fff;
background-color: #666;
}
}
.highlight {
.hll { background-color: #ffffcc }
.c { color: #999988; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #000000; font-weight: bold } /* Keyword */
.o { color: #000000; font-weight: bold } /* Operator */
.cm { color: #999988; font-style: italic } /* Comment.Multiline */
.cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.c1 { color: #999988; font-style: italic } /* Comment.Single */
.cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { color: #000000; font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #999999 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #aaaaaa } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.kt { color: #445588; font-weight: bold } /* Keyword.Type */
.m { color: #009999 } /* Literal.Number */
.s { color: #d01040 } /* Literal.String */
.na { color: #008080 } /* Name.Attribute */
.nb { color: #0086B3 } /* Name.Builtin */
.nc { color: #445588; font-weight: bold } /* Name.Class */
.no { color: #008080 } /* Name.Constant */
.nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.ni { color: #800080 } /* Name.Entity */
.ne { color: #990000; font-weight: bold } /* Name.Exception */
.nf { color: #990000; font-weight: bold } /* Name.Function */
.nl { color: #990000; font-weight: bold } /* Name.Label */
.nn { color: #555555 } /* Name.Namespace */
.nt { color: #000080 } /* Name.Tag */
.nv { color: #008080 } /* Name.Variable */
.ow { color: #000000; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #009999 } /* Literal.Number.Float */
.mh { color: #009999 } /* Literal.Number.Hex */
.mi { color: #009999 } /* Literal.Number.Integer */
.mo { color: #009999 } /* Literal.Number.Oct */
.sb { color: #d01040 } /* Literal.String.Backtick */
.sc { color: #d01040 } /* Literal.String.Char */
.sd { color: #d01040 } /* Literal.String.Doc */
.s2 { color: #d01040 } /* Literal.String.Double */
.se { color: #d01040 } /* Literal.String.Escape */
.sh { color: #d01040 } /* Literal.String.Heredoc */
.si { color: #d01040 } /* Literal.String.Interpol */
.sx { color: #d01040 } /* Literal.String.Other */
.sr { color: #009926 } /* Literal.String.Regex */
.s1 { color: #d01040 } /* Literal.String.Single */
.ss { color: #990073 } /* Literal.String.Symbol */
.bp { color: #999999 } /* Name.Builtin.Pseudo */
.vc { color: #008080 } /* Name.Variable.Class */
.vg { color: #008080 } /* Name.Variable.Global */
.vi { color: #008080 } /* Name.Variable.Instance */
.il { color: #009999 } /* Literal.Number.Integer.Long */
}
}
もうおしまいだ
では Rails を起動して、実際に何か Markdown で書いてみましょう。
$ bundle exec rails s
Web ブラウザで http://localhost:3000/pages/
にアクセスして body に Markdown で何か書く(せまい)。
# Headline 1
## Headline 2
Hello Kitty, Hello Kitty, Hello Kitty Good Pxxxy and Txxxy :cat:
```ruby:hello_kitty.rb
def hello_kitty
puts 'Hello Kitty'
end
できました!!
ちゃんと絵文字もシンタックスハイライトも使えてますね!