tabular 기초

표를 조판할 때 치는 &는 LaTeX에게 “앰퍼샌드”가 아닙니다. TeX가 카테고리 코드 4, alignment tab(정렬 탭) 이라고 부르는 특별한 문자입니다. 그래서 열 수를 틀렸을 때 나오는 오류가 화면 어디에도 없는 낱말로 쓰인 ! Extra alignment tab has been changed to \cr. 인 것입니다. 이 페이지에서는 tabular 환경의 세 가지 약속——&로 열을 나누고, \\로 행을 닫고, \hline으로 선을 긋는 것——을 그 아래에서 돌아가는 구조와 함께 살펴봅니다. 구조가 보이면 초보자가 거의 반드시 밟는 두 오류 Extra alignment tabMisplaced \noalign이 수수께끼가 아니라 지시로 읽히기 시작합니다.

tabular 환경의 세 기호: &, \\, \hline

tabular 본문에서 의미를 가지는 기호는 셋뿐입니다. & 는 같은 행의 셀과 셀을 나누고, \\ 는 행을 닫으며, \hline 은 그 자리에 표 전체 폭의 가로줄을 하나 긋습니다. 그리고 \begin{tabular}는 바로 뒤에 필수 인수, 즉 열 지정을 받습니다. \begin{tabular}{ccc}는 “가운데 정렬 열 세 개”라는 선언이고, 여기서 정한 열 개수가 표 전체의 골격이 됩니다. & 앞뒤의 공백은 무시되므로 소스에서는 읽기 좋게 자리를 맞춰도 됩니다.

latex
\begin{tabular}{ccc}
  \hline
  A & B & C \\
  D & E & F \\
  \hline
\end{tabular}

\\는 표 전용 기호가 아니라 LaTeX 전체의 줄바꿈 명령 입니다. 같은 기호가 수식의 pmatrixalign에서도 행 구분자로 작동합니다. 즉 “&로 자리를 맞추고 \\로 행을 바꾼다”는 감각은 표에서 수식으로 그대로 이어집니다. 마지막 행 뒤의 \\는 생략할 수 있지만, 그 아래에 선을 긋고 싶다면 반드시 \\로 행을 닫은 다음 \hline을 둡니다. 생략하면 이 페이지 뒤에서 다룰 Misplaced \noalign에 곧장 부딪힙니다. \\에는 대괄호 선택 인수도 있어서 \\[2pt]라고 쓰면 그 행 아래에 추가 세로 공간이 들어가고, 음수 값을 주면 좁아집니다.

\begin{tabular}은 열 지정 에 대괄호로 수직 위치 선택 인수도 받습니다. \begin{tabular}[t]{…}는 표의 위쪽을, [b]는 아래쪽을 주변 행의 기준선에 맞추며, 기본값은 표의 세로 가운데를 맞추는 것입니다. 다만 함정이 있습니다. 표의 처음이나 끝이 \hline이면 선의 위치에서 맞춰져 기대한 모습이 나오지 않습니다. array 패키지는 이 증상을 위해 \firsthline\lasthline 을 마련해 두었습니다. \hline 대신 이들을 쓰면 본문의 첫 행・마지막 행에 제대로 맞습니다.

Extra alignment tab has been changed to \cr — 열 수가 맞지 않습니다

이 오류는 단 한 가지를 뜻합니다. 선언한 열 수보다 &가 많다 는 것입니다. {ll}로 선언한 표의 행에 A & B & C라고 쓰면 반드시 나옵니다. TeX는 넘치는 &를 행 끝(\cr)으로 읽고 계속 진행하므로 출력이 사라지지는 않고 어긋난 표 가 만들어집니다. 대부분은 열 지정을 잘못 센 탓이지만, 다음 세 가지도 흔합니다. \multicolumn{3}{c}{…}가 이미 세 열을 다 먹은 행에 &를 또 쓴 경우, 셀 안에 \\를 쓴 경우, 그리고 array>{\raggedright}마지막 열 에 붙인 경우입니다. 마지막 경우는 \raggedright\\를 재정의하는 바람에 행 끝이 듣지 않고, 다음 행의 &가 넘쳐 같은 오류가 납니다. >{\raggedright\arraybackslash}라고 쓰면 해결됩니다.

반대로 &모자란 것은 아무 말도 하지 않습니다. 빠진 셀은 그냥 빈칸으로 조판되고 오류도 경고도 나지 않습니다. 그래서 표가 눈에 띄게 어긋나는데도 깔끔하게 컴파일된다면 먼저 빠뜨린 &를 의심하세요. 또 하나의 단서로, 열 지정에 모르는 글자를 쓰면 오류 문구가 어떤 패키지를 불러왔는지에 따라 달라집니다. 순수 LaTeX은 ! LaTeX Error: Illegal character in array arg., array를 불러왔다면 ! Package array Error: Illegal pream-token이 나옵니다. 어느 쪽이 나오는지로 지금 표가 어떤 구현 위에서 돌고 있는지 알 수 있습니다.

Misplaced \noalign — \hline은 행과 행 사이에만 놓입니다

이 오류의 원인은 거의 언제나 하나, 행을 \\로 닫지 않은 채 \hline을 쓴 것 입니다. 마지막 행 뒤에 \\를 빠뜨리고 \hline을 이어 쓰면 TeX Live 2024 로그에는 오류 세 개가 연쇄로 나타납니다. ! Misplaced \noalign., ! You can't use \hrule here except with leaders., ! Missing number, treated as zero. 입니다. 셋 다 같은 하나의 원인에서 나옵니다. 이유는 \hline의 정의 자체에 있습니다. latex.ltx를 열면 \def\hline{\noalign{…\hrule \@height \arrayrulewidth …}}라고 적혀 있습니다. \noalign은 “정렬 구조의 행과 행 사이 에 이 재료를 끼워 넣는다”는 뜻만 가진 TeX 원시 명령입니다. 행 도중에 불리면 갈 곳이 없으니 \noalign과 그 안에 있어야 할 \hrule이 차례로 드러난 채 흘러나옵니다.

latex
% WRONG: the last row was never closed, so \hline has no gap to sit in
\begin{tabular}{ll}
  A & B \\
  C & D
  \hline
\end{tabular}

% RIGHT: close the row first, then draw the rule
\begin{tabular}{ll}
  A & B \\
  C & D \\
  \hline
\end{tabular}

같은 이치로 \hline셀 도중 에 써도 똑같은 세 개의 오류가 납니다. 반대로 \\ 바로 뒤에 \hline만 단독으로 두는 것은 언제나 안전하고, \hline \\처럼 빈 행을 만드는 것도 오류가 아닙니다. 눈에 보이는 공백이 늘어날 뿐입니다. tabular 주변에서 자주 나오는 것이 하나 더 있는데 ! LaTeX Error: \caption outside float. 입니다. \captiontabular 안에 쓴 전형적인 결과로, 다음 절에서 설명하듯 제목은 table의 일 이기 때문입니다. \end{tabular}를 빠뜨리면 행 번호까지 알려 주는 친절한 ! LaTeX Error: \begin{tabular} on input line N ended by \end{document}. 가 나옵니다.

선을 긋는 법, 그리고 긋지 않는 편이 나은 선

가로줄은 \hline에서, 세로줄은 열 지정에 |를 써 넣어 만듭니다. {|l|c|r|}라고 쓰면 3열의 바깥쪽과 각 열 사이에 세로줄이 들어가고, \hline과 함께 쓰면 모든 셀이 격자의 칸이 됩니다. \hline\hline은 이중선이며 두 줄 사이의 간격은 길이 \doublerulesep(기본 2pt)입니다. 선의 굵기는 길이 \arrayrulewidth로, 표준 클래스의 기본값은 0.4pt 입니다. \cline{2-3}은 열 번호 범위를 받아 일부 열에만 선을 긋습니다. 여기까지가 표준 LaTeX으로 그릴 수 있는 선의 전부입니다.

표기하는 일주의
&같은 행의 셀을 나눕니다카테고리 코드 4. 많으면 Extra alignment tab
\\행을 닫습니다align・pmatrix에서도 같은 역할
\\[2pt]행 아래에 공간을 더합니다음수 값으로 좁힐 수 있습니다
\hline표 전체 폭의 가로줄굵기는 \arrayrulewidth(기본 0.4pt)
\hline\hline이중 가로줄간격은 \doublerulesep(기본 2pt)
\cline{2-3}2열부터 3열까지만 선을 긋습니다병합 셀 아래에 선을 그을 때의 정석
|열 지정에 쓰는 세로줄정식 표에서는 피하는 것이 정석
||이중 세로줄간격은 역시 \doublerulesep

그런데 방금 든 도구 가운데 세로줄과 이중선은 아예 쓰지 않는 편이 좋다 는 것이 전문 조판의 입장입니다. booktabs의 설명서 『Publication quality tables in LaTeX』(Simon Fear, TeX Live 2024 동봉본은 2020년 1월 12일 개정)은 두 가지 지침을 내겁니다. “1. 세로줄은 절대로 쓰지 말 것. 2. 이중선도 쓰지 말 것.” 저자는 표의 왼쪽 절반과 오른쪽 절반이 선을 그어 나눠야 할 만큼 다르다면 표를 두 개로 나누라고까지 쓰고, 이중선에 대해서는 합계 행 위에 이중 가는 선을 요구하는 출판사와 일한 적이 있지만 “내 선택은 아니었다”고 솔직하게 덧붙입니다. 대신 권하는 것은 굵기가 다른 가로줄과 그 위아래로 넉넉히 둔 여백 입니다.

중요한 것은 이 지침이 모든 표에 적용되지는 않는다 는 점입니다. Fear는 “표지가 붙은 열에 값이 놓인” formal table(정식 표) 과, 아이콘이 잔뜩 붙고 색도 쓰는 일회성 배치인 tableau 를 분명히 구분하고, 두 지침은 전자에 대한 것이라고 못박습니다. 정식 표의 배치는 “여러 세기의 경험으로 확립된 것이므로 어지간한 사정이 아니면 바꾸지 말아야 한다”고 씁니다. 뒤집어 말하면 일정표나 UI 설명도 같은 tableau에 격자를 두르는 것은 이 지침의 대상이 아닙니다. 수치 표를 논문에 싣는다면 booktabs\toprule\midrule\bottomrule을 쓰는 것이 현대의 정석이며, 자세한 내용은 “선과 출판 품질의 표”에서 다룹니다.

행이 답답해 선이 글자에 닿아 보일 때는 \renewcommand{\arraystretch}{1.2}로 행 높이 배율을 올리는 것이 가장 빠릅니다(기본값은 1). 열과 열 사이의 간격은 길이 \tabcolsep으로 한쪽 6pt가 기본이므로 두 열 사이는 합쳐서 12pt입니다. array 패키지를 불러왔다면 \setlength{\extrarowheight}{2pt}도 쓸 수 있습니다. 이쪽은 각 행의 높이만 늘리고 깊이는 그대로 두므로, 선이 대문자 윗부분을 스치는 증상에 정확히 듣습니다.

tabular와 table의 차이: 표는 부동체가 아닙니다

tabular표의 내용 만 조판하는 환경으로, 번호도 캡션도 배치에 대한 재량도 없습니다. 글자와 똑같이 다뤄지므로 문단 중간에도, 목록 항목 안에도, 심지어 각주 안에도 놓을 수 있습니다. 반면 table부동체(float) 환경입니다. tabular를 감싸서 쓰면 \caption{…}에 의한 자동 번호 제목, \label{…}\ref{…}을 통한 상호 참조, [htbp] 같은 배치 지정을 얻습니다. \captiontabular 안에 쓰면 ! LaTeX Error: \caption outside float. 가 나오는데, 이 역할 분담이 그대로 오류 메시지가 된 것입니다.

document.tex
\begin{table}[htbp]
  \centering
  \caption{Quarterly sales}
  \label{tab:sales}
  \begin{tabular}{lrr}
    \hline
    Quarter & Sales & YoY \\
    \hline
    Q1 & 1{,}200 & +5\% \\
    Q2 & 1{,}350 & +8\% \\
    \hline
  \end{tabular}
\end{table}

% ... and refer to it from the running text:
See Table~\ref{tab:sales}.

부동체로 만드는 이유는 번호가 붙는다는 점보다 tabular가 페이지를 넘어 나뉘지 못한다 는 데 있습니다. tabular는 하나의 커다란 상자로 조판되므로 남은 지면에 들어가지 않으면 통째로 다음 쪽으로 밀려나고 그 앞에 큰 공백이 남습니다. table에 넣어 두면 LaTeX가 그 상자를 뒤쪽 페이지 위 같은 자리로 옮기고 빈 자리를 본문으로 메웁니다. [htbp]는 “여기・페이지 위・페이지 아래・독립된 쪽”이라는 희망 순서이고, LaTeX는 이 순서대로 자리를 찾습니다. 어느 한 쪽에도 담기지 않을 만큼 세로로 긴 표는 애초에 부동체로 다룰 수 없습니다. 페이지를 넘겨 나뉘는 longtable의 차례입니다.

긴 문장을 담는 표: p{width}가 없으면 지면을 넘칩니다

l, c, r 세 가지는 열을 내용의 자연 너비 만큼 넓힐 뿐, 행 안에서 줄바꿈하지 않습니다. 그래서 긴 설명문을 그대로 l 열에 넣으면 열이 그 한 줄의 길이만큼 가로로 늘어나 표가 판면을 넘칩니다. 이때 나오는 것이 경고 Overfull \hbox (…pt too wide) 입니다. 오류가 아니라 경고이므로 컴파일은 그냥 통과하고, PDF를 보고서야 알아차리게 되는 점이 이 증상의 성가신 부분입니다. 줄바꿈이 필요하다면 순수 tabular에서 쓸 수 있는 열 지정은 p{width} 하나뿐입니다. 지정한 폭의 단락 상자로 조판되어, 폭을 넘는 내용은 자동으로 다음 줄로 흘러갑니다.

latex
\begin{tabular}{l p{5cm} r}
  \hline
  Item & Description & Price \\
  \hline\hline
  Apple  & A large honey-cored variety, popular as a gift. & 380 \\
  Orange & A small, sweet citrus that peels by hand.       & 120 \\
  \hline
\end{tabular}

1열은 자연 너비의 왼쪽 정렬, 3열은 오른쪽 정렬이고, 2열만 폭 5cm의 p 열입니다. 긴 설명은 그 5cm에서 줄바꿈되어 그 셀만 여러 줄이 되고 행 높이가 늘어납니다. 같은 문장을 l 열에 넣으면 줄바꿈 없이 옆으로 늘어날 뿐인데, 이것이 p{width}가 만드는 결정적 차이입니다. 머리글 행 아래는 \hline\hline 이중선, 위아래는 단일 \hline입니다. p 열의 내용은 기본적으로 위쪽 정렬과 양쪽 정렬이며, 그 안에서 문단 들여쓰기 \parindent는 0으로 설정됩니다. 셀을 세로 가운데나 아래쪽에 두고 싶거나 양쪽 정렬 대신 왼쪽 정렬로 조판하고 싶다면 array 패키지의 영역이며, “열 지정 상세”에서 다룹니다.