LoginSignup
13
9

More than 3 years have passed since last update.

Re:VIEW Starterの新機能(2019年冬)

Last updated at Posted at 2019-12-27

はじめに

Re:VIEW Starterとは、技術同人誌を作成するのに広く使われているRe:VIEWを大幅に改善・拡張したツールです。オリジナルのRe:VIEWと比べて、Re:VIEW Starterは「かんたん」「きれい」「はやい」という特徴があります。また0O1lの見分けがつきやすいフォントを選ぶなど、細かいところに気が利いています。詳しくは次の記事を参照してください。

この記事では2019年冬時点での新機能を紹介します。

なお「Re:VIEW Starter」はちょっと長いので、以降では「Starter」と呼びます。

インライン命令の入れ子に対応

ついに、インライン命令の入れ子ができるようになりました。
たとえば @<strong>{@<LaTeX>{}}@<code>$func(@<i>{arg})$ のような書き方ができます。

 * サンプル @<strong>{サンプル @<LaTeX>{}}
 * @<code>$func(arg1, @<i>{arg2})$

starter1-b.png

ただし @<m>{...}@<raw>{...}@<embed>{...} は対象外であり、入れ子のインライン命令を取れません。

またインライン命令の入れ子をしたくないときは、たとえば @<strong>$@<nop>{@}<TeX>{}$ のようにしてください(@<nop> は引数をそのまま表示する機能)。

 * @<strong>$@<nop>{@}<TeX>{}$

starter2-b.png

インライン命令を入れ子にできないことによる問題点

さて、今まではインライン命令の入れ子ができなかったので、たとえばコードの一部を太字にしたい場合、Re:VIEWでは「太字のコード」を表す @<ttb>{...} を使って次のようにします。

@<code>{git merge }@<ttb>{branch-name}@<code>{ -m }@<ttb>{"message"}

すぐに分かると思いますが、この方法だと入れ子にしたい命令の組み合わせをすべて専用命令として定義する必要があります。入れ子にできればこのようなことは必要ありませんが、入れ子にできないとこんな無理やりな方法になってしまいます。

またこれをHTMLに変換すると、次のようになります(読みやすいようインデントを追加しています)。

<p>
  <code>git merge </code>
  <code class="tt"><b>branch-name</b></code>
  <code> -m </code>
  <code class="tt"><b>&quot;message&quot;</b></code>
</p>

そして <code> に背景色をつけるよう、次のようなCSSを使ってみます。

code {
  background: #eee;
  padding: 2px 2px;
  margin: 0 2px;
  border-radius: 2px;
}

すると次のような、不自然な表示になってしまいます。

starter9-b.png

なぜこうなるかというと、本来なら1つの <code> タグになるはずのものが、複数の <code> タグになってしまっているからです。
そしてインライン命令が入れ子にできれば、1つの <code> タグにできるのでこのような問題は起こりません。

インライン命令の入れ子対応が遅れた理由

このインライン命令の入れ子機能は長いこと切望されていましたが、実現が遅れていました。技術的には別に難しいことはなく、初歩的な構文解析の知識で実現できます。にも関わらず遅れたのは、インライン命令の細かい仕様を把握するためにRe:VIEWのソースコードを読んでも、理解が難しかったからです。

たとえば皆さんは、インライン命令の書き方によって「'\'」でのエスケープができたりできなかったりすることを知ってましたか?

 * @<b>{\}}
 * @<b>$\$$
 * @<b>|\||

これをPDFに変換するとこうなります。つまり最初の書き方だと「\」でのエスケープが効くけど、2番目と3番目の書き方では効きません。

starter3-b.png

このような細かい仕様を把握するためにソースコードを読むのですが…他人が書いたソースコードは理解が難しいですね。仕方ないので諦めて、外部から分かる範囲でRe:VIEWの仕様を再現するようにしました。
なのでRe:VIEWとの仕様に違いがあるかもしれません。もし違いを見つけたらお手数ですがお知らせください。

LaTeXコンパイルを高速化

rake pdf を実行すると、今まではLaTeXのコンパイルが3回行われていました。これはRe:VIEWでPDF生成が遅い原因のひとつでした。

そこてStarterでは、LaTeXのコンパイルが1回か2回で済むように改良しました。このおかげでPDF生成が大きく高速化しました。特に原稿を少し修正してPDFで確認、少し修正してPDFで確認、と繰り返すときは高速化を実感できます。

そしてこの改善を実現するために、ReVIEW::PDFMaker クラスを全面的に書き換えました。もとのクラスは様々な責務が詰め込まれた大きなクラスでした。

  • 設定ファイル config.yml の読み込みと解析
  • コマンドラインオプションの解析
  • layout.tex.erb をレンダリングしてLaTeXファイルを生成
  • LaTeXファイルをコンパイルしてPDFを生成

Starterではこれらを別々のクラスに分離し、コードを整理しました。そのおかげでLaTeXのコンパイルやPDF生成を改善できるようになりました。整理されたコードは新機能を追加しやすいですね。

特定の章だけをコンパイル可能

環境変数 $STARTER_CHAPTER により、コンパイル対象となる章を指定できるようになりました。これを設定すると全体をコンパイルする必要がないので、コンパイルが短時間で済みます。

例:foobar.re だけコンパイルする。

bash$ export STARTER_CHAPTER=foobar
bash$ rake pdf

この場合、目次や大扉や奥付は表示されません。これは仕様です。

全体をコンパイルしたくなったら、環境変数をクリアしてください。

bash$ unset STARTER_CHAPTER

この機能は、ページ数の多い本を書くときにはとても重宝します。また複数人で執筆する合同誌の場合も、自分が担当する章だけをコンパイル&確認すればいいので役に立つでしょう。

なおこの機能が実現できたのも、ReVIEW::PDFMaker クラスを全面的に書き換えたおかげです。

原稿ファイルを置くディレクトリを指定

原稿ファイル(*.re)を置くディレクトリを指定できるようになりました。合同誌などで多数の原稿ファイルが存在する場合、いままではカレントディレクトリに散らかっていましたが、それを1か所にまとめられます。

やり方は簡単で、プロジェクト作成時に「原稿ファイルを contents ディレクトリにまとめる」というチェックボックスがあるのでチェックを入れてください。

starter4-b.png

または config.yml に contentdir: contents と指定しても同じことができます。

ただしこの機能を使った場合、カレントディレクトリに原稿ファイルがあるとエラーになるので注意してください。またこの機能はRe:VIEW3と同じですが、仕組みは違うので注意してください。

なおこの機能が実現できたのも、ReVIEW::PDFMaker クラスを全面的に書き換えたおかげです。

HTMLファイル生成を改善

  • rake web でhtmlページに変換する機能を強化しました。PDF生成と比べて非常に高速なので、原稿執筆中の確認方法として rake pdf のかわりに使ってください。またhtmlのデザインもなるべくPDFに似せています。
  • rake web 用に新しいCSSファイル css/webstyle.csscss/normalize.css を用意しました。今まではepub用のCSSファイルを使ってましたが、専用のCSSファイルを用意したので、デザインをカスタマイズしやすくなります。
  • rake web 用のレイアウトファイル layouts/layout.html5.erb を用意しました。ePub用とは別なので、ePubに影響を与えることなくhtmlをカスタマイズできます。
  • rake web 用の設定を config.yml の最後に追加しました。

コードブロックで取り消し線の自動折り返し

プログラムコードやターミナルの中で取り消し線 @<del>{...} を使った場合でも、長い行が自動的に折り返されるようになりました(以前までは @<del>{...} を使うと折り返しされませんでした)。

starter5-b.png

一見すると地味な機能ですが、この実現には非常に骨が折れました。取り消し線機能を提供しているライブラリはいくつかありますが、折り返しを実現する \seqsplit とはどれも相性が悪く、自動折り返しができません。仕方ないのでライブラリのソースを読み比べ、カスタマイズできそうなものを選び、モンキーパッチを当てるハックをすることでなんとか実現できました。

CSSだと簡単なことがLaTeXだととても大変な例です。

埋め込みコードに背景色をつける

文章中にコードを埋め込む @<code>{...} の背景色を薄いグレーにするオプションを用意しました。プロジェクト作成時に指定するか、またはconfig-starter.ymlにおいて inlinecode_gray: falsetrue に変更してください。

starter6-b.png

表示結果は次のようになります。

starter7-b.png

コード内でのふきだしを実装

Re:VIEW3で追加された @<balloon>{} をStarterにも追加しました。これはコード内でのふきだし説明を表します。

//list{
function f(n) {
  if (n === 1) {
    return 1;                @<balloon>{初期値}
  } else {
    return n * fib(n-1);     @<balloon>{再帰呼び出し}
  }
}
//}

「ふきだし」と言ってますが、Re:VIEWでもふきだしの形はしておらず、単に「←」で表示するだけです。
Starterでは表示を少し改善して、次のようにグレーの文字で表示します。

starter8-b.png

細かい改善点

PDF関連

  • たとえば rake pdf && open xxx.pdf を実行すると、従来は実行のたびに新しいウィンドウが開いていましたが、これが同じウィンドウで開くようになりました。これはPDF生成時に「古いPDFを削除して新規作成」ではなく「古いPDFを上書き」するよう変更したおかげです。 このような変更ができたのは、もちろん ReVIEW::PDFMaker を書き直したおかげです。

インライン命令関連

  • Re:VIEW3に合わせて、\reviewbold\reviewstrong\reviewcode などのLaTeXマクロを導入しました。カスタマイズがより簡単にできます。
  • ルビを振る @<ruby>{単語, よみ} をサポートしました。
  • 傍点をつける @<bou>{単語} をサポートしました。
  • リンクを表す @<href>{url,label} において、今まではurl中の「,」は「\,」のようにエスケープする必要がありました。これはわかりにくいので、urlとlabelの区切りを半角空白つきの「, 」にした場合はurl中の「,」をエスケープしなくても済むようにしました。
  • ルビを表す @<ruby>{text,yomi} において、今まではtext中の「,」は「\,」のようにエスケープする必要がありました。これはわかりにくいので、textとyomiの区切りを半角空白つきの「, 」にした場合はtext中の「,」をエスケープしなくても済むようにしました。

コマンドなど

  • review-pdfmaker が使えなくなりました。理由は review-pdfmaker だと新しい ReVIEW::PDFMaker クラスを読み込めないからです。かわりに rake pdf を使ってください。
  • rake pdfrake epub を実行すると、必ずコンパイルされるように変更しました。従来はRe:VIEWの仕様により、たとえば原稿ファイルのタイムスタンプが更新されていないけど画像は更新されているような場合に、コンパイルがスキップされていました。
  • rake pdf config=config.yml のように、rakeタスクでconfigファイル名を指定できるようになりました。これは review-pdfmaker config.yml と同じ機能です。
  • 原稿ファイルの改行文字が \r\n の場合でも動作するようになりました。

導入事例

技術書典7や夏コミでは、Re:VIEW Starterで執筆された同人誌が増えました。

ご利用報告、ありがとうございます。

まとめ

今後ともRe:VIEW Starterをよろしくお願いします。

このほか、PDFにノンブルをつける「PDF Operation」というサービスも作っています。ノンブルは印刷所に入稿するとき必要なので、このサービスでノンブルをつけるといいでしょう。

関連記事

こんな記事も書いてるので、よければ見てください。

13
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9