「Ruby on Rails 教育関連 Trac」 Redmine化計画 (Redmine wikiの機能拡張)
EY-OfficeのRuby on Rails教育で作っている、Ruby on Rails 教育関連 Trac を Trac から Redmine に移行しようとしています。
Tracは完成度も高いのですが、やはり何か機能を変更したいと思った場合、Pythonで書かれているので私には敷居が高すぎます。また Railsの実行環境として Passenger が出てきて環境の構築が簡単になった事もあり ey-office.com にある Trac を
Redmine に変更しようと考えています。
まず、コンテンツの移行ですが、Redmine には Trac からコンテンツを移行する機能を持っています ^^)/
Tracの動いている環境のあるサーバーまたは、Tracのプロジェクトをコピーしてきて
rake redmine:migrate_from_trac RAILS_ENV="production"
を実行し、質問に答えていくだけでコンテンツが移行でききました。 完全にTracのWiki記法に対応しているわけではないですが、リンク等を少し変更するだけで済みました。
さて、Ruby on Rails 教育関連 Tracでは 練習問題の解答例が書かれていますが、以下のように追加部分を赤字で表示しています。
これは絶対にRedmineでも対応したいポイントです。 TracのWikiはHTMLを直接書ける機能があるので、それを使って赤字を表示しています。 しかし、 Redmine のWikiにはこのような機能はありません。
RedmineのWikiには Macro で機能を追加できるようになっていますが、インライン要素用で コードの表示等には使えそうもありません。
# Builtin macros desc "Sample macro." macro :hello_world do |obj, args| "Hello world! Object: #{obj.class.name}, " + (args.empty? ? "Called with no argument." : "Arguments: #{args.join(', ')}") end desc "Displays a list of all available macros, including description if available." macro :macro_list do out = '' @@available_macros.keys.collect(&:to_s).sort.each do |macro| out << content_tag('dt', content_tag('code', macro)) out << content_tag('dd', textilizable(@@available_macros[macro.to_sym])) end content_tag('dl', out) end ....
RedmineのWikiはTextileに独自機能を追加しています。追加機能の1つに (Ruby)コードのシンタックスハイライトがあります。 <pre><code class="ruby"> ..... のように書くと 拡張部分でシンタクスハイライト機能を呼び出すようになっています。
# Patch to add code highlighting support to RedCloth def smooth_offtags( text ) unless @pre_list.empty? ## replace <pre> content text.gsub!(/<redpre#(\d+)>/) do content = @pre_list[$1.to_i] if content.match(/<code\s+class="(\w+)">\s?(.+)/m) content = "<code class=\"#{$1} CodeRay\">" + CodeRay.scan($2, $1.downcase).html(:escape => false, :line_numbers => :inline) end content end end end
この部分に手を入れて、<pre><code="color">の場合は、独自の色づけができるようなコードを追加すれば良さそうです。
そこで、プラグインを作ってみました。
module Redmine module WikiFormatting class TextileFormatter < RedCloth alias :smooth_offtags_orgin :smooth_offtags private :smooth_offtags def smooth_offtags( text ) unless @pre_list.empty? ## replace <pre> content text.gsub!(/<redpre#(\d+)>/) do content = @pre_list[$1.to_i] if content.match(/<code\s+class="(color)">\s?(.+)/m) content = "<code>" + $2.gsub('##(', '<span style="color:#F00">').gsub(')##', '</span>') elsif content.match(/<code\s+class="(\w+)">\s?(.+)/m) content = "<code class=\"#{$1} CodeRay\">" + CodeRay.scan($2, $1.downcase).html(:escape => false, :line_numbers => :inline) end content end end end end def self.to_html(text, options = {}, &block) TextileFormatter.new(text).to_html(&block) end end end
これで、Redmine でも赤字が表示できました ^^)/〜
ただし、プラグインコードの最後の def self.to_html コードがなぜ必要なのかが分かりません・・・ これがないと元のWikiFormattingモジュールにはto_htmlメソッドがあるのに、 to_htmlメソッドがないというエラーになってしまいます。
分かる方教えて下さい m(__)m