문장부호와 괄호

LaTeX에게 마침표는 “점을 찍는 명령”이 아니라 다음에 오는 공백의 폭을 바꾸는 명령입니다. Dr. Smith의 공백은 3.33252pt, ends here. Next의 공백은 4.44336pt로, 키보드에서는 같은 .을 쳤는데도 10pt 문서에서 1.11084pt의 차이가 납니다. 게다가 판단의 근거는 마침표 앞의 문자여서, 소문자면 문장 끝, 대문자면 약어로 간주됩니다. 이 한 줄짜리 규칙이 NASA. Next 뒤가 늘어지는 이유이자, Fig. 1의 이상한 공백, e.g. 뒤의 어색함의 정체입니다. 이 페이지에서는 그 장치(\sfcode)와 고치는 법(\@, \ , ~, \frenchspacing), 말줄임표 \ldots\dots의 구분, 숫자의 자릿수 구분 \,, 그리고 일본어 구두점과 괄호의 선택까지 다룹니다.

마침표 뒤의 공백이 넓어지는 이유 — \sfcode라는 장치

문자마다 스페이스 팩터(space factor) 값이 붙어 있고, 바로 앞 문자가 남긴 값이 2000을 넘으면 TeX이 다음 공백에 폰트의 “여분 공백” \fontdimen7을 더하기 때문입니다. 10pt article에서 재면 보통 낱말 사이 \fontdimen2는 3.33252pt, 여분 공백은 1.11084pt로 합쳐서 4.44336pt입니다. 곧 문장 끝 공백은 낱말 사이의 정확히 1.33배입니다. 값은 \the\sfcode 뒤에 문자를 붙여 들여다볼 수 있으며 마침표는 3000을 보고합니다. 이 3000이 모든 것의 출발점입니다.

문자기본 sfcode다음 공백에 대한 효과
. ? !3000문장 끝 공백. 10pt에서 +1.11084pt
:2000조금 넓은 공백. 임계값에 딱 걸침
;1500늘어남과 줄어듦만 조금 달라짐
,1250위와 같음. 문장 끝으로 치지 않음
)0투명. 앞 문자가 남긴 값을 그대로 넘김
A B C9991000 미만이라 뒤따르는 .의 3000을 상쇄

Dr. Smith는 좁고 ends here. Next는 넓다 — 대문자의 sfcode가 999인 이유

대문자의 sfcode가 999, 곧 1000을 살짝 밑도는 값으로 설정되어 있기 때문입니다. TeX의 규칙은 이렇습니다. 현재 스페이스 팩터가 1000 미만일 때, 다음 문자가 1000보다 큰 값을 갖더라도 스페이스 팩터는 1000까지만 올라갑니다. 그래서 A 뒤에 .(3000)이 와도 실제로 남는 값은 1000이고, 문장 끝의 여분 공백은 생기지 않습니다. 반대로 소문자 a는 정확히 1000이므로 뒤따르는 .의 3000이 그대로 통과합니다. 실측하면 A. a는 18.60657pt이고, 공백을 명시한 A.\ a똑같이 18.60657pt입니다. 한편 a. a는 17.21802pt이며 \frenchspacing을 선언하면 16.10718pt로 줄어듭니다. 그 1.11084pt의 차이가 바로 문장 끝의 여분 공백입니다.

이 설계는 TeX이 만들어지던 무렵 영어 조판 관습을 그대로 구현한 것입니다. 당시에는 문장과 문장 사이를 낱말 사이보다 넓게 두는 것이 보통이었습니다. 그리고 약어의 마침표 — Dr., Ph.D., Mr. — 를 문장 끝으로 오인하지 않기 위해 “대문자로 끝나면 약어”라는 한 줄짜리 경험칙을 채택했습니다. 경험칙이니 당연히 양쪽으로 빗나갑니다. NASA. Next는 정말 문장 끝인데도 좁게 조판되고, Fig. 1은 약어인데도 넓게 조판됩니다. 다음 두 절이 각각의 해결책입니다.

\@로 “여기가 문장 끝”이라고 알려 주기 — NASA\@. Next

\@는 “바로 뒤의 약물을 문장 끝으로 다루라”는 지시이며 마침표 앞에 놓습니다. He joined NASA\@. Then he left.처럼 쓰면 대문자 A가 세운 999가 상쇄되고 .의 3000이 그대로 통과합니다. 실측해도 A. a의 18.60657pt에 비해 A\@. a는 19.7174pt로, 차이 1.11083pt가 바로 문장 끝의 여분 공백입니다. 자리를 잘못 잡아 NASA.\@ Next라고 써도 효과가 없습니다. \@는 마침표 앞이라고 외워 두세요. 문장이 두문자어(NASA, USA, DNA)나 대문자로 끝나는 고유명사로 끝날 때만 쓰는, 1년에 몇 번짜리 도구입니다.

약어 뒤에는 \ 또는 ~e.g.Fig.~1

반대 방향의 오판 — 소문자로 끝나는 약어가 문장 끝으로 간주되는 경우 — 은 공백 자체를 명령으로 써서 고칩니다. \ (백슬래시+공백)는 “여기에 보통 낱말 사이 공백을 두라”는 뜻이며 스페이스 팩터를 보지 않습니다. 실측하면 Fig. 1은 26.5213pt, Fig.\ 1은 25.41046pt로 1.11084pt 줄어 올바른 낱말 사이 공백이 됩니다. e.g., i.e., etc., cf., vs., Fig., Eq., No.는 모두 이 함정에 빠지는 낱말입니다.

다만 Fig. 1 같은 참조 번호에는 \ 보다 ~(물결표)가 적절합니다. ~는 “낱말 사이와 같은 폭이면서 여기서 줄을 바꾸지 못하는 공백”으로, 실측해도 Fig.~1Fig.\ 1과 같은 25.41046pt입니다. 폭은 같고 개행 금지만 더해집니다. 그림·수식 번호나 이름의 이니셜이 행 끝에서 떨어져 나가면 읽기 어려우므로 Fig.~\ref{fig:one}, Eq.~\eqref{eq:main}, D.~E.~Knuth처럼 쓰는 것이 정석입니다. 참조 번호에는 ~, 그 밖의 약어에는 \ 라고 외워 두면 헷갈리지 않습니다.

latex
% a sentence really ending on a capital
He joined NASA\@. Then he left.

% abbreviations that must NOT get a sentence space
See, e.g.\ Knuth (1984); cf.\ the appendix.

% reference numbers: same width, but unbreakable
Fig.~\ref{fig:one} and Eq.~\eqref{eq:main}, after D.~E.~Knuth.

\frenchspacing — 영어가 아닌 문서라면 거의 반드시 필요한 한 줄

\frenchspacing은 문장 끝의 여분 공백을 한꺼번에 끄는 선언으로, 프리앰블에 한 줄만 쓰면 됩니다. 내부는 놀랄 만큼 단순해서, latex.ltx의 정의는 여섯 개의 sfcode를 1000으로 맞출 뿐입니다. 곧 ., ?, !, :, ;, , 전부가 보통 문자와 같은 대우를 받습니다(기본값 \nonfrenchspacing은 3000/3000/3000/2000/1500/1250으로 되돌립니다). 실측해도 a. a는 17.21802pt에서 16.10718pt로 줄고, A. a는 18.60657pt 그대로입니다. 애초에 여분 공백이 없던 자리는 당연히 변하지 않습니다.

이름과 달리 이 좁은 간격은 프랑스어만의 방식이 아닙니다. 프랑스어・독일어・스페인어・이탈리아어를 비롯해 영어를 뺀 대부분의 언어는 문장 사이를 낱말 사이보다 넓게 두지 않습니다. 현대 영어 조판에서도 한 칸 간격이 주류가 되었습니다. babel에 언어를 넘기면 대개 자동으로 전환되지만, 직접 \frenchspacing을 선언해 두는 편이 확실합니다. 참고로 LaTeX 자신도 verbatim 환경 내부에서 이를 씁니다. 코드 안에서 . 뒤가 늘어나면 곤란하기 때문입니다. 문장 끝 공백을 남길지 없앨지는 공저자와 처음에 정해 두어야 할 방침이며, 중간에 바꾸면 차이가 전 페이지로 번집니다.

latex
\documentclass{article}
\usepackage[T1]{fontenc}
\frenchspacing          % . ? ! : ; , all behave like ordinary letters
\begin{document}
This ends here. Next sentence starts with an ordinary space.
\end{document}

말줄임표는 ...이 아니라 \ldots — 그리고 \ldots\dots의 차이

마침표 셋을 늘어놓은 ...는 폭이 8.3313pt, \ldots는 13.33008pt로 1.6배나 차이가 납니다. ...는 점이 뭉쳐서 “줄임”으로 읽히지 않지만, \ldots는 점 사이에 올바른 공백을 넣습니다. 그러니 본문의 말줄임표는 반드시 \ldots\dots를 쓰세요. 그렇다면 둘의 차이는 무엇일까요. 맨 LaTeX에서는 차이가 없습니다. latex.ltx\dots를 정의한 뒤 \let\ldots\dots라고 적어 두었으므로 둘은 말 그대로 같은 명령입니다. 실측해도 텍스트 모드에서 13.33008pt이고 \textellipsis와도 일치합니다.

차이가 생기는 것은 amsmath를 읽어 들였을 때, 그것도 수식 모드 안에서만입니다. amsmath는 둘을 따로 다시 정의해, \ldots는 언제나 아래쪽 점이 되고 \dots앞뒤를 미리 읽어 점의 높이를 고르는 명령이 됩니다. 쉼표가 늘어선 자리면 낮은 점(\dotsc), 이항 연산자나 관계 기호 사이면 가운데 점(\dotsb\cdots), 적분이면 \dotsi, 곱셈이면 \dotsm을 고릅니다. 실제로 컴파일해 pdftotext로 뽑아 보면 $a+\dots+b$는 “a + · · · + b”, $a+\ldots+b$는 “a + . . . + b”로 정말 다른 문자가 나옵니다. 다만 텍스트 모드에서는 둘 다 \textellipsis로 떨어지므로 본문에서는 고민할 필요가 없습니다.

명령출력언제 쓰는가
\ldots…(아래쪽)본문의 말줄임표. 수식에서는 언제나 낮은 점
\dots문맥 의존amsmath 아래에서는 앞뒤를 보고 높이를 고름. 수식의 기본
\cdots⋯(가운데)a+\cdots+b처럼 연산자 사이에 놓을 때
\vdots⋮(세로)행렬이나 연립식에서 행을 생략할 때
\ddots⋱(대각)행렬의 대각 방향 생략
latex
\usepackage{amsmath}
% ...
He hesitated\ldots{} then went on.
\[
  x_1, x_2, \dots, x_n \qquad a_1 + a_2 + \dots + a_n
\]
\[
  \begin{pmatrix} a & \cdots & b \\ \vdots & \ddots & \vdots \end{pmatrix}
\]

숫자 자릿수 구분은 \, — 1.6663pt로 “1 000” 만들기

\,가는 공백(thin space) 을 넣는 명령으로 폭은 1.6663pt, 곧 1 em의 6분의 1입니다. 1\,000을 재면 21.66142pt, 1000은 19.99512pt로 차이는 정확히 1.6663pt입니다. 자릿수 구분에 쉼표를 쓰느냐 점을 쓰느냐가 나라마다 정반대이므로(영어권의 1,000은 독일어권에서 1.000), 국제 관행은 오래전부터 가는 공백으로 구분할 것을 권해 왔습니다. \,가 바로 그 공백입니다. 단위 앞에도 같은 명령을 써서 5\,\mathrm{kg}처럼 적습니다.

다만 자릿수가 늘어나면 \,를 손으로 뿌리는 일은 수지가 맞지 않습니다. 수치와 단위를 많이 다루는 원고라면 siunitx에 맡겨 \num{1000000}, \qty{5}{\kilogram}처럼 쓰는 편이 자릿수 구분도, 단위 앞 공백도, 음수 부호 처리까지 일관됩니다. \,는 “본문에 우연히 나온 수치 하나”를 위한 도구라고 생각하세요.

일본어는 「、。」인가 「,.」인가 — jsclasses에 전환 옵션은 없다

어느 쪽이 나오는지는 원고에 무엇을 입력하느냐로 정해지며, 클래스 옵션으로는 바꿀 수 없습니다. jsarticle・jsbook을 비롯한 jsclasses에는 구두점을 ,.로 바꾸는 옵션이 없습니다. 콤마・피리어드를 쓰고 싶다면 본문에 ,.를 직접 입력하는 것이 가장 솔직한 방법입니다. 이 방식 자체는 규격표의 양식을 정한 JIS Z 8301이 가로쓰기에서 「,」「.」를 써 온 흐름을 잇는 것으로, 수학서와 이공계 논문에서 지금도 널리 쓰입니다. 한편 2022년(레이와 4년) 문화심의회 건의 「공용문 작성의 사고방식」은 쉼표에는 원칙적으로 「、」를 쓰고, 가로쓰기에서는 사정에 따라 「,」도 쓸 수 있다고 정리했습니다. 투고 규정과 분야의 관습을 따르고, 한 문서 안에서는 반드시 통일할 것 — 판단 기준은 그것뿐입니다.

latex
% comma-period style: just type the marks you want
\documentclass{ltjsarticle}
\begin{document}
本稿では,記法を次のように定める.まず,集合 $A$ を……
\end{document}

일본어 괄호 「」『』() — 어느 것을 언제 쓰는가

대화・인용・어구를 도드라지게 할 때는 낫표 「」, 책이나 작품의 제목과 「」 안쪽의 중첩 인용에는 겹낫표 『』가 기본입니다. 보충과 읽는 법은 전각 ()를 씁니다. 일본어에는 전각 괄호를 쓰고 서양의 반각 ()를 섞지 마세요. 반각 괄호는 앞뒤 공백을 잡는 방식이 달라서, 한 군데만 섞여도 글줄 속에서 눈에 띄게 떠 보입니다. 반대로 서양어(라틴) 인용 안에서는 반각 ( )를 씁니다.

괄호이름주요 용도
「 」낫표대화・인용・어구 강조. 일본어의 일차 인용부호
『 』겹낫표작품명, 그리고 「」 안쪽의 중첩
( )전각 소괄호보충・주기・읽는 법
[ ]전각 대괄호편집자의 보충과 생략 표시
【 】먹구름 괄호제목・항목명을 강하게 드러낼 때
〔 〕거북등 괄호주기와 보충. 대괄호의 대용

한편 일본어 약물이 어떻게 공백을 얻는지 — JFM에 적힌 글자폭, 닫는 괄호가 이어질 때의 조임, \inhibitxspcode, 일본어와 라틴 문자 사이에 자동으로 들어가는 \xkanjiskip, 행두・행말 금칙과 그 벌점 — 는 「일본어 조판의 세부」 페이지가 다룹니다. 여기서 챙길 실무상의 요점은 단순합니다. 약물 앞뒤에 직접 공백을 치지 말 것. 치면 엔진이 마련한 공백과 겹쳐 부자연스럽게 벌어집니다.

제출 전 소스를 검색한다 — 약물의 흔들림을 한 번에 잡기

약물의 어긋남은 컴파일 오류가 되지 않고 PDF 위의 위화감으로만 드러납니다. 그러니 마지막에 한 번 소스를 기계적으로 검색해 잡는 편이 확실합니다. 특히 공동 집필에서는 어떤 장은 \frenchspacing을 전제로 쓰이고, 어떤 장은 e.g. 뒤가 맨 공백으로 남고, 어떤 장은 일본어에 반각 괄호가 섞이는 흔들림이 반드시 생깁니다. 다음 네 가지를 grep으로 훑으세요.

  • 약어 뒤의 맨 공백. e.g., i.e., cf., etc., Fig. 뒤에 이어지는 공백을 찾아 \ 또는 ~로 바꿉니다(\frenchspacing을 쓴다면 불필요합니다).
  • 대문자로 끝나는 문장. 두문자어+. 형태(NASA., USA., DNA.)를 찾아 정말 문장 끝이면 \@를 넣습니다.
  • 말줄임표. 마침표 세 개 ...를 찾아 \ldots로 고칩니다. 수식 안이라면 amsmath\dots에 맡깁니다.
  • 일본어 속 반각 괄호. 일본어 줄에 섞인 ( )를 찾아 전각 ( )로 고칩니다. 겸사겸사 약물 앞뒤에 손으로 친 공백이 없는지도 확인합니다.
terminal
# abbreviation followed by a bare space
grep -nE "(e\.g\.|i\.e\.|cf\.|etc\.|Fig\.) " *.tex

# a sentence that may end on an acronym
grep -nE "[A-Z]{2,}\." *.tex

# three typed periods instead of \ldots
grep -n "\.\.\." *.tex