ReVIEWの外部ファイル取り込み(プリプロセッサ)

 ReVIEWではドキュメントの中に、外部のテキストファイルの内容やコマンドの結果を取り込む方法が用意されています。ReVIEWドキュメントの中を検索しながら編集しなくても、外部ファイルを差し替えればすべての参照箇所が書き換えられます。

特定の単語を差し込む

 まずは簡単な単語差し込みを試してみましょう。ReVIEWドキュメントと同じ階層に「name.txt」というテキストファイルを用意してください。「name.txt」の中身は自分の名前を書いておきます。
f:id:seuzo:20120309173744p:image
f:id:seuzo:20120309173759p:image
 ReVIEWドキュメントの方は「name.txt」を参照するためにインライン要素@<include>{pathname}を使います。たとえば、実際にはこうなります。

私が担当の@<include>{name.txt}です。

f:id:seuzo:20120309174456p:image
 このReVIEWドキュメントからHTMLを生成すると、「name.txt」の内容を差し込みしました。
f:id:seuzo:20120309174913p:image
 このname.txtにはReVIEW記法が使えます。テキストの差し込みが行われた後に、ReVIEW記法が評価されているようです。
f:id:seuzo:20120309175307p:image
f:id:seuzo:20120309175310p:image
 ちなみに、@<include>{pathname}はパスを理解するので、「name.txt」がimagesディレクトリの中にあれば、@<include>{images/name.txt}と書けるでしょう。

段落を含んだ文章を差し込む

 @<include>{pathname}はあくまでインライン要素として文中に差し込むためのコマンドです。別管理されたコードリストなどの外部ファイルの内容など、複数行の段落にわたるブロックとして取り込みたいときには、ちょっと手順を踏む必要があります。

(1)外部ファイルを用意する
 ここでは「script.rb」というテキストファイルを用意しました。
f:id:seuzo:20120309232059p:image
f:id:seuzo:20120309232008p:image

(2)オリジナルReVIEWドキュメントにファイル指定する
 オリジナルReVIEWドキュメント「ch02_org.re」の中の挿入位置に下記マーキングをします。

#@mapfile(script.rb)
#@end

f:id:seuzo:20120309232544p:image

(3)review-preprocコマンドで外部ファイルをマージする
 ターミナルから下記review-preprocコマンドをタイプします。

$ review-preproc ch02_org.re > ch02.re

 プリプロセッサで生成した「ch02.re」を見てみましょう。
f:id:seuzo:20120309233133p:image
 「script.rb」の内容が「ch02.re」の中に挿入されているのがわかります。あとで「script.rb」の中を修正したとしても、プリプロセッサで再マージすれば常に新しいReVIEWドキュメントが生成されます。「#@mapfile(script.rb)」と「#@end」の行は「ch02.re」内に残っていますが、「review-compile」コマンドで変換時、EPUBXMLなどの最終生成物には残りません。
 一連の手順を図にするとこんな感じになります。
f:id:seuzo:20120309233811p:image
 「#@mapfile(pathname)」で展開されるテキスト中にあるタブ文字は、すべてスペースに変換されますから注意してください。もしタブ文字のままであったら、表組みのTSVなども差し込みできるのになあ... と思います。

外部ファイルの一部だけを利用する

 外部ファイルの一定の範囲だけを選択的に差し込むためには

#@maprange(filepath, rangename)
#@end

を使うらしいのですが、ちょっとよくわかっていません。MLでそれらしい議論もあるのですが...
外部ファイルを読み込む記法 - qwik.jp/review
 詳細が分かり次第、追記したいと思います。
(追記:2012-06-06T16:17:57+0900)http://qwik.jp/review/81.html で高橋征義さんによってmaprange()の使い方が解説されていました。以下テストしてみました。

(1)外部ファイルの取り込みたい部分を「#@range_begin(rangename)」から「#@range_end(rangename)」で囲います。*1
 ここでは「script04.rb」というファイル内で「config」というラベル名で範囲を指定しました。
f:id:seuzo:20120606185136p:image

(2)オリジナルReVIEWドキュメントにファイルとラベルを指定する
f:id:seuzo:20120606185625p:image

(3)review-preprocコマンドで外部ファイルをマージする

$ review-preproc ch04_org.re > ch04.re

 「ch04.re」は指定範囲が取り込まれているのが分かります。
f:id:seuzo:20120606185853p:image
f:id:seuzo:20120606190422p:image

コマンドの実行結果を取り込む

 「#@mapoutput(コマンド) 〜 #@end」を使えば、コマンドの実行結果を取り込むことができます。
 たとえば、今年の年号を表記する時などはこのように書くことができます。

#@mapoutput(date +"%Y")
#@end

f:id:seuzo:20120311220524p:image
 review-preprocコマンド後には展開されてこうなります。
f:id:seuzo:20120311220810p:image
 review-compileでHTMLを生成するとこうなります。
f:id:seuzo:20120311221012p:image

 コマンドで展開できるのは、既存のアプリケーションだけではありません。テキストを返すものならば、自作のスクリプトでもよいのです。たとえば、昨日こちらのアップした「特定のTweet引用時の正書法」をつかってみましょう。

#@mapoutput(ruby19 cite_a_tweet.rb "https://twitter.com/#!/never4get_jp/status/178718486745452544")
#@end

f:id:seuzo:20120311222418p:image
 review-preprocコマンド後には展開されてこうなります。
f:id:seuzo:20120311222850p:image
 review-compileでHTMLを生成するとこうなります。
f:id:seuzo:20120311223217p:image

*1:この目印のためのマーキングは「^#@range_begin(.+?)」でなければなりません。行頭から「#」始まりである必要があります。#がコメント扱いになる言語に最適化されています