Famille pTeX

Le répertoire bin de TeX Live 2024 aligne six commandes — ptex, uptex, eptex, euptex, platex, uplatex — et ls -l révèle que toutes les six sont des liens symboliques vers un unique exécutable nommé euptex. La famille de moteurs LaTeX conçus pour le japonais — pTeX, upTeX, e-pTeX, e-upTeX — a convergé vers une seule implémentation en un quart de siècle. Cette page suit cette convergence en lisant les bannières, les journaux et les valeurs réellement mesurées. L'art de la composition verticale et des règles de coupure appartient à d'autres pages ; ce qui se joue ici, c'est le moteur lui-même.

Six commandes, un seul exécutable

Il n'existe aucun exécutable nommé platex. Dans TeX Live 2024, platex est un lien symbolique vers euptex, tout comme ptex, uptex, eptex et uplatex. Ce qui change, c'est le format que chacun charge. Un programme de la famille TeX regarde sous quel nom il a été appelé et charge le fichier de format (.fmt) portant ce nom. La correspondance figure dans fmtutil.cnf, où deux lignes se suivent : platex euptex language.dat *platex.ini et uplatex euptex language.dat *uplatex.ini. La deuxième colonne donne le moteur, la quatrième le fichier ini qui sert à graver le format. Autrement dit, pLaTeX et upLaTeX sont deux formats distincts posés sur un seul et même moteur, 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

Lancez les six et ne gardez que la première ligne : la structure apparaît d'elle-même. Le corps de la bannière est toujours identique — This is e-upTeX, Version 3.141592653-p4.1.1-u1.30-230214-2.6 (TeX Live 2024) — et seule la parenthèse change : le côté platex affiche (utf8.euc), le côté uplatex affiche (utf8.uptex). Cette parenthèse nomme l'encodage japonais interne, unique indice extérieur qui sépare la lignée pTeX de la lignée upTeX. On demande souvent pourquoi lancer platex affiche « e-upTeX » ; rien n'est cassé — c'est exactement ainsi qu'une installation saine se présente.

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)

Cette longue suite de chiffres n'est pas un numéro de version mais quatre lignées distinctes mises bout à bout. Le 3.141592653 de tête est le TeX nu, p4.1.1 est pTeX, u1.30 est upTeX, 230214 est e-pTeX (une date) et le 2.6 final est e-TeX. Ce n'est pas une conjecture : le moteur expose chacune sous forme de primitive, si bien qu'on peut les lire depuis le document avec \the\ptexversion et ses parents. Une fois cette ligne déchiffrée, la question qu'est-ce que e-pTeX reçoit une réponse concrète : c'est pTeX avec les extensions e-TeX fusionnées, et le e-upTeX qui tourne ici y superpose encore upTeX — quatre couches.

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
Fragment de bannièreProvenanceComment le relire
3.141592653le TeX nu de Knuthseulement dans la bannière, pas de primitive
p4.1.1pTeX — les extensions japonaises issues d’ASCII\ptexversion, \ptexminorversion, \ptexrevision
u1.30upTeX — la refonte Unicode\uptexversion, \uptexrevision
230214e-pTeX — une date en guise de version\epTeXversion
2.6les extensions e-TeX\eTeXversion, \eTeXrevision

Ce que pTeX a inscrit dans le moteur : direction d’écriture et JFM

Deux choses ont contraint pTeX à être une modification du moteur plutôt qu'un jeu de macros : la direction d'écriture (\tate et \yoko) et JFM, la métrique de fonte japonaise. Il a été développé chez ASCII Corporation — l'éditeur japonais connu pour ses magazines d'informatique et de jeux — et le p vient de publishing : l'objectif était un TeX japonais tenant la route en édition commerciale. La direction d'écriture semble n'être qu'une question de sens de lecture, mais à l'intérieur de TeX c'est un événement où le sens des dimensions d'une boîte s'inverse. Mesurez, et les chiffres le disent sans détour.

Placez les mêmes trois kana dans une \hbox et comparez ses dimensions en mode horizontal puis vertical. À l'horizontale, la hauteur vaut 8.46753pt et la profondeur 1.15465pt — la silhouette dissymétrique de ce qui repose sur une ligne de base, exactement comme en typographie latine. À la verticale, hauteur et profondeur valent toutes deux 4.8111pt, soit exactement la moitié du cadratin de 9.6222pt, également réparti. En composition verticale, le caractère ne repose sur aucune ligne de base : il chevauche l'axe médian de la colonne. Basculer cette interprétation des dimensions à l'intérieur du moteur, voilà le cœur de pTeX, et précisément ce qu'aucun jeu de macros ne peut imiter.

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

Où loge l’espacement : \kanjiskip et \xkanjiskip

L'espacement entre caractères japonais ne fait pas partie de la largeur du glyphe : il entre comme ressort — un blanc extensible et compressible. La famille pTeX le range dans deux registres : \kanjiskip entre deux caractères japonais, \xkanjiskip là où le japonais rencontre le latin. Mesuré dans ujarticle à 10pt de corps, \kanjiskip vaut 0.0pt plus 0.4pt minus 0.5ptlargeur naturelle nulle mais élastique, donc précisément le jeu dont dispose l'algorithme de coupure. \xkanjiskip vaut 2.40555pt plus 1.0pt minus 1.0pt, et ce 2.40555 d'apparence bancale est exactement le cadratin de 9.6222pt divisé par quatre : un quart de cadratin. La règle traditionnelle qui veut qu'un quart de blanc sépare le texte japonais d'un mot latin figure là, telle quelle, comme valeur par défaut de registre.

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
RegistreValeur mesurée dans TeX Live 2024Ce qu’il gouverne
\kanjiskip0.0pt plus 0.4pt minus 0.5ptblanc entre deux caractères japonais ; largeur naturelle nulle, pure élasticité
\xkanjiskip2.40555pt plus 1.0pt minus 1.0ptblanc à la rencontre japonais/latin ; exactement le quart du cadratin de 9.6222pt
\prebreakpenalty10000 pour la virgule idéographiquecaractères interdits en début de ligne ; 10000 signifie « jamais de coupure »
\postbreakpenalty10000 pour le crochet d’ouverturecaractères interdits en fin de ligne ; le kinsoku s’exprime en pénalités
\jcharwidowpenalty500décourage un paragraphe se terminant par un seul caractère japonais isolé

Ce qu'il faut retenir : le kinsoku n'est pas encodé comme une règle mais comme un nombre. TeX coupe les lignes en additionnant les coûts des points de coupure candidats et en retenant le moins cher ; donner à la virgule une pénalité de 10000 — la valeur plafond — suffit donc à rendre absolu le « jamais de début de ligne ici ». Baissez le nombre et l'interdit se relâche. JFM, de son côté, est une métrique qui consigne non seulement la largeur, la hauteur et la profondeur de chaque glyphe japonais, mais aussi combien de blanc revient à tel couple de caractères ; c'est de là que vient le resserrement autour de la ponctuation et des parenthèses. Le réglage fin de chaque signe et l'usage de \inhibitglue relèvent des pages consacrées à la composition japonaise.

La différence entre pTeX et upTeX, tranchée par un seul caractère

Toute la différence tient à l'encodage employé en interne. pTeX travaille intérieurement en EUC-JP ou Shift_JIS, ce qui le lie de fait aux kanji de la norme JIS. upTeX est Unicode à l'intérieur : la clôture disparaît. L'énoncé abstrait ne parle guère, alors essayons avec un seul caractère — la variante « haute » du caractère de nom taka, (U+9AD9). Donnez-le à platex et la compilation s'arrête sur ! LaTeX Error: Unicode character ^^e9^^ab^^99 (U+9AD9) not set up for use with LaTeX. Confiez le même caractère à uplatex (via \documentclass[uplatex]{jsarticle}) et tout va jusqu'à Output written on ... .dvi. Quand un document plein de noms de personnes et de lieux échoue soudain sous platex, c'est presque toujours pour cette raison.

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 est développé depuis 2007 par Takuji Tanaka. Le fichier uplcore.ltx livré avec TeX Live porte encore en tête la ligne Copyright (c) 2016 Takuji Tanaka, témoignage direct de l'origine de cette branche. L'idée de conception la plus rentable est \kcatcode : elle permet de décider, plage de caractères par plage de caractères, si le texte est traité comme japonais ou comme latin. C'est pourquoi upTeX compose non seulement le japonais mais le chinois simplifié et traditionnel ainsi que le hangul coréen dans un même document — la description de tlmgr info uptex dit explicitement qu'il traite les quatre écritures simultanément. Rien de tout cela n'était à portée à l'époque de pTeX.

D’où vient e-pTeX : d’un compte rendu de travaux dirigés

e-pTeX a commencé par un compte rendu que Hironori Kitagawa a remis pour un travail pratique universitaire intitulé « Mathématiques computationnelles II ». Cela paraît improbable, mais le document accompagne toujours TeX Live sous le nom eptex_resume.pdf — la couverture porte « Mathématiques computationnelles II, journal de travail » et le nom d'équipe est epsilon. Le même rapport note qu'Akira Kakuto avait mené le 30 décembre 2007 une expérience combinant pTeX et e-TeX, baptisée peTeX, et remarque au passage que l'ordre inversé du p et du e a son charme. Le README du lot ptex-manual de TeX Live précise que ces vieux documents ne sont inclus « que pour des raisons historiques ». Les pièces fondatrices d'un moteur qui compose aujourd'hui des milliers de documents japonais survivent sous forme de devoir d'étudiant.

Qu'ont donc apporté les extensions e-TeX ? De l'arithmétique entière comme \numexpr, un préfixe \protected qui empêche une macro de s'expanser là où il ne faut pas, un réservoir de registres bien plus vaste et les fondations de la composition bidirectionnelle. Peu spectaculaire — mais quantité de packages LaTeX modernes sont écrits en supposant que tout cela existe. De plus en plus de choses ont donc cessé de fonctionner sans e-TeX dans l'écosystème japonais, et e-pTeX / e-upTeX sont devenus la valeur par défaut. Sans \protected, une commande placée dans l'argument d'un \section s'expanse dans la table des matières et la casse ; c'est quotidien, pas théorique. L'aboutissement de cette convergence, c'est exactement le tableau du début : six commandes, un euptex.

Qui en assure aujourd’hui la maintenance

La Japanese TeX Development Community, généralement écrite texjporg. Le moment où le travail est passé d'une entreprise à une communauté est gravé dans les mentions de copyright elles-mêmes. Les deux premières lignes de plcore.ltx — le cœur de pLaTeX — dans TeX Live 2024 disent Copyright (c) 2010 ASCII MEDIA WORKS puis Copyright (c) 2016-2020 Japanese TeX Development Community, suivies de This file is part of the pLaTeX2e system (community edition). Le pendant upLaTeX, uplcore.ltx, aligne au même endroit trois parties : ASCII MEDIA WORKS, Takuji Tanaka et la Japanese TeX Development Community. Trente ans de TeX japonais passant d'un éditeur à un individu puis à une communauté, repliés en trois lignes de commentaire.

En marge de cette lignée existe aussi pTeX-ng, dont la commande s'appelle ApTeX, une réimplémentation due à Clerk Ma. Elle fournit les primitives d'e-TeX, pTeX et upTeX pour rester compatible avec e-upTeX, élargit les composants internes à tout Unicode et intègre libdpx — dvipdfmx transformé en bibliothèque — de sorte qu'elle produit du PDF directement, sans étape DVI. Disons-le franchement : elle ne figure pas dans TeX Live 2024. tlmgr info ptex-ng répond cannot find package ptex-ng. (Une trace de son existence est bien livrée : le package ctex contient un fichier de définition de moteur nommé ctex-engine-aptex.def.) Le choix par défaut en pratique reste e-upTeX ; pTeX-ng s'installe à part, pour essayer.

MoteurEncodage internee-TeXCe que c’est réellement dans TeX Live 2024
pTeXEUC-JP / Shift_JISnonpas de binaire propre ; ptex est un lien vers euptex
upTeXUnicode (UTF-8)nonde même ; uptex est aussi un lien vers euptex
e-pTeXEUC-JP / Shift_JISouile format eptex ; bannière (utf8.euc)
e-upTeXUnicode (UTF-8)ouile seul vrai binaire ; platex comme uplatex tournent dessus
pTeX-ng / ApTeXUnicode (jusqu’à 0x10FFFF)ouinon livré ; tlmgr info ptex-ng signale qu’il est introuvable

En pratique : de uplatex à PDF en passant par dvipdfmx

La famille pTeX n'émet pas de PDF. Sa sortie est toujours du DVI, que dvipdfmx convertit ensuite en PDF. C'est la différence décisive avec pdfTeX, XeTeX et LuaTeX, qui écrivent directement du PDF ; l'ignorer, c'est rester bloqué sur « j'ai lancé uplatex et je n'ai pas de PDF ». La séquence standard : uplatex deux fois, pour que les renvois et la table des matières se stabilisent, puis dvipdfmx une fois. Notez que dans TeX Live, dvipdfmx est lui-même un lien symbolique vers xdvipdfmx ; ls -l affichera donc un nom inattendu — c'est normal aussi.

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 aucun PDF n'apparaît, vérifiez d'abord l'existence du .dvi. S'il est là, la faute est du côté de dvipdfmx ; sinon, du côté de uplatex. Cette seule vérification réduit de moitié le champ de recherche.
  • Si le texte sort en charabia, vérifiez dans l'ordre que la source est enregistrée en UTF-8 et que la classe vise upLaTeX (ujarticle / utarticle, ou \documentclass[uplatex]{jsarticle}). Côté moteur, les options sont -kanji=STRING (entrée et sortie ; euc|jis|sjis|utf8|uptex) et -kanji-internal=STRING (le code interne ; euc|sjis|uptex).
  • Pour poser une question ou signaler un bogue, joignez toujours trois éléments : le nom de la commande (platex ou uplatex), la première ligne de bannière du journal et l'encodage d'enregistrement de la source. Que la bannière indique (utf8.euc) ou (utf8.uptex) règle déjà la moitié de l'affaire.
  • Vous commencez un document ? Sans modèle imposé : source UTF-8 avec uplatex, dvipdfmx et jlreq ou la classe fournie par l'établissement. Si un modèle existant suppose platex, suivez sa procédure de compilation au lieu de le moderniser par principe.
  • Pour choisir librement les fontes, ne forcez pas la voie pTeX : LuaLaTeX avec LuaTeX-ja ou XeLaTeX avec xeCJK permettent de nommer directement les polices OpenType du système et sortent le PDF en une étape.

La décision se replie ainsi : pour des articles japonais éprouvés, rapides et sûrs : e-upTeX (uplatex) → dvipdfmx. S'il faut des polices système ou une extension côté Lua : LuaLaTeX. Si vous avez déjà un fonds XeTeX : XeLaTeX avec xeCJK. Et gardons-nous de prendre l'ancienneté de la lignée pTeX pour un défaut. C'est la décision, prise dans les années 1980, de placer l'écriture verticale et JFM à l'intérieur du moteur qui a rendu possible l'édition commerciale japonaise sous TeX. Quand vous tapez uplatex aujourd'hui, vous lancez la quarantième année de cette décision.