LaTeXの定理環境に囲みを付けたい

# はじめに
こんにちは，計数工学科に内定した学部２年生の実数（[@rityo_math](https://twitter.com/rityo_math)）です．
これは[物工/計数Advent Calendar 2019](https://adventar.org/calendars/4128)の20日目の記事です．

さて，この記事では， LaTeX の定理環境（`\begin{theorem}`〜`\end{theorem}`）に囲みを付けるための方法について解説していきます．こういった囲みの存在自体は LaTeX 文書の見栄えを良くするために有用だと思います．
実際，最近の理学書では命題や定理，補題等に囲みを付けているものが増えてきているように感じます．また，個人的には（最初に「ちょっと」苦労するだけで後は）簡単に見栄えがよくなるので結構気に入っています．

免責事項ですが， LaTeX のインストール方法[^fabon]や基本的な文法などについては[TeX Wiki](https://texwiki.texjp.org/)などを参考にしてください．また，基本的には pLaTeX でコンパイルすることを前提として話をします． upLaTeX や LuaLaTeX の場合でも基本的には変わりません

# 準備 
まず LaTeX の標準的な機能だけでは自由に囲みを描画・調節することは難しいため，何らかのパッケージを読み込む必要があります．いくつか選択肢はあるのですが，この記事ではページをまたぐことが可能だったり，オプションが多いなどの長所を持つ tcolorbox パッケージを取り上げます[^1]．tcolorbox パッケージは LaTeX を TeXLive でインストールした場合は既に入っているハズです．すぐ下のコードを実行してパッケージが見つからないというコンパイルエラー[^notfound]が出る場合は [TeX Wiki](https://texwiki.texjp.org/?LaTeX%E5%85%A5%E9%96%80%2F%E5%90%84%E7%A8%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E5%88%A9%E7%94%A8#b1d7dcd3) などを参考にして追加しましょう．

## 読み込み方
tcolorbox パッケージ自体はプリアンブル（`\begin{document}`の前）に `\usepackage{tcolorbox}` を書くだけで読み込まれます[^tikznado]が，この記事ではそれに加えて tcolorbox パッケージに付属するライブラリをいくつか読み込むことをオススメします．具体的には下のようにして breakable ライブラリ, skins ライブラリ, theorems ライブラリを読み込みましょう．

```latex:example1.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tcolorbox}
\tcbuselibrary{breakable, skins, theorems}
\begin{document} 
```

## tcolorboxの使い方
では本題に入る前に実際に tcolorbox を使っていくつか囲みを作ってみましょう．一番シンプルな tcolorbox は下のようにして作ることが出来ます． 

```latex:example2.tex
\begin{document}
\begin{tcolorbox}
    これが\textbf{tcolorbox}です．
\end{tcolorbox}
\end{document}
```
![Screenshot from 2019-12-21 15-44-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498769/9109dee3-9930-cdbb-5787-2b099266e920.png)

確かに文章を括弧で囲むことはできましたが，これだけではなにが嬉しいのかあまり良く分からないと思います．そこで，これにオプションをさらに追加していきます．

```latex:example3.tex
\begin{document}
\begin{tcolorbox}[
    colframe = red, 
    colback = yellow!20, 
    title = これは例だよ．, 
    fonttitle = \bfseries,
    sharp corners = downhill,
    breakable = true]
    この記事は物工/計数 Advent Calendar 20日目の記事です．
\end{tcolorbox}
\end{document}
```
![Screenshot from 2019-12-22 00-20-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498769/970ef51e-cd61-ee6a-3da0-44c72e461069.png)


角括弧`[]`でくくられているのがオプションで，これによって tcolorbox の見栄えを色々と変えることが出来ます．ここからはこのオプションの中身を解説していきます．

- `colframe`：枠線の色を指定．redやwhiteやblueなどが使える．
- `colback`：tcolorbox の背景の色を指定．
    - 色Xに対して`X!30`で X 30%に対して白(white)を残りの70%混ぜることを指す．
    - 色X,Yに対して`X!20!Y!30`でXを20%，Yを30%，残りの50%を白で混ぜることを指す，などの使い方も出来る[^xcolor]．
    - `\definecolor`コマンドによって他形式で色を定義し，それを渡すという指定もできる．くわしくは[これ](https://www.lightstone.co.jp/latex/betteruse/color.pdf)などを参照．
- `title` ： tcolorbox のタイトルを指定． 
- `fonttitle` : タイトルのフォント設定．`\bfseries`で太字になる．わいわい．
- `sharp corners` : box の所定の角を尖らせる．ここでは`downhill`，すなわち左上と右下の角を尖らせるように設定している．
    - 他にも`all` ,`north`（右上と左上） ,`southeast`（右下のみ）などがある．
- `breakable` : この画像からは読み取れないが，これを`true`にすることでページをまたぐことが出来るようになる．
    - ちなみにマニュアルによればこの`true`で 65536pt，約 90 ページのサイズの box まで耐えるとのこと． 

さらに skins ライブラリを使ってタイトルの入る囲みを設定してみましょう．

```latex:example4.tex
\begin{document}
\begin{tcolorbox}[enhanced,
    colframe = green!35!black,
    colback = white,
    title = これはタイトル．長さが自動で調節される．,
    fonttitle = \bfseries,
    breakable = true,
    coltitle = black,
    attach boxed title to top left = {xshift=5mm, yshift=-3mm}, 
    boxed title style = {colframe = green!35!black, colback = white},
    top = 4mm]
    これは本文．
\end{tcolorbox}
\end{document}
```
![Screenshot from 2019-12-21 15-49-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498769/9cd95712-97af-fa04-f542-212c4a34b7ef.png)
まだ説明していないオプションについて説明を加えておきましょう．

- `enhanced` : TikZ[^tikz] の内部処理を導入する．ある程度複雑なものには必須．ただしコンパイル時間が長くなる元凶にもなる．
- `coltitle` : タイトルの文字の色を変更する．デフォルトでは`white`．
- `attach boxed title to top left` : タイトルを box のどこに付けるかを指定していて，`attach boxed title to bottom center`なども可能．波括弧`{}`内で位置を微調整している．（$x$軸と$y$軸の向きは常識的な向きです）
- `boxed title style` : タイトルもまた１つの box とみなし，`colframe`や`colback`等の指定が出来るようになる．
- `top` : box 全体で，文章の１行目と上の枠線の幅を指定する．タイトルを入れると間が詰まって見えてしまうため広げた．

ここで取り上げたオプションは全体のごくごく一部なので，もっと知りたいという人は tcolorbox のマニュアルを読んでみると良いでしょう[^3]．

# 本題
さて，以上で tcolorbox の機能について軽く説明しましたが，本題は定理環境に囲みを付けたい，というものでした．これは上で説明した tcolorbox のオプションを使えば簡単に出来るように思えます．例えば amsthm パッケージの newtheorem コマンドを用いて下のようにするアイデアが浮かぶでしょう． 

```latex:example5.tex
\newtheorem{theorem1}{定理}
\begin{document}
\begin{tcolorbox}[
    colback = white,
    colframe = green!35!black,
    fonttitle = \bfseries,
    breakable = true]
    \begin{theorem1}
    有限閉区間\([a,b]\)上の可積分関数の列\((f_n)_{n\in\N}\)が関数\(g\)に一様収束するならば，\[\lim_{n\to\infty}\int_a^bf_n(x)dx=\int_a^bg(x)dx.\]
    \end{theorem1}
\end{tcolorbox}
\end{document}
```
![Screenshot from 2019-12-21 16-12-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498769/d231e558-82ec-d9a3-2b42-6a4c0e25c1c0.png)

これで **一応は** この記事の主目的が達成されました．めでたしめでたし．

しかし，これでは定理を書くたびにいちいち tcolorbox のオプションをコピペしてくることが求められ，とても面倒です．
ラクをするために例えば最初に一回 tcolorbox の設定を書いて，本文では`\begin{newtheorem}〜\end{newtheorem}`などと書くだけで自動でその設定を適用してくれるようにしたいところです．
さらにこのコードには，先程とりあげた skins ライブラリによるタイトルの修飾が（少なくともそのままでは）使えないという欠点があります．

ここではさきほど読み込んだライブラリの一つ， theorems ライブラリに用意されている`\newtcbtheorem`という関数を使って工夫することにします．プリアンブルと本文に下のように書きます．

```latex:example6.tex
\newtheorem{theorem2}{定理}
\newtcbtheorem{theorem2}{My Theorem}{enhanced, %TikZの内部処理を導入する．ある程度複雑なものには必須．
    attach boxed title to top left={xshift=5mm,yshift=-3mm}, 
    boxed title style={colframe = green!35!black, colback = white},
    coltitle = black,
    colback = white,
    colframe = green!35!black,
    fonttitle = \bfseries,
    breakable = true,
    top = 4mm
}{fuga}

\begin{document}

\begin{theorem2}{三次元極座標のラプラシアン}{korehatag}
    三次元極座標において，
    \[\nabla^2=\frac{1}{r^2}\pdv{r}\left(r^2\pdv{r}\right)+\frac{1}{r^2\sin\theta}\pdv{\theta}\left(\sin\theta\pdv{\theta}\right)+\frac{1}{r^2\sin^2\theta}\pdv[2]{\varphi}.\]
        %physicsパッケージの\pdvを使って書くのをラクにしている．
\end{theorem2}
一生に一度はやっておきたい，\ref{fuga:korehatag}の導出．
```
![Screenshot from 2019-12-21 16-22-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498769/76a0d450-6aea-384d-5396-e42608a6202c.png)


コードと実行結果から各引数の意味する雰囲気を読み取っていただきたいのですが，ここでは説明しておくことにします．分かる人は読み飛ばしてください．
まず，先程の`\newtcbtheorem`というコマンドはプリアンブルで１度使用することで環境のスタイルを定義し，あとは本文に`\begin{hoge}〜\end{hoge}`を書くことでその設定を呼び出すことを可能にしてくれるコマンドになっています．`\newtcbtheorem`の１つ目の引数は環境の名前（`\begin{hoge}〜\end{hoge}`の`hoge`）になります．２つ目の引数は出力 PDF の各 tcolorbox のタイトルの冒頭につく名前になります．３つ目の引数のスタイルを指定するオプションについては上で既に説明した通りです．４つ目の引数は文章中で`\ref{fuga:piyo}`というふうに数式を参照したいときに使う文字（この例では`fuga`部分）が入ります．
各環境（上の例で言う`\begin{theorem2}〜\end{theorem2}`）における１つ目の引数はタイトルの後半部分（無くても良い，その場合も波括弧だけは入力しなければならない）が入ります．２つ目の引数は文章中で`\ref`などで参照したいときに使います．参照を使わない場合でも波括弧だけは入力しておく必要があります．

# もっと知りたい人のために

まとめの代わりとして以上で見てきたコードをすべて書いたときの出力 PDF を Overleaf に置いておきます．結構便利．
**https://ja.overleaf.com/read/cdmwdmzzbbgy**

なお， `\newtcbtheorem`を使ったコードについて，LaTeX の `ref` 機能を使うことは無いので `\begin{theorem}`の２番目の引数の波括弧`{}`をいちいち書くのも面倒だ，という方はぜひ[うぶつんさんのブログ記事](https://ubutun.blogspot.com/2016/04/mdframedtcolorbox.html)を参考にしてください．マクロのテクニックとして参考にするべきところの多いコードだと思います．自分が常用している定理環境はこのコードにかなり近いです．

また，この記事では定理のナンバリング様式（counter）については一切触れませんでした．全体を通して「定理1，定理2，定理3，……」とするやり方もあれば，１節は「定理1.n」，２節は「定理2.n」，……とするやり方もあります．tcolorbox の使用にあたっては本質的ではないと判断し省きましたが，余裕があれば加筆したいと思います．ここでは一番最後の`\newtcbtheorem`を用いた例では，`\newtcbcounter[number within = section]{その他のoptions}`とすれば後者のカウント方式に切り替わる，ということだけ説明しておきます．

（2023年2月14日追記）その後加筆できていないこの部分の仕様について，dragon_notepadさんが具体的な使用例に即して詳しく説明してくださっていました．気になった方は参考にしてください．
- https://note.com/dragon_notepad/n/ne2a1392cf8ce

## 参考文献

最後に参考文献として，この記事を書くにあたって参考にしたサイトを掲載させていただきます(一部再掲)．特に最後のうぶつんさんのブログが無ければこの記事自体が存在しなかったでしょう．これらのサイトを執筆された方々にはこの場を借りてお礼を申し上げます．

-  http://konoyonohana.blog.fc2.com/blog-entry-61.html
-  http://texmedicine.hatenadiary.jp/entry/2015/12/17/000339
-  https://ubutun.blogspot.com/2016/04/mdframedtcolorbox.html

## 更新履歴
2020/03/11：なぜか数式環境を，現在は非推奨とされている古の書き方（\\$\\$数式\\$\\$）で書いていたので修正しました． [@sig_math](https://twitter.com/sig_math) 氏の指摘に感謝します．
2020/05/04：タイポを修正，`texdoc`コマンドが使用できることの説明を追加，この更新履歴を記事の一番下に移動しました．
2020/05/21 : タイポ修正．（そのうちの１つは[ @Focus_Sash ](https://twitter.com/Focus_Sash)氏の指摘による．感謝．）
2020/10/06 : １文加筆．newtheorem コマンドは amsthm パッケージが必要です（どうせみんな使ってるとは思いますが一応）．
2020/12/27 : overleafの方を微修正．具体的には，定理名と参照名を両方省略した場合についての例を追加，クラスファイルがなぜか `article` だったので `jsarticle` に設定しなおす，の２つ．
2023/02/14 ：dragon_notepadさんの記事を偶然見つけたので，参考資料として追加した．
2023/02/25 ：謎に半角スペースが入り込んでリンクが壊れていたので修正． 2023/06/06 の修正も同様．

[^tikznado]: ちなみにこのときに自動でxcolor, tikz, graphicxといった画像処理寄りのパッケージが読み込まれています． 
[^fabon]: ちなみに LaTeX のインストール時にISOイメージを使うとうまくいきやすい，という情報を[ @syobon_hinata ](https://twitter.com/syobon_hinata)氏に教えていただきました． Windows は[これ](https://texwiki.texjp.org/?TeX%20Live%2FWindows)， Mac/Linux は[これ](https://user.ecc.u-tokyo.ac.jp/users/user-15826/wiki/?TeX/Install)を参考にすると良さそうです．
[^notfound]: `! LaTeX Error: File 'tcolorbox.sty' not found.`というエラーが出ると思います．
[^1]: 他のパッケージについては[@TeXmedicine 様の記事](http://texmedicine.hatenadiary.jp/entry/2015/12/17/000339)や，[ Yamamoto 様の記事](http://www.yamamo10.jp/yamamoto/comp/latex/make_doc/box/box.php) が参考になると思います．シンプルな囲みで良いならば使用を検討してみるとよいでしょう．
[^xcolor]: [abenori様の記事](http://abenori.blogspot.com/2015/12/xcolor.html)等，本格的には xcolor パッケージのマニュアルを参照してください．
[^tikz]: LaTeXにおける図形描画に特化したパッケージで，かなり高度な描画機能を持つ．それゆえに[マニュアル](http://ftp.jaist.ac.jp/pub/CTAN/graphics/pgf/base/doc/pgfmanual.pdf)もかなり長く，記事公開時点(2019/12/22)で1318ページあります．[TeX Wiki](https://texwiki.texjp.org/?TikZ#qa783648)によれば読み方は「てぃくす」．
[^3]: tcolorboxのマニュアルは https://www.ctan.org/pkg/tcolorbox の Package Documentation にあります．もちろん TeXLive をインストールしてある人はターミナル（or PowerShell）で`texdoc tcolorbox`を叩くと見ることが出来ます．記事公開時点(2019/12/22)で513ページあります．あと，tcolorboxは内部でTikZを読み込んで使用している(ex.色のカスタム設定)ため，TikZパッケージの知識も必要になりそう．なりました．ページ数が多いのはふんだんにサンプルを掲載しているのも大きいので，ざっと読んで気に入ったものをコピペしてくるという使い方も出来ると思います．