enumerate

LaTeX 문서 끝의 참고문헌 목록에 늘어선 [1] [2] [3]이라는 번호를 매기는 것은 사실 enumerate4단계 카운터입니다. article.clsthebibliography는 자기 카운터를 만들지 않고 \usecounter{enumiv}이라고 적어 번호 목록의 가장 깊은 단계를 빌려 씁니다. 목록 장치가 문서의 뼈대에까지 그만큼 깊이 파고들어 있다는 뜻입니다. 이 페이지에서는 enumerate을 순서대로 살펴봅니다. 번호를 담는 카운터 enumi부터 enumiv, 그것을 글자로 바꾸는 \theenumi 계열, \label\ref으로 항목 하나를 가리키는 방법, 그리고 끊긴 목록의 번호를 이어 가는 방법입니다.

번호를 쥐고 있는 것은 환경이 아니라 카운터: enumi부터 enumiv까지

enumerate은 번호를 스스로 쥐고 있지 않습니다. latex.ltxenumi, enumii, enumiii, enumiv라는 네 개의 카운터를 평범한 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은 참조에 전혀 관여하지 않고, 그래서 그것이 붙인 둥근 괄호도 참조 쪽에는 나타나지 않습니다.

단계행 머리에 보이는 번호\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} 뒤에도 마지막 값을 그대로 지니고 있기 때문입니다. 닫은 직후에 자기 카운터로 옮겨 두면 사이에 단락이나 그림이 몇 개 들어와도 번호를 이어받을 수 있습니다. 더 깊은 단계를 잇고 싶다면 enumii, enumiii, enumiv를 같은 요령으로 다룹니다. 다만 이 상용구를 매번 쓰느니 enumitem을 불러오는 편이 빠릅니다. \begin{enumerate}[resume]은 앞 목록이 멈춘 곳부터 이어지고, \begin{enumerate}[start=7]은 7부터 시작합니다(start=에는 “빼는 1”이 필요 없습니다). 긴 절차서를 쓴다면 처음부터 enumitem을 넣어 둘 만합니다.

번호를 매겨야 할 때와 매기면 안 될 때

enumerate을 고르는 이유는 “번호가 있으면 정돈되어 보여서”가 아닙니다. 번호는 독자와 맺는 계약이며, 순서・우선순위・참조 대상 가운데 어느 하나가 여기서 실제로 의미를 갖는다고 선언하는 기호입니다. 순서가 없는 항목에 번호를 매기면 독자는 제멋대로 시간 순서나 중요도를 읽어 내고, 글쓴이가 의도하지 않은 주장이 생겨납니다. 반대로 순서가 정말 의미를 갖는 절차서에서 번호는 독자가 “3단계로 돌아가라”고 말할 수 있게 해 주는 도구입니다. 그리고 그 참조는 본문에 “3”이라고 찍어 넣지 말고 \label\ref에 맡기세요. 손으로 적은 번호는 항목 하나를 끼워 넣는 순간 모두 거짓이 됩니다.

  • 절차・시간 순서・우선순위에는 enumerate. 독자가 “3번으로 돌아가라”고 말할 수 있다는 것이 번호를 매기는 유일한 이유입니다.
  • 순서 없는 조건과 특징에는 itemize. 번호를 매기면 의도하지 않은 우열이나 순서를 주장하게 됩니다.
  • 참조할 항목에는 반드시 \label을. 본문에 번호를 직접 찍으면 항목 하나만 늘어도 전부 어긋납니다.
  • 중첩 항목은 \ref의 반환값을 확인하세요. 행에는 “(a)”라고 보여도 참조는 2a로 돌아옵니다.
  • 끊긴 절차는 번호를 이어 갑니다. 순정 LaTeX은 \setcounter으로, enumitemresume으로 처리합니다.