• このエントリーをはてなブックマークに追加

はじめに

お仕事で情報をテキストで共有するための書式に利用したり,「SiTeWiki」とかいうものを作ったり,もちろんRedmineのテキスト入力系でも使ったり,と,Textile記法 にちょこっと触れている今日この頃です.特に,アプリケーションを実装する際には,CPANモジュール Text::Textile にはお世話になりっぱなしです.

そんな中,Redmineでの commit:abcdef とか #1234 とかの表記がと特定ページへのリンクに変換されるような処理を,Text::Textile を使ったアプリケーションにも組み込みたくなり,ただ,直接処理を書くよりは,拡張部分だけを使い回しできるようなしくみにした方が後々幸せになれそう,みたいな背景のもと,Text::Textile::Pluggable という俺得モジュールを書いてみました.

GitHub で公開するとともに,PrePAN にも submit してみました(初PrePAN!).

概要と基本的な使い方

Text::Textile のサブクラスで,そこに「プラグイン」(作り方は後述)を読み込むしくみを追加しています.

使い方は次のとおりです:

use Text::Textile::Pluggable qw/textile/;
 
# procedural usage
my $html = textile($text, [qw/Foobar +MyApp::Textile::Plugin/]);
 
# OOP usage
my $textile = Text::Textile::Pluggable->new(
    plugins => [qw/Foobar +MyApp::Textile::Plugin/],
);
$html = $textile->process($text);

プラグインを読み込むことを除けば, 使い方は Text::Textile と同様です.(プラグインを読み込まなければ,Text::Textile そのまんまですねw)

プラグインの作り方

テキトーな名前のモジュールに,サブルーチン prepost を準備します.

package Text::Textile::Pluggable::Plugin::Foobar;
 
# before proceccing textiled text
sub pre {
    my $textile = shift;
    my $text    = shift;  # text BEFORE processing
    ...
    return $text;
}
 
# after proceccing textiled text
sub post {
    my $textile = shift;
    my $text    = shift;  # text AFTER processing
    ...
    return $text;
}
 
1;

pre には Textile記法 → HTML 変換前のテキストに対する処理を,post には変換後のテキストに対する処理を記述します.必要なければ定義は不要です.

名前空間を Text::Textile::Pluggable::Plugin::* とすれば,プラグイン読み込み時に plugins => ['Foobar'] のように省略できますが,必ずこの名前空間に従う必要もなく,好きな名前で作れます.

package MyApp::Textile::Plugin;
 
...
 
1;

独自の名前で準備した場合には, plugins => ['+MyApp::Textile::Plugin'] とすることで読み込めます.

サンプル

サンプルプラグインとして,次の2つを同梱しました:

  • Text::Textile::Pluggable::Plugin::GitHub::Links
  • Text::Textile::Pluggable::Plugin::GitHub::Gist

GitHub::Links プラグインは,github:issm とか github:issm/p5-Text-Textile-Pluggable とかの表記を,GitHub へのリンクに置き換えます.

% perl -MText::Textile::Pluggable=textile -le 'print textile("github:issm")'
<p>github:issm</p>
% perl -MText::Textile::Pluggable=textile -le 'print textile("github:issm", [qw/GitHub::Links/])'
<p><a href="https://github.com/issm">github:issm</a></p>
% perl -Ilib -MText::Textile::Pluggable=textile -le 'print textile("github:issm/p5-Text-Textile-Pluggable", [qw/GitHub::Links/])'
<p><a href="https://github.com/issm/p5-Text-Textile-Pluggable">github:issm/p5-Text-Textile-Pluggable</a></p>

GitHub::Gist プラグインは,gist:123456 とか gist:123456#file1 とかの表記を,番号「123456」に該当する gist のコードを埋め込むためのコードに変換します.

% perl -MText::Textile::Pluggable=textile -le 'print textile("gist:123456")'
<p>gist:123456</p>
% perl -MText::Textile::Pluggable=textile -le 'print textile("gist:123456", [qw/GitHub::Gist/])'
<script src="https://gist.github.com/123456.js"></script>
% perl -MText::Textile::Pluggable=textile -le 'print textile("gist:123456#file1", [qw/GitHub::Gist/])'
<script src="https://gist.github.com/123456.js?file=file1"></script>

おわりに

以上,Textile記法をちょこっと独自拡張するのに便利(自称)なモジュール Text::Textile::Pluggable を書いてみた,というお話でした.

とりあえずは,お仕事用に作っているアプリケーションにおけるTextile記法まわりを拡張するところから始めてみるとします.