%%% Copyright (C) 2015-2024 Vincent Goulet
%%%
%%% Ce fichier fait partie du projet
%%% «Rédaction avec LaTeX»
%%% https://gitlab.com/vigou3/formation-latex-ul
%%%
%%% Cette création est mise à disposition sous licence
%%% Attribution-Partage dans les mêmes conditions 4.0
%%% International de Creative Commons.
%%% https://creativecommons.org/licenses/by-sa/4.0/

\chapter{Commandes et environnements définis par l'usager}
\label{chap:commandes}

{\LaTeX} est un ensemble de macro-commandes conçu pour faciliter
l'utilisation du système {\TeX}. Dès lors, les utilisateurs peuvent à
leur tour définir des commandes. Il suffit généralement d'avoir rédigé
quelques documents --- ou quelques chapitres d'un long document ---
avec {\LaTeX} pour réaliser combien cette possibilité est de nature à
faciliter le travail.

La définition de nouvelles commandes et de nouveaux environnements
peut servir à créer des extensions à {\LaTeX} --- c'est d'ailleurs ce
que font plusieurs paquetages. Cependant, en usage courant, on fera
principalement appel à ces fonctionnalités pour l'une ou l'autre des
trois raisons suivantes:

\begin{enumerate}
\item créer des raccourcis pour de longues commandes utilisées
  fréquemment;
\item créer des commandes sémantiques afin d'uniformiser la
  présentation du texte;
\item modifier le comportement de commandes existantes --- car il est
  également possible de redéfinir une commande existante.
\end{enumerate}

\begin{exemple}
  \label{ex:commandes:intro}
  J'ai créé ou modifié des commandes pour chacune des raisons
  ci-dessus dans la préparation du présent ouvrage.
  \begin{enumerate}
  \item Une nouvelle commande \cmdprint{\doc} facilite et systématise
    l'insertion de liens vers la documentation. D'un seul appel, elle
    crée un hyperlien dans le texte suivi de l'icône {\faExternalLink*}
    et elle ajoute le nom du fichier de documentation dans la marge
    précédé de l'icône {\faBookmark}.
  \item Une nouvelle commande sémantique \cmdprint{\pkg} sert pour la
    mise en forme des noms de paquetages. Ainsi, leur présentation est
    toujours la même et, si je devais souhaiter en changer, il me
    suffirait de modifier la définition de la commande.
  \item La redéfinition de la commande \cmd{\chaptitlefont} de la
    classe \class{memoir} permet de modifier la police et la mise en
    forme des titres de chapitres.
  \end{enumerate}
  Je reviendrai sur les détails de ces exemples dans la suite du
  chapitre. %
  \qed
\end{exemple}


\section{Nouvelles commandes}
\label{sec:commandes:commandes}

Les commandes \cmd{\newcommand} et \cmd{\renewcommand} permettent
respectivement de définir une nouvelle commande et de redéfinir une
commande existante --- c'est-à-dire d'en modifier la définition. On
place généralement ces définitions dans le préambule du document.

\subsection{Commandes sans arguments}
\label{sec:commandes:commandes:sans_arg}

Certaines commandes ne requièrent pas d'argument; pensons à
\cmdprint{\LaTeX} ou \cmdprint{\bfseries}. Ce sont les commandes les
plus simples à créer. La syntaxe des commandes \cmd{\newcommand} et
\cmd{\renewcommand} pour de tels cas est la suivante:
\begin{lstlisting}
\newcommand{`\bs\meta{nom\_commande}'}`\marg{définition}'
\renewcommand{`\bs\meta{nom\_commande}'}`\marg{définition}'
\end{lstlisting}
Le premier argument, \bs\meta{nom\_commande}, est le nom de la
commande, avec le symbole «\bs». Pour \cmdprint{\newcommand}, ce nom
doit être différent de celui de toute commande active dans le
document\footnote{%
  Les commandes actives dans un document sont les commandes de base de
  {\TeX} et {\LaTeX} ainsi que les commandes de tous les paquetages
  chargés dans le préambule.}. %
À l'inverse, avec \cmdprint{\renewcommand}, le nom doit déjà être pris
par une commande active.

Le second argument, \meta{définition}, contient la définition de la
commande. Il peut s'agir de caractères à insérer dans le texte, de
commandes à exécuter ou d'une combinaison de tout cela.

\begin{exemple}
  La commande \cmd{\mathbb}, présentée à la
  \autoref{sec:math:symboles:mathcal}, permet de créer une lettre
  majuscule ajourée pour représenter un ensemble de nombres en
  mathématiques. Plutôt que de l'utiliser à divers endroits dans un
  document, il est préférable de définir une commande sémantique comme
  \cmdprint{\R} pour représenter l'ensemble des nombres réels:
\begin{lstlisting}
\newcommand{\R}{\mathbb{R}}
\end{lstlisting}
  Comme cela, si vous souhaitez pour une raison quelconque modifier la
  représentation de l'ensemble des nombres réels, il vous suffit de
  modifier la définition de la commande \cmdprint{\R} pour que le
  changement prenne effet dans tout le document. %
  \qed
\end{exemple}

\begin{exemple}
  Tel que mentionné à l'\autoref{ex:commandes:intro}, j'ai modifié la
  police des titres de chapitres dans le présent document en
  redéfinissant la commande \cmdprint{\chaptitlefont} de la classe
  \class{memoir}. Pour obtenir des titres de chapitres sans
  empattements, en caractères gras, de dimension \cmdprint{\Huge} et
  alignés à gauche, le préambule du document contient la
  déclaration
\begin{lstlisting}
\renewcommand{\chaptitlefont}{\normalfont%
  \sffamily\bfseries\Huge\raggedright}
\end{lstlisting}
  \qed
\end{exemple}


\subsection{Commandes avec arguments}
\label{sec:commandes:commandes:avec_arg}

Les commandes \cmdprint{\newcommand} et \cmdprint{\renewcommand} ont
d'autres tours dans leur sac. Leur syntaxe étendue permet également de
définir ou de redéfinir des commandes acceptant un ou plusieurs
arguments:
\begin{lstlisting}
\newcommand{`\bs\meta{nom\_commande}'}`\oarg{narg}\marg{définition}'
\renewcommand{`\bs\meta{nom\_commande}'}`\oarg{narg}\marg{définition}'
\end{lstlisting}
Le nouvel argument \meta{narg} est un nombre entre 1 et 9
spécifiant le nombre d'arguments de la commande. La \meta{définition}
de la commande doit alors contenir des jetons \code{\#1}, \code{\#2},
\dots\ pour identifier les endroits où les arguments 1, 2, \dots\
doivent apparaitre.

\begin{exemple}
  La nouvelle commande \cmdprint{\pkg} mentionnée à
  l'\autoref{ex:commandes:intro} affiche les noms de paquetages en
  caractères gras. La commande prend en argument le nom du paquetage.
  Sa définition est donc
\begin{lstlisting}
\newcommand{\pkg}[1]{\textbf{#1}}
\end{lstlisting}
  Il s'agit encore d'une commande sémantique permettant de changer
  aisément la mise en forme en modifiant une seule définition dans le
  préambule du document. %
  \qed
\end{exemple}

\begin{exemple}
  \label{ex:commandes:doc}
  La commande \cmdprint{\doc} mentionnée à
  l'\autoref{ex:commandes:intro} requiert trois arguments:
  \begin{enumerate}
  \item le texte de l'hyperlien qui sera placé au fil du texte;
  \item le nom du fichier de documentation à placer dans la marge dans
    une police non proportionnelle;
  \item l'adresse URL vers le fichier de documentation en ligne.
  \end{enumerate}
  Voici une version simplifiée de la définition de la commande:
\begin{lstlisting}
\newcommand{\doc}[3]{%
  \href{#3}{#1~\faExternalLink*}%
  \marginpar{\faBookmark~\texttt{#2}}}
\end{lstlisting}
  La commande \cmd{\href} qui permet d'insérer un hyperlien dans le
  texte provient du paquetage \pkg{hyperref} \citep{hyperref}. Les
  commandes \cmdprint{\faEx\-ter\-nal\-Link*} et \cmdprint{\faBookmark}
  proviennent du paquetage \pkg{fontawesome5} \citep{fontawesome5};
  elles insèrent dans le texte des icônes de la police libre %
  \link{https://fontawesome.com}{Font~Awesome}. %

  Avec la définition ci-dessus, la déclaration
\begin{lstlisting}
\doc{documentation}{hyperref}{%
  https://texdoc.net/pkg/hyperref}
\end{lstlisting}
  produit: \doc{hyperref}{https://texdoc.net/pkg/hyperref}. %
  \qed
\end{exemple}


\section{Nouveaux environnements}
\label{sec:commandes:environnements}

Tel que mentionné en introduction du chapitre, {\LaTeX} permet
également à l'utilisateur de définir ou de modifier des
environnements. La mécanique est similaire à celle de la définition de
commandes, sauf qu'un environnement compte trois parties: le début,
marqué par la déclaration \cmdprint{\begin\marg{...}} et, parfois, des
  commandes de configuration de l'environnement; le contenu en tant
  que tel; la fin, marquée par la déclaration
  \cmdprint{\end\marg{...}}.

Les commandes suivantes servent à créer ou à modifier des
environnements:
\begin{lstlisting}
\newenvironment`\marg{nom\_env}\oarg{narg}\marg{début\_déf}\marg{fin\_déf}'
\renewenvironment`\marg{nom\_env}\oarg{narg}\marg{début\_déf}\marg{fin\_déf}'
\end{lstlisting}
Les nombreux arguments sont les suivants:
\begin{list}{}{%
    \setlength{\labelsep}{1.5ex}
    \settowidth{\labelwidth}{\meta{début\_déf}}
    \setlength{\leftmargin}{\labelwidth}
    \addtolength{\leftmargin}{\labelsep}
    \setlength{\parsep}{0.5ex plus0.2ex minus0.2ex}
    \setlength{\itemsep}{0.3ex}
    \renewcommand{\makelabel}[1]{\meta{#1}\hfill}}
%

\item[nom\_env] nom de l'environnement à créer ou à modifier.
  Il est fortement recommandé de ne pas modifier les environnements de
  base de {\LaTeX};
\item[narg] un nombre entre 1 et 9 représentant le nombre
  d'arguments de l'environnement, lorsqu'il y en a. Les arguments sont
  utilisés de la même manière que dans les définitions de commandes;
\item[début\_déf] commandes et texte à insérer au début de
  l'environnement, lors de l'appel \cmdprint{\begin\marg{nom\_env}}.
  C'est dans ce bloc que doivent se trouver les jetons \code{\#1},
  \dots, \code{\#}\meta{narg} lorsque l'environnement a des
  arguments.
\item[fin\_déf] commandes et texte à insérer à la fin de
  l'environnement, lors de l'appel \cmdprint{\end\marg{nom\_env}}.
  \end{list}

\begin{exemple}
  \label{ex:commandes:citation}
  Créons un environnement pour composer les citations hors paragraphe
  de la manière suivante:
  \begin{quote}
    \small\itshape%
    Texte en italique, dans une police de taille inférieure au texte
    normal et en retrait des marges gauche et droite.
  \end{quote}
  Ceci est simple à réaliser en se basant sur l'environnement standard
  \Ie{quote} et en modifiant les attributs de police:
\begin{lstlisting}
\begin{quote}
  \small\itshape%
  Texte en italique...
\end{quote}
\end{lstlisting}

  Pour automatiquement composer toutes les citations de la même
  manière, il suffit de créer un nouvel environnement, disons
  \Ie{citation}:
\begin{lstlisting}
\newenvironment{citation}%
  {\begin{quote}\small\itshape}%
  {\end{quote}}
\end{lstlisting}
  Le bloc de code ci-dessus peut ensuite être remplacé par
\begin{lstlisting}
\begin{citation}
  Texte en italique...
\end{citation}
\end{lstlisting}
  \qed
\end{exemple}

\tipbox{N'hésitez pas à créer des nouvelles commandes et des nouveaux
  environnements dès lors qu'une mise en forme particulière revient
  plus d'une ou deux fois dans un document.}



%%%
%%% Exercices
%%%

\section{Exercices}
\label{sec:commandes:exercices}

\Opensolutionfile{solutions}[solutions-commandes]

\begin{Filesave}{solutions}
\section*{Chapitre \ref*{chap:commandes}}
\addcontentsline{toc}{section}{Chapitre \protect\ref*{chap:commandes}}

\end{Filesave}

\begin{exercice}
  Certains auteurs composent les sigles et les acronymes\footnote{%
    Un sigle est une abréviation formée par une suite de lettres qui
    sont les initiales d'un groupe de mots. Un acronyme est un sigle
    qui se prononce comme un mot ordinaire.} %
  en petites capitales, avec ou sans les points: \textsc{c.q.f.d.},
  \textsc{nasa}.
  \begin{enumerate}
  \item Créer une commande \cmdprint{\NASA} qui insère l'acronyme
    \textsc{nasa} dans le texte. Rappelons que l'on compose du texte en petites
    capitales avec la commande \cmd{\textsc}.
  \item Créer une commande plus générale \cmdprint{\sigle} qui affiche
    son argument en petites capitales. La commande devra convertir
    l'argument en minuscules avec \cmd{\MakeLowercase} afin que le
    résultat soit toujours le même peu importe la casse utilisée dans
    le code. Ainsi, \lstinline=\sigle{nasa}=, \lstinline=\sigle{Nasa}= et
    \lstinline=\sigle{NASA}= donneront toujours
    \textsc{nasa}.
  \item Après avoir utilisé la commande \cmdprint{\sigle} à quelques
    reprises dans un document, modifier sa définition pour plutôt
    composer les sigles en majuscules.
  \end{enumerate}
  Utiliser le gabarit de document \fichier{exercice-gabarit.tex} pour
  créer et tester les commandes ci-dessus.
  \begin{sol}
    \begin{enumerate}
    \item \lstinline=\newcommand{\NASA}{\textsc{nasa}}=
    \item \lstinline=\newcommand{\sigle}[1]{\textsc{\MakeLowercase{#1}}}=
    \item \lstinline=\newcommand{\sigle}[1]{\MakeUppercase{#1}}=
    \end{enumerate}
  \end{sol}
\end{exercice}

\begin{exercice}
  Je n'ai pas abordé dans le chapitre une fonctionnalité plus avancée
  de \cmd{\newcommand} et \cmd{\renewcommand}, soit celle de pouvoir
  définir des commandes dont un argument est optionnel ou, plus
  précisément, de donner une valeur par défaut à un argument.

  La syntaxe réellement complète de \cmd{\newcommand} et
  \cmd{\renewcommand} est la suivante:
\begin{lstlisting}
\newcommand{`\bs\meta{nom\_commande}'}`\oarg{narg}\oarg{option}\marg{déf}'
\renewcommand{`\bs\meta{nom\_commande}'}`\oarg{narg}\oarg{option}\marg{déf}'
\end{lstlisting}
  L'argument additionnel \meta{option} contient la valeur par défaut
  du \emph{premier} argument de \bs\meta{nom\_commande}. Dès lors, la
  commande ne compte plus \meta{narg} arguments obligatoires, mais
  bien $\text{\meta{narg}} - 1$ arguments obligatoires et un optionnel.

  Modifier la définition de la commande \cmdprint{\doc} de
  l'\autoref{ex:commandes:doc} pour que «documentation» soit le texte
  par défaut de l'hyperlien qui est placé au fil du texte.
  \begin{sol}
    Avec la définition
\begin{lstlisting}
\newcommand{\doc}[3][documentation]{%
  \href{#3}{#1~\raisebox{-0.2ex}{\faExternalLink}}%
  \marginpar{\faBookmark~\texttt{#2}}}
\end{lstlisting}
    la déclaration à deux arguments
\begin{lstlisting}
\doc{hyperref}{https://texdoc.net/pkg/hyperref}
\end{lstlisting}
    produit toujours \doc{hyperref}{https://texdoc.net/pkg/hyperref}.
  \end{sol}
\end{exercice}

\begin{exercice}
  Modifier l'environnement \Ie{citation} de
  l'\autoref{ex:commandes:citation} afin de composer les citations
  hors paragraphe comme suit:
  \begin{quote}
    \begin{tabularx}{\linewidth}{X}
      \toprule
      \small\sffamily%
      La citation est toujours en retrait des marges gauche et droite,
      mais également surmontée et suivie de filets horizontaux. Le
      texte est en police de taille \cmdprint{\small}, droite et sans
      empattements. \\
      \bottomrule
    \end{tabularx}
  \end{quote}
  \emph{Astuce}: utiliser un tableau pleine largeur à l'intérieur de
  l'environnement \Pe{quote} pour disposer le texte et créer les
  filets horizontaux.
  \begin{sol}
    La définition suivante donne les résultats demandés:
\begin{lstlisting}
\newenvironment{citation}
  {\begin{quote}
     \begin{tabularx}{\linewidth}{X}
       \toprule\small\sffamily}%
  {\\ \bottomrule
     \end{tabularx}
   \end{quote}}
\end{lstlisting}
    Dans le troisième argument, la présence de la commande de fin de
    ligne {\pixbsbs} doit précéder \cmdprint{\bottomrule}.
  \end{sol}
\end{exercice}

\Closesolutionfile{solutions}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "formation-latex-ul"
%%% TeX-engine: xetex
%%% coding: utf-8
%%% End:
