texdoc / texfot / Ghostscript / dvisvgm

La plupart des commandes de TeX Live ne composent pas un document. Elles en lisent un. texdef montre comment une commande est réellement définie ; chktex et lacheck signalent les tics du fichier source ; texfot ramène un journal de mille lignes à une poignée ; texcount compte les mots ; texloganalyser extrait d’un .log les seules lignes utiles. Ce qui coûte du temps dans le travail avec LaTeX, ce n’est pas la composition mais la recherche de la raison pour laquelle quelque chose n’a pas marché : ce coin de la distribution rembourse largement l’heure qu’il faut pour l’apprivoiser. Ouvrir le manuel d’un package avec texdoc relève d’une autre page ; on traite ici tout le reste, en terminant par Ghostscript pour intervenir sur le PDF fini.

texdef : comment cette commande est-elle vraiment définie

Quand des redéfinitions se télescopent, le plus rapide pour savoir quelle définition est en vigueur est d’interroger directement le moteur. Tapez latexdef \section et vous obtenez \long macro:->\@startsection {section}{1}{\z@ }{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus .2ex}{\normalfont \Large \bfseries } — la valeur réelle, dans votre installation réelle. Pour la voir avec un package chargé, ajoutez -p : latexdef -p amsmath \tfrac renvoie \genfrac {}{}{}1, et l’on constate aussitôt que \tfrac n’est qu’une mince enveloppe autour de \genfrac. Passez-lui un nom inexistant : la réponse est un sec undefined. L’auteur est Martin Scharrer ; la version présente dans TeX Live 2024 est la 1.9, datée du 2020/09/27.

Le même tour que pour dvipdfmx réapparaît ici. latexdef est un lien symbolique vers texdef, et le programme décide du format à charger d’après le nom sous lequel il a été appelé : texdef signifie plain TeX, latexdef signifie LaTeX. C’est pourquoi un simple texdef \LaTeX répond undefined, et ce n’est pas un défaut. La même chose se dit explicitement avec -t latex ou -t lualatex. Plus utiles encore sont les options de localisation. -F indique le lieu de la définition : latexdef -p booktabs -F \toprule répond \toprule first defined in "/usr/local/texlive/2024/texmf-dist/tex/latex/booktabs/booktabs.sty". Et -l énumère les commandes destinées à l’utilisateur que fournit un package — commode pour voir ce qui existe avant d’ouvrir le manuel.

terminal
latexdef \section                    # the definition in force right now
latexdef -p amsmath \tfrac           # with a package loaded
latexdef -p booktabs -F \toprule     # which file defined it
latexdef -p geometry -l              # the user-level commands a package adds
latexdef -c beamer \frametitle       # inside a different document class

chktex et lacheck : deux linters qui ne regardent pas la même chose

Tous deux attrapent la catégorie de problèmes où le document compile mais la page est fausse, avec des spécialités différentes. chktex regarde les habitudes typographiques. Le même fichier donne des reproches numérotés comme Warning 26 in lint.tex line 4: You ought to remove spaces in front of punctuation. et Warning 44 in lint.tex line 5: User Regex: 1:Capitalize before references., chacun accompagné d’un ^ sous la colonne fautive. Numéroté signifie qu’on peut le faire taire : si la règle 18, qui demande de remplacer un guillemet droit par de vrais guillemets TeX, gêne, chktex -n18. lacheck regarde la correspondance structurelle. Quand environnements, accolades ou délimiteurs mathématiques ne s’accordent pas, il montre les deux extrémités avec leurs numéros de ligne, appariées par <- et ->. Sur un fichier volontairement cassé, il a affiché "broken.tex", line 5: <- unmatched "\end{enumerate}" immédiatement suivi de "broken.tex", line 3: -> unmatched "\begin{itemize}" — plus tôt que le moteur, et sous une forme bien plus lisible.

Si vous les intégrez à l’intégration continue, une différence est décisive. lacheck renvoie le code de sortie 0 quoi qu’il trouve. Le fichier cassé ci-dessus — deux environnements mal appariés et une formule non fermée — a tout de même donné 0. Impossible d’en faire une barrière : il faut capturer sa sortie standard et juger soi-même. chktex -q, à l’inverse, a renvoyé 2 à chaque exécution ayant imprimé des avertissements, et 0 sur un fichier propre. C’est celui-là qui peut servir de barrière. Autre remarque : le chktex de cette version macOS de TeX Live 2024 est compilé avec les expressions régulières étendues POSIX, et l’une de ses règles par défaut emploie une anticipation à la Perl ; chaque exécution commence donc par une ligne débutant par chktex: WARNING -- Compilation of regular expression. C’est sans conséquence, mais apprendre à votre journal d’intégration continue à l’ignorer évite le bruit.

terminal
chktex -q paper.tex           # exit 2 when it prints warnings, 0 when clean
chktex -q -n18 -n26 paper.tex # mute the quotation-mark and punctuation rules
lacheck paper.tex             # unmatched groups, shown as a <- and -> pair
lacheck paper.tex | tee lacheck.out   # its exit code is always 0, so read this

Pour saisir le caractère de ces outils, la section BUGS de la page de manuel de lacheck mérite la lecture. Elle admet que le programme est désorienté par les macros avancées et trompé par les simples, qu’il n’aime pas TeX, qu’il n’offre aucun moyen de désactiver telle ou telle alerte — et se décrit lui-même comme « at best a crude approximation ». C’est peut-être cette franchise qui explique qu’un petit outil écrit par Kresten Krab Thorup au début des années 1990, modifié par Per Abrahamsen, soit encore livré avec TeX Live. chktex affiche de même toujours la bannière Copyright 1995-96 Jens T. Berger Thielemann. Des outils vieux de près de trente ans qui font encore des remarques utiles sur un manuscrit écrit aujourd’hui : c’est aussi la vitesse du monde LaTeX.

texfot : 24 lignes de journal réduites à 4

Si personne ne lit la sortie de TeX, c’est simplement qu’il y en a trop. texfot lance le moteur à votre place et ne laisse passer que les lignes dignes d’attention. Ici, un document d’une page utilisant lipsum a fait défiler 24 lignes sous pdflatex nu ; la même exécution sous texfot pdflatex en a produit 4. Ont survécu la ligne de version du moteur, Overfull \hbox (122.18651pt too wide) detected at line 4 et Output written on over.pdf (1 page, 19010 bytes). Rien n’est perdu pour autant : la sortie complète, non filtrée, est dupliquée vers un fichier temporaire, donc relisible au besoin — --tee= change la destination, --tee=/dev/null la supprime. Le code de sortie est retransmis tel quel depuis le moteur : l’insérer dans latexmk ou dans l’intégration continue ne casse rien ; sur un document erroné, il a renvoyé 1, exactement comme pdflatex seul. L’auteur est Karl Berry.

terminal
texfot pdflatex paper.tex
# texfot: invoking: pdflatex paper.tex
# This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024)
# Overfull \hbox (122.18651pt too wide) detected at line 4
# Output written on paper.pdf (1 page, 19010 bytes).

texfot --tee=/dev/null lualatex paper.tex   # do not keep the full copy

# .latexmkrc: wrap the engine
$pdflatex = 'texfot pdflatex %O %S';

texcount et texloganalyser : compter les mots, fouiller le journal

Quand une soumission impose « 8 000 mots de texte au maximum », wc -w ne sert à rien : il compte \usepackage et chaque nom de macro. texcount — TeXcount 3.1.1, daté d’octobre 2018 — comprend la syntaxe LaTeX et compte en conséquence, en distinguant corps de texte, titres et légendes, jusqu’au nombre de formules. Avec -brief, tout tient en une ligne du genre 2+0+0 (0/0/0/0) File: over.tex. L’autre outil, texloganalyser (Thomas van Oudenhove, version 0.11, licence BSD), fouille un .log déjà écrit : -o n’extrait que les boîtes overfull, -r que les avertissements de renvois, -i les images chargées, -s les fichiers .sty et .cls utilisés. Là où texfot filtre pendant l’exécution, celui-ci creuse dans le journal terminé ; ils ne se recouvrent pas, garder les deux ne coûte rien.

terminal
texcount -brief paper.tex        # words in text + headers + captions
texcount -inc -sum paper.tex     # follow \input and \include, one total

texloganalyser -o paper.log      # only the overfull boxes
texloganalyser -r paper.log      # only the reference warnings
texloganalyser -s paper.log      # which .sty and .cls were actually loaded

Ghostscript : fusionner des PDF, et quand la « compression » ne fait rien

gs est l’interpréteur PostScript et PDF, et c’est aussi ce que ps2pdf exécute en dessous. Avec -sDEVICE=pdfwrite, il écrit du PDF, ce qui règle en une ligne chacune des tâches suivantes : conversion depuis PostScript, fusion de plusieurs PDF, extraction de pages. La fusion est la plus simple : il suffit d’énumérer les entrées dans l’ordre. Ici, un PDF de 7 940 octets et un autre de 6 865 octets ont donné un volume unique de 12 543 octets. À noter : gs ne fait pas partie de TeX Live ; c’est le Ghostscript qu’ajoutent séparément MacTeX et consorts, ici en version 10.03.0.

terminal
gs -q -sDEVICE=pdfwrite -dNOPAUSE -dBATCH \
   -sOutputFile=merged.pdf front.pdf body.pdf

gs -q -sDEVICE=pdfwrite -dNOPAUSE -dBATCH \
   -dFirstPage=3 -dLastPage=8 -sOutputFile=extract.pdf paper.pdf

gs -q -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH \
   -sOutputFile=small.pdf big.pdf

Une affirmation très répandue mérite ici d’être corrigée. -dPDFSETTINGS n’est pas un interrupteur qui compresse un PDF. Ces préréglages gouvernent surtout la politique de rééchantillonnage des images, le plancher de résolution montant de /screen à /ebook, /printer puis /prepress. Un document sans image matricielle n’a donc rien à réduire. À l’essai ici, un PDF de texte seul de 6 865 octets est ressorti à 7 310 avec /screen, 7 309 avec /ebook, 7 302 avec /prepress et jusqu’à 9 869 avec /printerles quatre plus gros que l’original, puisqu’il ne reste que le surcoût de la reconstruction du fichier. L’option se justifie sur des documents bourrés de photographies et de numérisations. Et dans tous les cas, vérifiez à l’œil avant et après : fontes incorporées, liens, signets et format de page. pdfwrite reconstruit le PDF, et des informations invisibles peuvent s’y perdre.

Quelle commande répond à quelle question

CommandeLa question à laquelle elle répond
latexdef NAMEComment cette commande est-elle définie à l’instant — et avec -F, par quel fichier
chktex -qLa source a-t-elle de mauvaises habitudes typographiques — avec un statut exploitable en CI
lacheckEnvironnements et accolades sont-ils bien appariés — mais le code de sortie vaut toujours 0
texfot ENGINE FILEDans le journal de cette exécution, quelles quelques lignes comptent vraiment
texcount -briefCombien de mots de texte, sans compter les macros ni \usepackage
texloganalyser -oExtraire d’un .log existant les seules boîtes overfull ou alertes de renvois
gs -sDEVICE=pdfwriteFusionner des PDF, extraire des pages ou alléger un PDF chargé d’images