Re:VIEW Starterの新機能（2019年夏）

（追記 2019-12-27: [2019年冬の新機能](https://qiita.com/kauplan/items/e36edd7900498e231aaf)もご覧ください。）


## はじめに

Re:VIEW Starterとは、主に書籍や技術同人誌を書くためのツールです。
初期設定がGUIで行えるので初心者でも楽に導入でき、最初から見栄えのいいデザインが用意されていて、かついろんなところに気が効いています。

* Re:VIEW Starter (https://kauplan.org/reviewstarter/)

以前、Re:VIEW Starterを紹介したときは多くの方から反響をいただきました。
ありがとうございます。

* 技術系同人誌を書く人の味方「Re:VIEW Starter」の紹介<br>
  https://qiita.com/kauplan/items/d01e6e39a05be0b908a1

今回はその続編として、前回の紹介記事よりあとに実装された新機能を紹介します。
技術書典7も近いので[^1]、参考にしてください。

[^1]: 原稿執筆時点である2019年8月のこと。

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


## 等幅フォントをGUIで選択可能に

プログラムコードやターミナルの表示で使う等幅フォントを、GUIで選べるようになりました。

* 等幅フォントをプレビューしながら選べます。
* 各フォントの特徴も画面で簡単に説明しています。
* プログラムコードとターミナルでそれぞれ別の等幅フォントを指定できます。

GUIで等幅フォントを選ぶ画面：

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/6a6840d5-498c-933c-82d7-43e87e8e20f3.png" alt="等幅フォントをプレビューしながら指定できる" width="">

Tipsですが、Inconsolataフォントで「文字列をさらに狭める」というオプションを選ぶと、フォント幅が狭くなって1行にたくさん詰め込めます。
また半角文字と全角文字の幅がだいたい1:2になるので（厳密な1:2ではない）、出力結果などに使うといいでしょう。

もしプロジェクトをダウンロードしたあとに等幅フォントを変更したいなら、設定ファイル `config-starter.yml` の項目「`program_ttfont:`」や「`terminal_ttfont:`」を変更してください。


## テキストの横に画像を表示する

テキストの横に画像を表示するブロックコマンド「`//sideimage`」を用意しました。
著者紹介でTwitterアイコンとともに使うといいでしょう。

```
//sideimage[tw-icon][20mm][side=L,sep=7mm,border=on]{
//noindent
@<strong>{カウプラン機関極東支部}

 * @<href>{https://twitter.com/_kauplan/, @_kauplan}
 * @<href>{https://kauplan.org/}
 * 技術書典7新刊「わかりみSQL」出します！@<br>{}
   レビュアーも募集中！

//}
```

表示例：

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/ee43c201-a55b-69c3-3cfd-c068863f4e25.png" alt="テキストの横に画像を表示する例" width="80%">

ブロックの中には箇条書きやプログラムコードを入れられますが、「途中で改ページされない」「画像下へのテキストの回り込みはできない」「脚注が使えない」という制限があります[^2]。
詳しくは[ドキュメント](https://pbs.twimg.com/media/ECJi_wpUEAA3eVr?format=png)を参照してください。
[^2]: これらの制限は内部でLaTeXのminipage環境を使っているせいです。よい解決方法があれば教えて下さい。


## プログラムコードを枠線で囲む

プログラムコードを枠線で囲むオプションを用意しました。
プログラムコードが途中で改ページされるとき、枠線があったほうが少し読みやすくなります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/ece66668-8655-7446-2137-1270ee51b561.png" alt="プログラムコードを枠線で囲む理由" width="">

この機能を有効化するには、`config-starter.yml`で「`program_border: true`」を設定してください。


## 節(Section)ごとに改ページする

節 (Section) ごとに改ページする機能を用意しました。
初心者向けの入門書だと、節ごとに改ページするのはよく見かけます。

設定方法は、`config-starter.yml`で「`section_newpage: true`」を指定してください。

ただし、章ごとの最初の節では改ページしません。
これは意図した挙動であり、バグではないので注意してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/b92156ac-1283-3c3b-711d-4cbb7b07c790.png" alt="節ごとに改ページする" width="50%">


## 節や項がページ先頭なら余白を入れない

節 (Section) や項 (Subsection) がページ先頭にきた場合、従来はタイトルの上に余白が入っていました。
しかしページ先頭の場合は、この余白はなくても問題ないはずです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/9d642f89-aa34-9307-5494-362f090e8acc.png" alt="節や項がページ先頭なら上の余白はいらない" width="70%">

なので、Starterではデフォルトでこの余白を入れないようにしました。
`config-starter.yml`の「`section_notopmargin: true`」を`false`にすると、入るように変更できます。


## 節や項がページ最下部で改ページされるのを防ぐ

LaTeXでは、ページ最下部の段落が最初の1行のみになるのを嫌います。
もしそうなりそうになったら、段落の直前で改ページします。

このせいで、節 (Section) や項 (Subsection) のタイトルが、十分なスペースがありそうなのに改ページされてしまうことがあります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/5a25a6ab-5800-c7bb-729e-6366f2c36441.png" alt="十分なスペースがありそうなのに改ページされる" width="50%">

Starterでは、ページ最下部の段落が最初の1行のみになるのを許しています。
そのため、節や項のタイトルがページ最下部にきても改ページされず、余計なスペースが空かないようになっています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/509970ca-a8ec-0f91-2c92-e0cccded4937.png" alt="ページ最下部の段落が最初の1行のみになるのを許すとスペースが空かない" width="50%">

この設定は、`config-starter.yml`の「`page_clubline: true`」[^5]で変更できます。

[^5]: 「clubline」とは、ページ最後の段落が最初の1行だけになっていることを表す言葉だそうです。


## 設定ファイル「config-starter.yml」を追加

Re:VIEW Starter独自の設定ファイル「`config-starter.yml`」を用意しました（これはRe:VIEWの設定ファイル`config.yml`とは別です）。
今まではプロジェクト作成時にしか選択できなかった設定が、プロジェクト作成後も `config-starter.yml` で簡単に設定できるようになりました。

たとえば以下のような項目が設定できます。

<!--
 * `target` … 出力のターゲット。`pbook`、`ebook`、`tablet`のどれかを指定
 * `draft` … ドラフトモード。trueなら画像を読み込むかわりに枠を表示
 * `section_notopmargin` … ページ先頭なら節や項のタイトルの前に余白を入れない
 * `caption_small:` … プログラムやターミナルのキャプションを小さくする
 * `caption_pretty:` キャプションの見映えをよくする
 * `caption_needspace:` … キャプション直後での改ページを防ぐための高さ
 * `program_widen:` … 折り返しが右端まで達しないときに設定
 * `terminal_widen:` … 折り返しが右端まで達しないときに設定
 * `program_border:` … プログラムコードを枠で囲む
 * `terminal_border:` … ターミナルを枠で囲む
 * `colophon_poweredby:` … 奥付に「powered by Re:VIEW Starter」と入れる
 * `page_clubline:` … 十分なスペースがあるのに節や項のタイトル直前で改ページされるのを避ける。
-->
 * `chapter_decoration` … 章 (Chapter) タイトルの装飾
 * `chapter_align:` … 章タイトルの左寄せ/右寄せ/中央揃え
 * `chapter_oneline:` … 章番号と章タイトルとの間で改行するかどうか
 * `section_newpage:` … 節 (Section) ごとに改ページする
 * `section_decoration:` … 節 (Section) タイトルの装飾
 * `subsection_decoration:` … 項 (Subsection) タイトルの装飾
 * `program_fontsize:` … プログラムコードのフォントサイズ
 * `terminal_fontsize:` … ターミナルのフォントサイズ
 * `program_ttfont:` … プログラムコードの等幅フォント
 * `terminal_ttfont:` … ターミナルの等幅フォント
 * `image_position:` … 画像位置に後続のテキストを流し込む

詳しくは`config-starter.yml`の中を見てください。


## キャプション直後の改ページを防ぐパラメータを導入

プログラムコードやターミナルには、キャプション（説明書き）がつけられます。
このキャプションの直後で改ページされると、キャプションとプログラムコードが別々のページになってしまうため、読みやすさが損なわれます。

キャプション直後で改ページされた例：
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/bc55b304-f29d-b627-5df8-b6906d397462.png" alt="キャプション直後で改ページされた例" width="70%">

Starterではこの問題を防ぐよう対策をしていましたが、設定値に甘さがあったため、防ぎきれてはいませんでした。
現在は何度も実験をして設定値を決めたため、以前よりはずっと発生しにくくなっています。

それでも完全に防ぐのは難しいです。
これはフォントや行間などに依存するので、どの書籍でも通用するような完璧な設定値はありません。

そこで、この設定値を各自で調整できるようにしました。
`config-starter.yml`で「`caption_needspace: 4.8zh`」という箇所を調整してください。

* キャプション直後の改ページが発生するなら、この値を少し増やしてください。
* 十分なスペースがあるのに改ページされるなら、この値を少し減らしてください。

なおLaTeXでは、プログラムコードが1行だけで改ページされることはないらしく、そうなりそうになったらプログラムコードの前で全体を改ページするようです。
この挙動を変更する方法を知ってる人がいたら教えてください[^4]。

[^4]: `\clubpenalty` を 0 にすればいいかと思いましたが、試した限りはうまくいきませんでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/ec351dee-eff4-642a-a496-526513517da7.png" alt="プログラムコードが、1行だけで改ページされることはないらしい" width="70%">

## フォントサイズを変更するコマンド

テキストのフォントサイズを変更するインラインコマンドを用意しました。

* `@<small>{...}` … 文字を小さくする
* `@<xsmall>{...}` … 文字をより小さくする
* `@<xxsmall>{...}` … 文字をもっと小さくする
* `@<large>{...}` … 文字を大きくする
* `@<xlarge>{...}` … 文字をより大きくする
* `@<xxlarge>{...}` … 文字をもっと大きくする

またテキストを強調する`@<strong>{}`の派生コマンドとして、フォントサイズを大きくするものを用意しました。

* `@<xstrong>` … 文字を大きくする
* `@<xxstrong>` … 文字をもっと大きくする

どのくらい小さくまたは大きくなるかは、次の画像を参考にしてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/d9f39540-f944-bd24-63e1-36b1b7eb1ad2.png" alt="フォントサイズのプレビュー" width="70%">


## テキストを目立たせないための`@<weak>{}`

テキストを目立たせる「`@<strong>{}`」とは逆に、目立たせないための「`@<weak>{}`」を用意しました。
プログラムコードのおまじないを目立たせたくないときに使ってください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/7b9563db-5e76-74be-3098-2871fa25a663.png" alt="おまじないを目立たなくする" width="">


## ターミナルのカーソルを表示する

ターミナルのカーソルを表す「`@<cursor>{}`」を用意しました。

たとえば次の例では、「f」にカーソルが載っていることを表します。

```
//terminal{
function fib(n) {
  return n <= 1 ? n : @<cursor>{f}ib(n-1) : fib(n-2);
}
~
~
"fib.js" 3L, 74C written
```

表示例：

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/ed975ea7-a6cc-8ad8-7706-0f731486303e.png" alt="ターミナルのカーソル" width="">

なおこの機能は、とある利用者からの要望により実装しました。
すべての要望に答えられるとは限りませんが、他にも要望があれば教えて下さい。
できる範囲で対応します。


## 折返しが右端まで達するようにする

Starterでは、プログラムコードの長い行を自動的に折り返してくれ、また折返し記号もつけてくれます。

しかし、一見すると右端まで到達してないのに折り返しているように見えることがあります。
たとえば次の例だと、もう1文字入るように見えませんか？

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/8f8961dc-1ebb-7490-9c0c-ef9aa7df6610.png" alt="一見すると、右端にもう1文字入りそうに見える" width="">

このような場合は、プログラムコードの表示幅をほんの少しだけ広げると、折返しが右端まで到達するようになります。
具体的には`starter-config.yml`に「`program_widen: 0.3mm`」と設定すると、次の例のように右端まで達するようになりました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/8f97d804-ba64-605f-feee-277835c7bf0e.png" alt="折返しが右端まで到達するようになった" width="">

ここで「`program_widen: 0.3mm`」という値は各自で調整してください。
`1mm`なんて大きな値は必要ないはずで、せいぜい`0.5mm`とかでいいはずです。


## コンパイル時間を短縮するドラフトモードを実装

画像やスクリーンショットを多用する書籍だと、コンパイルに時間がかかります。
印刷用に高解像度の画像を使った場合はなおさらです。

そこでStarterでは、画像を枠線だけで表示する「ドラフトモード」を用意しました。
このモードでは画像を表示するかわりに枠線を表示するので、コンパイルが非常に速くなります（正確にいうと、LaTeXのコンパイル時間は変わらないけどそのあとのPDF生成が速くなります）。

ドラフトモードにするには、`config-starter.yml` で「`draft: true`」を設定するか、または環境変数「`$STARTER_DRAFT`」に何らかの値を入れてください。

```console
### ドラフトモードにしてPDFを生成する
$ export STARTER_DRAFT=1  # ドラフトモードをonにする
$ rake pdf

$ unset STARTER_DRAFT     # ドラフトモードをoffにする
```

またドラフトモードの場合でも、`//image[][][draft=off]` のように指定すると、その画像はドラフトモードにならず通常通り表示されます。

```
ドラフトモードであっても、この画像↓は画像として表示する。
//image[ファイル名][画像の説明][scale=0.8,draft=off]
```

この機能は、締め切りが迫ったときには大活躍します。
今のうちに試してみるといいでしょう。


## 印刷用PDFとダウンロード用PDFを切り替える

印刷用PDFとダウンロード用PDFとで、仕様を少し変えたいことがあります。

* 印刷用PDFは白黒だけど、ダウンロード用PDFはカラーにしたい。
* 印刷用PDFは本文を見開きの外側に少し寄せるけど、ダウンロード用は本文をページ中央に置く。
* 印刷用PDFはリンク機能をオフにするけど、ダウンロード用PDFではオンにしたい。

このようなときは、環境変数「$STARTER_TARGET」を設定することで印刷用とダウンロード用を切り替えられます。

* 環境変数の値が「pbook」なら印刷用
* 環境変数の値が「ebook」ならダウンロード用
* 環境変数が空または未設定なら、`config-starter.yml`の「`target:`」に従う

コンパイル方法：

```console
### 印刷用PDFを生成
$ rake pdf   # または STARTER_TARGET=pbook rake pdf

### ダウンロード用PDFを生成
$ STARTER_TARGET=ebook rake pdf
```

この値は、LaTeXのスタイルファイルでは「`\starter@target`」で参照できます。
たとえばLaTeXのスタイルシート `sty/starter.sty` では、ダウンロード用PDFではカラーを使うようになっています。

```latex
%%% \starter@target を調べて各種変数を設定する
\iffalse
\else\ifstreq{\starter@target}{pbook}    % pbook (printing book) なら
  \def\starter@colormode{mono}           %   白黒
\else\ifstreq{\starter@target}{ebook}    % ebook (electric book) なら
  \def\starter@colormode{rgb}            %   カラー (RGB)
  %\def\starter@colormode{cmyk}          %   カラー (CMYK)
\else                                    % それら以外なら
  \def\starter@colormode{mono}           %   白黒
\fi
```

また `sty/mytextsize.sty` では、印刷用の場合だけ本文を見開きの外側に寄せています。

```latex
%% 奇数・偶数ページで余白幅を変える場合
%% （ただし pbook (printing book) の場合だけ）
\newcommand\if@pbook{         % \starter@target の値が pbook かどうかを調べる
  \def\@tempa{pbook}
  \ifx\starter@target\@tempa  % \starter@target は layouts/layout.tex.erb の先頭で定義される
}
\if@pbook
  \addtolength{\oddsidemargin}{1.5zw}   % 奇数ページで1.5文字分広げる
  \addtolength{\evensidemargin}{-1.5zw} % 偶数ページで1.5文字分狭める
\fi
```


## LaTeXスタイルファイルから環境変数を参照する

LaTeXのスタイルファイルの中から、環境変数を参照できるようになりました。
とはいっても、変数名が「STARTER_」で始まる環境変数だけが対象です。

たとえば環境変数 `$STARTER_FOO_BAR` を設定すると、LaTeXのスタイルファイルでは「`\STARTER@FOO@BAR`」として参照できます。
もうお分かりだと思いますが、環境変数の「`_`」を「`@`」に変換した名前になります。

使い道は特に限定してないので、自由に使ってください。


## 細かなバグフィックス

Starterにもいくつかバグがあったので、修正しています。

たとえば、複数のプログラムコードを並べたときに2つめ以降のマージンが広がってしまうバグがありました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/04f576a4-6b3a-5903-7477-cd37ae10b62f.png" alt="2つめ以降のマージンが広がっている" width="60%">

これは解決策が長らく分からなかったのですが、TeXには直前の余白の幅や高さを表す「`\lastskip`」[^3]なる素敵な機能があることが分かったため、解決することができました。
つまり直前に余白があれば、その分を差し引いて余白を追加しています。
CSSなら自動でやってくれることを手動でやっているわけですが、解決できてほんとよかった。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/0e8ee612-6984-7893-8653-8ff706748246.png" alt="マージンが均等になった！" width="60%">

[^3]: 実際には `\addvskip` を使っています。また `\lastskip` はLaTeXの本だと載ってないようで、TeXの本には載ってました。LaTeXじゃ足りなくてTeXにまで手を出さないといけないの、つらい。

(La)TeXはちっとも思い通りに動いてくれないのでクソゲー感満載ですけど、諦めかけたころになってこういう機能が見つかったりするので、ムリゲーではないんですよね。
こういうところがまた腹が立ちます。

他にバグがあれば、教えてもらえると助かります。


## （追記）プログラムコードの文字サイズを変更する

（追記 2019-08-27：紹介し忘れていたので追加しました。）

プログラムコードやターミナルの表示において、「ここだけ文字を小さくして長い行を収めたいなー」と思ったことはありませんか？
Starterならそれができます。

`//list[][][]` と `//terminal[][][]` の第3引数に、フォントサイズを指定できるようになりました。

* `fontsize=small` … 小さくする（すでに小さくしている場合は影響なし）
* `fontsize=x-small` … もっと小さくする
* `fontsize=xx-small` … もっともっと小さくする（通常は使うべきではない）

表示例：
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224266/e12ab31d-af56-b3c0-865f-451e472ec9da.png" alt="プログラムコードのフォントサイズを変更" width="70%"/>

この例では `//list` を使っていますが、`//terminal` でも使えます。


## 実装が間に合わなかったもの

前回の記事では、「[今後の計画](https://qiita.com/kauplan/items/d01e6e39a05be0b908a1#%E4%BB%8A%E5%BE%8C%E3%81%AE%E8%A8%88%E7%94%BB)」として「インライン命令の入れ子」の実装を挙げていました。
しかし残念ながら、技術書典7には間に合いそうにありません。

実は仮実装をしてみたのですが、Re:VIEWとの互換性をなるべくとりたいのに、Re:VIEWの細かい仕様が把握できないため、導入に踏み切れないのです。

Re:VIEWのインライン命令の仕様を把握するためにソースコードを読んでみたのですが、こう言っていいか分かりませんが、僕の頭では理解しかねるコードでした。
どうやら「`@<x>{...}`」と「`@<x>$...$`」と「`@<x>|...|`」の3つの書き方に対応するために複雑になっているようで、一時的にnull文字で置き換えてまた元に戻すとか、そんな感じになっていて正直理解できませんでした。

そういうわけで、Re:VIEWにおけるインライン命令の細かい仕様が分からないため、実装にはまだ時間が必要です。
僕としてはとても残念です。
期待していた方、申し訳ありません。


## ユーザの感想

ユーザから感想をいただきました。ありがとうございます。
(https://twitter.com/konosumi/status/1162615784234860544)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今回の変更点かなり良かったです。技術書典6の頃から使い始めてるのですが、何より余計なことを考えなくて済むので、執筆とRe:VIEWの主要な文法を覚えることだけに集中すればRe:VIEW Starterで本ができます。 <a href="https://t.co/bZsAnFNtTO">https://t.co/bZsAnFNtTO</a></p>&mdash; このすみ@技術書典7 (@konosumi) <a href="https://twitter.com/konosumi/status/1162615784234860544?ref_src=twsrc%5Etfw">August 17, 2019</a></blockquote> 

他にも感想お待ちしています。


## まとめ

LaTeXの苦しみとRe:VIEWの機能不足は、Re:VIEW Starterが受けとめます。
皆さんは原稿を書くことに集中して、すてきな書籍や技術同人誌を生み出してください。

ご意見、ご要望、バグ報告はハッシュタグ [#reviewstarter](https://twitter.com/search?q=%23reviewstarter) をつけてツイートしてください。


## おまけ

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

* はじめての表紙デザイン（技術系同人誌向け）<br>
  https://qiita.com/kauplan/items/2b2f1acbd8efe76c490b
* PDFにノンブルをつける「PDFOperation」<br>
  https://qiita.com/kauplan/items/cf17e8d8446d70b5e973
* Re:VIEW 2.5での改善点と残っている問題点<br>
  https://qiita.com/kauplan/items/5068e2a0da7847c2014e