Help us understand the problem. What is going on with this article?

cleverefで賢く参照する

More than 3 years have passed since last update.

cleveref とは

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

cleverでないref

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

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.や2.は避けようがないですし、書き換える箇所もそれぞれ1箇所しかないので、大した手間はかかりません。
しかし、3.は参照している部分全ての書き換えが必要ですし、置換もやりづらいです。
cleverefを使えば、3.の手間を省くことができます。

cleverefの使い方

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

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の前後は編集せずに済みます。

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

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

cleverですね。

エディタの補完機能を活用する

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

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

\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で指定した方が良いと思います。
(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マニュアルを参照して下さい。


  1. labelの名前がtheoremのままですが、出力には関係ないですし、エディタの置換機能を使えば容易に書き換えられます。 

  2. 例えばarXivへの投稿など 

wktkshn
数学専攻の院生
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away