2013-05-12 12:24

マークダウンとシンタックスハイライト

redcarpetpygments.rbを使い、Markdown記法を使えるようにして、さらにSyntaxHighlightも実装します。

マークダウンとは

文書を記述するための軽量マークアップ言語のひとつである、らしい。
要は、プレーンテキストとして書きやすい形式で記述された文書を、XHTMLとかHTMLで見やすい形式に変換してくれる、てこと。

例えば、、、

プレーンテキスト
### これはh3です。

これはh3です。

となる。

他にも、テーブルが作成できたり、リンクや画像を配置できたり。
まぁ便利なんです。

マークダウン記法についてはこちら ⇒ Markdown記法 -チートシート-

シンタックスハイライトとは

指定したプログラミング言語上の分類ごとにソースコードをカラーリングしてくれる機能のこと。
このサイトでもたびたび登場します。

例えば、、、

ruby
# -*- coding: utf-8 -*-

class ArticlesController < ApplicationController
  # 記事一覧
  def index
    @articles = Article.order("posted_at DESC")
  end

  # 記事詳細
  def show
    @article = Article.find(params[:id])
  end
end

という感じになります。
日本語もちゃんと表示できてる。
カラーリングの設定はcssで行っています。

ここでは、pygments.rbというgemを使います。
Pygmentsは元々Pythonのライブラリなのですが、それをRubyで使用します。
他にも色々とシンタックスハイライトのライブラリがあるみたいなんだけど、カバーしている言語が比較的豊富だったのでpygments.rbにしました。

マークダウンとシンタックスハイライトの実装

まず、GemfileにGemを追加しましょう。

Gemfile
gem 'redcarpet'
gem 'pygments.rb'

gem 'rubypython'

rubypythonはRubyにPythonを組み込む拡張ライブラリで、Python用に作られた任意のモジュールをRubyスクリプトから呼び出すことができる。
つまり、Pythonがインストールされていない環境でもpygments.rbが問題なく起動できるようになる、ということ。
Herokuとかでも使える。

んで、bundle installしておく。

ターミナル
$ bundle install

次いで、application.rbにrubypythonのセットアップのコードを書く。

class Applicationの中に、

application.rb
    RubyPython.start(python_exe: "python2.6")

を追加。

で、最後にapplication_helper.rbに実装。
以下のコードをmodule ApplicationHelper内に追加してください。

application_helper.rb
  # マークダウン
  def markdown( text )
    html_render = HtmlWithPygments.new( :hard_wrap => true, :filter_html => true )
    markdown = Redcarpet::Markdown.new( html_render,
                                        :autolink => true,
                                        :fenced_code_blocks => true,
                                        :space_after_headers => true )
    return markdown.render( text ).html_safe
  end

  # シンタックスハイライト
  class HtmlWithPygments < Redcarpet::Render::HTML
    def block_code( code, language )
      Pygments.highlight( code, lexer: language, options: { encoding: 'utf-8' } )
    end
  end

簡単に解説しておくと、、、

後半部分でRedcarpet::Render::HTMLを継承したHtmlWithPygmentsクラス作成して、その中でPygmentsを使ったハイライトのメソッドを追加しています。

前半部分ではmarkdownメソッドの中でHtmlWithPygmentsを初期化し、レンダラーhtml_renderを作成。
作成したレンダラーを第一引数としてRedcarpet::Markdown.newでマークダウンオブジェクトmarkdownを生成する。
最後のmarkdown.render( text ).html_safeでtext中のマークダウン記法を解釈しHTML形式に変換している。

Redcarpetの使い方やオプションはこちらが詳しいです。
参考にさせていただきました。
おもしろWEBサービス開発日記

Viewでの対応

こうして実装すれば、下記のようにViewでmarkdownメソッドを使うことができ、マークダウンとシンタックスハイライトが解釈されてHTMLで表示される。

show.html.erb
<%= markdown(@article.body) %>

あとは、自分の好みのようにCSSを作成するだけ!
参考までに、このブログで使用しているシンタックスハイライト用のCSSを掲載しておきます。
シンタックスハイライトのCSS