LaTeX -> Macros:

* Macros à arguments
 * Environnements
This commit is contained in:
noirel 2005-12-06 19:04:02 +00:00
parent 2ede9df587
commit 18fecddd53

View file

@ -12,19 +12,24 @@
<h2>Les macros, des abréviations</h2>
<p>Il est très facile de définir de nouvelles commandes qui seront autant
d'abréviations. Par exemple :</p>
<p>
Il est très facile de définir de nouvelles commandes qui seront autant
d'abréviations. Par exemple :
</p>
<pre>
\newcommand\cad{c'est-à-dire}
</pre>
<p>Cette ligne crée une nouvelle commande, <code>\cad</code>, qui sera
<p>
Cette ligne crée une nouvelle commande, <code>\cad</code>, qui sera
automatiquement remplacée lors de la compilation par le texte
« c'est-à-dire ». Vous pouvez ainsi remplacer les choses un peu
longues à taper par des commande abrégées. Pour une thèse sur le
« c'est-à-dire ». Remarquez que LaTeX proteste si la commande que
vous définissez existe déjà. Vous pouvez ainsi remplacer les choses un peu
longues à taper par des commandes abrégées. Pour une thèse sur le
chevalier Paul-Louis de la Grange-Noble, vous aurez tout intérêt à
définir dès le début :</p>
définir dès le début :
</p>
<pre>
\newcommand\PL{Paul-Louis de la Grange-Noble}
@ -32,42 +37,380 @@ d
<h2>Espaces après les macros</h2>
<p>Après toute commande dont le nom est composé de lettres (comme
<p>
Après toute commande dont le nom est composé de lettres (comme
<code>\LaTeX</code>, par exemple et à l'inverse de <code>\$</code>), les
espaces sont ignorées. Par conséquent si
vous voulez que votre macro soit suivie d'un espace dans le résultat
final, utilisez l'une des méthodes suivantes&nbsp;:</p>
espaces sont ignorées. Par conséquent, si
vous voulez que votre macro soit suivie d'une espace dans le résultat
final, utilisez l'une des méthodes suivantes&nbsp;:
</p>
<pre>
Le Maître du Monde, \cad\ moi, ...
Le Maître du Monde, \cad{} moi, ...
Le Maître du Monde, \cad\ moi, ...
Le Maître du Monde, {\cad} moi, ...
</pre>
<p>Ce serait une très mauvaise idée de mettre une espace dans la
définition de la macro, car vous auriez <em>toujours</em> une espace, y
compris avant une ponctuation.</p>
compris avant une ponctuation.
</p>
<p>Vous pouvez utiliser le package <code>xspace</code> pour remédier à
cette nécessité. Dans le préambule, ajoutez&nbsp;:
<code>\usepackage{xspace}</code> Ensuite, écrivez vos macros de la façon
suivante&nbsp;:</p>
suivante&nbsp;:
</p>
<pre>\newcommand\cad{c'est-à-dire\xspace}</pre>
<pre>
\newcommand\cad{c'est-à-dire\xspace}
</pre>
<p>La commande <code>\xspace</code> teste ce qui suit la commande&nbsp;:
si c'est une ponctuation ou <code>{</code> ou <code>}</code>, elle ne fera
rien; dans les autres cas, elle ajoute une espace. Une conséquence de ce
fonctionnement est qu'une <code>\footnote</code> suivant <code>\cad</code>
va produite une espace inopportune. Elle peut être évitée en
tapant&nbsp;</p>
va produire une espace inopportune. Elle peut être évitée en
tapant&nbsp;
</p>
<pre>
(...) \cad{}\footnote{Ma note de pied de page} (...)
</pre>
<h2>Commandes à arguments</h2>
<p>
Les commandes utilisées comme raccourcis atteignent vite leurs limites.
D'ailleurs les raccourcis peuvent être également du ressort des éditeurs
(cf. le chapitre « Abréviations » de la page <a
href="&url.tuteurs;unix/editeurs/super_emacs.html">Emacs avancé</a>).
Les commandes peuvent avoir des rôles bien plus importants :
</p>
<ul>
<li>elles sont à la base de la séparation fond-forme ;</li>
<li>elles peuvent être utilisées pour accomplir des tâches très
complexes.</li>
</ul>
<h3>Un élément sémantique, une commande</h3>
<p>
La séparation fond-forme peut être atteinte en assignant à chaque
élément sémantique une commande (on appelle cela aussi le balisage
générique). Par exemple <code>\auteur</code> pour
citer des auteurs, ou <code>\source</code> pour indiquer la source d'une
citation. Supposons que nous souhaitions afficher les auteurs avec leur
nom en petites capitales grâce à la commande utilisée ainsi
</p>
<pre>
\auteur{<var>prénom</var>}{<var>nom</var>}
</pre>
<p class="continue">
on dit alors que la commande <code>\auteur</code> « prend deux
arguments », tous deux délimités par des paires d'accolades.
Du coup, la définition de la commande devient
</p>
<pre>
\newcommand\auteur[2]{...}
</pre>
<p class="continue">
Le <code>2</code> voulant dire que la commande <code>\auteur</code> a
besoin de deux arguments pour fonctionner.
On voudrait que la commande <code>\auteur</code> accomplisse
l'équivalent de
</p>
<pre>
<var>prénom</var>~\textsc{<var>nom</var>}
</pre>
<p class="continue">
<code>~</code> est l'espace insécable, et le nom est mis en petites
capitales.
Pour TeX, <var>prénom</var> étant le premier argument on va l'appeler
<code>#1</code> et <var>nom</var> fort logiquement <code>#2</code>.
Nous n'avons plus qu'à compléter la définition
</p>
<pre>
\newcommand\auteur[2]{#1~\textsc{#2}}
</pre>
<p>
L'avantage de procéder ainsi est que, plus tard, si les petites
capitales ne vous conviennent plus vous pourrez changer de manière
cohérente tout votre document (qu'il fasse deux ou plus de 1000 pages)
en changeant une ligne.
La même modification serait au contraire extrêmement fastidieuse si vous
aviez tapé systématiquement
<code><var>prénom</var>~\textsc{<var>nom</var>}</code> car il faudrait
relire l'ensemble du document et procéder aux modifications en prenant
garde de ne pas modifier un <code>\textsc</code> qui ne serait pas celui
d'un auteur. Vous pouvez vous créer un fichier de style avec
vos définitions les plus courantes : cf. <a
href="nouveau_package.html">Écrire son propre package</a> qui pourra
inclure (ce ne sont que des exemples, ce sont les besoins spécifiques
d'un document particulier qui décident quelles commandes il est
souhaitable de définir)
</p>
<pre>
\newcommand\titre[1]{\emph{#1}}
\newcommand\auteur[2]{#1~\textsc{#2}}
\newcommand\source[1]{\footnote{#1}}
</pre>
<h3>Tâches complexes</h3>
<p>
En plus de vous permettre de contrôler le rendu de votre document,
l'utilisation de commandes spécifiques à chaque besoin permet
d'accomplir des tâches complexes adaptées à chaque élément de votre
document. Supposons que votre commande <code>\auteur</code> vous
satisfasse dans un premier temps, mais que plus tard vous arriviez à
vous dire qu'un index des auteurs (avec les pages où ils sont
mentionnés) serait du meilleur effet. Puisque vous avez une commande
spécifique, il vous suffit de la « surcharger », c'est-à-dire de lui
ajouter toute la machinerie nécessaire à la réalisation de la toute
nouvelle tâche complexe (et cela sans toucher au reste du texte). Vous
pourriez essayer de remplacer votre
définition initiale par (cf. <a href="makeindex.html">Faire un index
avec MakeIndex</a>)
</p>
<pre>
\newcommand\auteur[2]{#1~\textsc{#2}\index{#2, #1}}
</pre>
<p class="continue">
qui produit « <var>prénom</var>&nbsp;<var>nom</var> » et indexe l'auteur
sous la forme « <var>nom</var>, <var>prénom</var> » (pour faciliter la
recherche).
</p>
<p>
En fait, la définition précédente est très largement perfectible,
notamment parce que MakeIndex ne comprend pas très bien les accents (on
peut pour cette raison, lui préférer Xindy). Ce qu'il faut retenir de
tout cela, c'est qu'une fois que la macro spécifique est mise en place
(ici <code>\auteur</code>), peaufiner la présentation du document se
bornera à effectuer de petites modifications sur quelques commandes.
Le seul prérequis est que vous définissiez assez tôt la commande et cela
même si vous pensez ne pas être compétent pour écrire le code
nécessaire : écrivez dans ce cas une commande qui ne fasse rien comme
</p>
<pre>
\newcommand\auteur{}
</pre>
<p class="continue">
car vous pourrez toujours modifier la macro à mesure que vous progressez
en LaTeX ou alors quelqu'un de plus savant pourra vous venir en aide, il
sera toujours plus facile pour lui de ne travailler que sur une macro
isolée plutôt que sur tout un document.
</p>
<p>
Enfin sachez qu'il est possible de définir des commandes prenant des
arguments optionnels à l'instar de, par exemple,
<code>\usepackage</code>. C'est-à-dire qu'il est possible de définir
une commande <code>\auteur</code> telle que
<code>\auteur{<var>prénom</var>}{<var>nom</var>}</code> fasse ce qui a
été dit jusqu'alors et que
<code>\auteur[textit]{<var>prénom</var>}{<var>nom</var>}</code> mette
en italique le numéro de page dans l'index (pour distinguer divers types
de mention de l'auteur). Il est même possible d'avoir trois commandes
en une :
</p>
<pre>
\auteur*{<var>prénom</var>}{<var>nom</var>} % Imprime seulement
\auteur {<var>prénom</var>}{<var>nom</var>} % Imprime et indexe
\auteur[textit]%
{<var>prénom</var>}{<var>nom</var>} % Imprime, indexe
% et met la page en italique
</pre>
<p class="continue">
Par souci d'exhaustivité, je place le code correspondant. Il est certes
un peu complexe, mais on ne peut pas attendre d'une macro qu'elle abatte
des montagnes sans l'éduquer un tant soit peu.
</p>
<pre>
% Tester si une chaîne est vide
\usepackage{ifmtarg}
% À partir de maintenant, pour TeX, « @ » est une lettre et peut donc
% participer à l'élaboration de noms de commande complexes comme
% \@ifmtarg défini par le package homonyme ou \@ifstar défini par LaTeX
\makeatletter
% Si \auteur est suivi d'une étoile appeler \sauteur, sinon \oauteur
\newcommand*{\auteur}{\@ifstar\sauteur\oauteur}
% \sauteur{prénom}{nom} imprime seulement
\newcommand*{\sauteur}[2]{#1~\textsc{#2}}
% \oauteur[comment]{prénom}{nom} imprime et indexe
\newcommand*{\oauteur}[3][]{% Par défaut &lt;comment&gt; est vide
\sauteur{#2}{#3}%
\@ifmtarg{#1}{% #1 est-il vide ?
\index{#3, #2}% Oui (mise en page par défaut)
}{%
\index{#3, #2|#1}% Non (mise en page particulière)
}%
}
% À partir de maintenant, pour TeX, « @ » n'est plus une lettre
\makeatother
</pre>
<h2>Environnements</h2>
<p>
Les environnements
<code>\begin{<var>env</var>}...\end{<var>env</var>}</code> sont une
structure classique de LaTeX que vous pouvez aussi adapter à vos
besoins. Pour cela on utilise la commande <code>\newenvironment</code> :
</p>
<pre>
\newenvironment{<var>env</var>}{%
<var>begin</var>
}{%
<var>end</var>
}
</pre>
<p class="continue">
à ce moment-là, lorsque vous utiliserez
</p>
<pre>
\begin{<var>env</var>}
.
.
.
\end{<var>env</var>}
</pre>
<p class="continue">
TeX substituera essentiellement (remarquez les accolades qui forment un
« groupe »)
</p>
<pre>
{<var>begin</var>
.
.
.
<var>end</var>}
</pre>
<p>
Prenons un exemple &mdash; peu intéressant, mais commençons doucement
&mdash; pour être clair. On définit l'environnement
<code>itenv</code> ainsi
</p>
<pre>
\newenvironment{itenv}{%
\itshape
}{%
% Rien
}
</pre>
<p class="continue">
Maintenant, quand vous tapez
</p>
<pre>
\begin{itenv}Texte\end{itenv}
</pre>
<p class="continue">
vous obtiendrez le même résultat que
</p>
<pre>
{\itshape Texte}
</pre>
<p class="continue">
qui met « Texte » en italique. Développons un exemple plus
intéressant. Supposons que vous vouliez avoir plus de souplesse avec
les citations de votre document (pour l'interlignage, la police, etc.).
Pour cela vous pourriez définir un
environnement <code>myquote</code> ainsi
</p>
<pre>
\newenvironment{myquote}{%
\begin{quote}% Environnement quote
\itshape % ... en italique
\small % ... en plus petit
}{%
\end{quote}%
}
</pre>
<p>
Remarques : 1. de manière analogue aux commandes, on ne peut pas définir
un environnement qui existe déjà ; 2. il n'est pas possible de définir
un environnement portant le même nom qu'une commande existant déjà (par
exemple, il n'est pas possible de définir un environnement
<code>usepackage</code>) et réciproquement (il n'est pas possible de
définir une commande <code>\center</code>).
</p>
<h2>Éléments de programmation</h2>
<p>
Pour réaliser des macros complexes, on pourra se référer à la FAQ
anglaise qui contient de nombreux trucs de programmation dans la section
« Macro programming » comme
</p>
<ul>
<li>Detecting that something is empty</li>
<li>More than one optional argument</li>
<li>Commands defined with * options</li>
</ul>
<p class="continue">
Les packages suivants sont d'un grand intérêt pour des applications
complexes :
</p>
<dl>
<dt>ifthen</dt>
<dd>
pour des tests conditionnels « if-then-else », des boucles
« while-do », etc. ;
</dd>
<dt>calc</dt>
<dd>
pour de l'arithmétique des compteurs et des longueurs plus aisée ;
</dd>
<dt>ifmtarg</dt>
<dd>
pour tester si quelque chose est vide.
</dd>
</dl>
<div class="metainformation"> Auteurs : Émilia Robin (1999),
François-Xavier Coudert. Dernière modification le 2003-05-20, par
Josselin Noirel</div>
François-Xavier Coudert, Josselin Noirel (2005). Dernière modification le <date
value="$Date: 2005-12-06 19:04:02 $" />.</div>
</body> </html>