Familia pTeX

El directorio bin de TeX Live 2024 alinea seis órdenes — ptex, uptex, eptex, euptex, platex, uplatex — y ls -l revela que las seis son enlaces simbólicos a un único ejecutable llamado euptex. La familia de motores LaTeX construidos para el japonés — pTeX, upTeX, e-pTeX, e-upTeX — confluyó en una sola implementación a lo largo de un cuarto de siglo. Esta página sigue esa confluencia leyendo las banderas de arranque, los registros y los valores realmente medidos. El oficio de la composición vertical y de las reglas de corte pertenece a otras páginas; lo que aquí se trata es el motor mismo.

Seis órdenes, un solo ejecutable

No existe ningún ejecutable llamado platex. En TeX Live 2024, platex es un enlace simbólico a euptex, igual que ptex, uptex, eptex y uplatex. Lo que cambia es el formato que carga cada uno. Un programa de la familia TeX mira con qué nombre se le ha invocado y carga el archivo de formato (.fmt) de ese nombre. La correspondencia vive en fmtutil.cnf, donde dos líneas van seguidas: platex euptex language.dat *platex.ini y uplatex euptex language.dat *uplatex.ini. La segunda columna indica el motor y la cuarta el archivo ini con el que se graba ese formato. Dicho de otro modo, pLaTeX y upLaTeX son dos formatos distintos montados sobre un único motor, e-upTeX.

terminal
$ ls -l /usr/local/texlive/2024/bin/universal-darwin/ | grep -E "ptex|platex"
lrwxr-xr-x  platex   -> euptex
lrwxr-xr-x  ptex     -> euptex
lrwxr-xr-x  uplatex  -> euptex
lrwxr-xr-x  uptex    -> euptex
lrwxr-xr-x  eptex    -> euptex
-rwxr-xr-x  euptex          # the only real binary

$ grep -E "^(platex|uplatex|ptex|uptex|eptex) " texmf-dist/web2c/fmtutil.cnf
platex  euptex language.dat *platex.ini
eptex   euptex language.def *eptex.ini
ptex    euptex -            ptex.ini
uplatex euptex language.dat *uplatex.ini
uptex   euptex -            uptex.ini

Ejecute las seis y quédese solo con la primera línea: la estructura se muestra sola. El cuerpo de la bandera es idéntico cada vez — This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (TeX Live 2024) — y solo cambia el paréntesis: el lado platex imprime (utf8.euc) y el lado uplatex, (utf8.uptex). Ese paréntesis nombra la codificación japonesa interna y es la única pista externa que separa la línea pTeX de la línea upTeX. Suele preguntarse por qué al ejecutar platex aparece «e-upTeX»; nada falla — así se ve una instalación sana.

terminal
$ for c in ptex uptex eptex euptex platex uplatex; do
>   printf "%s: " $c; echo "\\end" | $c | head -1
> done
ptex:    This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (utf8.euc)   (TeX Live 2024) (preloaded format=ptex)
uptex:   This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (utf8.uptex) (TeX Live 2024) (preloaded format=uptex)
eptex:   This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (utf8.euc)   (TeX Live 2024) (preloaded format=eptex)
platex:  This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (utf8.euc)   (TeX Live 2024) (preloaded format=platex)
uplatex: This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (utf8.uptex) (TeX Live 2024) (preloaded format=uplatex)

Esa larga tira de cifras no es un número de versión sino cuatro linajes distintos empalmados. El 3.141592653 inicial es el TeX desnudo, p4.1.1 es pTeX, u1.30 es upTeX, 230214 es e-pTeX (una fecha) y el 2.6 final es e-TeX. No es conjetura: el motor expone cada uno como primitiva, de modo que pueden leerse desde el documento con \the\ptexversion y sus parientes. Una vez que se sabe leer esa línea, la pregunta qué es e-pTeX tiene respuesta concreta: es pTeX con las extensiones e-TeX fusionadas, y el e-upTeX que aquí corre añade además upTeX encima — cuatro capas.

latex
% read the version primitives back out of the running engine
\typeout{PTEX=\the\ptexversion.\the\ptexminorversion\ptexrevision}
\typeout{UPTEX=\the\uptexversion\uptexrevision}
\typeout{EPTEX=\the\epTeXversion}
\typeout{ETEX=\the\eTeXversion\eTeXrevision}
%  PTEX=4.1.1   UPTEX=1.30   EPTEX=230214   ETEX=2.6
Fragmento de la banderaDe dónde vieneCómo leerlo
3.141592653el TeX desnudo de Knuthsolo en la bandera, sin primitiva
p4.1.1pTeX — las extensiones japonesas de ASCII\ptexversion, \ptexminorversion, \ptexrevision
u1.30upTeX — la refundición Unicode\uptexversion, \uptexrevision
230214e-pTeX — una fecha usada como versión\epTeXversion
2.6las extensiones e-TeX\eTeXversion, \eTeXrevision

Lo que pTeX incrustó en el motor: dirección de escritura y JFM

Dos cosas obligaron a que pTeX fuera una modificación del motor y no un paquete de macros: la dirección de escritura (\tate y \yoko) y JFM, la métrica de fuente japonesa. Se desarrolló en ASCII Corporation — la editorial japonesa conocida por sus revistas de informática y videojuegos — y la p viene de publishing: el objetivo era un TeX japonés apto para la imprenta comercial. La dirección de escritura suena a mera cuestión de hacia dónde corren los caracteres, pero dentro de TeX es un suceso en el que el significado de las dimensiones de una caja se intercambia. Mídalo y los números lo dicen sin rodeos.

Meta los mismos tres kana en una \hbox y compare sus dimensiones en modo horizontal y vertical. En horizontal la altura es 8.46753pt y la profundidad 1.15465pt — la silueta asimétrica de algo apoyado en una línea de base, igual que en la tipografía latina. En vertical, altura y profundidad valen ambas 4.8111pt: exactamente la mitad del cuadratín de 9.6222pt, repartido por igual. En composición vertical el carácter no descansa sobre ninguna línea de base; cabalga sobre el eje central de la columna. Conmutar esa interpretación de las dimensiones dentro del motor es el núcleo de pTeX, y justamente lo que ningún paquete de macros puede imitar.

latex
\documentclass{utarticle}   % ut... = upLaTeX, vertical writing
\begin{document}
\setbox0=\hbox{あいう}
\typeout{TATE w=\the\wd0\space h=\the\ht0\space d=\the\dp0}
\yoko
\setbox0=\hbox{あいう}
\typeout{YOKO w=\the\wd0\space h=\the\ht0\space d=\the\dp0}
\end{document}
% TATE w=28.86658pt h=4.8111pt  d=4.8111pt
% YOKO w=28.86658pt h=8.46753pt d=1.15465pt

Dónde vive el espaciado: \kanjiskip y \xkanjiskip

El espaciado entre caracteres japoneses no forma parte del ancho del glifo: entra como goma — blanco estirable y encogible. La familia pTeX lo guarda en dos registros: \kanjiskip entre dos caracteres japoneses y \xkanjiskip allí donde el japonés se encuentra con el latino. Medido en ujarticle con cuerpo de 10pt, \kanjiskip vale 0.0pt plus 0.4pt minus 0.5ptancho natural cero pero elástico, y por tanto justo la holgura con la que juega el algoritmo de corte. \xkanjiskip vale 2.40555pt plus 1.0pt minus 1.0pt, y ese 2.40555 de aspecto tan raro es exactamente el cuadratín de 9.6222pt dividido entre cuatro: un cuarto de cuadratín. La regla tradicional de dejar un cuarto de blanco entre el texto japonés y una palabra latina está ahí, tal cual, como valor por omisión de un registro.

latex
\documentclass{ujarticle}
\begin{document}
\typeout{KANJISKIP=\the\kanjiskip}
\typeout{XKANJISKIP=\the\xkanjiskip}
\setbox0=\hbox{}\typeout{EM=\the\wd0}
\setbox0=\hbox{あAい}\typeout{WITH=\the\wd0}
{\xkanjiskip=0pt \setbox0=\hbox{あAい}\typeout{WITHOUT=\the\wd0}}
\end{document}
% KANJISKIP=0.0pt plus 0.4pt minus 0.5pt
% XKANJISKIP=2.40555pt plus 1.0pt minus 1.0pt
% EM=9.6222pt   WITH=31.5555pt   WITHOUT=26.7444pt
% 31.5555 - 26.7444 = 4.8111 = 2 x 2.40555
RegistroValor medido en TeX Live 2024Qué gobierna
\kanjiskip0.0pt plus 0.4pt minus 0.5ptblanco entre dos caracteres japoneses; ancho natural nulo, pura elasticidad
\xkanjiskip2.40555pt plus 1.0pt minus 1.0ptblanco donde el japonés toca el latino; exactamente un cuarto del cuadratín de 9.6222pt
\prebreakpenalty10000 para la coma ideográficacaracteres que no pueden empezar línea; 10000 significa «nunca cortar»
\postbreakpenalty10000 para el corchete de aperturacaracteres que no pueden acabar línea; el kinsoku se expresa como penalizaciones
\jcharwidowpenalty500desalienta que un párrafo acabe con un solo carácter japonés en su línea

Lo que conviene retener: el kinsoku no está codificado como una regla sino como un número. TeX corta líneas sumando el coste de los puntos de corte candidatos y quedándose con el más barato, de modo que dar a la coma una penalización de 10000 — el valor techo — basta para volver absoluto el «aquí nunca empieza línea». Baje el número y la prohibición se afloja. JFM, por su parte, es una métrica que registra no solo el ancho, alto y profundidad de cada glifo japonés, sino también cuánto blanco corresponde a qué par de caracteres; de ahí viene el apretado en torno a la puntuación y los paréntesis. El ajuste fino de cada signo y el uso de \inhibitglue corresponden a las páginas de composición japonesa.

La diferencia entre pTeX y upTeX, decidida por un solo carácter

Toda la diferencia se reduce a la codificación usada internamente. pTeX trabaja por dentro en EUC-JP o Shift_JIS, lo que lo ata de hecho a los kanji de la norma JIS. upTeX es Unicode por dentro, así que esa valla no existe. El enunciado abstracto no cala, así que pruébelo con un solo carácter: la variante «alta» del carácter de apellido taka, (U+9AD9). Páselo a platex y la compilación se detiene en ! LaTeX Error: Unicode character ^^e9^^ab^^99 (U+9AD9) not set up for use with LaTeX. Entregue el mismo carácter a uplatex (mediante \documentclass[uplatex]{jsarticle}) y todo llega hasta Output written on ... .dvi. Cuando un documento lleno de nombres propios y topónimos falla de pronto bajo platex, casi siempre es por esto.

terminal
$ platex kanji.tex          # \documentclass{jsarticle} + 髙
! LaTeX Error: Unicode character ^^e9^^ab^^99 (U+9AD9)
               not set up for use with LaTeX.

$ uplatex kanji2.tex        # \documentclass[uplatex]{jsarticle} + 髙
Output written on kanji2.dvi (1 page, 304 bytes).

upTeX lo desarrolla desde 2007 Takuji Tanaka. El archivo uplcore.ltx que se distribuye con TeX Live conserva en su cabecera la línea Copyright (c) 2016 Takuji Tanaka, testimonio directo del origen de esta rama. La idea de diseño más rentable es \kcatcode: permite decidir, rango de caracteres a rango de caracteres, si algo se trata como texto japonés o como texto latino. Por eso upTeX compone no solo japonés sino chino simplificado y tradicional y hangul coreano en un mismo documento — la descripción de tlmgr info uptex dice sin rodeos que procesa las cuatro escrituras a la vez. Nada de eso estaba al alcance en la época de pTeX.

De dónde viene e-pTeX: de un informe de prácticas universitarias

e-pTeX empezó como un informe de prácticas que Hironori Kitagawa entregó para una asignatura universitaria llamada Matemática Computacional II. Parece inverosímil, pero el documento sigue distribuyéndose con TeX Live como eptex_resume.pdf: en la portada se lee «Matemática Computacional II, registro de trabajo» y el nombre del grupo es epsilon. El mismo informe anota que Akira Kakuto había realizado el 30 de diciembre de 2007 un experimento que combinaba pTeX con e-TeX, al que llamó peTeX, y comenta de pasada que el orden invertido de la p y la e tiene su gracia. El README del paquete ptex-manual de TeX Live advierte que esos documentos antiguos se incluyen «solo por razones históricas». Los papeles fundacionales de un motor que hoy compila miles de documentos japoneses sobreviven como un trabajo de clase.

¿Qué añadieron entonces las extensiones e-TeX? Aritmética entera como \numexpr, un prefijo \protected que impide que una macro se expanda donde no debe, un depósito de registros mucho mayor y los cimientos de la composición bidireccional. Poco vistoso — pero muchísimos paquetes LaTeX modernos están escritos suponiendo que todo eso existe. Así, cada vez más cosas dejaron de funcionar sin e-TeX en el ecosistema japonés, y e-pTeX / e-upTeX pasaron a ser lo predeterminado. Sin \protected, una orden colocada en el argumento de \section se expande dentro del índice y lo rompe; es cosa de todos los días, no una preocupación teórica. El punto final de esa confluencia es justo la estampa del principio: seis órdenes, un euptex.

Quién mantiene todo esto ahora

La Japanese TeX Development Community, escrita habitualmente texjporg. El momento en que el trabajo pasó de una empresa a una comunidad está grabado en los propios avisos de copyright. Las dos primeras líneas de plcore.ltx — el núcleo de pLaTeX — tal como se distribuye en TeX Live 2024 dicen Copyright (c) 2010 ASCII MEDIA WORKS y Copyright (c) 2016-2020 Japanese TeX Development Community, seguidas de This file is part of the pLaTeX2e system (community edition). Su contraparte de upLaTeX, uplcore.ltx, alinea en el mismo lugar tres partes: ASCII MEDIA WORKS, Takuji Tanaka y la Japanese TeX Development Community. Treinta años de TeX japonés pasando de una editorial a una persona y luego a una comunidad, plegados en tres líneas de comentario.

Al margen de esa línea existe también pTeX-ng, cuya orden se llama ApTeX, una reimplementación de Clerk Ma. Ofrece las primitivas de e-TeX, pTeX y upTeX para seguir siendo compatible con e-upTeX, amplía sus interioridades a todo Unicode e incorpora libdpx — dvipdfmx convertido en biblioteca — de modo que emite PDF directamente, sin fase DVI. Digámoslo con franqueza: no está en TeX Live 2024. tlmgr info ptex-ng responde cannot find package ptex-ng. (Una huella de su existencia sí se distribuye: el paquete ctex incluye un archivo de definición de motor llamado ctex-engine-aptex.def.) El valor por omisión en la práctica sigue siendo e-upTeX; pTeX-ng se instala aparte, para experimentar.

MotorCodificación internae-TeXQué es realmente en TeX Live 2024
pTeXEUC-JP / Shift_JISnosin binario propio; ptex es un enlace a euptex
upTeXUnicode (UTF-8)noigual; uptex también es un enlace a euptex
e-pTeXEUC-JP / Shift_JISel formato eptex; la bandera muestra (utf8.euc)
e-upTeXUnicode (UTF-8)el único binario real; tanto platex como uplatex corren sobre él
pTeX-ng / ApTeXUnicode (hasta 0x10FFFF)no incluido; tlmgr info ptex-ng informa de que no lo encuentra

En la práctica: de uplatex a PDF pasando por dvipdfmx

La familia pTeX no emite PDF. Su salida es siempre DVI, que dvipdfmx convierte después en PDF. Esa es la diferencia decisiva con pdfTeX, XeTeX y LuaTeX, que escriben PDF directamente, y desconocerlo es lo que deja a la gente atascada en «ejecuté uplatex y no obtengo PDF». La secuencia estándar es uplatex dos veces — para que se asienten las referencias cruzadas y el índice — y después dvipdfmx una vez. Conviene saber que en TeX Live dvipdfmx es a su vez un enlace simbólico a xdvipdfmx, así que ls -l mostrará un nombre inesperado; eso también es normal.

latex
\documentclass{ujarticle}   % uj... = upLaTeX, horizontal;  ut... = vertical
\begin{document}
こんにちは、\LaTeX。日本語が美しく組めます。
\[ E = mc^2 \]
\end{document}
terminal
$ uplatex document.tex      # pass 1 -> document.dvi + document.aux
$ uplatex document.tex      # pass 2 -> cross-references settle
$ dvipdfmx document.dvi     # -> document.pdf
  • Si no aparece PDF, compruebe primero si existe el .dvi. Si está, el fallo es del lado de dvipdfmx; si no, del lado de uplatex. Esa única comprobación reduce a la mitad el espacio de búsqueda.
  • Si el texto sale ilegible, revise por orden que la fuente esté guardada en UTF-8 y que la clase apunte a upLaTeX (ujarticle / utarticle, o \documentclass[uplatex]{jsarticle}). Del lado del motor, las opciones son -kanji=STRING (entrada y salida; euc|jis|sjis|utf8|uptex) y -kanji-internal=STRING (el código interno; euc|sjis|uptex).
  • Al pedir ayuda o informar de un error, incluya siempre tres datos: el nombre de la orden (platex o uplatex), la primera línea de bandera del registro y la codificación en que se guardó la fuente. Que la bandera diga (utf8.euc) o (utf8.uptex) resuelve ya media pregunta.
  • ¿Empieza algo nuevo? Sin plantilla obligatoria: fuente en UTF-8 con uplatex, dvipdfmx y jlreq o la clase que suministre la institución. Si una plantilla existente presupone platex, siga su procedimiento de compilación en lugar de modernizarla por moda.
  • Si necesita elegir tipografías libremente, no fuerce la vía pTeX; considere LuaLaTeX con LuaTeX-ja o XeLaTeX con xeCJK, donde las fuentes OpenType del sistema se nombran directamente y el PDF sale en un solo paso.

La decisión se pliega así: para artículos japoneses probados, rápidos y seguros: e-upTeX (uplatex) → dvipdfmx. Si hacen falta fuentes del sistema o extensión por el lado de Lua: LuaLaTeX. Si ya hay material de XeTeX: XeLaTeX con xeCJK. Y conviene no confundir la antigüedad de la línea pTeX con un defecto. Fue la decisión de los años ochenta de meter la escritura vertical y JFM dentro del motor la que hizo posible la edición comercial japonesa en TeX. Cuando hoy teclea uplatex, lo que arranca es el cuadragésimo año de aquella decisión.