\LaTeX is great라고 쓰면 나오는 결과는 “LaTeXis great”입니다. 공백이 하나 사라졌는데도 오류는 한 줄도 나오지 않습니다. 이것은 버그가 아니라 TeX가 규칙대로 그 공백을 버린 결과입니다. LaTeX의 표기 규칙——명령 이름이 어디서 끝나는지, 공백과 줄바꿈이 어떻게 접히는지, % 주석이 실제로 무엇을 지우는지——은 모두 “TeX가 원고를 한 줄씩 어떻게 읽는가”라는 한 가지에서 나옵니다. 이 페이지에서는 그 읽기 과정을 따라가며, 초보자가 반드시 한 번은 밟는 세 가지 지뢰, 곧 사라지는 공백, 늘어나는 공백, 멈추지 않는 글꼴 변경을 증상이 아니라 구조 쪽에서 정리합니다.
명령은 어디서 끝나는가: 제어어와 제어기호
명령의 이름은 처음 나타난 “영문자가 아닌 문자”에서 끝납니다. 원고의 대부분은 그대로 조판되는 본문이지만, 백슬래시 \(일부 일본어 환경에서는 엔 기호 ¥로 보이기도 합니다)가 나타나는 순간 TeX는 읽는 방식을 바꾸어 이름을 읽기 시작합니다. 이름을 잡는 방식은 두 가지뿐입니다. \ 뒤에 영문자(A–Z, a–z)만 이어지면 제어어(control word), \ 뒤에 영문자가 아닌 문자 하나가 오면 제어기호(control symbol) 입니다. \section, \LaTeX, \newpage는 앞쪽에, \$, \%, \&, \ (백슬래시+공백)는 뒤쪽에 해당합니다.
이 구분은 말장난이 아니라, 잘못 썼을 때의 증상 자체를 바꿉니다. 제어어의 이름은 영문자가 이어지는 한 계속 늘어나므로, \LaTeXlogo라고 쓰면 TeX는 \LaTeX와 logo로 나누지 않고 \LaTeXlogo라는 하나의 이름으로 읽으며, 그런 명령은 없기에 ! Undefined control sequence.로 멈춥니다. 로고 뒤에 영문자를 이으려면 공백, 기호, {}처럼 영문자가 아닌 무언가로 이름을 끊어야 합니다. 반면 제어기호는 한 문자에서 확정되어 더 늘어날 수 없으므로 \$5는 “달러 기호 뒤에 5”로 순순히 읽힙니다. 숫자나 기호가 바로 뒤에 와도 \$나 \%가 안전한 것은 이 한 글자짜리 성질 덕분입니다.
% A control word is letters only; its name stops at the first non-letter.
\LaTeX % the logo
\LaTeXlogo % ! Undefined control sequence. -- read as ONE name
% A control symbol is exactly one non-letter after the backslash.
\$ \% \& \_ % the literal characters $ % & _
\, % a thin space\LaTeX is가 “LaTeXis”가 되는 이유
제어어 바로 뒤의 공백은 몇 개가 있든 모두 건너뜁니다. 그 공백은 이름이 끝났다는 신호로 소비될 뿐, 출력에는 한 조각도 남지 않습니다. 그래서 \LaTeX is great는 “LaTeXis great”가 됩니다. 여기서 놓치기 쉬운 점은 사라지는 것이 스페이스만이 아니라는 사실입니다. 탭도 마찬가지이고, 줄바꿈도 똑같이 삼켜집니다. 원고를 읽기 좋게 하려고 \LaTeX에서 줄을 접고 다음 줄에 is great라고 써도 결과는 달라지지 않습니다. “분명히 공백을 넣었는데”가 가장 통하지 않는 자리가 바로 명령 바로 뒤입니다.
고치는 방법은 세 가지이고, 결과는 모두 같은 “LaTeX is great”입니다. (1) 빈 중괄호 \LaTeX{} is —— {}는 영문자가 아니므로 이름이 거기서 끝나고, 뒤따르는 공백은 보통의 단어 사이 공백으로 살아남습니다. (2) 제어 공백 \LaTeX\ is —— \ (백슬래시+공백)는 “여기에 단어 사이 공백을 하나 놓아라”라는 명령 그 자체입니다. (3) 명령을 통째로 중괄호로 감싸기 {\LaTeX} is. 실무에서는 (1)이 무난합니다. 뒤에 오는 것이 공백이든 기호든 똑같이 작동하고, 나중에 문장을 고쳐도 무너지지 않습니다. 이 공백 사라짐은 직접 정의한 명령에서 가장 자주 일어나기 때문에 tools 번들에는 xspace 패키지(David Carlisle 등)가 들어 있습니다. 정의 끝에 \xspace를 두면 다음 문자가 문장 부호가 아닐 때만 공백을 채워 줍니다.
\LaTeX is great % -> LaTeXis great (the space is eaten)
\LaTeX{} is great % -> LaTeX is great
\LaTeX\ is great % -> LaTeX is great
{\LaTeX} is great % -> LaTeX is great
% In your own macros, let xspace decide:
\usepackage{xspace}
\newcommand{\myTeX}{\LaTeX\xspace}
\myTeX is great, and \myTeX, and \myTeX. % space added, then not, then not반대로 제어기호는 바로 뒤의 공백을 먹지 않습니다. \$ 5라고 쓰면 달러 기호와 5 사이에 단어 사이 공백이 남습니다. 여기서 \ 의 또 다른 쓰임이 보입니다. LaTeX는 기본적으로 문장 끝 마침표 뒤를 조금 더 넓히기 때문에, 단지 약어를 나타내는 마침표——Prof. Smith, et al. (1993)——까지 덩달아 벌어집니다. 그래서 Prof.\ Smith, et al.\ (1993)처럼 써서 “여기는 문장 끝이 아니다”라고 알려 단어 간격을 고르게 합니다. 반대로 “여기서 줄이 꺾이면 안 된다”면 타이 ~ 를 씁니다. Fig.~1, Chapter~12, Donald~E. Knuth의 ~는 폭은 보통 단어 사이 공백과 같지만 그 자리에서 줄이 나뉘는 일은 결코 없습니다. 미세 조정에는 \,(얇은 공백)가 있어, 수식에서는 \thinmuskip, 곧 3 mu(= 1/6 em), 본문에서는 0.16667 em으로 어느 쪽이든 같은 폭이 됩니다.
중괄호의 두 가지 일: 인수 전달과 범위 구분
중괄호 { }는 필수 인수를, 대괄호 [ ]는 선택 인수(옵션) 를 감쌉니다. 순서는 원칙적으로 \command[options]{required}입니다. \section{Introduction}의 {Introduction}은 필수 제목 문자열이고, \documentclass[12pt]{article}에서는 [12pt]가 옵션, {article}이 필수 클래스 이름입니다. 한 글자짜리 인수라면 괄호를 생략할 수 있는 자리도 있지만, 생략하지 않는 편이 안전합니다. 나중에 단어를 덧붙이는 순간, 괄호 없는 인수는 옆 글자를 끌어들이거나 반대로 끌려 들어가는 두 방식 중 하나로 무너집니다.
그리고 { }에는 또 하나, 그룹을 여는 일이 있습니다. 글꼴이나 크기를 바꾸는 선언형 명령——\bfseries(굵게), \itshape(기울임), \large(크게)——은 인수를 전혀 받지 않고 “여기서부터”를 통째로 바꿉니다. 그대로 두면 문서 끝까지 굵은 글씨로 남는 이유가 여기에 있습니다. 중괄호로 감싸면 효과는 그 그룹 안에만 갇히고, 닫는 }를 넘는 순간 이전 설정이 돌아옵니다. {\bfseries bold here} back to normal과 인수를 받는 형태인 \textbf{bold here} back to normal은 결과가 같지만, 앞쪽은 범위를 구분해 두므로 여러 선언을 한꺼번에 적용하고 싶을 때 쓰입니다.
\section{Introduction} % {...} = mandatory argument
\documentclass[12pt]{article} % [...] = optional, {...} = mandatory
{\bfseries bold here} back to normal % braces fence the declaration in
\textbf{bold here} back to normal % the argument form does the same
{\large\bfseries several at once} back to normal이 “범위를 구분한다”는 발상은 \begin{...} … \end{...} 환경과 완전히 같은 것입니다. 환경은 시작할 때 그룹을 열고 끝날 때 닫으므로, 안에서 바꾼 글꼴이 밖으로 새지 않습니다. 중괄호와 환경은 규모만 다른 같은 도구이며, 자세한 이야기는 환경 페이지가 이어받습니다.
공백, 줄바꿈, 빈 줄은 어떻게 접히는가
연속된 공백은 몇 개가 이어져도 단어 사이 공백 하나가 되고, 소스 안의 줄바꿈 하나도 마찬가지로 단어 사이 공백 하나가 됩니다. 단어 사이를 한 칸 띄우든 열 칸 띄우든, 혹은 줄을 접든 출력은 같습니다. 이는 불편하기는커녕 설계의 핵심입니다. 줄을 어디서 끊을지를 LaTeX가 단독으로 정할 수 있기에 양끝맞춤과 하이픈 넣기가 성립하기 때문입니다. 덕분에 원고 쪽은 원하는 폭으로 줄을 바꿀 수 있고, 버전 관리의 차이도 한 문장씩 읽히는 줄로 유지할 수 있습니다.
그렇다면 단락은 어떻게 바꿀까요. 답은 빈 줄입니다. 아무것도 쓰지 않은 줄을 하나 두면 그곳이 단락의 경계가 됩니다. 빈 줄을 두 개 이상 이어도 경계는 한 번뿐입니다. 여기에 알아채기 어려운 세부가 있습니다. 공백만 늘어선 줄도 빈 줄로 취급됩니다. TeX는 각 줄을 읽기 전에 줄 끝의 공백을 버리므로, 스페이스만 있는 줄은 “아무것도 없는 줄”이 되기 때문입니다. 끊길 리 없는 곳에서 단락이 끊기거나 끊겨야 할 곳에서 끊기지 않는다면, 편집기 화면에서는 구별되지 않는 바로 그 줄을 의심하세요. 단락 자체의 처리(\par, \parindent)는 줄바꿈·단락 페이지가 맡습니다.
These extra spaces collapse into one,
and this newline becomes a single space too.
A blank line -- and only a blank line -- starts a new paragraph.
Two blank lines do exactly what one does.% 는 그 줄만이 아니라 줄 끝의 줄바꿈까지 지웁니다
% 부터 그 줄 끝까지는 주석이며 조판할 때 완전히 무시됩니다. 게다가 사라지는 것은 줄의 나머지만이 아니라 줄 끝의 줄바꿈 자체까지입니다. 메모를 남기거나 명령을 임시로 꺼 두는 것이 본래 용도지만, 이 “줄바꿈까지 사라진다”는 성질이 사실 %의 또 다른 주력 용도를 낳았습니다. 앞 절에서 보았듯 소스의 줄바꿈은 공백 하나가 됩니다. 즉 긴 단어나 긴 명령을 소스에서 접고 싶을 뿐인데, 접는 순간 원치 않은 공백이 끼어듭니다. 줄 끝에 %를 두면 그 공백이 생기지 않고 다음 줄과 빈틈없이 이어집니다. 게다가 % 뒤에 시작하는 줄은 줄머리의 공백도 건너뛰므로 이어지는 줄은 얼마든지 들여쓸 수 있습니다. 소스는 보기 좋게 정리하면서 출력은 한 단어 그대로 유지됩니다.
Visible text % from here to the end of the line is dropped, newline included
Anti%
disestablishmentarianism % -> one word: the indent is dropped too
\newcommand{\courseTitle}{%
Advanced Topics in \LaTeX%
} % no stray space at either seam
The rate was 100\% last year. % a literal percent sign is \%여기서 한 가지 주의가 필요합니다. % 자체가 특수 문자이므로 문자로서의 퍼센트 기호를 출력하려면 \%라고 씁니다. 잊으면 그 줄의 나머지가 통째로 사라집니다. 오류도 경고도 없이 문장의 뒷부분만 PDF에서 빠지므로, 증상으로는 가장 고약한 축에 듭니다. \%는 제어기호라 바로 뒤의 공백은 먹지 않습니다. 다른 특수 문자(#, $, &, _, {, }, ~, ^, \)를 벗어나게 하는 방법은 특수 문자 페이지에 정리되어 있습니다.
여러 줄을 한꺼번에 꺼 두려면 줄마다 %를 붙이는 것 말고도 두 가지 방법이 있습니다. verbatim 패키지(또는 comment 패키지)가 제공하는 comment 환경으로 \begin{comment} … \end{comment}처럼 감싸는 방법과, TeX 조건문인 \iffalse … \fi 로 감싸는 방법입니다. 후자는 패키지가 필요 없어 간편하지만 감싼 내용도 TeX가 읽으므로, 세워 둔 글 안에 \if 짝이 맞지 않으면 거기서 무너집니다. 초고를 통째로 재워 둘 때는 comment 환경이 더 예측 가능합니다.
\usepackage{verbatim} % in the preamble
\begin{comment}
This whole block is ignored.
\end{comment}
\iffalse
Draft text, parked with no package needed.
\fi공백이 사라지거나 늘어났을 때 확인하는 순서
먼저 증상에 오류가 따라왔는지로 두 갈래로 나눕니다. ! Undefined control sequence.처럼 멈추는 문제는 명령 이름이 어디서 끝났는지를 의심하고, 오류도 경고도 없이 출력만 이상한 문제는 공백과 주석을 의심합니다. 이것이 순서입니다. 후자는 쓸 만한 줄 번호를 주지 않으므로 유형으로 범위를 좁히는 수밖에 없습니다. 보고된 줄보다 조금 앞에서부터, 명령 이름이 뒤따르는 영문자를 삼키지 않았는지, {...}와 [...]의 짝이 맞는지 보고, 다음으로 줄 끝의 %가 필요한 공백까지 지우지는 않았는지, 문자로서의 퍼센트를 낼 자리에서 \%를 빠뜨리지는 않았는지 확인합니다.
| 쓴 것 | 증상 | 고치는 방법 |
|---|---|---|
\LaTeXlogo | ! Undefined control sequence. 로 중단 | \LaTeX{}logo처럼 영문자가 아닌 것으로 이름을 끊습니다 |
\LaTeX is | 단어가 붙어 “LaTeXis”가 됨 | \LaTeX{} is 또는 \LaTeX\ is. 자작 명령이라면 \xspace |
\bfseries | 그 뒤가 계속 굵은 글씨로 남음 | {\bfseries ...}로 감싸거나 \textbf{...}를 씁니다 |
100% | 그 줄의 나머지가 조용히 사라짐 | 문자로서의 퍼센트는 100\%라고 씁니다 |
(a line of spaces) | 의도하지 않은 곳에서 단락이 끊김 | 공백만 있는 줄도 빈 줄입니다. 편집기에서 보이지 않는 문자를 표시하세요 |
마지막으로, 규칙을 외우기보다 망가지지 않는 쓰기 방식을 정해 두는 편이 효과적입니다. 명령 바로 뒤에 영문자가 이어지면 {}로 끊습니다. 의미 단위는 {...}로 감쌉니다. 긴 정의는 한 줄에 욱여넣지 말고 줄 끝 %를 붙여 접습니다. 그리고 주석 처리한 옛 원고를 .tex에 쌓아 두지 않습니다. 비교하고 싶은 판은 Git 같은 이력 도구에 맡기고 지금 조판할 내용만 남기면, 오류 줄 번호가 실제 원고와 맞아떨어져 디버깅이 빨라집니다. 이 네 가지로 초반의 시행착오는 대부분 사라집니다.