RedmineのデフォルトのテキストフォーマッタはTextileですが、社内でMarkdownを使いたいという声が大きかったのでMarkdownを使えるようにして運用しています。 しかし、RedmineのMarkdownはRedcarpetを使用しているため3レベル以上のリストを書くときのインデントが辛い感じでした。 Redmineで3レベル以上の箇条書きでも2インデントでよくしたい · Issue #8 · clear-code/statistics
そこで、ククログでも使用しているCommonMarkerを使えるようにしてみました。
インストール方法はリンク先を参照してください。
Redmineを新しい記法に対応させる方法
上記プラグインを実装している過程でRedmineを新しい記法に対応させる方法をソースコードを読んで調べました。 ソースコードはdd9c0a82を使いました。
Redmine::WikiFormatting.map do |format|
format.register :commonmark # :新しい記法の名前
Redmine::WikiFormatting::CommonMark::Formatter # 新しい記法で使うフォーマッタのクラス
Redmine::WikiFormatting::CommonMark::Helper # 新しい記法で使うヘルパーのクラス
Redmine::WikiFormatting::CommonMark::HtmlParser # 新しい記法で使うHTMLパーサーのクラス
end
という感じで登録すればよいです。
あとは必要なクラスを実装していけば、新しい記法を追加することができます。
一番最後の引数にハッシュを指定すると、追加のオプションを指定できます。調べた時点だと:label
というキーで、設定画面に表示するラベルを変更できるだけでした。1
新しい記法で使うフォーマッタのクラスは、以下のインスタンスメソッドを実装している必要があります。
-
initialize(text)
-
to_html(*args)
-
get_section(index)
-
update_section(index, update, hash=nil)
-
extract_section(index)
セクションごとの更新が不要であれば、*_section
系のメソッドは何もしないようにすることも可能でしょう。
新しい記法で使うヘルパーのクラスは、編集画面で使用するツールバーを読み込むためのヘルパーメソッドを定義します。
-
wikitoolbar_for(field_id)
-
initial_page_content(page)
-
heads_for_wiki_formatter
編集画面にツールバーが不要であれば、何もしないようにすることも可能でしょう。
新しい記法で使うHTMLパーサーのクラスでは、HTMLを新しい記法のテキストに変換するためのルールを定義します。 MarkdownやTextileだとHTMLタグと記法の対応が決まっているので、その対応が定義されていました。
CommonMarkと(Redcarpetの)Markdownは、ほぼ同じなのでredmine_common_markではRedmineのMarkdown記法で使われているRedmine::WikiFormatting::Markdown::Helper
とRedmine::WikiFormatting::Markdown::HtmlParser
を流用しました。
非互換
互換性のないところがいくつかあります。
`#prefer_delayed_commit`| `#prefer_buffered_processing`| 結果
:----------------------:|:----------------------------:|:---------------------:
false | false | non-buffered
false | true | buffered synchronous
true | true | buffered asynchronous
true | false | 選択不可
上のようなテーブルを書くと、3行目以降が整形済みテキストになってしまいます。 以下のように行頭にパイプを追加することで回避できます。
|`#prefer_delayed_commit`| `#prefer_buffered_processing`| 結果
|:----------------------:|:----------------------------:|:---------------------:
| false | false | non-buffered
| false | true | buffered synchronous
| true | true | buffered asynchronous
| true | false | 選択不可
CommonMarkerで使っているgithub/cmarkにオートリンクのバグがありました。既に報告済みで、報告してから11時間くらいで修正されていました。
まとめ
このようにRedmineは、ちょっとした改造なら本体に手を入れなくても、プラグインを作れば実現できてとても便利です。
-
redmine_common_markで使っています ↩