TeX은 256자짜리 글꼴을 전제로 설계되었습니다. 한자는 수만 자입니다. 1994년에 시작된 CJK 패키지의 답은 노골적일 만큼 단순했습니다. 글꼴을 256자씩 조각내고, 다음 글자가 속한 조각만 불러오는 것입니다. 오늘 pdfLaTeX으로 중국어 문단을 조판해도 PDF에 박히는 것은 말 그대로 그것입니다. gbsnu4e, gbsnu5b, gbsnu65처럼 Unicode 블록마다 하나씩 들어가는 하위 글꼴입니다. 이 페이지가 다루는 것은 pTeX 세계 바깥의 CJK, 곧 pdfLaTeX의 CJK/CJKutf8, XeLaTeX의 xeCJK, 중국어를 위한 ctex, 한국어를 위한 kotex입니다. 이 경로들은 모두 글꼴에서 먼저 무너지므로, 손대지 않은 TeX Live 2024이 실제로 어떤 CJK 글꼴을 주는지도 함께 밝힙니다.
pdfLaTeX에서 중국어와 한국어 조판 — CJKutf8은 아직 작동합니다
pdfLaTeX에 묶여 있어도 중국어와 한국어는 조판할 수 있습니다. TeX Live 2024에서는 \usepackage{CJKutf8}을 넣고 본문을 CJK* 환경으로 감싸기만 하면 글꼴을 따로 설치하지 않아도 그대로 통과합니다. 실측에서 간체(gbsn), 번체(bsmi), 한국어(mj), 일본어(min) 모두 첫 실행에서 컴파일이 끝났고 PDF에는 Type 1 하위 글꼴이 박혔습니다. 제작자는 Werner Lemberg이고 저작권 표시는 1994–2021년, TeX Live 동봉판은 2021년 10월 16일자 4.8.5입니다. 망가진 것이 아니라 얼어붙은 것이라고 보면 됩니다. 다만 CJK는 미리 TeX용으로 변환된 글꼴만 읽습니다. 운영체제에 설치한 OpenType 글꼴에는 손이 닿지 않습니다. 바로 이 한 가지가 XeLaTeX과의 갈림길입니다.
% pdflatex — simplified Chinese, no extra fonts needed
\documentclass{article}
\usepackage{CJKutf8}
\begin{document}
\begin{CJK*}{UTF8}{gbsn}
这是一段中文,混排 English words 也没问题。
\CJKfamily{gkai}换成楷体。
\end{CJK*}
\end{document}환경의 첫 인자는 인코딩, 둘째 인자는 글꼴 패밀리이며, 여기에 무엇을 쓸 수 있는지는 미리 변환된 글꼴이 무엇이 있느냐로 결정됩니다. TeX Live 2024에서 손대지 않고 통과한 것은 아래 표의 여덟 가지입니다. song만 Font cyberb30 at 600 not found로 실패했는데, 따로 구해야 하는 Cyberbit 글꼴을 전제하기 때문입니다. 또 하나 누구나 한 번은 겪는 사고가 한자를 환경 밖에 쓰는 것입니다. 그러면 ! LaTeX Error: Unicode character 日 (U+65E5) not set up for use with LaTeX.가 나오고, 글자 하나마다 오류가 하나씩 생깁니다. 문단 하나를 통째로 바깥에 두면 수십 개가 쏟아지므로, 개수가 아니라 첫 오류를 보아야 합니다.
| 패밀리 | 언어 | 실제 글꼴 | TeX Live 2024 |
|---|---|---|---|
gbsn | 간체 중국어 | Arphic GB 송체(arphic) | 동봉, 그대로 컴파일 |
gkai | 간체 중국어 | Arphic GB 해서(arphic) | 동봉, 그대로 컴파일 |
bsmi | 번체 중국어 | Arphic Big5 명조(arphic) | 동봉, 그대로 컴파일 |
bkai | 번체 중국어 | Arphic Big5 해서(arphic) | 동봉, 그대로 컴파일 |
mj | 한국어 | UHC 명조(uhc) | 동봉. kotex 쪽이 더 낫습니다 |
min | 일본어 | Wadalab 명조(wadalab) | 동봉. upLaTeX 쪽이 더 낫습니다 |
goth | 일본어 | Wadalab 고딕(wadalab) | 동봉, 그대로 컴파일 |
maru | 일본어 | Wadalab 둥근 고딕(wadalab) | 동봉, 그대로 컴파일 |
song | 중국어 | Cyberbit(별도 입수) | Font cyberb30 at 600 not found로 실패 |
CJK와 CJK*의 차이는 장식이 아니라 실제 피해의 유무입니다. CJK.sty의 주석이 그대로 말합니다. CJK*는 CJK 문자 뒤의 공백을 삼키지만 CJK는 삼키지 않습니다. 실제 원고에서는 중국어 문장을 소스에서 줄바꿈하기 마련이고, 그 줄바꿈은 TeX에게 공백 하나입니다. CJK 환경에서는 汉字之间不应该 出现空格。처럼 문장 한가운데에 틈이 남았고, CJK* 환경에서는 汉字之间不应该出现空格。으로 올바르게 붙었습니다. 중국어와 일본어라면 CJK*가 기본 선택입니다. 같은 이유로 \begin{CJK*}{UTF8}{gbsn} 바로 뒤에서는 반드시 줄을 바꿔야 합니다. 같은 줄에 남은 글자는 CJK 의미가 적용되기 전에 읽혀 버립니다. 도중에 글꼴을 바꾸려면 \CJKfamily{gkai}를 쓰면 되고, 환경을 중첩할 필요는 없습니다.
일본어를 pdfLaTeX으로 조판해야만 한다면, CJK 위에 얹히는 bxcjkjatype(ZR 제작, TeX Live 2024 동봉판은 2023년 7월 23일자 v0.5)이 훨씬 편합니다. \usepackage[whole]{bxcjkjatype}이라고 쓰면 문서 전체가 자동으로 감싸이므로 CJK* 환경을 직접 쓸 일이 없고, 줄바꿈으로 생기는 공백과 일본어·라틴 문자 사이의 간격도 알아서 처리합니다. 실측에서도 올바르게 붙었고, 박힌 것은 IPAex 명조를 Type 1으로 변환한 ipaex-type1이었습니다. 다만 이것은 pdfLaTeX에 묶였을 때의 우회책일 뿐입니다. 엔진을 고를 수 있다면 이어지는 절을 보십시오.
XeLaTeX에서 CJK — xeCJK 글꼴 설정이 어긋나는 지점
xeCJK은 XeLaTeX 전용이고, 컴파일이 되느냐 죽느냐는 글꼴 이름을 어떻게 적느냐에서 갈립니다. 아무 설정 없이 \usepackage{xeCJK}만 써도 실측에서는 오류 하나 없이 PDF가 나옵니다. 기본값으로 Fandol Song이 실리기 때문입니다. 그런데 Fandol Song은 중국어 글꼴입니다. 같은 문서에 한국어를 섞으면 로그에 Missing character: There is no 한 (U+D55C) in font [FandolSong-Regular.otf]가 줄줄이 찍히고, 종료 코드는 0인 채로 한글만 PDF에서 사라집니다. 텍스트를 추출해 확인해 보니 한국어 문장은 아예 존재하지 않았습니다. 여러 문자 체계가 섞인 문서에서 xeCJK을 쓸 생각이라면 문자 체계마다 글꼴을 지정하는 일은 선택이 아닙니다.
% xelatex — one font per script; file names, not family names
\documentclass{article}
\usepackage{xeCJK}
\setCJKmainfont{FandolSong-Regular.otf}[
BoldFont = FandolSong-Bold.otf,
ItalicFont = FandolKai-Regular.otf]
\setCJKsansfont{FandolHei-Regular.otf}
\newCJKfontfamily\korean{UnBatang.ttf}
\begin{document}
这是一段中文。{\korean 한국어 문장입니다.}
\end{document}여기서 발목을 잡는 것은 XeTeX이 글꼴을 운영체제에 묻는다는 성질입니다. \setCJKmainfont{FandolSong-Regular.otf}는 파일 이름이라 TeX 트리에서 해결되어 통합니다. 같은 글꼴을 패밀리 이름으로 \setCJKmainfont{Fandol Song}이라고 쓰면 ! Package fontspec Error: The font "Fandol Song" cannot be found.로 죽습니다. TeX Live에 들어 있는데도 그렇습니다. 반대로 운영체제가 아는 글꼴, 즉 macOS의 Songti SC, PingFang SC, Hiragino Sans는 패밀리 이름으로 문제없이 통했습니다. 여기저기 복사되는 \setCJKmainfont{Noto Sans CJK SC}도 마찬가지로 실패합니다. Noto CJK는 TeX Live에 동봉되어 있지 않기 때문에, 직접 설치하지 않았다면 The font "Noto Sans CJK SC" cannot be found.가 나옵니다. 원칙은 간단합니다. TeX 트리의 글꼴은 확장자까지 붙인 파일 이름으로, 운영체제의 글꼴은 패밀리 이름으로 지정합니다. 이 동작 자체는 XeTeX 페이지에서 자세히 다룹니다.
글꼴이 정리되면 다음은 간격입니다. xeCJK은 \xeCJKsetup{...}으로 글자 사이 간격을 노출합니다. CJKglue는 CJK 글자끼리의 간격, CJKecglue는 CJK와 라틴 문자 사이의 간격입니다. TeX Live 2024의 기본값은 CJKglue가 0pt plus 0.08\baselineskip, CJKecglue가 ~입니다. 즉 한자와 영어 단어 사이에는 보통의 낱말 간격이 하나 들어갑니다. pTeX을 아는 독자에게는 \kanjiskip・\xkanjiskip과 같은 발상이되 기본값이 다르다고 하면 됩니다. 그쪽은 일본어 조판 세부 페이지가 맡습니다. 구두점 압축은 PunctStyle, 구두점 사이의 줄바꿈 허용은 AllowBreakBetweenPuncts로 바꿉니다. 참고로 LuaLaTeX에서 xeCJK을 불러오면 ! Critical Package xeCJK Error: The xeCJK package requires XeTeX to function.으로 멈춥니다. 이름은 장식이 아닙니다.
중국어라면 ctex — 사용법과 fontset의 함정
중국어 문서라면 xeCJK을 직접 손보는 것보다 ctex을 쓰는 편이 빠릅니다. \documentclass{ctexart}(ctexrep, ctexbook, ctexbeamer도 있습니다)를 쓰거나 기존 클래스에 \usepackage[UTF8]{ctex}를 얹으면 서체, 행간, 중국어식 표제 체재, 구두점 압축, 한자 숫자 장 번호까지 한 번에 맞춰 줍니다. ctex은 엔진을 자동으로 판별하는데, 방식은 소박합니다. ctex-engine-<엔진>.def라는 파일이 있는지 볼 뿐입니다. 지원 대상은 xelatex, lualatex, pdflatex, uplatex, aplatex이고, 그 밖이면 Engine '...' is not yet supported, ctex will abort!로 멈춥니다. TeX Live 2024 동봉판은 2.5.10입니다.
% xelatex or lualatex — fandol is the only fontset TeX Live guarantees
\documentclass[fontset=fandol]{ctexart}
\begin{document}
\section{中文标题}
这是一段中文,混排 English words。今天是\today。
\end{document}문제는 엔진이 아니라 글꼴 세트입니다. ctex은 운영체제도 판별하려 듭니다. Windows면 windows, macOS면 mac, 나머지는 fandol입니다. macOS 판정 방식이 재미있는데, /System/Library/Fonts/Menlo.ttc라는 파일이 있는지를 봅니다. 조판 패키지가 프로그래머용 고정폭 글꼴의 유무로 운영체제를 알아맞히는 셈입니다. 추측이 맞는 동안은 쾌적하지만, 빗나가면 요란하게 무너집니다. 실측에서 fontset 없이 ctexart을 돌렸을 때 XeLaTeX은 통했지만 LuaLaTeX은 ! Package fontspec Error: The font "STHeiti" cannot be found.로 죽었고, pdfLaTeX은 ! Critical Class ctexart Error: CTeX fontset 'mac' is unavailable in current mode.로 죽었습니다. 결론은 하나입니다. fontset=은 반드시 직접 쓰십시오. TeX Live에 반드시 들어 있는 중국어 글꼴은 Fandol뿐이므로, 남에게 보낼 문서라면 fontset=fandol이 안전합니다. 그래도 pdfLaTeX에서는 CTeX fontset 'fandol' is unavailable in current mode.가 나옵니다. fandol은 Unicode 엔진 전용이기 때문입니다. pdfLaTeX의 ctex은 내부에서 CJKutf8과 CJKpunct/CJKspace를 불러오며 Windows 글꼴을 전제합니다. 중국어를 pdfLaTeX으로 조판해야 한다면 ctex과 씨름하기보다 CJKutf8의 gbsn으로 내려오는 편이 현실적입니다.
한국어는 kotex — 한 줄이면 어느 엔진에서나 통합니다
한국어는 \usepackage{kotex} 한 줄이면 pdfLaTeX, XeLaTeX, LuaLaTeX 어디서나 통합니다. CJK 세 언어 가운데 가장 순한 상황이며, kotex.sty를 열어 보면 이유를 알 수 있습니다. 이 파일은 패키지라기보다 분배기입니다. \directlua와 \XeTeXrevision의 유무를 보고 속이 완전히 다른 세 패키지 중 하나를 불러옵니다. pdfTeX이면 kotexutf(cjk-ko), XeTeX이면 xetexko, LuaTeX이면 luatexko입니다. 옵션도 그대로 하위로 넘어가므로 쓰는 쪽은 어느 경로인지 신경 쓸 필요가 없습니다. 글꼴도 실제로 동봉되어 있습니다. 실측에서 pdfLaTeX 경로는 나눔명조 Type 1 하위 글꼴(nanumtype1)을, XeLaTeX 경로는 UnBatang(unfonts-core)을 넣었고, 둘 다 텍스트 추출이 올바르게 되었습니다.
% pdflatex, xelatex or lualatex — all three work unchanged
\documentclass{article}
\usepackage[hangul]{kotex}
\begin{document}
\section{한국어 시험}
오늘은 \today 입니다.
\end{document}[hangul]을 붙이면 문서 문자열과 날짜도 한국어가 됩니다. 실측에서 \today는 2026년 8월 13일, 그림 표제는 그림 1:로 바뀌었습니다(이 옵션이 없으면 August 13, 2026 그대로입니다). 글꼴을 바꿀 때는 XeLaTeX의 이름 해결 버릇이 다시 물어뜯습니다. \setmainhangulfont{UnBatang}은 ! Package fontspec Error: The font "UnBatang" cannot be found.로 죽었고, \setmainhangulfont{UnBatang.ttf}는 통했습니다. UnBatang.ttf는 TeX 트리 안에 있는데도 패밀리 이름으로는 찾지 못합니다. xetexko를 직접 불러올 수도 있지만, kotex을 거치면 원고가 특정 엔진을 못 박지 않으므로 공동 집필이나 투고에서 다루기가 편합니다.
TeX Live에 실제로 들어 있는 CJK 글꼴
TeX Live 2024의 글꼴 트리에는 Noto CJK가 전혀 없습니다. NotoSansCJK나 NotoSerifCJK라는 이름의 파일은 하나도 없고, TeX Live의 noto 패키지가 실제로 제공하는 것은 NotoSerif, NotoSans, NotoSansMono, 곧 라틴 계열입니다. 웹에서 보이는 \setCJKmainfont{Noto Sans CJK SC}가 도는 것은 그 글을 쓴 사람이 운영체제에 Noto CJK를 깔아 두었기 때문일 뿐입니다. 배포할 문서나 컨테이너 이미지에 그 줄을 넣으면 남의 환경에서는 반드시 실패합니다. 진짜로 동봉된 것은 아래 표와 같고, 중국어 쪽이 얼마나 얇은지 드러납니다. OpenType는 Fandol 한 가족뿐이고, 나머지는 CJK 패키지용으로 미리 변환된 Arphic입니다. 일본어(Harano Aji, IPAex)와 한국어(Un 글꼴, Baekmuk, Nanum)는 선택지가 제법 남아 있습니다.
| TeX Live 패키지 | 언어 | 형식 | 쓰이는 경로 |
|---|---|---|---|
fandol | 중국어 | OpenType | xeCJK 기본값, ctex의 fontset=fandol |
arphic | 중국어 | Type 1 하위 글꼴 | CJKutf8의 gbsn/gkai/bsmi/bkai |
arphic-ttf | 중국어 | TrueType | Unicode 엔진에서 파일 이름으로 지정 |
haranoaji | 일본어 | OpenType | LuaTeX-ja, zxjatype 등의 기본값 |
ipaex | 일본어 | TrueType | Unicode 엔진에서 파일 이름으로 지정 |
wadalab | 일본어 | Type 1 하위 글꼴 | CJKutf8의 min/goth/maru |
unfonts-core | 한국어 | TrueType | xetexko/luatexko의 기본값 |
nanumtype1 | 한국어 | Type 1 하위 글꼴 | pdfLaTeX의 kotex(cjk-ko) |
uhc | 한국어 | Type 1 하위 글꼴 | CJKutf8의 mj |
어느 경로를 고를까
엔진을 마음대로 고를 수 있다면 중국어는 ctex + XeLaTeX/LuaLaTeX, 한국어는 kotex, 일본어는 upLaTeX 또는 LuaTeX-ja가 기본 답입니다. CJK/CJKutf8로 내려가는 것은 클래스나 템플릿이 pdfLaTeX을 못 박을 때뿐이며, 대개 학회 투고 규정이 그렇습니다. 일본어만 셈이 다릅니다. 금칙, JFM, 루비, 세로쓰기가 얽히기 시작하면 xeCJK은 pTeX 계열과 LuaTeX-ja가 쌓아 온 것에 미치지 못합니다. 일본어 경로 비교는 “일본어 조판 방법” 페이지가, 미세한 간격 조정은 “일본어 조판 세부 사항” 페이지가 맡습니다. 언어를 넘나드는 문서, 이를테면 독일어 본문에 중국어 인용을 끼우는 경우는 babel, polyglossia와 글꼴 전환의 이야기가 되므로 “다국어” 페이지가 본체입니다.
- 중국어 → XeLaTeX 또는 LuaLaTeX에서
\documentclass[fontset=fandol]{ctexart}.fontset은 반드시 명시합니다. - 한국어 →
\usepackage{kotex}, 엔진은 가리지 않습니다. 문서 문자열까지 한국어로 하려면[hangul]. - pdfLaTeX을 벗어날 수 없을 때 →
CJKutf8+CJK*환경. 중국어는gbsn/bsmi, 한국어는kotex(내부에서 cjk-ko로 내려갑니다). - XeLaTeX에서 여러 문자 체계 혼용 →
xeCJK에 문자 체계마다\newCJKfontfamily하나씩. 설정하지 않으면 없는 글자가 조용히 사라집니다. - 일본어 → 이 페이지의 범위 밖입니다. upLaTeX이나 LuaTeX-ja를 고르십시오.