LaTeX de 余白のない PDF を作って画像に変換 (1)

# LaTeX de 余白のない PDF を作って画像に変換 (1)

[1]: https://qiita.com/Yarakashi_Kikohshi/items/8a46d2d16cf770b0259e
[2]: https://qiita.com/Yarakashi_Kikohshi/items/fdd0bf140b1deb0c8448

PDF から画像を作りたいなら，スクリーンショットすれば良いかもしれない．しかし，1 つ 1 つスクショしてトリミングするのは非常に面倒くさい．大量になれば尚更である．

TeX で PDF を作成するなら，そのまま画像にまでしてしまおう!! というのが本記事のモチベーションになる．

:::note info
記事が長くなってしまったので，本記事では LaTeX から余白のない PDF を作成するのみとしています．
PDF を画像 (PNG/ SVG) に変換する方法は次の記事で紹介します．
:::

> [LaTeX de 余白のない PDF を作って画像に変換 (2) \- Qiita][2]

表や数式，TikZ などの余白のない PDF を作る方法として以下の 3 つを紹介したい．

- standalone クラス
- preview パッケージ
- トリミング (pdfcrop)

次の項でどの方法を利用するのが良いか示している．

## Summary

> 目的とタイプセット方法，利用するパッケージなどが明らかな方が目次を見るよりも明瞭な気がしてきたので表にした．
> 以下の表で 6 つの項目に対するオススメの方法を示しておく．

| 画像にしたいコンテンツ |                     LuaLaTeX                      |                  (u)pLaTeX +dvipdfmx                   |
| :--------------------: | :-----------------------------------------------: | :----------------------------------------------------: |
|        行内数式        | [standalone](#-数式), [preview](#-番号付きの数式) |                  [standalone](#-数式)                  |
|      別行立て数式      |            [preview](#-番号付きの数式)            |             [トリミング](#-トリミングする)             |
|           表           |    [standalone](#-表), [preview](#-table-環境)    |                   [standalone](#-表)                   |
|   キャプション付き表   |              [preview](#-table-環境)              |             [トリミング](#-トリミングする)             |
|          TikZ          |     [standalone](#-tikz), [preview](#-tikz-1)     | [トリミング](#-トリミングする), ([standalone](#-tikz)) |
|          文章          |      [トリミング](#-トリミングする), preview      |             [トリミング](#-トリミングする)             |

" トリミング " としている箇所は A4 などで通常通りに作成してから，pdfcrop でトリミングすることを指している．

**(u)pLaTeX+dvipdfmx の注意点**
: まったく利用できないわけではないが，いくつかの点で期待通りの結果を得られない場合がある．特定のフォント等で使用したい場合を除いては LuaLaTeX を利用した方が良いだろう．
あるいは，トリミングすることを主軸に考えた方が有用だろう．

standalone では余白がなく出力サイズがコンテンツの最大の高さ/ 幅に合わせられている．
しかし，preview では余白が少しだけ作成される．

# ○ standalone クラス

> [standalone | CTAN](https://www.ctan.org/pkg/standalone)

standalone バンドル（クラスとパッケージの両方がある）は docmute や subfiles と同じようにファイルを分割することでそれぞれのタイプセットを軽くするためのものになっている．(実は一部 preview パッケージを利用しているようだ)

ただし，docmute や subfiles と大きく異なる点として，standalone が扱うものは 1 つのページそのものではなく，ドキュメントを構成するコンテンツのみを作成する (表や TikZ による描画を余白がない PDF にする) ことが出来る点にある．

これを利用して，表や TikZ による描画を余白なしに PDF を作成することを考えたい．
本来はここで作成した表などを挿入したいドキュメントに戻して作成することになるが，ここでは最終的に画像を作成したいだけなのでドキュメントに挿入する方法は述べない．

**cf. The standalone pakcage, §5 Usage of the standalone class**

基本的な使い方は以下のようになる．

```latex
\documentclass{standalone}
%
% some packages
%
\begin{document}
  % tabular, formular, TikZ ...etc
\end{document}
```

複数のオプションを指定する場合には `,` で区切る．

## ■ 各種設定

### ▽ dvipdfmx の利用

タイプセットには (u)pLaTeX+dvipdfmx を利用しても問題ないようだ．ただし，DVI に依存するパッケージを利用する際には dvipdfmx をグローバルオプションとして読み込ませておく必要がある．(パッケージのドキュメントには dvipdfmx への言及はなされていないが，実行することは可能となっている)

> [standalone クラスは dvipdfmx でも使えるような気がする - GitHub](https://gist.github.com/zr-tex8r/3845085)

以下のようにドキュメントクラスを読み込もう．

```latex
\documentclass[dvipdfmx]{standalone}
```

ただし，複数ページに渡る場合には，1 ページ目のサイズが 2 ページ目以降にも反映されるという問題が生じてしまう．
特にこだわりがなければ LuaLaTeX を利用するか，単数ページのみを作成するようにしよう．

### ▽ クラスの変更

基本的なドキュメントクラスは article となっている．
これを変更できる．`class` オプションを利用しよう．

**例**
:  jsarticle に変更することを考える．このときのタイプセットは upLaTeX+dvipdfmx で行う．

```latex
\documentclass[dvipdfmx,uplatex,class=jsarticle]{standalone}
```

`class` で読み込むクラスに必要なオプションは `class=hoge` より前に挿入する必要がある．

### ▽ 余白を作る

余白がまったくないので，PDF を生成するとギリギリに出力される．
画像として利用する場合には少しだけ余白があった方が良いだろう．(また，出力すると少し見切れていることがある)
`border` オプションを利用すれば良い．例として，周囲 1mm の余白を設定する．

```latex
\documentclass[border=1mm]{standalone}
```

以下のいずれかのようにしても良い．

```latex
border=<length (all sides)>
border={<length (left/right)> <length (bottom/top)>}
border={<length (left)> <length (bottom)> <length (right)> <length (top)>}
```

ちなみに `margin` でも `border` と同じ結果を得る．

### ▽ 複数コンテンツの作成

standalone ではコンテンツ全体が 1 つのブロックであり，1 つのページに表示されるべきであると想定しているため，そのままでは複数ページの作成は出来ない．
`multi` オプションを利用しよう．

このオプションは 1 つのページにしたいコンテンツを任意の環境に挿入することで得られる．
任意の環境名は，既存の環境名でも自作の環境名でも問わない．

```latex
\documentclass[multi=hoge]{standalone}
% some packages
\begin{document}
%
% Created here as a new page
\begin{hoge}
  % content
\end{hoge}
%
% Created here as a new page
\begin{hoge}
  % content
\end{hoge}
% more hoge environments ...
\end{document}
```

(u)pLaTeX+dvipdfmx を利用する場合は，1 ページ目のサイズが 2 ページ目以降にも反映されるため注意が必要．

## ■ 数式

equation 環境や align 環境などの別行立ての数式環境を利用することが出来ない．
したがって，利用できるのは行内環境のみになる．

そのため，以下のように `$` で囲み `\displaystyle` でディスプレイスタイルに変更する必要がある．

```latex
$\displaystyle
  % Equation
$
```

あるいは，`multi` オプションを利用して複数の数式を同時に作成したい場合には，math 環境を利用すると良いだろう．これは LaTeX 標準の行内数式環境である．
また，amsmath を読み込んでいても問題ない．

```latex
\documentclass[multi=math]{standalone}
% It doesn't matter if you load amsmath
\begin{document}
%
% Created here as a new page
\begin{math}\displaystyle
  % Equation
\end{math}
%
% Created here as a new page
\begin{math}\displaystyle
  % Equation
\end{math}
% more math environments ...
\end{document}
```

しかし，行内数式しか用いることが出来ないために以下のような数式を生成することは出来ない．

- 式番号付きの数式
- amsmath から提供される align 環境などの `&` で関係演算子などを揃えた数式 (数式環境内で使用される `-ed` 環境や行列環境は除く)

したがって，これらのような数式を作りたい場合には，次の preview パッケージを利用するかトリミングすることを考えると良いだろう．

## ■ 表

表を作成する場合には tabular 環境を利用すれば良い．
ここで table 環境を利用する必要はない．(というよりも利用できない)

```latex
%
% DO NOT surround in table environment
%
\begin{tabular}
  % table contents
\end{tabular}
```

preview パッケージでは table 環境を利用することが出来るようになる．利用したい場合には参照してほしい．

## ■ TikZ

TikZ を利用する場合は `tikz` オプションを利用する．このオプションを有効にするとき，`multi=tikzpicture,varwidth=false` と同じになる．

このオプションによって TikZ が自動的に読み込まれ，tikzpicture 環境を利用することが出来るようになる．
また，複数の tikzpicture 環境を用いると複数ページの PDF を得ることが出来る．

```latex
\documentclass[tikz]{standalone}
% some packages
\begin{document}
%
% Each tikzpicture environment switches pages
%
% first TikZ
\begin{tikzpicture}
  % tikz
\end{tikzpicture}
%
% second TikZ
\begin{tikzpicture}
  % tikz
\end{tikzpicture}
% more tikzpictures ...
\end{document}
```

----------

ただし，(u)pLaTeX+dvipdfmx を利用する場合には少し勝手が異なるようである．

> [standalone クラス \- Qiita](https://qiita.com/ryutaatkagawanct/items/7fff46f1f423a3a7df9a)

tikzpicture 環境が 1 つのみであれば `tikz` オプションの利用で問題ないが，複数の tikzpicture 環境を利用する場合には正常にオプションが機能しないようだ．

したがって，`multi=tikzpicture` を有効にして `\usepackage{tikz}` とすれば良い．

<!-- (`\documentclass[dvipdfmx,tikz]{standalone}` としても同じ結果を得るようだ．ただし，この場合にはオプションの順序が正しい必要がある．) -->

```latex
\documentclass[multi=tikzpicture,dvipdfmx]{standalone}
\usepackage{tikz}
% some packages
\begin{document}
  % tikzpicture environments
\end{document}
```

しかし，この場合であっても 1 ページ目のサイズが 2 ページ目以降にも反映されるため注意が必要．(単数ページの作成の時のみ有用だろう)

**やはり，LuaLaTeX を利用すればすべて解決！**

# ○ preview パッケージ

> [preview | CTAN](https://www.ctan.org/pkg/preview)

preview パッケージを利用すると standalone で不可能だった番号付き数式や tabel 環境を利用することが出来る．
ただし，このパッケージは dvipdfmx を利用して上手く余白を消すことが出来ない．

> [dvipdfmx で preview パッケージする件について \- マクロツイーター](https://zrbabbler.hatenablog.com/entry/20121007/1349622782)

上の記事では dvipdfmx であっても利用できるように解決している．ただし，TeX Live のみでは解決しないことに注意したい．

----------

以下では LuaLaTeX でタイプセットすることを前提に preview パッケージを利用することを想定する．

preview パッケージは以下のように読み込む．`active` と `tightpage` オプションは有効にしておく．これら無しでは余白を取り除くことが出来ない．
基本的には preview 環境内のコンテンツを余白のない 1 ページとして出力する．

```latex
\usepackage{article}
\usepackage[active,tightpage]{preview}
% some packages
\begin{document}
%
% Created here as a new page
\begin{preview}
  % tabular, formular, TikZ ...etc
\end{preview}
%
% Created here as a new page
\begin{preview}
  % tabular, formular, TikZ ...etc
\end{preview}
% more preview environments
\end{document}
```

## ■ 番号付きの数式

オプションから `displaymath` または `textmath` とすれば，別行立て数式，行内数式がページを変えて出力される．

これらの数式は preview 環境で囲う必要はない．(オプションを指定しない場合には preview 環境で囲う必要がある)

```latex
\documentclass{article}
\usepackage{amsmath}
% It doesn't matter if you load amsmath
% Loading order; amsmath --> preview with `displaymath` option
\usepackage[active,tightpage,displaymath,textmath]{preview}
\begin{document}
%
% Created here as a new page
$ \alpha $
%
% Created here as a new page
\begin{equation}
  % Numbered equation
\end{equation}
%
% Created here as a new page
\begin{align}
  % Numbered equaitons
\end{align}
% more mathematics environments ...
\end{document}
```

これで出力すると式番号が付与されている．

amsmath から提供されている `*` 付きの環境では式番号は付与されない．ただし，式番号を付与しない場合には右側が切り取られてしまう．
`displaymath` オプションを使用せずに preview 環境を利用すると解消されるが，この場合では align 環境を使用した数式の上側に余計は空白が作られてしまうようだ．

あるいは，mathtools の `showonlyrefs` オプションを用いれば式番号なしでも右幅を切り取られない結果を得ることが出来る．


```latex
\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\mathtoolsset{showonlyrefs}
\usepackage[active,tightpage,displaymath,textmath]{preview}
\begin{document}
%
\begin{equation}
  % single equation
\end{equation}
%
\begin{align}
  % multi equations
\end{align}
\end{document}
```

また，式番号を必要な式のみに出力したい場合には `\noeqref` を利用すれば良い．

<details><summary> 式番号を必要な式のみ出力する例 (折りたたみ)</summary><div><br>


以下の例では `\label` と `\noeqref` を合わせた `\onlylabel` を作成したうえでタイプセットしている．

1, 3, 4, 7 番目のみに式番号を与えている．

```latex
\documentclass{jlreq}
\usepackage{amsmath}
\usepackage{mathtools}
\mathtoolsset{showonlyrefs=true}
\usepackage[active,tightpage,displaymath]{preview}

\newcommand{\onlylabel}[1]{
  \noeqref{#1}
  \label{#1}
}

\begin{document}
%
% First page
\begin{align}
  f(x)
    & =
      ax^2 +bx +c
      \onlylabel{first}
      \\
    & =
      a\left( x^2 +\frac{b}{a}x \right) +c
      % \onlylabel{second}
      \\
    & =
      a\left( x +\frac{b}{2a} \right)^2 -\frac{b^2}{4a} +c
      \onlylabel{third}
\end{align}
%
% Second page
% @ f(x)=0
\begin{align}
  0
    & =
      a\left( x +\frac{b}{2a} \right)^2 -\frac{b^2 -4ac}{4a}
      \onlylabel{4th}
      \\
  \left( x +\frac{b}{2a} \right)^2
    & =
      \frac{b^2 -4ac}{4a^2}
      % \onlylabel{5th}
      \\
  x +\frac{b}{2a}
    & =
      \pm\frac{\sqrt{b^2 -4ac}}{2a}
      % \onlylabel{6th}
\end{align}
%
% Third page
\begin{equation}
  x
    =
      \frac{-b \pm\sqrt{b^2 -4ac}}{2a}
      \onlylabel{7th}
\end{equation}
%
\end{document}
```

|                    First page                     |
| :-----------------------------------------------: |
| ![Numbered only referenced equations][first page] |

[first page]: https://i.gyazo.com/facd679911fd11f78ad16760ee824364.png

----------

|                    Second page                     |
| :------------------------------------------------: |
| ![Numbered only referenced equations][second page] |

[second page]: https://i.gyazo.com/e644f6e7ec624b0babd77525a0d11e01.png

----------

|                    Third page                     |
| :-----------------------------------------------: |
| ![Numbered only referenced equations][third page] |

[third page]: https://i.gyazo.com/41c4548293533ae80bffb19f828883ef.png


以下のような警告が表示されなくなるまでタイプセットを繰り返せば完了する．

```
Label(s) may have changed. Rerun to get cross-references right.
```


</div></details>


## ■ table 環境

standalone では tabel 環境を利用できなかったが，preview パッケージでは利用することが出来る．
`floats` オプションを利用する．このとき，preview 環境で囲う必要はない．

```latex
\documentclass{article}
\usepackage[active,tightpage,float]{preview}
% some packages
\begin{document}
\begin{table}
  \centering
  \caption{CAPTION}
  \begin{tabular}
    % table contents
  \end{tabular}
\end{table}
\end{document}
```

キャプションの番号も機能している．ただし，レイアウトが少し残念な形になるように思われる．(テスト方法が悪かったか?)

## ■ TikZ

preview パッケージでももちろん TikZ で描画したものを出力することが出来る．

```latex
\documentclass{article}
\usepackage[active,tightpage]{preview}
\usepackage{tikz}
\begin{document}
%
% Created here as a new page
\begin{preview}
  \begin{tikzpicture}
    % tikz ...
  \end{tikzpicture}
\end{preview}
%
% Created here as a new page
\begin{preview}
  \begin{tikzpicture}
    % tikz ...
  \end{tikzpicture}
\end{preview}
% more preview environment with tikzpicture
\end{document}
```

## ■ 最大幅を揃える

PowerPoint などに PNG 画像として利用したいとする場合，横の最大幅を揃えておくと楽に挿入できると思われる．
これを実現してみよう．下に要件と解決方法を示す．

- 複数 preview 環境の幅を揃える

    ↳ 0pt の直線を引く

- それぞれのコンテンツを中央揃えにする

    ↳ center 環境を利用する


以上から，以下のように preview 環境を利用すれば良い．

```latex
\begin{preview}
  \begin{center}
    % tabular, formular, TikZ ...etc
  \end{center}
  \rule{\linewidth}{0pt}
\end{preview}
```

あるいはこれを swpreview(Same width preview) 環境として定義しても良いだろう．

```latex
\newenvironment{swpreview}
{
  \preview
  \center
}
{
  \endcenter
  \rule{\linewidth}{0pt}
  \endpreview
}
```

このようなテクニックは standalone では上手くできないようだ．これは standalone では 1 つのページに複数のコンテンツがある場合，横並びになってしまうからだ．

# ○ トリミングする

jsarticle などで作成して A4 サイズの PDF を作成して余白部分をトリミングで取り除きたい．
pdfcrop を利用してトリミングしよう．これは TeX Live にも収録されている．

> [pdfcrop - TeX Wiki](https://texwiki.texjp.org/?pdfcrop)

詳しい使い方は `$ texdoc pdfcrop` とするか `$ pdfcrop --help` とすれば見ることが出来る．

コマンドラインでは以下のように利用する．

```
$ pdfcrop test.pdf
```

`test-crop.pdf` が出力される．同じファイル名で出力したい場合は `test.pdf` を続けて追加する．

これにはページ番号も加味してトリミングされるため，ページ番号は消去しておいた方が良い．
TeX ファイルでページ番号が出力されないように以下をプリアンブルに追加する．

```latex
\pagestyle{empty}
```

また，数式に式番号を付与したい場合，用紙サイズを B5 にするなど A4 より少し小さくすると良い感じの大きさになる (気がする)

`\newpage` で改ページにすれば複数ページの PDF を作成できる．複数ページの PDF もいっきにトリミングすることが出来る．

<!--
■ トリミングの意味

トリミングする場合，これは PDF 上で非表示にしているだけに過ぎないらしい．

> [Adobe Acrobat での PDF ページのトリミング](https://helpx.adobe.com/jp/acrobat/using/crop-pdf-pages.html)
> > 注意：
> > トリミングを行っても、ファイルサイズは変わりません。それは、トリミング箇所が単に非表示になるだけで、破棄されるわけではないからです。

したがって，以下のように PDF の余白が SVG に引き継がれる場合があるようだ．(pdfinfo で確認しながらトリミングしてみたが，きちんとトリミングされているように思われる)

> [QA: standalone における align 環境について](https://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=2875)

余白をトリミングしたにも関わらず SGV に変換すると残ってしまう場合には諦めよう．
あるいは，たいていの場合 LuaLaTeX であればトリミングする必要はない．LuaLaTeX を使おう．
-->

## ■ 余白を残す

`--margings` オプションでドキュメント内の構造から左，上，右，下の順で余白 (単位: bp) を設定することが出来る．
これらの数値が 2 つの場合は左右，上下で等しい値，1 つの場合は上下左右で等しい値としてみなされる．

```
$ pdfcrop --margins "10 5" test.pdf
```

左右に 10bp，上下に 5bp の余白が作られる．

----------

**任意 PDF のトリミング**
: もしも，コマンドラインで任意の PDF をトリミングしたい場合には余白をマイナスにして欲しいところを逐次確認しながら切り出すことになる．
凄く面倒くさい．

> [pdfcrop で任意の範囲を切り抜く \- Qiita](https://qiita.com/ishiijunpei/items/312d1bdf0268a0f5d0cf)

これに関してはオンライン上のサービスを利用した方が懸命である．PDF を見ながら切り取ることが出来る．

> [PDF トリミング \- オンライン無料で PDF ページを切り取る \- HiPDF](https://www.hipdf.com/jp/crop-pdf)

また，PDF に含まれている画像を出したい場合であれば，トリミングするよりも画像抽出を考えた方が懸命である．
Poppler ライブラリの pdfimages を利用して抽出しよう．

> [Poppler：pdfimages の使い方 \| PDF](http://pdf-file.nnn2.com/?p=877)

## ■ VSCode でトリミング

コマンドラインをいちいち操作するのは面倒なので，VSCode +LaTeX Workshop で LaTeX 環境を構築しているならば，これを recipe から使えるようにしたい．
settings.json で以下のようにする．(TeX をタイプセットする tool や recipe は含めていないので注意．適宜挿入してほしい．)

```jsonc
    "latex-workshop.latex.recipes": [
      // Recipes for compiling TeX to PDF
      // ... ...
      {
        "name": "Trimming PDF",
        "tools": [
          "pdftrimming",
        ]
      },
    ],
    "latex-workshop.latex.tools": [
      // Tools for compiling TeX to PDF
      // ... ...
      {// Trimming PDF
        "name": "pdftrimming",
        "command": "pdfcrop",
        "args": [
          "--margins",
          "10 5",
          "%DOC%.pdf",
          "%DOC%.pdf",
        ]
      },
    ],
```

デフォルトでは "-crop" がファイル名に加わってしまうので，同じファイル名にするために `"%DOC%.pdf"` を加えている．

# まとめ

(u)pLaTeX+dvipdfmx を利用しているといくつか不具合が出てしまう方法が多い印象を受ける気がする．
好きなタイプセット方法を利用すれば良いと思うが，日本語文を打たない場合ならば，なおさら LuaLaTeX でタイプセットした方が有用だろうと思われる．

この記事の続きにあたる記事では，VSCode で利用する tools と recipes を本記事で紹介した pdfcrop も含めて紹介している．

> [LaTeX de 余白のない PDF を作って画像に変換 (2) \- Qiita][2]