LaTeX 이 예약하고 있는 특수 문자는 정확히 열 개——# $ % & ~ _ ^ \ { }——이지만, 이 목록은 누군가가 고른 것이 아닙니다. TeX 은 모든 문자에 카테고리 코드 라는 번호를 부여하며, 보통의 문자는 “글자(11)” 이거나 “기타(12)” 입니다. 인쇄 가능한 ASCII 중 그 어느 쪽도 아닌 번호를 가진 문자가 딱 열 개 있고, 그것이 예약 문자의 정체입니다. 그러니 “왜 하필 이 열 개인가” 의 답은 역사도 취향도 아니라 TeX 입력 처리기의 설정표 자체에 있습니다. 이 페이지에서는 그 열 개를 하나씩 그대로 인쇄하는 방법, 악센트 기호를 붙이는 방법, 그리고 UTF-8 이 기본이 된 지금의 LaTeX 에서 비 ASCII 를 입력하는 방법을 다룹니다.
열 개의 예약 문자와 카테고리 코드
예약 문자란 LaTeX 이 자기 문법의 일부로 쓰는 문자입니다. 입력해도 인쇄되지 않고 동작이 발동합니다. % 를 치면 그 줄의 나머지가 사라지고, $ 를 치면 수식 모드로 바뀌며, & 를 치면 표의 열이 나뉩니다. 카테고리 코드로 다시 말하면 \ 는 0(명령 시작), { 은 1, } 는 2(그룹 열기와 닫기), $ 는 3(수식 전환), & 는 4(정렬 탭), # 은 6(인수 번호), ^ 는 7(위 첨자), _ 는 8(아래 첨자), ~ 는 13(활성 문자), % 는 14(주석)입니다. a 는 11, 1 이나 + 는 12——그저 인쇄될 뿐인 문자입니다.
이들을 그대로 썼을 때 무슨 일이 일어나는지는 문자마다 다릅니다. 가장 위험한 것은 % 로, 오류가 전혀 나지 않은 채 조용히 그 줄의 나머지를 먹어 버립니다. & 는 ! Misplaced alignment tab character &., 본문 속의 _ 와 ^ 는 ! Missing $ inserted., } 는 ! Too many }'s., \ 는 뒤따르는 글자를 명령 이름으로 읽어 ! Undefined control sequence. 가 됩니다. # 만 메시지가 독특해서 ! You can't use 로 시작해 macro parameter character #' in horizontal mode. 로 이어집니다. ~ 는 유일하게 오류도 경고도 내지 않고 끊기지 않는 공백으로 조용히 조판됩니다.
| 문자 | 카테고리 코드 | 역할 | 그대로 쓰면 |
|---|---|---|---|
\ | 0 | 명령의 시작 | ! Undefined control sequence. |
{ | 1 | 그룹·인수의 시작 | 닫히지 않으면 파일 끝에서 오류 |
} | 2 | 그룹·인수의 끝 | ! Too many }'s. |
$ | 3 | 수식 모드의 시작과 끝 | 짝이 맞지 않으면 ! Missing $ inserted. |
& | 4 | 표와 정렬 환경의 열 구분 | ! Misplaced alignment tab character &. |
# | 6 | 매크로 정의의 인수 번호(#1, #2, …) | ! You can't use … in horizontal mode. |
^ | 7 | 수식 모드의 위 첨자 | 본문에서는 ! Missing $ inserted. |
_ | 8 | 수식 모드의 아래 첨자 | 본문에서는 ! Missing $ inserted. |
~ | 13 | 활성 문자. 끊기지 않는 공백 | 오류 없음. 조용히 비분할 공백이 됩니다 |
% | 14 | 주석. 줄의 나머지를 무시 | 오류 없음. 줄의 나머지가 조용히 사라집니다 |
그대로 인쇄하기: 일곱은 이스케이프만 하면 됩니다
열 개 가운데 일곱은 간단합니다. 바로 앞에 백슬래시 하나를 놓으면 됩니다——\#, \$, \%, \&, \_, \{, \}. \$1.23 이라고 쓰면 $1.23 이 나옵니다. 백슬래시는 “다음 한 글자는 명령의 시작이 아니라 그 글자 자신이다” 라는 신호입니다. 구조도 단순해서, 커널 안에서 \%, \&, \# 는 \chardef——“이 번호의 문자를 인쇄하라” 는 정의 그 자체——로 적혀 있습니다. \$ 와 \{, \} 만은 수식 모드인지 살펴 동작을 바꾸므로, 수식 안에서도 같은 표기가 통합니다.
| 입력 | 출력 | 참고 |
|---|---|---|
\# | # | 앞에 백슬래시 하나만 |
\$ | $ | 수식 모드 안에서도 쓸 수 있습니다 |
\% | % | 50\% 처럼 퍼센트에 |
\& | & | 회사명이나 서명 속의 “and” 에 |
\_ | _ | 기본 인코딩에서는 글리프가 아니라 선으로 그려집니다 |
\{ | { | 수식 모드 안에서도 쓸 수 있습니다 |
\} | } | 수식 모드 안에서도 쓸 수 있습니다 |
\textasciitilde | ~ | \~{} 도 같습니다. 맨 \~ 는 악센트 명령입니다 |
\textasciicircum | ^ | \^{} 도 같습니다. 맨 \^ 는 악센트 명령입니다 |
\textbackslash | \ | \\ 는 줄바꿈 명령이라 백슬래시가 나오지 않습니다 |
남은 셋: 물결표, 캐럿, 백슬래시
~, ^, \ 이 셋만은 이스케이프만으로 끝나지 않습니다. 이유는 단순합니다. 그 “이스케이프한 형태” 가 이미 다른 뜻을 가지고 있기 때문입니다. \~ 와 \^ 는 악센트 명령 으로, 다음 한 글자 위에 물결이나 갓을 얹습니다——\~n 은 ñ, \^o 는 ô 입니다. 기호 자체를 원할 때는 빈 인수를 주어 얹을 곳을 없앱니다. 그것이 \~{} 와 \^{} 이고, 실제로 커널의 \textasciitilde 와 \textasciicircum 기본 정의가 문자 그대로 이 둘입니다. 이름이 붙은 쪽이 의도를 읽기 쉬우므로, 원고에서는 \textasciitilde{} 와 \textasciicircum{} 을 권합니다.
백슬래시 자체는 \textbackslash 로 출력합니다. \\ 를 쓰면 안 됩니다——그것은 백슬래시 두 개가 아니라 줄바꿈 명령이라 화면에는 아무것도 나오지 않습니다. 재미있는 점은 기본 본문 글꼴에 백슬래시 글자가 아예 없다 는 사실입니다. 커널은 \textbackslash 를 수식 기호 인코딩에서 가져오도록 선언하고 있고, 실제로 \textbackslash 만 담은 한 쪽짜리 PDF 에 묻히는 글꼴은 수식 기호용 CMSY10 입니다. 같은 이유로 기본의 \_ 도 문자가 아니라 직접 그린 가는 선 이어서, \_ 만 있는 한 쪽에서는 글꼴이 하나도 묻히지 않습니다. \usepackage[T1]{fontenc} 을 넣으면 둘 다 본문 글꼴의 정식 글리프로 바뀝니다. 덧붙이면, 예약 문자가 아닌 < > | 도 기본 인코딩에서는 ¡ ¿ — 로 둔갑합니다. 이 역시 fontenc 로 해결됩니다.
\usepackage[T1]{fontenc} % real glyphs for \, _, < > |
100\% \& \$5 cost \#1
A Windows path: C:\textbackslash Users\textbackslash doc
Standalone marks: \textasciitilde{} and \textasciicircum{}악센트 기호 붙이기
초기의 TeX 은 7 비트 ASCII 밖에 읽지 못했습니다. 그래서 é 를 내려면 “e 위에 예음 부호를 얹어라” 라고 명령해야 했고, 그 명령이 오늘날까지 남아 있습니다. 쓰는 방식은 “악센트 명령+글자” 로, \'e 가 é, \"o 가 ö, \^e 가 ê, \~n 이 ñ, \c{c} 가 ç, \v{s} 가 š, \r{a} 가 å 입니다. 함정이 하나 있습니다. i 와 j 에 악센트를 얹을 때는 점이 방해가 되므로 점 없는 \i 와 \j 를 써서 \'{\i} 처럼 적습니다.
| 명령 | 예 | 이름 |
|---|---|---|
\' | é | 예음 부호(어큐트) |
\` | è | 억음 부호(그레이브) |
\^ | ê | 곡절 부호(서컴플렉스) |
\" | ö | 움라우트·분음 부호 |
\~ | ñ | 물결표 |
\= | ō | 마크론(장음 부호) |
\. | ż | 위 점 |
\u | ğ | 브레베(단음 부호) |
\v | š | 하체크(캐런) |
\H | ő | 이중 예음 부호 |
\c | ç | 세디유 |
\r | å | 위 고리 |
\d | ṣ | 아래 점 |
\b | o̲ | 아래 선 |
\t | o͡o | 두 글자를 잇는 연결 기호 |
악센트로는 만들 수 없는 글자도 있습니다. 독일어의 에스체트 \ss(ß), 북유럽의 \aa(å) 와 \o(ø), 폴란드어의 \l(ł), 그리고 합자 \ae(æ) 와 \oe(œ) 는 각각 독립된 글자여서 독립된 명령을 가집니다. 대문자는 철자를 대문자로 바꾸기만 하면 됩니다: \AA, \O, \L, \AE, \OE. 이들 명령은 모두 표준 LaTeX 이라 추가 패키지가 필요 없습니다.
UTF-8 로 그대로 입력하기
오늘날의 LaTeX 에서는 café 도 Grüße 도 naïve 도 그대로 칠 수 있습니다. 2018 년 4 월 릴리스(LaTeX News 28 의 “UTF-8: the new default input encoding” 절)에서 UTF-8 이 커널의 기본 입력 인코딩이 되었기에 \usepackage[utf8]{inputenc} 는 더 이상 필요 없습니다(써도 해롭지 않고 오래된 문서도 그대로 컴파일됩니다). 그래도 \usepackage[T1]{fontenc} 은 넣을 값어치가 있습니다. 출력 쪽이 8 비트 글꼴 인코딩으로 바뀌어 악센트 붙은 낱말이 올바로 하이픈되고, PDF 에서 글자를 복사해도 깨지지 않기 때문입니다. XeLaTeX 과 LuaLaTeX 이라면 이야기가 더 간단합니다. fontspec 으로 OpenType 글꼴을 지정하면 입력도 출력도 처음부터 유니코드입니다.
% pdfLaTeX: UTF-8 input is the default; T1 fixes output and hyphenation
\usepackage[T1]{fontenc}
café, Gr\"u\ss e, na\"{\i}ve, \AA ngstr\"om, \oe uvre, a\~no
% XeLaTeX / LuaLaTeX: Unicode all the way through
% \usepackage{fontspec}
% \setmainfont{TeX Gyre Pagella}기호가 많을 때: \verb 와 \url
기호투성이 조각을 한 글자씩 이스케이프하는 일은 고되고, 빠뜨릴 확률도 빠르게 올라갑니다. 그래서 verbatim 구조를 씁니다. 본문 안에서는 \verb|...| 라고 쓰고, 내용에 나오지 않는 임의의 문자(여기서는 |)로 감싸면 그 안에서는 예약 문자의 특별한 뜻이 모두 끊기고 고정폭으로 조판됩니다. 여러 줄이라면 verbatim 환경입니다. 제약이 하나 있습니다. \verb 는 인수 안에서 쓸 수 없어서, \section{... \verb|x| ...} 라고 쓰면 ! LaTeX Error: \verb illegal in argument. 가 납니다. ~, #, %, _ 를 품기 쉬운 문자열——무엇보다 URL——에는 url 이나 hyperref 패키지의 \url{...} 이 최선입니다. 안의 예약 문자를 자동으로 처리하고, 고정폭으로 조판하며, 긴 주소를 적절한 자리에서 끊어 줍니다.
\usepackage{hyperref} % provides \url as well
Use \verb|a_b^c & d%| to show specials literally.
\begin{verbatim}
foo_bar = 100% & #1 % every character printed as-is
\end{verbatim}
See \url{https://example.com/path?id=1#sec_2~ok}붙여 넣은 데이터가 표를 망가뜨릴 때
실제 원고에서 특수 문자는 스스로 쳐서 섞여 드는 일이 드뭅니다. CSV 나 웹 페이지, 메일, PDF 에서 붙여 넣어져 들어옵니다. 특히 위험한 곳이 표입니다. & 는 열 구분자이므로 회사명이나 논문 제목에 든 맨 & 하나로 열 수가 어긋나, ! Misplaced alignment tab character &. 가 나거나 행의 뒷부분이 조용히 사라집니다. 가장 빠른 방어는 붙여 넣기 전에 재료를 세 종류로 갈라 두는 것입니다——산문으로 읽힐 글, 그대로 보여 줄 코드, 링크로 처리할 URL. 갈라 놓고 나면 이스케이프 방식은 저절로 정해집니다.
% before pasting into a table, search the pasted region for & % _ #
\begin{tabular}{ll}
Smith \& Wesson & company name \\
95\% & reported rate \\
\end{tabular}
% do not escape URLs by hand; hand them to \url
\url{https://example.com/report?id=95#table_1}정리하면 판단은 대체로 세 단계입니다. 산문 속의 한두 개 기호 는 표대로 이스케이프합니다. 덩어리로 된 코드나 터미널 출력 은 \verb 나 verbatim 에 넘깁니다. URL 은 \url{} 에 맡깁니다. 그런 뒤 증상이 나타나면——표가 한 열 밀렸다, 행의 뒷부분이 사라졌다, 갑자기 ! Missing $ inserted. 가 났다——붙여 넣은 범위만 검색해 &, %, _, # 를 하나씩 “산문인가, LaTeX 문법인가” 로 갈라 봅니다. 원인은 거의 틀림없이 거기에 있습니다.