Comment détecter le moteur utilisé ?#

Détecter le moteur utilisé pour compiler un document peut être important, en particulier pour des documents partagés entre plusieurs utilisateurs. En effet, l’ensemble des fonctions disponibles diffère selon le moteur. Pour que vos commandes fonctionnent quelque soit le moteur, elles doivent « savoir » ce qu’elles peuvent et ne peuvent pas faire, ce qui dépend du moteur utilisé.

1.  Avec l’extension iftex#

L’extension iftex, du Project Team, permet de répondre très largement à cette question.

Elle fournit des commandes permettant de tester différents moteurs et formats de sortie :

  • \ifpdf, valant vrai si la sortie est en PDF ;

  • \ifpdftex, valant vrai pour une compilation avec ou ;

  • \ifxetex valant vrai pour une compilation avec ;

  • \ifluatex valant vrai pour une compilation avec et LuaHbTex ;

  • \ifluahbtex valant vrai si la bibliothèque Lua Harfbuzz est disponible ;

  • \ifptex valant vrai pour une compilation avec les variantes japonaises de etc.

Pour des raisons historiques, ces commandes sont également fournies avec des noms en majuscules, \ifXeTeX par exemple.

Ces commandes peuvent être utilisées dans la structure conditionnelle de à l’image de :

\ifthenelse{\boolean{pdf}}{⟨si pdf⟩}{⟨sinon⟩}

Une des commandes a un rôle un peu plus particulier : \iftutex. Elle est vraie pour les moteurs Unicode ( et ). Elle permet d’opérer des changements de chargements des polices, selon la possibilité ou pas d’utiliser des polices Unicode :

\iftutex
  \usepackage{fontspec}
  \setmainfont{TeX Gyre Termes}
\else
  \usepackage{times}
\fi

En complément, cette extension fournit des commandes telle RequireLuaTeX qui génère un message d’erreur si le document contenant cette commande n’est pas compilé avec le moteur indiqué (pour la commande citée, ce serait ).

Avertissement

Les solutions indiquées par la suite sont bien moins recommandées (car plus anciennes ou moins précises).

2.  Avec des extensions dédiées à chaque moteur#

Il existe toute une série d’extensions qui traitent ce sujet. Elles créent chacune une commande conditionnelle et sont donc moins générales que iftex :

  • ifpdf crée la commande \ifpdf ;

  • ifxetex crée la commande \ifxetex ;

  • ifluatex crée la command \ifluatex.

L’extension ifxetex fournit également une commande \RequireXeTeX qui crée une erreur si le code n’est pas exécuté avec . Bien que les autres extensions ne fournissent pas une telle commande, il n’est pas réellement difficile d’en écrire une soi-même.

3.  Avec une méthode fait maison#

Pour ceux qui veulent faire le travail par eux-même, voici quelques réflexions sur le travail à effectuer pour et \ifpdf. Le programmeur motivé peut de la même manière regénérer \ifxetex ou \ifluatex. Mais tout ceci n’est pas recommandé…

Supposons que vous devez tester si le document que vous allez produire sera un PDF ou un DVI. L’idée la plus naturelle est de vérifier si vous avez accès à une primitive définie uniquement pour Une bonne primitive à essayer (et pas des moindres puisqu’elle était présente dans les premières versions de ) est \pdfoutput. Vous essayez donc :

\ifx\pdfoutput\undefined
  ... % ce n'est pas pdfTeX qui est utilisé
\else
  ... % c'est pdfTeX qui est utilisé
\fi

Sauf qu’aucune des deux branches de ce test n’est totalement fiable. Ainsi, la première branche peut être trompeuse car un utilisateur « bizarre » pourrait avoir écrit

\let\pdfoutput\undefined

de telle façon que votre test va se diriger par erreur la première branche. Bien que ce soit un problème théorique, il y a peu de chance qu’il soit majeur.

Plus important est le cas de l’utilisateur qui charge une extension qui utilise le test en style pour détermine si le nom d’une commande existe (par exemple, l’extension graphics de ). Une telle extension peut vous avoir devancé et demander à ce que votre test soit plus élaboré :

\ifx\pdfoutput\undefined
  ... % ce n'est pas pdfTeX qui est utilisé
\else
  \ifx\pdfoutput\relax
    ... % ce n'est pas pdfTeX qui est utilisé
  \else
    ...% c'est pdfTeX qui est utilisé
  \fi
\fi

Si vous avez seulement besoin de savoir si une fonctionnalité (tel le crénage marginal) est présent, vous pouvez vous arrêter ici : vous savez désormais tout ce dont vous avez besoin.

Toutefois, si vous avez besoin de savoir si vous créez un fichier de sortie en PDF, vous avez alors besoin de savoir quelle est la valeur de \pdfoutput :

\ifx\pdfoutput\undefined
  ... % ce n'est pas pdfTeX qui est utilisé
\else
  \ifx\pdfoutput\relax
    ... % ce n'est pas pdfTeX qui est utilisé
  \else
    % c'est pdfTeX qui est utilisé avec
    \ifnum\pdfoutput>0
      ... % une sortie PDF
    \else
      ... % une sortie DVI
    \fi
  \fi
\fi