tuteurs.ens.fr/logiciels/latex/macros.tml

429 lines
12 KiB
Text
Raw Normal View History

2002-11-12 17:51:48 +01:00
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html
PUBLIC "-//ENS/Tuteurs//DTD TML 1//EN"
"tuteurs://DTD/tml.dtd">
<html>
<head>
2002-11-12 21:13:01 +01:00
<title>Macros <20>l<EFBFBD>mentaires</title>
2002-11-12 17:51:48 +01:00
</head>
<body>
<h1>Faire des macros <20>l<EFBFBD>mentaires</h1>
<h2>Les macros, des abr<62>viations</h2>
<p>
Il est tr<74>s facile de d<>finir de nouvelles commandes qui seront autant
d'abr<62>viations. Par exemple<6C>:
</p>
2002-11-12 17:51:48 +01:00
<pre>
\newcommand\cad{c'est-<2D>-dire}
</pre>
<p>
Cette ligne cr<63>e une nouvelle commande, <code>\cad</code>, qui sera
2002-11-12 17:51:48 +01:00
automatiquement remplac<61>e lors de la compilation par le texte
<EFBFBD><EFBFBD>c'est-<2D>-dire<72><65>. Remarquez que LaTeX proteste si la commande que
vous d<>finissez existe d<>j<EFBFBD>. Vous pouvez ainsi remplacer les choses un peu
longues <20> taper par des commandes abr<62>g<EFBFBD>es. Pour une th<74>se sur le
2002-11-12 17:51:48 +01:00
chevalier Paul-Louis de la Grange-Noble, vous aurez tout int<6E>r<EFBFBD>t <20>
d<EFBFBD>finir d<>s le d<>but<75>:
</p>
2002-11-12 17:51:48 +01:00
<pre>
\newcommand\PL{Paul-Louis de la Grange-Noble}
</pre>
2008-03-24 18:12:36 +01:00
<p>
Il arrive fr<66>quemment d'avoir besoin de red<65>finir une commande qui existe
d<EFBFBD>j<EFBFBD>. Dans ce cas-l<>, on utilise simplement:
</p>
<pre>
\renewcommand\nom{contenu}
</pre>
<p class="continue"> <20> la place de <code>newcommand </code>.
</p>
2002-11-12 17:51:48 +01:00
<h2>Espaces apr<70>s les macros</h2>
<p>
Apr<EFBFBD>s toute commande dont le nom est compos<6F> de lettres (comme
<code>\LaTeX</code>, par exemple et <20> l'inverse de <code>\$</code>), les
espaces sont ignor<6F>es. Par cons<6E>quent, si
vous voulez que votre macro soit suivie d'une espace dans le r<>sultat
final, utilisez l'une des m<>thodes suivantes<65>:
</p>
2002-11-12 17:51:48 +01:00
<pre>
Le Ma<4D>tre du Monde, \cad{} moi, ...
Le Ma<4D>tre du Monde, \cad\ moi, ...
Le Ma<4D>tre du Monde, {\cad} moi, ...
2002-11-12 17:51:48 +01:00
</pre>
<p>Ce serait une tr<74>s mauvaise id<69>e de mettre une espace dans la
d<EFBFBD>finition de la macro, car vous auriez <em>toujours</em> une espace, y
compris avant une ponctuation.
</p>
2002-11-12 17:51:48 +01:00
<p>Vous pouvez utiliser le package <code>xspace</code> pour rem<65>dier <20>
cette n<>cessit<69>. Dans le pr<70>ambule, ajoutez<65>:
2002-11-12 17:51:48 +01:00
<code>\usepackage{xspace}</code> Ensuite, <20>crivez vos macros de la fa<66>on
suivante<EFBFBD>:
</p>
2002-11-12 17:51:48 +01:00
<pre>
\newcommand\cad{c'est-<2D>-dire\xspace}
</pre>
2002-11-12 17:51:48 +01:00
<p>La commande <code>\xspace</code> teste ce qui suit la commande<64>:
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<6E>quence de ce
fonctionnement est qu'une <code>\footnote</code> suivant <code>\cad</code>
va produire une espace inopportune. Elle peut <20>tre <20>vit<69>e en
tapant<EFBFBD>
</p>
2002-11-12 17:51:48 +01:00
<pre>
(...) \cad{}\footnote{Ma note de pied de page} (...)
</pre>
<h2>Commandes <20> arguments</h2>
<p>
Les commandes utilis<69>es comme raccourcis atteignent vite leurs limites.
D'ailleurs les raccourcis peuvent <20>tre <20>galement du ressort des <20>diteurs
(cf. le chapitre <20><>Abr<62>viations<6E><73> de la page <a
href="&url.tuteurs;unix/editeurs/super_emacs.html">Emacs avanc<6E></a>).
Les commandes peuvent avoir des r<>les bien plus importants<74>:
</p>
<ul>
<li>elles sont <20> la base de la s<>paration fond-forme<6D>;</li>
<li>elles peuvent <20>tre utilis<69>es pour accomplir des t<>ches tr<74>s
complexes.</li>
</ul>
<h3>Un <20>l<EFBFBD>ment s<>mantique, une commande</h3>
<p>
La s<>paration fond-forme peut <20>tre atteinte en assignant <20> chaque
<EFBFBD>l<EFBFBD>ment s<>mantique une commande (on appelle cela aussi le balisage
g<EFBFBD>n<EFBFBD>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<67>ce <20> la commande utilis<69>e ainsi
</p>
<pre>
\auteur{<var>pr<70>nom</var>}{<var>nom</var>}
</pre>
<p class="continue">
on dit alors que la commande <code>\auteur</code> <20><>prend deux
arguments<EFBFBD><EFBFBD>, tous deux d<>limit<69>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'<27>quivalent de
</p>
<pre>
<var>pr<70>nom</var>~\textsc{<var>nom</var>}
</pre>
<p class="continue">
<code>~</code> est l'espace ins<6E>cable, et le nom est mis en petites
capitales.
Pour TeX, <var>pr<70>nom</var> <20>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'<27> compl<70>ter la d<>finition
</p>
<pre>
\newcommand\auteur[2]{#1~\textsc{#2}}
</pre>
<p>
L'avantage de proc<6F>der ainsi est que, plus tard, si les petites
capitales ne vous conviennent plus vous pourrez changer de mani<6E>re
coh<EFBFBD>rente tout votre document (qu'il fasse deux ou plus de 1000<30>pages)
en changeant une ligne.
La m<>me modification serait au contraire extr<74>mement fastidieuse si vous
aviez tap<61> syst<73>matiquement
<code><var>pr<70>nom</var>~\textsc{<var>nom</var>}</code> car il faudrait
relire l'ensemble du document et proc<6F>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<63>er un fichier de style avec
vos d<>finitions les plus courantes<65>: cf.<2E><a
href="nouveau_package.html"><3E>crire son propre package</a> qui pourra
inclure (ce ne sont que des exemples, ce sont les besoins sp<73>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<74>ler le rendu de votre document,
l'utilisation de commandes sp<73>cifiques <20> chaque besoin permet
d'accomplir des t<>ches complexes adapt<70>es <20> chaque <20>l<EFBFBD>ment de votre
document. Supposons que votre commande <code>\auteur</code> vous
satisfasse dans un premier temps, mais que plus tard vous arriviez <20>
vous dire qu'un index des auteurs (avec les pages o<> ils sont
mentionn<EFBFBD>s) serait du meilleur effet. Puisque vous avez une commande
sp<EFBFBD>cifique, il vous suffit de la <20><>surcharger<65><72>, c'est-<2D>-dire de lui
ajouter toute la machinerie n<>cessaire <20> 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<EFBFBD>finition initiale par (cf.<2E><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 <20><><var>pr<70>nom</var><3E><var>nom</var><3E><> et indexe l'auteur
sous la forme <20><><var>nom</var>, <var>pr<70>nom</var><3E><> (pour faciliter la
recherche).
</p>
<p>
En fait, la d<>finition pr<70>c<EFBFBD>dente est tr<74>s largement perfectible,
notamment parce que MakeIndex ne comprend pas tr<74>s bien les accents (on
peut pour cette raison, lui pr<70>f<EFBFBD>rer Xindy). Ce qu'il faut retenir de
tout cela, c'est qu'une fois que la macro sp<73>cifique est mise en place
(ici <code>\auteur</code>), peaufiner la pr<70>sentation du document se
bornera <20> effectuer de petites modifications sur quelques commandes.
Le seul pr<70>requis est que vous d<>finissiez assez t<>t la commande et cela
m<EFBFBD>me si vous pensez ne pas <20>tre comp<6D>tent pour <20>crire le code
n<EFBFBD>cessaire<EFBFBD>: <20>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 <20> 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<EFBFBD>e plut<75>t que sur tout un document.
</p>
<p>
Enfin sachez qu'il est possible de d<>finir des commandes prenant des
arguments optionnels <20> l'instar de, par exemple,
<code>\usepackage</code>. C'est-<2D>-dire qu'il est possible de d<>finir
une commande <code>\auteur</code> telle que
<code>\auteur{<var>pr<70>nom</var>}{<var>nom</var>}</code> fasse ce qui a
<EFBFBD>t<EFBFBD> dit jusqu'alors et que
<code>\auteur[textit]{<var>pr<70>nom</var>}{<var>nom</var>}</code> mette
en italique le num<75>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<6E>:
</p>
<pre>
\auteur*{<var>pr<70>nom</var>}{<var>nom</var>} % Imprime seulement
\auteur {<var>pr<70>nom</var>}{<var>nom</var>} % Imprime et indexe
\auteur[textit]%
{<var>pr<70>nom</var>}{<var>nom</var>} % Imprime, indexe
% et met la page en italique
</pre>
<p class="continue">
Par souci d'exhaustivit<69>, 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'<27>duquer un tant soit peu.
</p>
<pre>
% Tester si une cha<68>ne est vide
\usepackage{ifmtarg}
% <20> partir de maintenant, pour TeX, <20><>@<40><> est une lettre et peut donc
% participer <20> l'<27>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 <20>toile appeler \sauteur, sinon \oauteur
\newcommand*{\auteur}{\@ifstar\sauteur\oauteur}
% \sauteur{pr<70>nom}{nom} imprime seulement
\newcommand*{\sauteur}[2]{#1~\textsc{#2}}
% \oauteur[comment]{pr<70>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<64>?
\index{#3, #2}% Oui (mise en page par d<>faut)
}{%
\index{#3, #2|#1}% Non (mise en page particuli<6C>re)
}%
}
% <20> partir de maintenant, pour TeX, <20><>@<40><> 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 <20> vos
besoins. Pour cela on utilise la commande <code>\newenvironment</code><3E>:
</p>
<pre>
\newenvironment{<var>env</var>}{%
<var>begin</var>
}{%
<var>end</var>
}
</pre>
<p class="continue">
<EFBFBD> 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
<EFBFBD><EFBFBD>groupe<EFBFBD><EFBFBD>)
</p>
<pre>
{<var>begin</var>
.
.
.
<var>end</var>}
</pre>
<p>
Prenons un exemple &mdash; peu int<6E>ressant, mais commen<65>ons doucement
&mdash; pour <20>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 <20><>Texte<74><65> en italique. D<>veloppons un exemple plus
int<EFBFBD>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<EFBFBD>: 1. de mani<6E>re analogue aux commandes, on ne peut pas d<>finir
un environnement qui existe d<>j<EFBFBD><6A>; 2. il n'est pas possible de d<>finir
un environnement portant le m<>me nom qu'une commande existant d<>j<EFBFBD> (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<EFBFBD>finir une commande <code>\center</code>).
</p>
<h2><3E>l<EFBFBD>ments de programmation</h2>
<p>
Pour r<>aliser des macros complexes, on pourra se r<>f<EFBFBD>rer <20> la FAQ
anglaise qui contient de nombreux trucs de programmation dans la section
<EFBFBD><EFBFBD>Macro programming<6E><67> 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<6E>r<EFBFBD>t pour des applications
complexes<EFBFBD>:
</p>
<dl>
<dt>ifthen</dt>
<dd>
pour des tests conditionnels <20><>if-then-else<73><65>, des boucles
<20><>while-do<64><6F>, etc.<2E>;
</dd>
<dt>calc</dt>
<dd>
pour de l'arithm<68>tique des compteurs et des longueurs plus ais<69>e<EFBFBD>;
</dd>
<dt>ifmtarg</dt>
<dd>
pour tester si quelque chose est vide.
</dd>
</dl>
<div class="metainformation"> Auteurs<72>: <20>milia Robin (1999),
Fran<EFBFBD>ois-Xavier Coudert, Josselin Noirel (2005). Derni<6E>re modification le <date
2008-03-24 18:12:36 +01:00
value="$Date: 2008-03-24 17:12:36 $" />.</div>
2002-11-12 17:51:48 +01:00
</body> </html>