LaTeXの相互参照を賢くする (cleveref) 


# TL;DR

- `cleveref`は便利だから皆に使ってほしい
- だけど日本語環境下で使うためには色々設定しないといけないため，調べるコストがまあまあ高い

- なので`cleveref`をどう設定すれば自分好みの参照形式に出来るかまとめた

# はじめに

[cleveref](https://ctan.org/pkg/cleveref) はlatexにおいて数式や図表，さらには章の相互参照をうまく管理して処理してくれるパッケージです．

その使い方については以下の記事で詳しく解説されています．（これらの記事は`cleveref`についてのみならず，LaTeXで文書を書く上で非常に参考になると思います）

[cleverefで賢く参照する](https://qiita.com/wktkshn/items/110cd6007837938e6c88)

[amsmathの数式環境まとめ](https://qiita.com/t_kemmochi/items/a4c390b4967b13f3afb7#showonlyrefstrue%E3%81%A8cleverefsty%E3%81%A8%E3%81%AE%E5%85%B1%E5%AD%98)

[イショティハドゥスにキレられないための LaTeX 論文執筆メソッド](https://qiita.com/Ishotihadus/items/bbbb85f54e6a4e7aaac0#cleveref-%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8)

私もこれらの記事を参考に`cleveref`を使い始めたのですが，日本語環境（uplatex + dvipdfmx）下で使う際の設定や，参照時のラベルの設定方法で躓いた部分があったため，その知見を共有できればと思ってこの記事を書きました．

### 動作確認環境

本記事の動作確認はwindows10とtexlive 2019で行っております．

# `cleveref`の利点

上記の記事と内容が一部重複しますが，まず`cleveref`を使う利点を紹介します．

### 環境名ごと参照してくれる

定理を参照する際，通常の`\ref`を用いると本文に環境名（Theorem）を書く必要があります．（以下Theorem環境の定義等は省略）

```latex
 \begin{theorem}
 	\label{thm:sample1}
  	Great theorem.
 \end{theorem}
 Theorem \ref{thm:sample1} ...
```

`cleveref`を導入すると`\cref`を用いて

```latex
 \begin{theorem}
 	\label{thm:sample1}
  	Great theorem.
 \end{theorem}
 \cref{thm:sample1} ...
```

と環境名を省略出来るようになります．`\newcommand{\rthe}[1]{Theorem \ref{#1}}`などとすることで同様のことは可能ですが，コマンドを使い分けなくて良いのでこちらの方がエレガントに感じます（個人的意見）．

また，「定理じゃなくて補題にしたいな...」という際も，変更する部分が大幅に減るというメリットがあります．ラベル名も変更する場合はその優位性が少し減りますが．

### 複数の参照をソートしてくれる

`cleveref`は複数のラベルを参照する際に効果を発揮します．

通常の`\ref`を用いて複数の式の相互参照を行う場合，つぎのように記述する必要があります．

```latex
\begin{align}
    x + y = z \label{eq:superEq} \\
    a + b = c \label{eq:hyperEq} \\
    1 + 1 = 2 \label{eq:greatEq} \\
    p + q = r \label{eq:goodEq}
\end{align}

Eq. (\ref{eq:superEq}) is ...

Eqs. (\ref{eq:superEq}) and (\ref{eq:hyperEq}) are ...

Eqs. (\ref{eq:superEq})--(\ref{eq:goodEq}) are ...

Eqs. (\ref{eq:superEq}), (\ref{eq:hyperEq}) and (\ref{eq:goodEq}) are ...
```

この出力はつぎの画像の通りになります．

![出力結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607211/def50dc4-f7e3-4a4e-af73-94d4b25c6ffb.png)


`cleveref`を導入すると同じ出力を出したい場合でも`\cref`を用いて

```latex
...

\cref{eq:superEq} is...

\cref{eq:goodEq,eq:hyperEq} are ...

\cref{eq:superEq,eq:greatEq,eq:goodEq,eq:hyperEq} are ...

\cref{eq:superEq,eq:goodEq,eq:greatEq} are ...
```

と書けるようになります．参照するラベルの個数や順番に合わせてソートを行い，`and`や`--`を入れてくれていることが分かります．

こうした処理は`\newcommand{\req}[1]{Eq (\ref{#1})}`などでは難しいため，`cleveref`を使うモチベになるのではないでしょうか．

### `\ref`と競合しない

元々の`\ref`を上書くといったことはしないため，古いスタイルファイルなどとも共存が可能です．



# `cleveref`の日本語環境下での使い方

ごちゃごちゃ書いてきましたが，ようやく使い方の説明に入ります．

まず私が日本語の文書を書く際の普段の使い方を以下に示します．

```latex:main.tex
\documentclass[uplatex,a4paper]{jsarticle}
\usepackage[dvipdfmx]{graphicx}

% #################### Package for math ###########################
% # amsmath : for complex math eqs. e.g. align, gather, etc...    # 
% # amsssymb: math font for AMS(American Mathematical Society)    #
% # amsthm  : theorem environment for AMS                         #
% # mathtool: dcase etc...                                        #
% # hyperref: hyperref                                            #
% # cleveref: ref not only number but also "theorem","lemma"      #
% # autonum : automatically put number only refered eq            #
% # loading order of package is important                         #
% #################################################################
\usepackage{amsmath,amssymb,amsthm}% 数式関連のパッケージ
\usepackage{mathtools}
\usepackage[dvipdfmx,hypertexnames=false,setpagesize=false]{hyperref}
\usepackage{pxjahyper}
\usepackage{cleveref}
\usepackage{autonum}

\crefname{equation}{式}{式}% {環境名}{単数形}{複数形} \crefで引くときの表示
\crefname{figure}{図}{図}% {環境名}{単数形}{複数形} \crefで引くときの表示
\crefname{table}{表}{表}% {環境名}{単数形}{複数形} \crefで引くときの表示
\crefname{algorithm}{Algorithm}{Algorithm}

\crefname{section}{第}{第}
\creflabelformat{section}{#2#1節#3}
\crefname{subsection}{第}{第}
\creflabelformat{subsection}{#2#1小節#3}

\theoremstyle{definition}% 日本語用．定理とか斜体にならないようにする
\newtheorem{theorem}{定理}
\crefname{theorem}{定理}{定理}
\newtheorem{lemma}{補題}
\crefname{lemma}{補題}{補題}
\newtheorem{corollary}{系}
\crefname{corollary}{系}{系}
\newtheorem*{proof*}{証明}
\crefname{proof*}{証明}{証明}
\newtheorem{assumption}{仮定}
\crefname{assumption}{仮定}{仮定}
\newtheorem{definition}{定義}
\crefname{definition}{定義}{定義}
\newtheorem{remark}{注意}
\crefname{remark}{注意}{注意}
\newtheorem{proposition}{命題}
\crefname{proposition}{命題}{命題}


\newcommand{\crefpairconjunction}{と}
\newcommand{\crefrangeconjunction}{から}
\newcommand{\crefmiddleconjunction}{，}
\newcommand{\creflastconjunction}{，および}

\begin{document}
\section{数式}\label{sec:eq}
 \begin{align}
     x + y = z \label{eq:superEq} \\
     a + b = c \label{eq:hyperEq} \\
     i + j = k \\% この数式は参照されないので番号が振られない
     1 + 1 = 2 \label{eq:greatEq} \\
     p + q = r \label{eq:goodEq}
 \end{align}

 \cref{eq:superEq}は...

 \cref{eq:goodEq,eq:hyperEq}は...

 \cref{eq:superEq,eq:greatEq,eq:goodEq,eq:hyperEq}は...

 \cref{eq:superEq,eq:goodEq,eq:greatEq}は...


\section{定理}\label{sec:thm}
 \begin{theorem}
    \label{thm:sample1}
    すごい定理
 \end{theorem}
\cref{thm:sample1}は...


\section{節}\label{sec:sec}
 \cref{sec:eq,sec:thm}では...
 
\end{document}

```

出力結果はこんな感じです．

![出力結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607211/cf8e47d1-43a7-0a16-4eaf-75c78ed57772.png)


ポイントを順番に解説します．

### パッケージの読み込む順番

`cleveref`は`hyperref`や`mathtool`と使う際に，読み込む順番に注意しなければなりません．

上の例のように，

`amsmath`

`mathtools`

`hyperref`

`pxjahyper`

`cleveref`

`autonum`

の順番で読み込むことで，正しく表示されます．

最後の`autonum`によって，参照されない数式に番号が付与されなくなります．

### 表示名の日本語化

参照時の環境名の表示は`\crefname{}{}{}`で変更が可能です．

例えば「式 (1)」などと表示したい場合は

`\crefname{equation}{式}{式}`

としてやればOKです．

#####　使い方

1つめの引数には環境名（equationやfigureなど）を入れます．

2・3つめの引数は本文に表示する際の単数形・複数形を入れます．英文の場合はfig. figs.と使い分けたりしますが日本語の場合は同じで良いでしょう．表示を省きたい場合は空にしておきます．

余談ですが，ここで`{eq. }{eqs. }`とした場合でも`\Cref{}`で参照することで頭文字が大文字に（Eq./Eqs.）なります．`\Cref`で参照する際の表示も同様に`\Crefname`で変更可能です．

### ラベル書式の変更

`\crefname`では，参照番号の前の部分しかいじれないため，section参照時に「n節」といった表現が実現できません．この場合は`\creflabelformat`を使用します．

例えば「n節」と表示したい場合は

`\creflabelformat{section}{#2#1節#3}`

とします．`#1`のところに番号が入り，`#2`と`#3`で囲った部分がhyperrefによってリンクとなります．

上の例では`\crefname`と組み合わせて「第 n節とm節」といった表示を可能にしています．

似たコマンドに`\crefformat`がありますが，こいつで変更した場合は，複数参照した際に変なことになるため`\creflabelformat`を使用しています．

### 接続詞の日本語化

複数ラベルを参照した際の接続詞を日本語化します．

#### 2つのラベルの場合

`\newcommand{\crefpairconjunction}{}`で変更します．

「式 (1)と(2)」と表示したい場合は

`\newcommand{\crefpairconjunction}{と}`

とすればOKです．

#### 3つ以上の連続するラベルの場合

`\newcommand{\crefrangeconjunction}{}`で変更します．

「式 (1)から(4)」と表示したい場合は

`\newcommand{\crefrangeconjunction}{から}`

とすればOKです．

「Eqs. from (1) to (3) ,」と表示したい場合のように，番号の前と後にも何かを入れたいときは

`\newcommand{\crefrangepreconjunction}{from}`と`\newcommand{\crefrangepostconjunction}{,}`を追加することで実現可能です．

#### 3つ以上の不連続なラベルの場合

`\newcommand{\crefmiddleconjunction}{}`と`\newcommand{\creflastconjunction}{}`で変更します．途中の区切りが前者，最後の区切りが後者によって設定できます．

「式 (1)，(2)，および(4)」としたい場合は

`\newcommand{\crefmiddleconjunction}{，}` 

`\newcommand{\creflastconjunction}{，および}`

とすればOKです．

英文を書く場合でも，デフォルトではオックスフォードカンマが挿入されないため，気になる方はこいつらを設定しなおす必要があると思います．



# おわりに

非常に便利なパッケージだと思うのでみんな使って圧倒的進捗を出しましょう．

こんな使い方もあるよ！とかあったら教えて頂けるとうれしいです！

# 参考

[Package cleveref - CTAN](https://ctan.org/pkg/cleveref)

[cleverefで賢く参照する](https://qiita.com/wktkshn/items/110cd6007837938e6c88)

[amsmathの数式環境まとめ](https://qiita.com/t_kemmochi/items/a4c390b4967b13f3afb7#showonlyrefstrue%E3%81%A8cleverefsty%E3%81%A8%E3%81%AE%E5%85%B1%E5%AD%98)

[イショティハドゥスにキレられないための LaTeX 論文執筆メソッド](https://qiita.com/Ishotihadus/items/bbbb85f54e6a4e7aaac0#cleveref-%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8)