Précédent: , Monter: Lengths   [Table des matières][Index]


14.7 Expressions

Synopsis, l’un parmi :

\numexpr expression
\dimexpr expression
\glueexpr expression
\muglue expression

En tout lieu où vous pourriez écrire un entier, une dimen, une muglue ou une glue de TeX, vous pouvez à la place écrire une expression pour écrire ce genre de quantité.

Un exemple est que \the\dimexpr\linewidth-4pt\relax produit en sortie la longueur égale à quatre points de moins que la largeur de la ligne (le seul usage de \the est d’afficher le résultat dans le document). De même, \romannumeral\numexpr6+3\relax produit ‘ix’, et \the\glueexpr 5pt plus 1pt * 2 \relax produit ‘10.0pt plus 2.0pt’.

Une commodité ici par rapport à effectuer les calculs en allouant des registres et en utilisant \advance, etc., est que l’évaluation d’expression n’implique par d’affectations et peut donc être effectuée à des endroits où les affectations ne sont pas autorisées. L’exemple suivant calcule la largeur de la \parbox.

\newlength{\offset}\setlength{\offset}{2em}
\begin{center}
\parbox{\dimexpr\linewidth-\offset*3}{Sans animosité envers
quiconque, charitables envers tous, et sûrs de notre droit en tant que
Dieu nous en accorde conscience, mettons-nous à l'œuvre afin d'achever
la tâche qui nous occupe, de panser les blessures de notre nation, de
porter soin à l'homme qui a affronté le combat et soulagement à sa veuve
et à son orphelin, enfin de faire tout pour réaliser et honorer une paix
juste et durable entre nous et avec toutes les nations.  --- Abraham
Lincoln, second discours d'investiture, inscrit dans le mémorial
Lincoln}
\end{center}

L’expression consiste en un ou plusieurs termes du même type (entier, dimension, etc.) qui sont ajoutés ou soustraits. Un terme est un type de nombre, dimension, etc., et consiste en un facteur de ce type, optionnellement multiplié ou divisé par des facteurs. Un facteur d’un type est soit une quantité de ce type ou une sous-expression parenthésés. L’expression produit un résultat du type donné, de sorte que \numexpr produit un entier, \dimexpr produit une dimension dimension, etc.

Dans l’exemple de citation donné plus haut, changer l’expression en \dimexpr\linewidth-3*\offset produit l’erreur Illegal unit of measure (pt inserted). La raison en est que pour \dimexpr et \glueexpr, l’entrée consiste en une valeur de dimension ou de glue suivie par un facteur multiplicatif optionnel, et non l’inverse. Ainsi \the\dimexpr 1pt*10\relax est valide et produit ‘10.0pt’, mais \the\dimexpr 10*1pt\relax produit l’erreur Illegal unit.

Les expressions absorbent les unités lexicales et effectuent les opérations mathématiques appropriées jusqu’à ce qu’un \relax (qui est absorbé), ou jusqu’à ce que la première unité lexicale non valide soit rencontrée. Ainsi, \the\numexpr2+3px imprime ‘5px’, parce que LaTeX lit le \numexpr2+3, ce qui est composé de nombres, et ensuite trouve la lettre p, qui ne peut pas faire partie d’un nombre. Il termine alors l’expression et produit le ‘5’, suivi par le texte ordinaire ‘px’.

Ce comportement de terminaison est utile dans les comparaisons. Dans \ifnum\numexpr\parindent*2 < 10pt Oui\else Non\fi, le signe inférieur à termine l’expression et le résultat est ‘Non’ (dans un document de classe LaTeX standarde article).

Les expressions peuvent utiliser les opérateurs +, -, * et / ainsi que les parenthèses pour les sous-expressions, (...). Dans les expressions glue les parties en plus et minus ne nécessitent pas de parenthèses pour être affectés par un facteur. Ainsi le résultat de \the\glueexpr 5pt plus 1pt * 2 \relax est ‘10pt plus 2pt’.

TeX convertit les autres types numériques de la même façon que lorsqu’il fait une affectation à un registre. Ainsi le résultat de \the\numexpr\dimexpr 1pt\relax\relax est ‘65536’, ce qui est 1pt exprimé en points proportionnés (voir sp, l’unité interne de TeX) et ensuite converti en entier. Si ça avait été une \glueexpr, on aurait laissé tomber la dilatation et la contraction. Dans l’autre sens, une \numexpr au sein d’une \dimexpr ou d’une \glueexpr nécessite l’ajout d’unité appropriées, comme dans \the\dimexpr\numexpr 1 + 2\relax pt\relax, ce qui produit ‘3.0pt’.

Voici les détails de l’arithmétique : chaque facteur est vérifié comme étant compris dans l’intervalle autorisé, les nombres doivent être inférieurs à 2^{31} en valeur absolue, et les composantes de dimensions ou glues doivent être inférieures à 2^{14} points, ou mu, ou fil, etc. Les opérations arithmétiques sont effectuées individuellement, sauf pour les opérations de dilatation (une multiplication immédiatement suivie d’une division) qui sont faites comme une opération combinée avec un produit sur 64-bit comme valeur intermédiaire. Le résultat de chaque opération est de nouveau vérifié comme appartenant à l’intervalle autorisé.

Finalement, on notera que les divisions et dilatations sont faites avec un arrondi au plus proche (contrairement à l’opération \divide de TeX qui prend un arrondi vers zéro). Ainsi \the\dimexpr 5pt*(3/2)\relax met ‘10.0pt’ dans le document, parce qu’il arrondit 3/2 en 2, tandis que \the\dimexpr 5pt*(4/3)\relax produit ‘5.0pt’.


Précédent: , Monter: Lengths   [Table des matières][Index]