ソースコードを見やすく表示する(CodeRay)

作成者 Satoshi -- 2009年01月18日 16時42分

すでにいくつかのプログラムサンプルを掲載していますが、これらは全て CodeRay ライブラリを用いて整形されています。

CodeRay ライブラリは、プログラムの構文を解析し、キーワードや文字列、コメント等をわかりやすく表示できる HTMLに変換してくれます。例えば、

require 'rubygems'
require 'coderay'

# CodeRay を利用したサンプルプログラム
text = '@blogs = Blog.find(:all, :conditions => [ "category_id = ?" ],
                          :order => "created_at desc")'
print CodeRay.highlight(text, :ruby, :css => :class, :wrap => :div)

というプログラムソースを整形すると、

<div class="CodeRay">
  <div class="code">
    <pre>
require <span class="s"><span class="dl">'</span><span class="k">rubygems</span><span class="dl">'</span></span>
require <span class="s"><span class="dl">'</span><span class="k">coderay</span><span class="dl">'</span></span>

<span class="c"># CodeRay を利用したサンプルプログラム</span>
text = <span class="s"><span class="dl">'</span><span class="k">@blogs = Blog.find(:all,
           :conditions => [ &quot;category_id = ?&quot; ],
           :order => &quot;created_at desc&quot;)</span><span class="dl">'</span></span>
print <span class="co">CodeRay</span>.highlight(text, <span class="sy">:ruby</span>,
           <span class="sy">:css</span> => <span class="sy">:class</span>,
           <span class="sy">:wrap</span> => <span class="sy">:div</span>)
</pre></div>
</div>
</div>

のような HTMLに変換されます(見やすくする為に改行をしています)。

Ruby on Rails で利用する為の準備

まずは、CodeRay をインストールします。コマンドラインで以下のコマンドを実行します。

   # gem install coderay

あと、 config/environment.rb に以下の記述もしておきます。

  config.gem "coderay"

Ruby on Rails で使う

例えば、以下のようなヘルパーを app/helpers/application_helper.rb に定義します。
引数は、プログラムコード( code )とパラメータです。パラメータは、 :lang 以外は CodeRay の highlight() のものと同じです(そのまま渡しています)。

def syntax_highlight(code, params = { })
  lang = params.delete(:lang) || :ruby
  params[:css] ||= :style
  params[:wrap] ||= :div
  CodeRay.highlight(code, lang, params)
end

で、テンプレートからは以下のように呼び出します。 @entry には、プログラムコード( source_code )、そのコードの開始行番号( line_number_start )が入っているものとします。また、スタイルシートは別途準備する必要があります。

<h2><%= @entry.title %></h2>
<div class="source-code">
<%= syntax_highlight @entry.source_code, :lang => :ruby, :css => :class, 
    :line_numbers => :inline, :line_number_start => @entry.line_number_start %>
</div>

まあ、あまり実用的なサンプルではありませんね。一つのエントリに一個ソースコードの破片を書いて、それを議論するようなサイトなら使えるのかな。

ブログエントリ中のソースコードを整形

僕がやりたいと思うのは、ブログのエントリの中にあるソースコードを整形してもらうようなものなので、実際に当サイトでやっているのは以下のようなコードです。例のフォーマットを指定して、HTML文書に変換するヘルパーに組み込んでいます。エントリ中の <coderay> タグの中身を CodeRay で整形させます。

def text_to_html(text, params = { })
  params[:format] = :textile unless params[:format]

  text.gsub!(/<coderay\s+lang="([^"\s]+)">((?:(?!<\/coderay>).)*)<\/coderay>/m) do
    lang = $1.to_sym
    highlight = syntax_highlight($2.gsub(/>/, '>').gsub(/</, '<'),
                                 :lang => lang)
    if params[:format] == :textile
      "<notextile>" + highlight + "</notextile>"
    else
      highlight
    end
  end if params[:format] != :text
  
  if params[:format] == :html
    text
  elsif params[:format] == :text
    # 改行を HTMLタグに。URL等はリンクに
    auto_link(simple_format(text), :all)
  elsif params[:format] == :markdown
    markdown(text)
  else
    textilize(text)
  end
end

params[:format]:text の時の処理が出来ていないので、その場合は処理しないようになっています。あと、正規表現の部分があやしいです。本来なら textile の処理は CodeRay::ForRedCloth でなんとかするのではないかと思っているのですが、使い方がよく分からなかったので下手な小細工をやっています。

いつか、もうちょっとまともな処理にしたいと思っていますが。

さて、使い方ですが、テンプレートはそのままです。たとえば、show.html.erb ファイルなんかに以下のコードを書きます。 Entry モデルの body フィールドにブログ記事の本文が格納されているものとします。

<div class="entry">
  <h1><%=h @entry.title %></h1>
  <div class="body">
    <%= text_to_html @entry.body, @entry.format_sym %>
  </div>
</div>

あとは ブログ記事の中で、ソースコードを <coderay lang="ruby"> とか、 <coderay lang="rhtml"> で囲めばうまく表示されるはずです。

ブックマークリンク: ソースコードを見やすく表示する(CodeRay).. を含むブックマーク はてなブックマーク - ソースコードを見やすく表示する(CodeRay) この記事をクリップ! Buzzurl(バザール)でブックマーク Buzzurl(バザール)でのブックマーク数

(必須)

(必須)


(必須)

コメント本文を入力してください。HTMLは使えません。

(必須)
simple_captcha.jpg
画像に書かれた文字を入力してください

キャンセル