2020/10/29 by @kmuto

Re:VIEW 5.0 での変更点

Re:VIEW 5.0 において 4 系から変更した点について解説します。


Re:VIEW は定期的に機能向上のためのリリースを続けていますが、2020年10月29日にメジ ャーバージョン改訂となる「Re:VIEW 5.0.0」をリリースしました。

バージョン3 → 4が1年でしたが、今回もバージョン4 → 5は1年なので、今のところ1年ごとにメジャーバージョン改訂をしているんですね。4.3 ではなく 5 としたのは、やはり内部実装を大きく変更していることによります。

多数の改良を施していますが、外部に見えやすい実装の目玉としては、永らく切望されていた「入れ子」の対応があります。


既知の問題

現在はまだありません。


インストール

新規インストールの場合

$ gem install review

更新の場合

$ gem update review

既存プロジェクトのバージョンアップ追従

Re:VIEW 3〜4のプロジェクトについては基本的に後方互換性を保持しているため、Re:VIEW 5.0 でもそのまま利用できます(review-ext.rb での拡張をしていない状態で何か問題が出たとすれば、それはバグですのでご報告いただければと思います)。せいぜい、major version of configuration file is different.というメッセージが出るくらいでしょうか。

警告メッセージを出したくない、あるいは後述の機能の中で TeX 関連の機能向上を反映させたいといった理由で既存のプロジェクトを 5.0 に更新するには、Re:VIEW 5.0 をインストール後、プロジェクトフォルダ内で review-update コマンドを実行してください。

$ review-update
** review-update はプロジェクトを 5.0.0 に更新します **
config.yml: 'review_version' を '5.0' に更新しますか? [y]/n 
プロジェクト/sty/review-base.sty は Re:VIEW バージョンのもの (/var/lib/gems/2.5.0/gems/review-5.0.0/templates/latex/review-jsbook/review-base.sty) で置き換えら
れます。本当に進めますか? [y]/n 
プロジェクト/sty/review-jsbook.cls は Re:VIEW バージョンのもの (/var/lib/gems/2.5.0/gems/review-5.0.0/templates/latex/review-jsbook/review-jsbook.cls) で置き換えられます。本当に進めますか? [y]/n 
完了しました。

続いて、リリースノートをベースに、新規に導入した機能や変更点について理由を挙げながら解説します。

新機能

review-jsbook / review-jlreq クラスに、cover_fit_page オプションを追加しました

Re:VIEWでは、表紙画像は紙面相当サイズ(および塗り足しサイズ加味)であることを想定し、実寸で中央配置しています。これは商業印刷においてデザイナーの設計のとおりを再現するための必須の措置です。

しかし、同人誌においては紙面サイズの画像を用意する、というのは意外と大変なようで、(画像サイズが不正確なために)画像がはみ出す、うまく置けないといったユーザーのtweetをたびたび目にしていました(ピクセル単位では操作できても、mm単位で指定できてかつ手軽に入手できる画像ソフトウェアが少ないことも一因かもしれません)。

この対策として Re:VIEW 5.0 では、review-jsbook, review-jlreq クラスのオプションとして、新たに cover_fit_page オプションを追加しました。texdocumentclass パラメータに cover_fit_page=true を付加すると、画像サイズがどのようなものであっても仕上がりサイズに拡大(あるいは拡縮)して表紙に貼り込みます。

あくまでも仕上がりサイズであり、塗り足し領域までは拡大しないので、表紙も含めて印刷をするときには、塗り足し領域まで含めた実寸の画像を用意するようにしてください。

小さな囲み要素 (//note, //memo, //tip, //info, //warning, //important, //caution, //notice) の中で、//image などのブロック命令を含めたり、および箇条書きを入れたりできるようになりました

@takahashimさんの尽力で、//note などの囲み要素の中にほかのブロックや、箇条書きを入れる、いわゆる入れ子の機能が実装されました。

//note{
これまで段落しか入れられなかったのが

 * 箇条書きを
 * 入れたり

//image[note-fig1][note内の画像を入れたりできる]{
//}

//}

このブロック入れ子を許容しているのは //note, //memo, //tip, //info, //warning, //important, //caution, //notice に限定しています(表の中に表みたいな用途には使えません)。また、//note の中にさらに //note//tip を入れるといったことも禁止しています。

なお、review-ext.rb の拡張で類似のことを利用したいときには、defminicolumn で定義します。

箇条書きの入れ子を指示する命令として //beginchild, //endchild という1行命令を追加しました(実験的)

こちらは説明どおり、箇条書きの入れ子です。箇条書きの子にしたいものを //beginchild//endchild で囲むと、前に位置する箇条書きの子要素になります。

 1. 番号箇条書きAの1.

//beginchild

 * 番号箇条書きAの子となる中黒箇条書き

番号箇条書きAの文章続き

//endchild

 2. 番号箇条書きAの2.

//beginchild//endchild は必ず対になる必要があります。//beginchild で作った子の中にさらに //beginchild//endchild の孫、あるいはさらにひ孫を作っても構いません(ただ、LaTeX 等において深さの限界があります)。

ほかに良い文法があればよかったのですが、インデントを使うことはしたくないというポリシーがあり、いささか不格好ながら単一命令を使った手法をとることにしました。

この箇条書きの入れ子機能は実験的です 。今後のバージョンで挙動を変えたり廃止したりする可能性があります。

非互換の変更

review-jlreq.cls における hiddenfolio の配置を、jlreqtrimmarkssetup を使って実装するように変更しました。以前のバージョンとは位置や表示に若干の違いがあります

同人誌印刷等で使われるノドの隠しノンブル(隠れていないのに隠しとは……という不思議な感じですが)の表現について、これまで review-jlreq では review-jsbook と同じものを使っていたのですが、review-jlreq でより適切な手法として jlreqtrimmarksetup を使うようにしました。これに伴い、ちょっと見た目が変わっています。

review-jlreq を使っている方はまだ少ないでしょうし、この隠しノンブルの表示の変化も利用において大きな影響はないものと思います。

chapterlink パラメータのデフォルト値を true (有効) にしました

WebMaker および EPUB での章・項の参照や、図表・リスト・式・参考文献の参照などをハイパーリンク化する chapterlink パラメータはこれまで null(無効)をデフォルトにしていたのですが、実際の Web・EPUB というメディアにおいてはハイパーリンクであるほうが実用的です。

Re:VIEW 5.0 からこのパラメータのデフォルト値を true(有効)にしました。ハイパーリンクになるのが望ましくないときには、chapterlink: null を使ってください。

TeX PDF においては media=ebook のときのみ、章・項・参考文献の参照がハイパーリンク化されます。

バグ修正

PDFMaker: 同名で拡張子違いの図版ファイルがあるときに、位置がずれる問題を修正しました

これまで PDFMaker では、extractbb というコマンドを内部で呼び出し、TeX PDF コンパイルの補助情報として画像ファイルのサイズを書き出していました。問題は、この補助情報ファイルがファイル名に拡張子 .xbb を付けたものであることです。たとえば同じフォルダに画像ファイル「fig1.png」「fig1.pdf」が置かれていたとき、片方に対して作られた fig1.xbb は、もう1つの fig1.xbb で上書きされてしまいます。上書きされてしまったほうが TeX PDF で使うべき正しいものだった場合、ずれた結果になってしまうわけです。

xbb 補助情報は昔の TeX 環境では必要な措置でしたが、最近(といってもTeXLive 2015 以降)はもうこの補助情報ファイルがなくても内部的に必要なファイルにのみ extractbb を実行するようになっています。

もはや TeXLive 2014 は対応する必要もないかと思われるので、Re:VIEW 5.0 では extractbb コマンドの明示呼び出しを止めました。これにより、同名拡張子違いの画像ファイルが存在しても問題なく適切に配置されます。

PDFMaker: 著者名 (aut) パラメータが空のときにエラーになる問題を修正しました

自分の利用範囲だとまずないケースだったので、こういうのは見落としますね…。

PDFMaker: //indepimage 命令で画像が存在せず、かつ ID に TeX のエスケープ対象となる文字を含んでいるとエラーが起きる問題を修正しました

2つの条件が合わないと発生しない、レアケースでした。

なお後述しますが、Re:VIEW 5.0 では、ID に TeX あるいは EPUB に悪影響を及ぼす可能性がある文字があるときには警告されるようになっています。

PDFMaker: booktitlenameaut パラメータに TeX のエスケープ対象となる文字を入れると PDF メタ情報がおかしくなる問題を修正しました

PDF には書名や著者名などを PDF メタ情報として入れていましたが、このエスケープが二重エスケープになっていました。

対策の副作用で、PDF メタ情報が入るのは texdocumentclass パラメータに media=ebook を付けているときのみとなります。

内部的には PDF の生のメタ情報を書き込むのではなく、TeX の hyperref パッケージの hypersetup 命令を使って指定しています。このため、hyperref の機能を実質的にオフにしている media=print の状態では作用できません。

WebMaker: HTML テンプレートで nil が入ってしまうのを修正しました

WebMaker の HTML テンプレートに不具合があったので修正しています。

PDFMaker: 章番号を非表示にするとエラーで失敗するのを修正しました

locale.yml で chapter: "" のように何も表示しないようにしたときにエラーになるのに対処しました。

MarkdownBuilder: note 等の中の段落を改行区切りではなく空行区切りにしました

Markdown 変換ってどのくらい使っている方いるんでしょうね……。ともあれミニコラム内での複数段落表現が Re:VIEW と一致するようになりました。

機能強化

図表などのアイテムでエラーが発生したときの表示を詳細にしました

ID が重複したときのメッセージの詳細が不明瞭だったので、より詳しい情報を出すようにしました。

これまで:
WARN review-epubmaker: warning: duplicate ID: fig1 (#<ReVIEW::Book::Index::Item:0x000055943be68488>)

Re:VIEW 5.0
WARN review-epubmaker: warning: duplicate ID: fig1 (#<ReVIEW::Book::Index::Item:0x0000560877fe01c0 @id="fig1", @number=2, @caption="ある図", @path=nil, @index=nil>)

PDFMaker: @<hd> 命令で展開した項・段について、media=ebook のときにはハイパーリンクになるようにしました

これまで @<hd> を TeX に展開した \reviewsecref ではリンク情報自体は渡していたものの何も使っていなかったのですが、TeX hyperrefパッケージでのハイパーリンクにする調整を行い、有効化しました。

HTMLBuilder および IDGXMLBuilder において、文字列のエスケープを従来の cgi/util の代わりにより高速な cgi/escape が利用できるときにはそれを利用するようにしました。また、ReVIEW::HTMLUtils.escape も書き換えられました

ほとんどの場合は関係ありませんが、「'」文字の取り扱いが変わります。Re:VIEW 4 系までは変換してもそのまま「'」が使われていたのに対し、Re:VIEW 5.0 では「&#39;」と実体参照になります。

フックで HTML ファイルを書き換えるなどの加工をしていたときには注意してください。

@<icon> 命令の利用時に ID の重複の警告が出るのを抑制しました

アイコンなどのインライン画像を挿入する @<icon> では同じファイルを使い回すことも多いため、いちいち重複の警告を出すのを止めました。

不正なエンコーディングのファイルを受け取ったときに妥当なエラー表示をするようにしました

Re:VIEW の re ファイルは UTF-8 エンコーディングのみのサポートとしていますが、Shift JISなどの他エンコーディングのファイルを受けたときにわかりにくい内部エラーを返していました。

エンコーディング問題のエラーを検出して、コンパイルエラー(invalid byte sequence in UTF-8)を出すようにしました。

IndexBuilder を導入しました

内部実装的には Re:VIEW 5.0 での最も大きな変更です

これまで図表等の番号の管理および参照はその都度対象ファイルを解析する方法でしたが、IndexBuilder はまずプロジェクト全体を走査し、以降の各ビルダのために番号を保持して提供します。

review-ext.rb でブロック命令やインライン命令のメソッドを追加していた場合、IndexBuilder クラス (またはその基底クラスである Builder クラス) にも追加が必要です。番号を使っていなければ「何もしない」空のメソッドを定義するだけでよいでしょう。

ID やラベルに以下の文字または空白文字が含まれていると、TeX のコンパイルあるいは生成される EPUB においてエラーが発生するため、これらの文字が含まれているときには警告を出すようにしました

いろいろ調べた結果、TeX と EPUB のどちらかあるいは両方で ID に入っていると厄介なことになる(TeX のコンパイルが通らない、EPUB チェックが通らない)のは、空白と、#、%、\、{、}、[、]、~、/、$、'、"、|、*、?、&、<、>、` でした。

これらのいずれかの文字が使われていたときには警告を出します。

ドキュメント

format.ja.md と format.md のタイプミスを修正しました

ご指摘ありがとうございます!

makeindex.ja.md のサンプル結果の誤りを修正しました

ご指摘ありがとうございます!

その他

Rubocop 0.92.0 に対応しました

恒例ですね。あまり好みに合わないのは disable にしていますが。

Re:VIEW::Compiler 内の @strategy は実際はビルダなので、@builder という名前に変更しました

内部の話なのであまり影響はないかもしれませんが、review-ext.rb で Compiler 部分を書き換えていたときには、@strategy@builder にするか、@strategy = @builder と代入するかの対処が必要になるでしょう。

Rubocop-performance 1.7.1 に対応しました

こちらも先と同様です。

syntax-book サンプルドキュメントの Gemfile を更新しました

古かったので更新しています。

ImageMagick における GhostScript の呼び出しが非推奨となったため、テストを除去しました

ImageMagick も GhostScript もセキュリティ問題がぽろぽろ出るのは同程度な感じがしますが、Debian の ImageMagick はデフォルトでの GhostScript 呼び出しを止めたようで、テストが動かないケースが出てきました。

ImageMagick の policy.xml で戻せばいいという話ではありますが、テストにそれを求めても仕方がないので、テスト自体を除去しています。あまり変化のあるところでもないですし。

一部のテストユニットの不要な標準エラー出力を抑制しました

rake test したときにちょこちょこ標準エラー出力が出ていたのを抑制しています。

Compilable モジュールの代わりに、Chapter および Part のスーパークラスとなる BookUnit 抽象クラスを導入しました

内部表現の調整です。review-ext.rb でカウンタを独自に作っていた場合は影響があるかもしれません。

ReVIEW::Book::Base.load をやめ、ReVIEW::Book::Base.load または ReVIEW::Book::Base.new を使うようにしました。ReVIEW::Book::Base.load:config オプションを加えました

こちらも中身の整理です。テストなどもしやすくなったはず。

内部のパラメータの汎用構成のために ReVIEW::Configure.create コンストラクタを導入しました

これでパラメータ構成はだいぶ綺麗になったはずですが、EPUBMaker が昔の独立ライブラリを引きずっていてまだ完全には綺麗にできていないですね。次の TODO です。

WebMaker: 使われていない clean_mathdir メソッドを削除しました

整理したら、いらなくなりました。

catalog.yml の解析を ReVIEW::Book::Base.new の中で最初に実行するようにしました

これまでは ReVIEW::Book::Base.catalog を呼び出したときにまだ解析してなかったら初めて解析する、という仕組みだったようです。あえて動的読み込みをする必要もないので、最初に解析するようにします。

ファイルの書き出しで可能なところは File.write を使うようにしました

書き出しのコードが少しシンプルになりました。

Builder クラスの builder_init メソッドを削除し、initialize を使うようにしました

もともと何だったんだろうこれ、というメソッドですが、拡張されるときも普通は builder_init_file を使っていると思いますので、影響はほぼないでしょう。

終わりに

今回の Re:VIEW 5.0 ではかなり改修を行いましたが、EPUB ライブラリの改修や、scaffold の仕組みなどいくつか TODO で残してしまったものがあります。文法のほうはだいぶ固まったかなという気はしますが(表という不倶戴天の難敵はありますが…)、今後も定期的な改善を継続していきます。お楽しみに。