cleverefで賢く参照する

# cleveref とは
cleverefは賢く参照してくれるパッケージで、LaTeX文章での参照を楽にしてくれます。
機能は色々とありますが、一つ挙げるとすれば、`Theorem \ref{theorem:hoge}`を`\cref{theorem:hoge}`と書けることです。
(arXivで発生する問題の解決方法は[次回](http://qiita.com/wktkshn/items/f38a759fd6b9e0a81de7)書きます)

# cleverでないref
まずはcleverefを使わずに参照する例を挙げて、その問題点を述べます。
皆さんご存知の通り、LaTeXでは`\label{theorem:hoge}`と`\ref{theorem:hoge}`のペアによって定理や定義、命題、セクションなどを参照しますね。

```latex:notclever.tex
\documentclass{article}
\newtheorem{theorem}{Theorem}[section]
\begin{document}

\section{hoge}
 \begin{theorem}
  \label{theorem:hoge}
  This is a theorem.
 \end{theorem}

 By Theorem \ref{theorem:hoge}, we have ...

\end{document}
```

さて、ここでこのTheoremをPropositionに替えたくなったとしましょう。
こういうのはLaTeXで論文を書いているときによくあることですね。
このときにやるべきことは

1. プレアンブルでproposition環境を定義(propositionが初出のときのみ)
2. `\begin{theorem}`を`\begin{proposition}`に書き換える(endの方も)
3. `Theorem \ref{theorem:hoge}`を`Proposition \ref{theorem:hoge}`に書き換える

の3つです[^1]。
[^1]: labelの名前がtheoremのままですが、出力には関係ないですし、エディタの置換機能を使えば容易に書き換えられます。
1.や2.は避けようがないですし、書き換える箇所もそれぞれ1箇所しかないので、大した手間はかかりません。
しかし、3.は参照している部分全ての書き換えが必要ですし、置換もやりづらいです。
cleverefを使えば、3.の手間を省くことができます。

# cleverefの使い方
次のようなコードで、上のものと同じ出力が得られます。

```latex:clever.tex
\documentclass{article}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}[section]
\crefname{theorem}{Theorem}{Theorems}
\begin{document}

\section{hoge}
 \begin{theorem}
  \label{theorem:hoge}
  This is a theorem.
 \end{theorem}

 By \cref{theorem:hoge}, we have ...

\end{document}
```

この形であれば、TheoremをPropositionに換えるときに\crefの前後は編集せずに済みます。

さらに、複数の定理を一斉に参照することもできます。

```latex:moreclever.tex
\documentclass{article}
\usepackage{cleveref}
\newtheorem{theorem}{Theorem}[section]
\crefname{theorem}{Theorem}{Theorems}
\begin{document}

\section{hoge}
 \begin{theorem}
  \label{theorem:hoge}
  This is a theorem.
 \end{theorem}

 \begin{theorem}
  \label{theorem:fuga}
  This is also a theorem.
 \end{theorem}
 
 By \cref{theorem:hoge,theorem:fuga}, we have ...
 
\end{document}
```

これの出力結果は下の画像のようになります。

![cleveref_multi.png](https://qiita-image-store.s3.amazonaws.com/0/154104/c3bfdd36-bd75-16d4-4d2b-910a1d96f2a2.png)

cleverですね。

# エディタの補完機能を活用する
エディタによっては、`\ref`の引数を補完してくれるものがあります。
具体的には、`\ref{theorem:`までタイプすると`theorem:`から始まるlabelの一覧が表示されたりします。

ところが、これを`\cref`にすると補完機能が働かなくなってしまう場合があります。
もちろん、エディタの設定を編集して`\cref`でも補完するように設定するのが一番良いのですが、そのためにはそれなりに知識と労力が必要となります。
その代わりの妥協案ですが、プレアンブルに次を記述することで解決できます。

```latex
\let\normalref\ref
\renewcommand{\ref}{\cref}
```

これにより、`\ref`をあたかも`\cref`かのように使うことができます。
つまり、`\ref{theorem:hoge}`と書いただけで`Theorem 1.1`のように表示されるようになります。
しかも、ソースコードとしては普通の`\ref`を書いているだけな(ように見える)ので、エディタは普通の`\ref`だと思ってちゃんと補完してくれます。

なお、TeXのコマンド展開の仕様により、上の`\let`は`\newcommand`では代用できないことを注意しておきます。


# cleverefを使う際の注意点
使う際の注意点についてコメント
### プレアンブルに書く順番について
`\usepackage{cleveref}`は`\newtheorem`よりも前に書かれている必要があります。
また、hyperrefパッケージを同時に用いる場合は、cleverefよりも先にhyperrefを`\usepackage`する必要があります。

### `\crefname`による設定について
上記のソースコード中にあった`\crefname{theorem}{Theorem}{Theorems}`では、`\cref`で参照した際に表示される名前を`\crefname{環境名}{単数形}{複数形}`の形で設定しています。
実は、以下のいずれかの条件を満たす場合にはこの設定を省略することができます。

1. 単数形のみを用いる場合(この場合は`\newtheorem`の横の記述が流用されます)
2. 下記の環境名を用いる場合

> equation figure table page part chapter section appendix enumi footnote theorem lemma corollary proposition definition result example remark note algorithm listing line

しかし、省略したことにより問題が発生する場合[^2]もあるので、基本的には明示的に`\crefname`で指定した方が良いと思います。
[^2]: 例えば[arXivへの投稿](http://qiita.com/wktkshn/items/f38a759fd6b9e0a81de7)など

(12/11 25時ごろ追記)`\crefname`を省略する場合には、下記の`capitalize`オプションを指定してください。

# `\cref`と`\Cref`、および小文字と大文字について
(12/11 25時ごろ追記)
この記事の投稿時には`\cref`と`\Cref`はそれぞれ小文字用と大文字用だと思っていたのですが、そうではなく文中用と文頭用だということをtwitterで指摘されました。
マニュアルをちゃんと読むと確かにそう書いてありますね(Section 2, 7.1を参照)。
というわけで修正しておきました。
なお、上記のコードでは全て明示的に`\crefname`で表示名を大文字で定義しているので、ただ単に`\cref`と入力しただけで大文字で表示されています。
また、`\crefname`で定義せず、cleverefのデフォルト設定や`\newcommand`の表示名を利用する場合には、`\usepackage[capitalize]{cleveref}`とオプション指定することで`\cref`の表示が大文字になります。


# まとめ
というわけで、非常に便利なパッケージcleverefを皆さん使いましょう。
上記では説明しきれなかった詳細については、[cleverefマニュアル](http://tug.ctan.org/macros/latex/contrib/cleveref/cleveref.pdf)を参照して下さい。