TeX Live 2024에서 which context를 실행하고, 나온 경로를 ls -l로 들여다보면 context -> luametatex이라고 나옵니다. ConTeXt를 부르는 명령의 정체가 ConTeXt 개발진이 자신들을 위해 만든 엔진 luametatex 그 자체였던 것입니다. 이 한 줄에 ConTeXt라는 기획 전체가 요약되어 있습니다——ConTeXt는 LaTeX에 얹는 패키지가 아니라 LaTeX 대신 쓰는 문서 작성 시스템이며, 게다가 바탕 엔진까지 자체적으로 가지고 있습니다. 이 페이지에서는 \setup... 중심의 문법, MkII / MkIV / LMTX라는 삼대의 계보, 첫 실행이 왜 느린지, 그리고 실제 로그를 읽으며 누가 정말로 ConTeXt를 골라야 하는지를 살펴봅니다.
ConTeXt는 LaTeX의 패키지가 아닙니다
\usepackage{context} 같은 명령은 존재하지 않으며, ConTeXt 문서 안에 \usepackage라고 쓰면 Undefined control sequence로 멈춥니다. LaTeX과 ConTeXt는 같은 TeX을 바탕으로 한 형제 포맷이며 서로의 명령이 전혀 통하지 않습니다. 파일 확장자는 똑같이 .tex지만, 처리하는 것은 pdflatex도 lualatex도 아닌 context 명령입니다. 공동 집필자나 CI가 LaTeX인 줄 알고 돌렸다가 실패하는 사고가 드물지 않으니, README에 “이 문서는 context main.tex로 만든다”는 한 줄을 적어 두면 사고가 줄어듭니다.
$ cat up.tex
\usepackage{amsmath}
\starttext
Hi
\stoptext
$ context up.tex
tex error > tex error on line 1 in file ./up.tex: Undefined control sequence
mtx-context | fatal error: return code: 1ConTeXt를 써 온 사람은 네덜란드의 Hans Hagen과 그의 회사 PRAGMA ADE(Advanced Document Engineering)입니다. 이름은 “TeX으로 쓰는 text”, 곧 con-tex-t에서 왔습니다. 학술적 부산물이 아니라 자사 수주 업무를 위한 제작 도구로 자란 점이 성격을 결정했고, 교육 자료·매뉴얼·카탈로그처럼 “판면을 스스로 설계하는” 일에 맞는 구조가 되었습니다. 오래되었다는 사실은 소스를 열면 보입니다——TeX Live 2024에 든 cont-nl.mkxl의 헤더는 지금도 version=1997.08.19, author=Hans Hagen, copyright={PRAGMA ADE & ConTeXt Development Team} 그대로입니다.
ConTeXt와 LaTeX의 차이——\setup...과 \start…/\stop…
가장 큰 차이는 체재 지정이 모두 하나의 명령족으로 모여 있다는 점입니다. LaTeX에서는 여백은 geometry, 색은 xcolor, 각주 체재는 또 다른 무언가로 패키지마다 문법이 다르지만, ConTeXt에서는 용지가 \setuppapersize, 본문 글꼴이 \setupbodyfont, 문단 여백이 \setupwhitespace——전부 \setup으로 시작하고 전부 key=value를 받습니다. 개수가 많으냐 하면 정말 많아서, TeX Live 2024의 LMTX 소스(tex/context/base/mkxl)를 훑으면 \setup으로 시작하는 명령이 498종 있습니다. 외워야 할 것은 명령 이름이 아니라 작명 규칙이라는 설계입니다.
마크업 쪽도 규칙적입니다. LaTeX이 \begin{env}…\end{env}로 환경을 쓰는 자리에서 ConTeXt는 \start…과 \stop…의 짝을 씁니다. 본문은 \starttext … \stoptext, 절은 \startsection … \stopsection, 별행 수식은 \startformula … \stopformula. 그리고 LaTeX의 \documentclass에 해당하는 필수 선언이 없습니다. 파일 첫머리에 곧바로 \setuppapersize[A4]라고 쓰고 본문으로 들어가면 됩니다. “클래스를 고른 다음 그에 맞는 패키지를 찾는다”는 LaTeX식 사고 순서가 그대로 사라집니다.
% first-context.tex -- compile with: context first-context.tex
\setuppapersize[A4]
\setupbodyfont[12pt]
\starttext
\startsection[title=Introduction]
Hello, \ConTeXt!
\startformula
E = mc^2
\stopformula
\stopsection
\stoptext| LaTeX | ConTeXt | 하고 싶은 일 |
|---|---|---|
\documentclass{article} | (불필요) | 문서 클래스 선언이 필수가 아님. 체재는 \setup...에 둡니다 |
\begin{document} | \starttext | 본문 시작. 끝은 \stoptext |
\section{...} | \startsection[title=...] | 절. 제목만 필요하면 \section도 있습니다 |
\[ ... \] | \startformula … \stopformula | 별행 수식 |
\usepackage{geometry} | \setuppapersize 등 \setup... | 용지·여백·판면. 패키지를 더한다는 발상이 없습니다 |
pdflatex | context | 처리 명령. .tex라도 LaTeX용 명령은 쓸 수 없습니다 |
LMTX란——MkII·MkIV·LMTX 삼대
LMTX가 현행 세대입니다. ConTeXt는 바탕 엔진의 세대에 따라 셋으로 나뉩니다. MkII는 pdfTeX(및 XeTeX) 위에서 도는 가장 오래된 계통, MkIV는 LuaTeX 위에서 도는 Lua 시대의 재작성, LMTX(내부명 MkXL)는 LuaMetaTeX 위에서 도는 현행 계통입니다. TeX Live 2024에서 context --version을 실행하면 context.mkiv와 context.mkxl이 같은 날짜로 함께 보고됩니다——MkIV도 동봉되어 있는 것입니다. 하지만 context 명령 자체가 luametatex으로 가는 심볼릭 링크라서 아무 지정 없이 실행하면 LMTX가 돕니다. 실행 로그의 첫 줄이 그것을 분명히 말합니다: ConTeXt ver: 2024.02.27 09:18 LMTX.
$ ls -l $(which context)
context -> luametatex
$ luametatex --version
This is LuaMetaTeX, Version 2.11.02
Functionality : level 20240226
$ context --version
mtx-context | ConTeXt Process Management 1.06
mtx-context | main context file: .../tex/context/base/mkiv/context.mkiv
mtx-context | current version: 2024.02.27 09:18
mtx-context | main context file: .../tex/context/base/mkxl/context.mkxl
mtx-context | current version: 2024.02.27 09:18핵심은 LuaMetaTeX입니다. Hans Hagen과 ConTeXt 개발진이 LuaTeX의 후계로서 ConTeXt를 위해 다시 만든 경량 엔진이며, 과감한 부분은 더한 것이 아니라 덜어 낸 것입니다. PDF 출력 백엔드, 글꼴 처리, 많은 프리미티브를 LuaTeX에서 의도적으로 제거하고 그것들을 ConTeXt 쪽 Lua 코드로 구현했습니다. 그 결과 외부 라이브러리에 의존하지 않고, 복잡한 빌드 환경도 필요 없으며, 운영체제를 넘어 옮기기 쉬워졌습니다. 실제로 LMTX 실행 로그에는 used backend: pdf라고 나오지만, 그 PDF는 Lua 쪽 구현이 써 내는 것입니다. 여기서 솔직히 적어 둘 것이 하나 있습니다——LuaMetaTeX을 본격적으로 쓰는 것은 현재로서는 사실상 ConTeXt뿐입니다. 범용 엔진이라기보다 ConTeXt의 일부로 보는 편이 실상에 가깝습니다.
옛 세대가 어디에 남아 있는지도 설정 파일을 보면 알 수 있습니다. TeX Live의 fmtutil.cnf에는 cont-en pdftex - -8bit *cont-en.mkii와 cont-en xetex - -8bit *cont-en.mkii 두 줄이 있는데, 이것이 MkII용 포맷 정의입니다. 즉 MkII는 지금도 pdfTeX과 XeTeX 위에서 구울 수 있는 상태로 남아 있습니다. 반면 LMTX는 이 구조를 쓰지 않고, 뒤에 설명하듯 자체 캐시에 포맷을 만듭니다. 새로 시작한다면 망설임 없이 LMTX를 쓰고, MkII와 MkIV는 “옛 문서가 있으니 남아 있는 것”으로 여기면 됩니다.
첫 한 번만 느린 이유——mtxrun --generate와 캐시
ConTeXt는 포맷을 캐시에 스스로 굽기 때문에 첫 회에만 시간이 걸립니다. 실측하면, 깨끗한 상태에서의 1회차는 total runtime: 3.559 seconds, 같은 파일의 2회차는 0.248 seconds——14배 차이입니다. 그 첫 회 동안 캐시에 생성된 것이 약 19 MB의 cont-en.fmt이고, 이후로는 이것을 읽기만 합니다. 그보다 한 단계 앞에는 mtxrun --generate로 만드는 파일 데이터베이스가 있습니다. 이를 해 두지 않은 환경에서 context --version을 치면 언뜻 영문을 알 수 없는 오류가 나옵니다.
# before the file database exists
$ context --version
mtxrun | unknown script 'mtx-context.lua' or 'mtx-mtx-context.lua'
$ mtxrun --generate # builds the file database
mtxrun | elapsed lua time: 3.034 seconds
$ context first.tex # run 1: also dumps ~19 MB cont-en.fmt
system | total runtime: 3.559 seconds
$ context first.tex # run 2: format is cached
system | total runtime: 0.248 seconds이 오류의 정체는 mtx-context.lua가 없다는 뜻이 아니라 파일 목록이 아직 만들어지지 않아 찾지 못한다는 뜻입니다. mtxrun --generate를 한 번 돌리면 해소됩니다. 여기까지 넘기면 ConTeXt에는 LaTeX 사용자를 놀라게 하는 성질이 하나 더 있습니다——상호 참조와 목차를 위해 스스로 여러 번 돕니다. 목차가 있는 문서에 context toc.tex를 한 번만 쳐도 로그에는 --c:currentrun=1과 --c:currentrun=2라는 두 번의 내부 실행이 기록되고, 상한을 나타내는 --c:maxnofruns=9도 보입니다. LaTeX에서 “두 번 돌린다”, “latexmk를 쓴다”고 신경 쓰던 부분이 여기서는 기본 동작입니다. 생성되는 보조 파일의 확장자도 .aux가 아니라 .tuc입니다.
MetaPost가 같은 컴파일 안에서 돕니다
ConTeXt의 간판 기능 중 하나는 작도 언어 MetaPost가 본체에 내장되어 있어 외부 프로그램을 띄우지 않고 그 자리에서 그림을 그린다는 점입니다. 문서 안에 \startMPcode … \stopMPcode라고 쓰기만 하면 컴파일 도중에 그림이 생성됩니다. 로그를 보면 This is MPLIB for LuaMetaTeX, version 3.14, running in double mode와 loading metafun for lmtx가 나란히 나옵니다——MetaPost가 라이브러리 MPlib로 엔진 안에 살고 있다는 증거입니다(MPlib는 Taco Hoekwater와 Hans Hagen이 2007년에 MetaPost를 라이브러리화한 것입니다). MetaPost는 커누스의 METAFONT의 기술 방식을 이어받은 언어라, 선과 곡선을 좌표가 아니라 “제약”으로 쓸 수 있는 것이 특징입니다.
\starttext
\startMPcode
fill fullcircle scaled 3cm withcolor .6red;
draw fullcircle scaled 3cm withpen pencircle scaled 1mm;
\stopMPcode
\stoptext
% one run of `context` produces the PDF; no external MetaPost binary is called이것은 겉보기보다 큰 차이입니다. 그림이 별도 프로세스가 아니라 같은 실행 안에 있으므로 본문의 치수를 그림이 참조할 수 있습니다——판면 폭에 정확히 맞춘 그림, 절 번호에 연동된 장식, 데이터에서 생성하는 괘선과 배경 같은 것을 후처리 없이 쓸 수 있습니다. ConTeXt 사용자가 괘선이나 배경까지 MetaPost로 만드는 이유가 여기에 있습니다. LaTeX에서 TikZ를 쓰는 감각과는 조금 달라서, 여기서 MetaPost는 페이지 요소 자체를 그리는 도구로 쓰입니다.
누가 ConTeXt를 골라야 하는가——솔직한 답
답은 “판면을 스스로 설계할 수 있는 일을 하는 사람”입니다. 교재, 매뉴얼, 카탈로그, 사내 간행물, XML이나 데이터베이스에서 대량으로 생성하는 조판——곧 체재의 결정권이 자신에게 있는 일에서는 설정을 \setup...에 모을 수 있는 ConTeXt의 일체형 설계가 효과를 냅니다. 반대로 투고처가 LaTeX 템플릿을 지정한 논문이나 학위논문에는 맞지 않습니다. 학회 템플릿, revtex 같은 클래스, 공저자의 환경, arXiv의 처리 계통——전부 LaTeX 전제이며, ConTeXt로 옮기는 수고에 걸맞은 대가가 없습니다. 이 선 긋기는 우열의 문제가 아니라 판면의 결정권이 누구에게 있는가의 문제입니다.
- 맞는 일: 소책자, 교재, 카탈로그, 매뉴얼 등 판면을 스스로 설계하는 것. 설정이
\setup...에 모이므로 나중에 판면을 바꿀 때 한 군데만 보면 됩니다. - 맞는 일: XML이나 데이터에서 자동 생성하는 조판. ConTeXt는 XML을 직접 읽어 조판하는 장치를 갖추었고, 처리는 Lua로 쓸 수 있습니다.
- 맞는 일: 그림과 본문을 하나의 소스로 끝내고 싶은 문서. MetaPost가 같은 실행 안에 있어 후처리도, 이미지 파일 관리도 필요 없습니다.
- 맞는 일: 슬라이드. TeX Live 2024에는
s-present-boring,s-present-dark,s-present-punk등 스무 가지가 넘는 발표용 스타일이 동봉되어 있고, 장식은 MetaPost로 만들 수 있습니다. - 맞지 않는 일: 투고처가 LaTeX 클래스를 지정한 논문·학위논문. 템플릿을 따르는 편이 빠르고 안전합니다.
- 맞지 않는 일: 공저자가 LaTeX만 쓰는 원고. ConTeXt에 대한 자료는 LaTeX보다 훨씬 적고, 막혔을 때 물어볼 사람도 제한적입니다.
자료가 모이는 방식도 LaTeX과 다릅니다. LaTeX 지식은 세계 곳곳의 책·Q&A 사이트·패키지 문서에 흩어져 있지만, ConTeXt는 공식 위키 contextgarden과 『ConTeXt: an excursion』 같은 입문서에 비교적 잘 모여 있고, 개발자와 사용자가 얼굴을 맞대는 연례 ConTeXt Meeting이 있습니다. 양은 적지만 중심이 뚜렷하다고 생각하면 크게 어긋나지 않습니다. ConTeXt다운 세부를 하나 더 들자면, 이 처리계는 명령 이름을 모국어로 번역한 인터페이스를 가지고 있습니다. TeX Live 2024의 LMTX 소스에는 영어 외에 체코어·독일어·프랑스어·이탈리아어·네덜란드어·페르시아어·루마니아어·영국 영어의 포맷 정의가 나란히 있습니다. 네덜란드어판 cont-nl이 남아 있는 것은 이 처리계가 어디서 태어났는지를 알리는 기념비 같습니다.
끝으로 실제 시작법입니다. ConTeXt는 TeX Live에 동봉되어 있으니, 우선 손에 있는 TeX Live에서 context first.tex를 치면 충분합니다. 늘 최신을 따라가고 싶다면 ConTeXt 그룹이 자체 배포하는 LMTX 배포판(옛 이름 ConTeXt Standalone)을 쓰는 것이 정석이며, ConTeXt 관련만 가볍게 묶어 자주 갱신됩니다. 쓰기 시작할 때 버릴 만한 습관은 “모자라면 패키지를 찾는다”는 LaTeX식 반사입니다. 먼저 \starttext, \startsection, \startitemize로 뼈대를 만들고, 여백과 글꼴 지정은 첫머리의 \setup...에 모읍니다. 장이 자라면서 설정을 더해 가면 체재가 본문에 흩어지지 않고, 판면을 바꾸고 싶을 때 볼 곳이 딱 한 군데로 남습니다.