株式会社クリアコード > ククログ

ククログ


RedmineのMarkdownで箇条書きを書きやすく

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::HelperRedmine::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は、ちょっとした改造なら本体に手を入れなくても、プラグインを作れば実現できてとても便利です。

*1 redmine_common_markで使っています

2017-10-11

«前の記事: PHPカンファレンス2017 - PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム - OSS Gate東京ワークショップ #phpcon2017 最新記事 次の記事: Firefox ESRの独自ビルドの作成方法(2017年版)»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|