[LaTeX] \phantom でいい感じに揃える

<!--
イントロ
- アドカレ
- 対象読者
- LaTeX を書いていて空白を調整したくなったことがある人
- できること
- 環境

\phantom, \hphantom, \vphantom について
- なぜ phantom か
- 汎用性が高い
- ベストプラクティスではなさそうなことが多いが...
- 具体的な解説

具体例
- \phantom{{}={}}
- iff, implies, implied まわり
- \sqrt{g} + \sqrt{h}
- 疑似的中央ぞろえ
-->

# はじめに

本記事は[物工/計数 Advent Calendar 2022](https://adventar.org/calendars/7701) の 12 日目の記事です．

本記事では，空白を出力する LaTeX の命令として，`\phantom` を解説します．
その後，実用を意識した具体例を紹介します．

空白を出力する命令はたくさんありますが，その中でも `\phantom` は幅や高さなどを揃える用途に向いています．
また，本記事では登場しませんが，特に Beamer で `\phantom` は有用だと感じます．
その点でも，`\phantom` について知っておくと良いと思います．

なお，`amsmath` パッケージの使用を前提とします．また，例は LuaLaTeX 環境で動作確認しました．

# `\phantom` の解説

## 簡単な例

`\phantom` は，引数の文字列と同じ幅，同じ高さ・深さ[^height_depth]の空白を出力します．
本文中・数式中どちらでも使えます．

[^height_depth]: 「高さ・深さ」は，縦の大きさだと読み替えて問題ありません．ベースラインから上端の幅を「高さ」と呼び，ベースラインから下端の幅を「深さ」と呼びます (参考文献 [1] 参照)．

```latex:\phantom の例
\begin{align}
	a b c d e \\
	a \phantom{b c} d e
\end{align}
```

出力：
```math
\begin{align}
	a b c d e \\
	a \phantom{b c} d e
\end{align}
```

1 行目 の $bc$ が，2 行目では同じ大きさの空白に置き換わっているのが分かります．


## `=` を含む例

`=` などの二項演算子を `\phantom` に渡す場合には注意が必要です．
`\phantom{=}` と書かず，`\phantom{{}={}}` と書きましょう．
理由は，空白に置き換えたい `=` が，二項演算子としての `=` であることを LaTeX に教えるためです．
`+` や `\iff` などについても同様です[^binary]．`\phantom{{}+{}}` や `\phantom{{}\iff{}}` と書きましょう．

[^binary]: 細かいことを言うと，仕様としては少し異なります．`+` は binary operation で，`=`, `\iff` は binary relation です．これらは，左右に入る空白の幅が異なります． (参考文献 [2, 3] 参照)．



```latex:= を含む例
\begin{align}
	a & = b                                    \\
	a & \phantom{{}={}} b & \text{$\cdots$ 正} \\
	a & \phantom{=} b     & \text{$\cdots$ 誤} \\
\end{align}
```

出力：
```math
\begin{align}
	a & = b                                    \\
	a & \phantom{{}={}} b & \text{$\cdots$ 正} \\
	a & \phantom{=} b     & \text{$\cdots$ 誤} \\
\end{align}
```

## `\hphantom`, `\vphantom` について

`\phantom` と類似の命令として，`\hphantom`, `\vphantom` があります．
`\hphantom` は，引数の文字列と同じ幅で，高さ・深さ $0$ の空白を出力します．
`\vphantom` は，引数の文字列と同じ高さ・深さで，幅 $0$ の空白を出力します．

```latex:\hphantom, \vphantom の例
\begin{align}
	\fbox{$\frac{1}{2}$} \fbox{$\vphantom{\frac{1}{2}}$} \\
	\fbox{$\hphantom{\frac{1}{2}}$} \fbox{}
\end{align}
```

出力：
```math
\begin{align}
	\fbox{$\frac{1}{2}$} \fbox{$\vphantom{\frac{1}{2}}$} \\
	\fbox{$\hphantom{\frac{1}{2}}$} \fbox{}
\end{align}
```

# `\phantom` の具体例

以降では，実用を意識した具体例を紹介します．

## 式で揃え，さらに項ごとに揃える

何をしたいかは，出力を見てもらうのが早いと思います．
ちなみに，`\phantom` を `\hphantom` に置き換えてもよいです．

### 簡単な例

```latex: 簡単な例
\begin{align}
	\fbox{最初}
	 & = \fbox{長い項 1}                 \\
	 & \phantom{{}={}} + \fbox{長い項 2} \\
	 & \phantom{{}={}} + \fbox{長い項 3} \\
	 & = \fbox{最後}
\end{align}
```

出力：
```math
\begin{align}
	\fbox{最初}
	 & = \fbox{長い項 1}                 \\
	 & \phantom{{}={}} + \fbox{長い項 2} \\
	 & \phantom{{}={}} + \fbox{長い項 3} \\
	 & = \fbox{最後}
\end{align}
```

### 少し凝った例

```latex: 少し凝った例
\begin{align}
	\fbox{最初}
	 & = \fbox{長い項 1}                                   \\
	 & \phantom{{}={}} + \fbox{長い項 2}                   \\
	 & \phantom{{}={}} + f\bigg( \fbox{長い項 3}           \\
	 & \phantom{{}={}  + f\bigg(} + \fbox{長い項 4}        \\
	 & \phantom{{}={}  + f\bigg(} + \fbox{長い項 5} \bigg) \\
	 & = \fbox{最後}
\end{align}
```

出力：
```math
\begin{align}
	\fbox{最初}
	 & = \fbox{長い項 1}                                   \\
	 & \phantom{{}={}} + \fbox{長い項 2}                   \\
	 & \phantom{{}={}} + f\bigg( \fbox{長い項 3}           \\
	 & \phantom{{}={}  + f\bigg(} + \fbox{長い項 4}        \\
	 & \phantom{{}={}  + f\bigg(} + \fbox{長い項 5} \bigg) \\
	 & = \fbox{最後}
\end{align}
```

## `\sqrt` の高さを揃える

`\sqrt` の中で `\vphantom` により縦の空白を確保し，`\sqrt` の高さを揃えています．

```latex: \sqrt の高さを揃える
\begin{align}
	 & \sqrt{x + 3} + \sqrt{x^2 - 3}                                                                         &  & \text{$\cdots$ 揃っていない} \\
	 & \sqrt{\vphantom{x + 3} \vphantom{x^2 - 3} x + 3} + \sqrt{\vphantom{x + 3} \vphantom{x^2 - 3} x^2 - 3} &  & \text{$\cdots$ 揃っている}
\end{align}
```

```math
\begin{align}
	 & \sqrt{x + 3} + \sqrt{x^2 - 3}                                                                         &  & \text{$\cdots$ 揃っていない} \\
	 & \sqrt{\vphantom{x + 3} \vphantom{x^2 - 3} x + 3} + \sqrt{\vphantom{x + 3} \vphantom{x^2 - 3} x^2 - 3} &  & \text{$\cdots$ 揃っている}
\end{align}
```

## `\iff` と同じ幅の `\implies`, `\impliedby` を作る

この例では，`mathtools` パッケージの `\mathllap`, `\mathrlap` という命令を用います．これらの命令は数式中で使います[^mathmode]．
`\mathllap` は，引数の数式を左に出力し，その後元の位置に戻ります．`\mathrlap` も同様に，引数の数式を右に出力し，その後元の位置に戻ります．

[^mathmode]: ちなみに，数式以外の本文中では `\llap`, `\rlap` を用います．

以上を踏まえて，`\iff` と同じ幅の `\implies`, `\impliedby` を作りましょう．

```latex: \iff と同じ幅の \implies, \impliedby
\begin{align}
	P & \iff Q                                          \\
	P & \hphantom{{}\iff{}} \mathllap{{}\implies{}} Q   \\
	P & \mathrlap{{}\impliedby{}} \hphantom{{}\iff{}} Q
\end{align}
```

出力[^llap]：
```math
\begin{align}
	P & \iff Q                                      \\
	P & \hphantom{{}\iff{}} \llap{{}\implies{}} Q   \\
	P & \rlap{{}\impliedby{}} \hphantom{{}\iff{}} Q
\end{align}
```

[^llap]: `\mathllap`, `\mathrlap` が Qiita の数式環境だと使えないため，`\llap`, `\rlap` で代用しています．

# まとめ

- `\phantom` は引数の文字列と同じ幅，同じ高さ・深さの空白を出力する
- `\hphantom` は幅だけを確保する
- `\vphantom` は高さ・深さだけを確保する

# 参考文献

[1] [Martin Scharrer (2020/8/19). The trimclip Package.](https://ctan.math.illinois.edu/macros/latex/contrib/adjustbox/trimclip.pdf) 2022 年 12 月 11 日閲覧．
[2] [Victor Eijkhout (1991). TeX by topic.](https://texdoc.org/serve/TeXbyTopic.pdf/0) 2022 年 12 月 11 日閲覧．
[3] [LaTeX2e unofficial reference manual (January 2022).](https://tug.org/texinfohtml/latex2e.html) 2022 年 12 月 11 日閲覧．
[4] 奥村晴彦・黒木裕介 (2020).［改訂第8版］LaTeX2ε美文書作成入門．