相互参照(ref / cref / varioref)

「図 3 を見よ」「式 (2) より」「2 ページ参照」——番号やページを手で書くと、図表や節を一つ動かしただけで全部ずれます。LaTeX は 名札を付けて、番号は機械に数えさせる 仕組みを持っています。核となる \label\ref\pageref から、amsmath の \eqref、hyperref の \autoref\nameref、そして varioref・cleveref まで、参照を自動で正しく保つ道具を順に見ていきます。

核となる仕組み — \label と \ref

相互参照の土台はたった二つの命令です。**\label{key} は、その地点で 最後に増えたカウンタ** の値に key という名札を結び付けます。**\ref{key} は、その名札の指す 番号** を本文に差し込みます。番号そのものは LaTeX が数えるので、あなたは番号を一切書きません。key は自由に付けられる文字列で、これがソースの中で図・式・節を指す「あだ名」になります。

肝心なのは「最後に増えたカウンタ」という点です。\label置く位置 で何を指すかが決まります。図・表なら **\caption の直後**(\caption がカウンタを進めるため。\begin{figure} の直後に置くと章番号などを拾ってしまいます)、数式なら **equation 環境の中、見出しなら \section(など)の直後**。番号を生み出す命令のすぐ後ろに置く、と覚えてください。

latex
\section{はじめに}
\label{sec:intro}

\begin{equation}
  \label{eq:euler}
  e^{i\pi} + 1 = 0
\end{equation}

\begin{figure}
  \centering
  \includegraphics{leaf}
  \caption{葉脈の構造}
  \label{fig:leaf}
\end{figure}\ref{sec:intro}節で述べたように、式~\ref{eq:euler}と図~\ref{fig:leaf}を参照する。

\ref は番号だけを返すので、「図」「式」「第…節」といった 語は自分で書きます。番号の直前は、改行で語と番号が泣き別れにならないよう、半角空白ではなく **連結スペース ~**(タイ)でつなぐのが定石です(例: 図~\ref{fig:leaf}Figure~\ref{fig:leaf})。この「語を手で書く」手間と取り違えの危険をなくすのが、後述の \autoref\cref です。

なぜ 2 回コンパイルするのか

相互参照は 1 回のコンパイルでは確定しません。LaTeX は \label に出会うたび、その番号とページを **.aux ファイル**(本文と同じ名前の補助ファイル)に書き出します。\ref が使えるのは、前回の実行で .aux に書き込まれた情報です。つまり最初の処理では参照先の番号がまだ分からず、出力には **太字の ??** が現れ、ログに次の警告が出ます。

latex
LaTeX Warning: Label(s) may have changed. Rerun to get cross references right.

もう一度コンパイルすれば、.aux の値が読み込まれて ?? が正しい番号に変わります。番号が前後にずれて参照値が変わると、再びこの警告が出るので、警告が消えるまで 繰り返します(実務では 2 回で足ります)。latexmk などのビルドツールはこの繰り返しを自動でこなします。Overleaf では裏で複数回処理されるため、この ?? を目にすることはほとんどありません。

ページ参照と名前の付け方

番号ではなく ページ を指したいときは **\pageref{key}** を使います。\ref と同じ名札を取り、その \label置かれたページの番号 を返します。「詳しくは…ページの図…を見よ」のように、番号とページを併記できます(例: 図~\ref{fig:leaf}(\pageref{fig:leaf}ページ))。

key は何でもよいのですが、種類を表す接頭辞 を付けるのが広く使われる作法です。sec:(節)、fig:(図)、tab:(表)、eq:(式)、ch:(章)、lst:(コード)など。利点は二つ。fig:leaf のように 意味で名付ければ、図の順番を入れ替えても名札を付け直す必要がありません。また \ref{fig:...} を見ただけで参照先の種類が分かり、\caption 用とリスト用で名前が衝突するのも防げます。

接頭辞対象
ch:章(chapter)
sec:節・小節(section)
fig:図(figure)
tab:表(table)
eq:数式(equation)
lst:コードリスト(listing)

数式の参照 — \eqref(amsmath)

数式の番号は慣習として 括弧付き で書きます(「式 (3) より」)。素の \ref3 としか返さないので括弧を手で足すことになりますが、amsmath を読み込むと使える **\eqref{key}括弧を補って** (3) を返します。しかも括弧は まわりの書体によらず常に立体(直立体) で組まれるため、斜体の文中でも括弧だけが傾く心配がありません。数式の参照には \ref より \eqref が便利です。

latex
\usepackage{amsmath}
% ...
式~\eqref{eq:euler}はオイラーの等式である。
% 出力: 式 (1) はオイラーの等式である。

hyperref の拡張 — \autoref と \nameref

hyperref を読み込むと、参照がそのまま PDF 内のハイパーリンクになり、さらに二つの便利な参照命令が加わります。\autoref{key} は、参照先の種類に応じて 「図」「節」などの語を自動で前置** し(節なら「section 3.4」、図なら「Figure 3」)、全体をリンクにします。図~\ref{...} の「図」を手で書く手間と取り違えがなくなるわけです。前置きの語は \figureautorefname\sectionautorefname などを再定義して変えられます(日本語化もこれで行います)。

もう一つの **\nameref{key} は、番号ではなく参照先の 見出しの文字列そのもの** を差し込みます。たとえば \section{はじめに} に付けた名札を \nameref で引くと「はじめに」という タイトル文 が出ます。「『はじめに』で述べたように」のように、番号ではなく題名で参照したいときに使います。

latex
\usepackage{hyperref}
% ...
\autoref{fig:leaf}を参照。   % 出力: Figure 3 を参照。(リンク付き)
\nameref{sec:intro}で述べた。 % 出力: はじめに で述べた。

ページを意識した参照 — varioref

製本した文書では「○ページの図」と機械的に書くより、近ければ「次のページの図」、同じ見開きなら「左ページの図」と書けた方が自然です。**varioref\vref{key}** は \ref のように番号を出しつつ、参照先が 別ページにあるかどうかを見て、「on the next page」「on the facing page」「on page 5」といった ページ案内の語句を自動で付け足します。同じページなら何も足しません。

ページだけを案内したいときは **\vpageref{key}** を使います(番号は出さず「次のページに」などだけ)。\vpageref には二つのオプション引数があり、第 1 引数で 同じページに来たときの語句、第 2 引数で 別ページのときの前置き語句 を指定できます。参照と対象が近く、改ページで分かれるか微妙な場合に便利です。番号がページ位置で動的に変わる性質上、varioref は通常 追加のコンパイル を要することがあります。

latex
\usepackage{varioref}
% ...
See~\vref{fig:leaf}.
% 同ページ: See figure 3.
% 別ページ: See figure 3 on the next page.  /  ... on page 12.

賢い参照 — cleveref(\cref / \Cref)

cleveref は参照を一段引き上げます。\cref{key}** は \autoref と同じく種類の語を自動で前置しますが(既定では「fig. 1」、noabbrev オプションで「figure 1」)、真価は 複数・範囲の参照 にあります。\cref{a,b,c} のようにカンマ区切り(空白なし)で渡すと、番号を 自動で並べ替え・連結 し、「figures 1, 2 and 3」「equations~(2) and~(4)」のように 語の単複まで整えて 出力します。連続する範囲は **\crefrange{first}{last}** で「figures 1 to 3」のように縮約されます。

文頭では語を大文字で始めたいので、**\Cref{key}**(先頭大文字)を使います。「Figure 3 shows …」のように文を始めるとき用です(文中は小文字の \cref)。文書全体で常に大文字にしたいなら capitalise オプションで読み込みます。前置きの語は **\crefname{type}{単数}{複数}**(先頭大文字版は \Crefname)で定義・変更でき、これで 日本語などへの localize も行います(例: \crefname{figure}{図}{図})。番号だけを素の \ref のように出したいときは **\labelcref{key}** を使います。

読み込み順序が決定的に重要 です。cleveref必ず最後hyperref に読み込みます。varioref も併用するなら、variorefhyperrefcleveref の順にします。順序を誤ると、警告も出ないまま 参照が全く別の対象を指す ことがあります。

latex
\usepackage{varioref}
\usepackage{hyperref}
\usepackage{cleveref}   % 必ず最後に / always last
% ...
\cref{fig:a,fig:b,fig:c}   % figures 1 to 3
\cref{eq:euler,eq:max}     % equations (1) and (4)
\Cref{sec:intro} discusses % Section 1 discusses ...

どれを使うか迷ったら、**文書全体で cleveref に統一する** のがおすすめです。種類の語・単複・複数参照・範囲をすべて自動で面倒見てくれるので、図~\ref{...} 方式の書き間違い(「図」と書くべきところを「表」と書く等)が起きません。

命令何を出すか
\label{key}直前のカウンタに名札を付ける(出力なし)
\ref{key}番号だけ(例: 3)
\pageref{key}その名札のあるページ番号
\eqref{key}括弧付きの式番号(例: (3))/amsmath
\autoref{key}種類の語+番号+リンク(例: Figure 3)/hyperref
\nameref{key}見出しのタイトル文字列/hyperref
\vref{key}番号+ページ案内(次のページ等)/varioref
\cref{key}種類の語+番号、複数・範囲も自動/cleveref
\Cref{key}\cref の先頭大文字版(文頭用)/cleveref
\crefrange{a}{b}連続範囲の参照(例: figures 1 to 3)/cleveref