enumerate(番号付き)

LaTeX の文書の末尾、参考文献一覧に並ぶ [1] [2] [3] という番号を振っているのは、実は enumerate第 4 階層のカウンタ です。article.clsthebibliography は自前のカウンタを作らず、\usecounter{enumiv} と書いてリストの一番深い階層の番号を借りています。番号付きリストの仕組みは、それくらい文書全体の骨格に食い込んでいるということです。このページでは enumerate を、番号を持つカウンタ enumienumiv、それを文字にする \theenumi\label\ref で項目を指す方法、そして中断したリストの番号を続ける方法という順で見ていきます。

番号を持っているのは環境ではなくカウンタ——enumi から enumiv

enumerate は番号を自分では持ちません。latex.ltxenumienumiienumiiienumiv という四つのカウンタを普通の LaTeX カウンタとして定義しておき、環境はいま何段目かに応じてそのうち一つを選ぶだけです。仕事は三つの層に分かれています。\begin{enumerate}\usecounter を呼んでカウンタを 0 に戻し、\item が本文を組む前に \refstepcounter で 1 進め、その値を \theenumi 系の命令が文字列に変換する——この順番を覚えておくと、後で出てくる「開始番号を 5 にしたいのに 4 と書く」理由がそのまま腑に落ちます。

階層カウンタ既定の書式行頭ラベル出力
enumi1\theenumi = \arabic{enumi}\labelenumi = \theenumi.1.
enumii2\theenumii = \alph{enumii}\labelenumii = (\theenumii)(a)
enumiii3\theenumiii = \roman{enumiii}\labelenumiii = \theenumiii.i.
enumiv4\theenumiv = \Alph{enumiv}\labelenumiv = \theenumiv.A.

この表の三列目と四列目を混同すると、後で必ず困ります。\theenumi番号そのもの の書き方を決め、\labelenumi行頭に置く飾り を決めます。第 2 階層を見ると違いがはっきりします——\theenumiia としか言っておらず、括弧を付けているのは \labelenumii のほうです。番号の体裁を変えたいなら \theenumi を、丸括弧やピリオドといった前後の記号を変えたいなら \labelenumi を書き換えます。数を文字に変える命令は \arabic(1, 2, 3)、\alph(a, b, c)、\Alph(A, B, C)、\roman(i, ii, iii)、\Roman(I, II, III)の五つで、どのカウンタにも使えます。

latex
% style of the number itself
\renewcommand{\theenumi}{\Roman{enumi}}
% punctuation around it: I) II) instead of I. II.
\renewcommand{\labelenumi}{\theenumi)}

項目に \label を付けて \ref で呼ぶ——ただし返る番号は見た目と違う

\item の本文の先頭に \label{キー} を置けば、文書のどこからでも \ref{キー} でその項目の番号を呼び出せます。\item が番号を進めるのに使う \refstepcounter は、値を進めると同時に「いま参照可能な対象はこの項目だ」と記録するので、\label は直前の \item に結び付きます。手順を入れ替えても参照が自動で追従するのはこの仕組みのおかげです。値は .aux ファイル経由で受け渡されるため、新しい \label を足した回のコンパイルでは番号が確定せず、二回まわす必要がありますhyperref を読み込んでいれば、この参照はそのままクリック可能なリンクになります。項目の番号ではなくその項目が載っているページ番号がほしいときは、同じキーで \pageref{キー} を使います。

latex
\begin{enumerate}
  \item Bring the sample to room temperature
  \item \label{step:weigh} Record the weight
  \item Add solvent and stir
\end{enumerate}
Use the value from step~\ref{step:weigh} in the yield calculation.

ここで、知らないと必ず面食らう挙動があります。入れ子になった項目を \ref すると、行頭に見えている番号とは違う文字列が返ります。 第 2 階層の項目は「(a)」と組まれているのに、\ref2a を返す。第 3 階層なら「i.」と見えているのに 2(a)i が返ります。バグではなく、\p@enumii という「接頭辞」の命令が働いているためです。article.cls\p@enumii\theenumi と定義しており、参照が返す文字列は 接頭辞 + \theenum… で組み立てられます。行頭ラベルを作る \labelenumii は参照には一切関与しないので、\labelenumii が付けている丸括弧も参照側には現れません。

階層行頭に見える番号\ref が返す文字列接頭辞の定義
enumi2.2接頭辞なし
enumii(a)2a\p@enumii = \theenumi
enumiiii.2(a)i\p@enumiii = \theenumi(\theenumii)
enumivA.2(a)iA\p@enumiv = \p@enumiii\theenumiii

この設計自体は理にかなっています。第 2 階層の項目を「a」とだけ書いて参照しても、読者はどの親項目の a なのか分かりません。とはいえ「2a」という表記が文書の流儀に合わないことはよくあります。親を付けずに a だけを返させたいなら \renewcommand{\p@enumii}{} と空に、「2.1」のように区切りたいなら \renewcommand{\p@enumii}{\theenumi.} と定義し直します。ここで \theenumii のほうをいじってはいけません——そちらを変えると行頭のラベルまで「2.1」になってしまい、リストの見た目が壊れます。参照だけを直したいときに触るのは \p@enum… です。

中断したリストの番号を続ける——なぜ 5 から始めるのに 4 と書くのか

手順の途中に説明の段落や図が挟まってリストを一度閉じると、次の enumerate は当然のように 1 から振り直します。\begin{enumerate} が呼ぶ \usecounter が、環境に入るたびにカウンタを 0 に戻すからです。番号を続けたいときは、リストを開いた 直後に \setcounter で値を入れ直します。ここで先ほどの三層の順番が効いてきます——\item は本文を組む前にカウンタを 1 進めるので、5 から始めたいなら 4 を設定する。「1 引く」のはおまじないではなく、\refstepcounter が先に走るという事実の裏返しです。

latex
\newcounter{savedstep}

\begin{enumerate}
  \item first
  \item second
\end{enumerate}
\setcounter{savedstep}{\value{enumi}}

An interrupting paragraph.

\begin{enumerate}
  \setcounter{enumi}{\value{savedstep}}
  \item this one is numbered 3
\end{enumerate}

この書き方が確実なのは、enumi\end{enumerate} の後も最後の値を保っているからです。閉じた直後に自前のカウンタへ退避しておけば、あいだにいくつ段落や図が入っても番号を引き継げます。第 2 階層以下を続けたいなら enumiienumiiienumiv を同じ要領で扱います。もっとも、この定型を毎回書くくらいなら enumitem を読み込むほうが早い——\begin{enumerate}[resume] は前のリストの続きから、\begin{enumerate}[start=7] は 7 から始めます(start= は「引きたい 1」が要りません)。長い手順書を書くなら最初から enumitem を入れておく価値があります。

番号を振るべきとき、振ってはいけないとき

enumerate を選ぶ理由は「番号があると整って見えるから」ではありません。番号は読者との契約で、順序・優先度・参照先 のいずれかが意味を持つと宣言する記号です。順序に意味のない項目に番号を振れば、読者は勝手に時系列や重要度を読み取り、書き手が意図しない主張が生まれます。逆に、本当に順序が意味を持つ手順書では、番号は読者が「手順 3 に戻る」と言えるようにするための道具になります。そしてその参照は、本文に「3」と打ち込むのではなく \label\ref に任せてください。手打ちの番号は、項目を一つ挿入した瞬間にすべて嘘になります。

  • 手順・時系列・優先順位 には enumerate。読者が「3 番に戻る」と言えることが、番号を付ける唯一の理由です。
  • 順序のない条件や特徴 には itemize。番号を振ると、意図しない優劣や時系列を主張してしまいます。
  • 参照する項目には必ず \label 本文に番号を直打ちすると、項目を一つ足しただけで全部ずれます。
  • 入れ子の参照は \ref の返り値を確かめる。 「(a)」と見えていても \ref2a を返します。
  • 中断する手順は番号を継ぐ。 素の LaTeX なら \setcounterenumitem なら resume を使います。