TeX/LaTeX와 일본어

일본어를 LaTeX으로 쓰기 시작하면 대개 platexuplatex라는 명령을 치라는 안내를 받습니다. 그런데 그 이름의 실행 파일은 어디에도 없습니다. 둘 다 euptex라는 하나의 엔진이 읽어 들이는 포맷의 이름이고, platex를 친 순간 화면에 뜨는 것은 “This is e-upTeX”이라는 한 줄입니다. 이 한 가지를 삼키고 나면 일본어 TeX의 알기 어려움은 절반쯤 사라집니다. 이 페이지에서는 애초에 일본어에 왜 전용 장치가 필요했는지, 지금 살아 있는 세 갈래(pLaTeX/upLaTeX + dvipdfmx, LuaLaTeX + LuaTeX-ja, XeLaTeX)가 무엇이 어떻게 다른지, 그리고 첫 문서를 어느 쪽으로 시작해야 하는지를 정리합니다.

일본어에 전용 엔진이 필요했던 이유

첫째 이유는 단순합니다. 원래의 TeX은 글꼴 하나당 256자밖에 다루지 못했습니다(초기에는 128자). 수천 자의 상용한자, 나아가 수만 자의 JIS 한자를 담으려면 글꼴을 256자씩 하위 글꼴로 잘라 쓰는 식의 세공이 필요했습니다. 둘째 이유는 뿌리가 더 깊습니다. 조판 규칙 자체가 다릅니다. 서구식 조판은 “단어 사이에서 줄을 바꾸고 단어 간 공백을 늘였다 줄인다”는 전제 위에 서 있지만, 일본어에는 단어의 경계가 없습니다. 어디서든 줄을 바꿔도 되는 대신, 줄을 바꾸면 안 되는 자리를 규칙으로 알려 주어야 합니다.

이 “해서는 안 되는 자리”의 규칙이 금칙 처리입니다. 구두점·닫는 괄호·장음 부호·작은 가나는 행 첫머리에 두지 않고, 여는 괄호는 행 끝에 두지 않는다는 약속을 지키게 합니다. 여기에 더해 일본어와 서구 문자가 이웃할 때 넣는 사분 공백(\xkanjiskip), 일본어 문자끼리의 간격(\kanjiskip), 약물의 조임, 그리고 세로쓰기가 있습니다. pTeX 계열 엔진은 이 모두를, 줄을 나눌 후보마다 “이 글자가 행 첫머리에 오면 몇 점”이라는 벌점을 매기고 문단 전체에서 벌점 합이 가장 작아지는 나눔을 고르는 방식으로 풉니다. TeX이 본래 갖고 있던 “문단 전체를 훑어 최적의 줄 나눔을 고른다”는 설계에, 일본어 규칙을 벌점으로 흘려 넣은 것입니다.

platexuplatex의 차이, 그리고 둘이 같은 엔진이라는 이야기

차이는 다룰 수 있는 문자의 범위입니다. platex는 JIS X 0208 안에 머물고, uplatex는 유니코드 전역을 다룹니다. 그리고 둘은 별개의 프로그램이 아니라 같은 euptex 엔진이 읽어 들이는 서로 다른 포맷입니다. TeX Live의 texmf-dist/web2c/fmtutil.cnf를 열면 이 관계가 두 줄로 그대로 적혀 있습니다. 첫째 열이 포맷 이름, 둘째 열이 그것을 만드는 엔진인데, 두 줄 모두 둘째 열은 euptex입니다. “엔진과 포맷은 다른 것”이라는 이야기가 일본어에서 가장 또렷하게 드러나는 대목입니다.

fmtutil.cnf
# texmf-dist/web2c/fmtutil.cnf -- format, engine, hyphenation, ini file
platex   euptex language.dat *platex.ini
uplatex  euptex language.dat *uplatex.ini

# and so the banner names the engine, not the command you typed:
$ platex  ... This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-... (utf8.euc)   (preloaded format=platex)
$ uplatex ... This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-... (utf8.uptex) (preloaded format=uplatex)

이 배너는 읽을 거리가 많습니다. 3.141592653은 커누스가 동결한 TeX의 판 번호 그 자체이고, p4.1.1은 pTeX 확장의 판, u1.30은 upTeX 확장의 판입니다. 세 세대의 이력이 한 줄에 포개져 있습니다. 끝의 괄호도 볼거리입니다. platex(utf8.euc), uplatex(utf8.uptex). 원고는 어느 쪽이든 UTF-8로 쓰지만, 엔진 내부에서 한자를 담는 부호가 다릅니다. 이는 추상적인 이야기가 아니라 그대로 피해로 나타납니다. platex에 JIS X 0208 바깥의 글자, 이를테면 髙·𠮷·鷗를 먹이면 다음 오류에서 멈춥니다.

log
! LaTeX Error: Unicode character ^^e9^^ab^^99 (U+9AD9)
               not set up for use with LaTeX.

# same file, same class, run through uplatex instead: compiles silently.

실무적 결론은 단순합니다. 새로 pLaTeX으로 쓰기 시작할 이유는 거의 없습니다. uplatex을 쓰세요. 인명의 이체자, 구자체, 보조 한자, 한국어나 중국어 인용문 — 어느 것도 희귀하지 않은데, 하나같이 platex을 그 자리에서 멈춰 세웁니다. platex을 고를 이유로 남는 것은 투고처의 클래스 파일이 pLaTeX 전용으로 쓰인 경우와 기존 원고를 이어받는 경우뿐입니다. 참고로 pTeX 계열의 엔진과 매크로는 현재 일본어 TeX 개발 커뮤니티가 유지보수하고 있습니다.

지금 살아 있는 세 갈래 경로

실제로 쓸 수 있는 길은 세 갈래입니다. upLaTeX으로 DVI를 만들고 dvipdfmx가 이를 PDF로 바꾸는 전통적 경로, LuaLaTeX에 luatexja를 얹어 PDF를 곧바로 내보내는 경로, 그리고 XeLaTeX에 xeCJK를 얹는 경로입니다. 네 번째로 pdfLaTeX + CJKutf8도 있지만, 본문을 \begin{CJK}{UTF8}{min}으로 감싸야 하고 금칙도 본격적이지 않아, 영어 논문에 일본어 몇 마디를 끼워 넣는 용도에나 맞습니다. 세 갈래를 가르는 것은 글꼴에 닿는 방식과 PDF까지 가는 길의 길이입니다.

경로클래스와 패키지성격과 적합한 용도
uplatex + dvipdfmxjlreq, jsarticle(jsclasses)빠름. 세로쓰기 실적이 가장 두텁고 학회에서 자주 지정. PDF까지 두 단계
lualatex + luatexjajlreq, ltjsarticle(ltjsclasses)OS의 OpenType 글꼴을 그대로 쓰고 PDF를 곧바로 출력. 유니코드에 가장 강함. 빌드는 느림
xelatex + xeCJKbxjsarticle(bxjscls) 등글꼴 지정이 간편. 중국어·한국어 혼식에 강함. 세밀한 일본어 규칙은 luatexja보다 약함
pdflatex + CJKutf8article + CJK 패키지영문 속 몇 단어만. 본문을 \begin{CJK}{UTF8}{min}으로 감싸야 하며 문서 전체에는 부적합

왜 일본어 경로만 DVI를 거치는가

pTeX 계열 엔진이 PDF를 직접 써 내지 못하기 때문입니다. pdfTeX이 PDF 출력을 내장한 것과 달리, pTeX은 TeX 본래의 출력 형식인 DVI를 뱉는 데서 일을 마칩니다. 그 DVI를 PDF로 바꾸는 것이 dvipdfmx이며, 일본어 글꼴 임베딩과 세로쓰기 좌표 변환을 떠맡습니다. 곧 일본어의 전통적 경로는 “조판”과 “PDF 생성”을 둘이 나눠 맡는 구성입니다. 로컬에서 uplatex을 거쳐 dvipdfmx에 걸면 수백 바이트의 .dvi가 수 킬로바이트의 PDF가 되고, pdffonts로 들여다보면 HaranoAjiMincho가 CID Type 0C로 임베드되어 있는 것이 보입니다.

shell
$ uplatex doc.tex      # typeset -> doc.dvi
$ dvipdfmx doc.dvi     # convert  -> doc.pdf
$ pdffonts doc.pdf
# HaranoAjiMincho-Regular   CID Type 0C   Identity-H   emb yes

# dvipdfmx is a symlink to xdvipdfmx: one binary serves both
# the Japanese .dvi route and XeTeX's .xdv output.

덧붙이면 디스크 위의 dvipdfmx는 사실 xdvipdfmx로의 심볼릭 링크입니다. 하나의 바이너리가 일본어의 .dvi와 XeTeX이 내놓는 .xdv를 모두 돌봅니다. 일본어를 위해 다듬인 변환기가 그대로 전 세계 XeTeX의 출력단이 된 셈으로, 일본에서 만든 도구가 TeX 본류에 편입된 예입니다. 임베드되는 하라노아지(Harano Aji) 글꼴도 마찬가지로 TeX Live에 기본으로 들어 있어, 글꼴을 따로 사지 않아도 첫 일본어 PDF가 나옵니다.

첫 문서는 어느 쪽으로 시작할 것인가

\documentclass{jlreq}이라고 쓰고 lualatex으로 돌리세요. 이유는 품질만이 아닙니다. 아베 노리유키가 만든 jlreq는 W3C의 「일본어 조판 처리 요건(JLReq)」에 따라 설계된 클래스이지만, 실무에서 가장 고마운 점은 같은 소스가 LuaLaTeX에서도 upLaTeX에서도 pLaTeX에서도 그대로 돌아간다는 것입니다. 엔진은 자동으로 판별되고, 필요하면 platex·uplatex·lualatex을 클래스 옵션으로 명시할 수도 있습니다. 곧 첫 선택이 되돌릴 수 없는 결단이 되지 않습니다. 실제로 같은 .texuplatexlualatex 양쪽에 걸어도, 어느 쪽이나 하라노아지 명조를 임베드한 PDF가 나옵니다.

latex
% runs unchanged under lualatex, uplatex and platex
\documentclass{jlreq}
\begin{document}
こんにちは、\LaTeX。日本語の組版です。
\end{document}

글꼴을 바꾸고 싶다면 LuaLaTeX에서 luatexja-fontspec를 읽어 들이고, \setmainjfont로 명조를, \setsansjfont로 고딕을 지정합니다. 전통적인 계열로 기울 경우에는 pLaTeX·upLaTeX용 jsclasses(jsarticle, jsbook)와 LuaLaTeX 전용 ltjsclasses(ltjsarticle 등)가 정석입니다. 다만 ltjsarticle을 골랐다면 컴파일러도 LuaLaTeX으로 맞추어야 합니다. 클래스와 엔진의 어긋남은 일본어 환경에서 가장 흔한 사고입니다.

처음에 걸려 넘어지는 곳

일본어가 나오지 않거나 깨질 때의 원인은 거의 원고의 문자 인코딩이거나 클래스와 엔진의 불일치 둘 중 하나입니다. 문자 인코딩은 UTF-8로 저장하세요. 한때는 EUC-JP·Shift_JIS·ISO-2022-JP가 공존해 nkf 같은 변환 도구가 필수품이었지만 지금은 그럴 필요가 없습니다. upTeX과 LuaTeX은 유니코드 네이티브이고, 현행 pLaTeX도 UTF-8 입력을 전제로 합니다. 변환이 필요한 것은 옛 원고를 이어받을 때뿐입니다. 또 하나의 함정은 줄바꿈 코드로, LF와 CRLF가 한 파일에 섞이면 원인을 짚기 어려운 형태로 무너질 수 있습니다.

  • pdflatex으로 일본어 본문을 조판하지 마세요. 오류나 깨짐이 보이면 먼저 컴파일러 설정을 의심합니다. CJKutf8을 쓰더라도 본문을 \begin{CJK}{UTF8}{min}으로 감싸야 합니다.
  • ltjsarticle이나 luatexja를 읽어 들인다면 lualatex으로, jsarticle이라면 uplatex으로 컴파일합니다. 클래스가 엔진을 정하므로 편집기의 빌드 설정도 함께 바꿉니다.
  • platex에서 ! LaTeX Error: Unicode character ... not set up for use with LaTeX.가 나오면 그 글자는 JIS X 0208 바깥입니다. uplatex으로 바꾸면 대개 해결됩니다.
  • 공저 작업에서는 엔진 이름·문자 인코딩·클래스 이름 세 가지를 README 한 줄에 적어 둡니다. 셋이 갖춰지지 않으면 상대의 환경에서 재현되지 않습니다.
  • 투고처가 platex 전용으로 쓰인 클래스 파일을 배포한다면 그대로 따릅니다. 다만 제출 전에 본문에 이체자가 섞여 들지 않았는지 확인하세요.