Re:VIEW で mermaid を使った際にT3フォントが埋込まれないらしい場合の対処（図が徐々に小さくなる場合の対処も）

# はじめに
[人生で初めて同人誌を作りました。](https://zenn.dev/kikuyuta/articles/fd459116c23d10)そこで大変困ったことが置きました。かなり時間をかけたので、何をやったかを書き記しておきます。同じ悩みをお持ちの方の参考になれば幸いです。

なお、本質的な解決ではなく当面の回避策です。あと、以下は途中経過を相当はしょって書いてますが、紆余曲折の挙げ句の解決です。

# 環境と問題点
最初は LaTeX で書くつもりだったのですが「同人誌ならこれを使ったらどう」と進められて
- 清書系：[Re:VIEW](https://github.com/kmuto/review/) 
- 作図系：[Mermaid](https://mermaid.js.org)

を使うことにしました。どちらも初体験です。環境は以下のとおりです。

- MacBook Pro (Apple M1 Pro)
- MacOS (Sonoma 14.1.1)
- MacTeX (brew mactex-no-gui 20230314)
- ReVIEW 5.8
- Mermaid 10.6.1

なお、[Re:VIEW フォーマットガイド](https://github.com/kmuto/review/blob/master/doc/format.ja.md) の [mermaid-の利用](https://github.com/kmuto/review/blob/master/doc/format.ja.md#mermaid-の利用)には「現時点で、Linux 以外の動作は確認していません。」とあるので、そもそもMacOS上での動作はサポート外かもしれませんが、これ見ないでインストールしたら環境が出来てしまったので何の迷いもなく使ってしまいました。

調子良く書いて・描いて、同人誌の印刷屋さんに入稿できました。するとものの数時間後にツッコミが来て「入稿したPDFに埋め込まれてないフォントがある」とのこと。フォントの指定なぞは一切してないのでフォントについて指摘を受けても心当たりがありません。最悪代替フォントが使われるだろうから印刷できないこともないでしょうが、それは最後の手段です。

# 原因（と思われること）
mermaid に図形ファイルを出力させる際に、一旦 Web ブラウザを裏でいごかしてるようです。より正確に言うと Google Chrome のベースになってる Chromium を用いてるようです。Chromium は Re:VIEW 内に埋め込んでいる mermaid の図の記述ごとに pdf ファイルを作成するようです。そしてその pdf ファイルを LaTeX が `\inclucegraphics` して本文に取り込みます[^reviewincludegraphics]。

で、どうもこの Chromium が吐いた PDF を使うとよろしくないフォントを使ってしまうようで、そこんところを埋め込んでくれないようです。そのあたりは Re:VIEW の作者さんの記事[Re:VIEWでダイアグラムツールのMermaidに対応する作業を進めてみた](https://kmuto.hatenablog.com/entry/2023/04/02/213023)でも当初から指摘されてます（さんざん潮干狩りして、随分と後になってからこの記事に気が付きました）。

[^reviewincludegraphics]: 実際は Re:VIEW 用に \includegraphics を改変した `\reviewincludegraphics` というのを使ってます。

# フォントのチェックの方法
まずはどんなフォントが問題を起こしているのか確認しましょう。

## Acrobat でフォントを調べる
PDFを扱うのに [Adobe Acrobat Pro](https://www.adobe.com/jp/acrobat.html) というのがあります。有料のソフトウェアです。ただし、7日間の無料トライアルが可能です。

Acrobat を使ってどんなフォントが使われてるか調べるには以下をやります。

- Acrobat に PDFファイルを食わせます
- 一番上のメニューバーで Acrobat 「ファイル」を選択
- プルダウンメニューで「文書のプロパティ」を選択
- ポップアップウィンドウが出てくるので「フォント」を選択

これでフォント一覧のリストが出てくるので、ずーっと眺めると怪しげな Type 3 ってのが出てきます。これをどうにかしないといけないようです

![acrobat-font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/ea92148c-3293-8062-b48a-f8cc141f0ed3.png)
。

## pdffonts でフォントを調べる
UNIXコマンドの `pdffonts` でも中身は調べられます[^pdffonts]。これで見ると emb 列が全部 yes なんで大丈夫そうに見えるんですが、この `[none]` で始まるやつがやばそうです。

```
...
[none]   Type 3   Custom   yes no  yes    578  0
...
```
[^pdffonts]: Homebrewで入れたようですが記憶がないです。何かのコマンドの依存関係とかで入ったのかもしれません。

# 解決法
印刷屋さんに入稿したのと、オンライン販売用に作成したのと、やり方を変えて2通り試してみました。

## PDFをアウトライン化する
まあフォントを取り去ってしまえば良いので PDF ファイル全体をアウトライン化するという手があります。これは入稿の〆切を過ぎてしまってるので、もう時間の余裕がなく、とっさに取った解決法です。Acrobat Pro を使いました。もっと気軽なツールでできるのかもしれません。

んで、アウトライン化は Acrobat Pro があれば一発です。一発なんですが、操作する場所がわかりにくいです。探すのに一苦労しました。

まずはアウトライン化したい元のPDFファイルをAcrobatに読ませます。次に、メニューバーの下の「すべてのツール」を選択します。

![スクリーンショット 2023-11-23 23.14.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/7e8e41bb-480d-84cc-3a00-88f2153dd6bb.png)

左側に「すべてのツール」が出てきますが、おそらくかなりの方の環境で、ツールが多すぎて一覧に入らないです。なのでまず目いっぱい上までスクロースします。

![スクリーンショット 2023-11-23 23.14.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/d1df92ad-5c44-ad7a-f7ca-41db14a00b21.png)

すると「さらに表示」ってのが出てくるのでクリック。
![スクリーンショット 2023-11-23 23.14.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/7b9596ea-fd7a-e3a2-5091-1a3e407c6ea6.png)

すると「印刷工程を使用」ってのが出現するのでそれをクリック。
![スクリーンショット 2023-11-23 23.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/db40768f-20d4-8050-749b-36211e8089dc.png)

「印刷工程を使用」の中に「プリフライト」ってがでてくるのでそれをクリック[^preflight]。
![スクリーンショット 2023-11-23 23.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/66426ff0-739e-2f12-e068-7eb26172f698.png)

すると突然「あれ俺のマシン、MacOS 9 になった感じ？」ってな統一感の欠けたポップアップウィンドウが出てきます。「フォントをアウトラインに変換」というのを確認したら、このポップアップウィンドウの一番下「解析してフィックスアップ」を押してください。

するとアウトライン化したPDFが出来上がります。どのフォントをアウトライン化するという選択は出来なくて（やり方が分からなくて）全部のフォントがアウトライン化されます。私の場合は、元々は1.8MB強だったPDFファイルを変換したら50MBを超えました。これを印刷屋さんに入稿して今回は事なきを得ました。

[^preflight]: プリフライトってなんやねん、って思いますが、無視して進んでください。

## 図のPDFを別の形式にあらかじめ変換する
印刷屋さんに入稿するときは多少ファイルがデカくても良いですが、オンラインで販売するときにあまりでかいのはよろしくないので、今度は別の方法をとってみました。

Chromium で作成する PDF が T3 font を使わないようにすれば良いのでしょうが、私の力量では無理そうなので、この PDF を他の図形フォーマットに変換することんにしました[^playwright-runner]。今回は png を使ってます。全体のプロセスはこんな風にします。

[^playwright-runner]: [Re:VIEW](https://github.com/kmuto/review/) を追いかけて[playwright-runner](https://github.com/kmuto/playwright-runner) の先でなにかすれば良いというところまでは行きました。その先は時間切れで追いかけきれずです。

1. Re:VIEW をデバッグモードでいごかして、ファイルを片っ端から残すようにする
1. Mermaid による図形のPDFファイルが残るので、それをPNGに変換する
1. LaTeX のファイルがPDFを参照しているのを PNGを参照するように変更する
1. LaTeX を3回かけて、dvipdfmx をする

### Re:VIEW がファイルを残すようにする
デフォルトの動作では作業で生成した中間ファイルを Re:VIEW が最後に消去してます。
これをデバッグモードでいごかすことでファイルを消さないようにできます。

デフォでは `config.yml` の `debug:` が `null` になってます。

```config.yml
# デバッグフラグ。nullでないときには一時ファイルをカレントディレクトリに作成し、削除もしない
debug: null
```

これを `true` にします。

```config.yml
# デバッグフラグ。nullでないときには一時ファイルをカレントディレクトリに作成し、削除もしない
debug: true
```

これで `rake pdf` とやると作業ファイルを残したまま PDF が作成されます。出来上がったページは `mybookname`.pdf というファイルになりまして、作業ファイルは`config.yml` 内の `mybookname`-pdf というディレクトリに残ります。ここで `mybookname` とは `config.yml` 内で `bookname:`で指定する名前です。

```config.yml
# ブック名(ファイル名になるもの。ASCII範囲の文字を使用)
bookname: mybookname
```

### Mermaid が作った図形用PDFファイルをPNGファイルに変換する
変換用には `pdftoppm` を使いました。持ってない方は `netbpm` をインストールしてください。

- 図形用PDFファイルは `mybookname-pdf/images/latex` に `*.pdf` という名前で置いてある
- 変換したPNGファイルは `mybookname-pdf/images/png` に `*.png` という名前で置くことにする

この作業をシェルコマンドで書いたのが以下です。

```sh
cd mybookname-pdf/images
mkdir png
for i in latex/*.pdf
do
        pdftoppm -r 300 -png latex/`basename $i .pdf`.pdf > png/`basename $i .pdf`.png
done
```

解像度は `-r` のオプションで指定してください。この例では 300dpi にしています。この解像度を高くするとファイルがデカくなります。

### LaTeX のファイルがPDFを参照しているのを PNGを参照するように変更する
Re:VIEW では各章ごとに `chap.re` ファイルとして文書を書きます。これに対応して `chap.tex` ファイルができます。ファイル内で `//graph[cite][mermaid][caption]{` と言う指示によって mermaid の図ができます。図は `cite.pdf` という名前のPDFファイルになり、以下のように `chap.tex` から参照されます。

```tex
\begin{reviewimage}%%cite
\reviewincludegraphics[width=\maxwidth]{images/latex/cite.pdf}
\reviewimagecaption{caption}
\label{image:chap:cite}
\end{reviewimage}
```

これを先程変換したPNGファイルを参照するように変更します。

```tex
\begin{reviewimage}%%cite
\reviewincludegraphics[width=\maxwidth]{images/png/cite.png}
\reviewimagecaption{caption}
\label{image:chap:cite}
\end{reviewimage}
```

これをshスクリプトにやらせます。

```sh
cd mybookname-pdf

for i in [a-z]*.tex
do
        echo $i
        sed -i -e 's/images\/latex\/\([a-z0-9-][.]\)pdf/images\/png\/\1png/g' $i
done
```

### LaTeX を3回かけて、dvipdfmx をする
以上でいろいろな変更は終わったので、あとは通常の Re:VIEW 同様に `LaTeX` して `.dvi` ファイルを `.pdf` に変換します。大元の LaTeX ファイルは `__REVIEW_BOOK__.tex` という名前です。


```sh
cd mybookname-pdf
uplatex -interaction=nonstopmode -file-line-error -halt-on-error __REVIEW_BOOK__
uplatex -interaction=nonstopmode -file-line-error -halt-on-error __REVIEW_BOOK__
uplatex -interaction=nonstopmode -file-line-error -halt-on-error __REVIEW_BOOK__
dvipdfmx -d 5 -z 9 __REVIEW_BOOK__
```

これでファイル名 `mybookname/__REVIEW_BOOK__.pdf` として出来上がります。

### 全部を1つのshスクリプトで
以上を全部まとめたスクリプトがこちらです。

```sh
cd mybookname-pdf

for i in [a-z]*.tex
do
        echo $i
        sed -i -e 's/images\/latex\/\([a-z0-9-]*[.]\)pdf/images\/png\/\1png/g' $i
done

(cd images;
mkdir png
for i in latex/*.pdf
do
        pdftoppm -r 300 -png latex/`basename $i .pdf`.pdf > png/`basename $i .pdf`.png
done)

uplatex -interaction=nonstopmode -file-line-error -halt-on-error __REVIEW_BOOK__
uplatex -interaction=nonstopmode -file-line-error -halt-on-error __REVIEW_BOOK__
uplatex -interaction=nonstopmode -file-line-error -halt-on-error __REVIEW_BOOK__
dvipdfmx -d 5 -z 9 __REVIEW_BOOK__
```

最後に `mv` して `mybookname/__REVIEW_BOOK__.pdf` を `mybookname.pdf` にすれば良いのでしょうが、変換前と変換後を残して置きたいのであえてそのままにしてます。

# 図がだんだん小さくなってしまう場合のハック
ここまでの、フォントが埋め込まれない場合の対処とは全然関係ないですが、もうひとつ困ったので、それの当面の回避策を残しておきます。

Mermaid で大量に図を入れたところ、徐々に図が小さくなっていく現象がありました。これは `selfcrop` を無効にすることで対処しました。以下がデフォです。

```config.yml
playwright_options:
  playwright_path: "./node_modules/.bin/playwright"
  selfcrop: true
  pdfcrop_path: "pdfcrop"
  pdftocairo_path: "pdftocairo"
```

これを以下のように変更します。

```config.yml
playwright_options:
  playwright_path: "./node_modules/.bin/playwright"
  selfcrop: false
#  selfcrop: true
  pdfcrop_path: "pdfcrop"
  pdftocairo_path: "pdftocairo"
```

ただこれをやると、図が小さくなっていくのは防げますが、図をページ幅一杯に入れようとするので図が大きくなりすぎるという欠点があります。

# まとめ
Re:VIEW で Mermaid を併用したときに起こるフォントの問題について2通りの回避策を示しました。いずれ根本的に解決すると思うので、この技は必要なくなるでしょう。



## 謝辞
まず、Re:VIEW の作者の方とメンテナの方に感謝したいと思います。
そして、今回の作業で[myasu](https://qiita.com/myasu)さんには大変お世話になりました。ここに記して感謝します。

## この記事の成果

[第9回 技術書同人誌博覧会](https://gishohaku.dev)の[香美山社中](https://gishohaku.dev/gishohaku9/circles/JZWuUGoo4hE1PcGEyRLP)というサークルで、私の書いた [理系のための経理入門](https://gishohaku.dev/gishohaku9/books/dKMFpsXGdstZ5BqeDb0U) と、[myasu](https://qiita.com/myasu)さんの書いた [いっしょに学ぶ Python & Elixir & Rust](https://gishohaku.dev/gishohaku9/books/X3lWRDLwbfEExio9f4N7) という書籍を販売してます。~~ぜひおいでてください。~~ ぜひご覧になってください。