%\iffalse
% makegobbler.dtx generated using makedtx version 1.3 (c) Nicola Talbot
% Command line args:
%   -dir ../../latex
%   -src "makegobbler\.sty\$=>makegobbler.sty"
%   -doc ../../doc/makegobbler-doc.tex
%   -codetitle "Le code"
%   -author "Vincent Bela{\\\"\i}che"
%   --nodrivendoc
%   makegobbler
% Created on 2026/2/16 10:18
%\fi
%\iffalse
%<*package>
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%</package>
%\fi
% \iffalse
% Doc-Source file to use with LaTeX2e
% Copyright (C) 2026 Vincent Bela{\"\i}che, all rights reserved.
% \fi
% \iffalse
%<*driver>
% !TEX encoding = IsoLatin9
\documentclass[a4paper]{ltxdoc}

\usepackage[latin9]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{doc}
\usepackage{efrench}
% Grosse magouille non à l'épreuve du temps pour contre-carrer ce que fait eFrench
{\makeatletter\@ifundefined{fr@di}{\let\@tempa\@empty}{\def\@tempa{\let\DocInput\fr@di}}\expandafter}\@tempa
\newcommand*\enquote[1]{\guillemets\,#1\,\endguillemets}
\usepackage[french]{datetime2}
\DTMsetstyle{french}
\DTMsavedate{date-doc}{2026-02-15}
\usepackage{amssymb}
\usepackage{placeins}
\usepackage{hyperref}
\usepackage{listings}
\lstset{language=bash}
\makeatletter
\newcommand*\codelinelabel[1]{%
  {\protected@edef\@currentlabel{\the\c@CodelineNo}%
    \label{#1}}}
\makeatother
\date{\DTMusedate{date-doc}}
\title{Le paquetage \texttt{makegobbler} v0.3.2 ({\DTMsetdatestyle{iso}\DTMusedate{date-doc}})}%\\{\protect\small Une fabrique conditionnelle à gobeurs ou dégobeurs}}
\author{Vincent Belaïche}
\newcommand*\vs{\leavevmode\hbox{\tt\char`\ }}
\newcommand\exampleframe[1]{\centering
  \framebox[\textwidth]{%
    \begin{minipage}[t]{\dimexpr\textwidth-2\fboxrule-2\fboxsep}\ttfamily\raggedright
      #1%
    \end{minipage}%
  }}%
\newenvironment{exemple}{\begin{figure}[h!t]}{\end{figure}\FloatBarrier}
\newenvironment{exemple*}{\mbox{}\\[.25ex]\begingroup}{\endgroup\\[.25ex]\noindent}
\providecommand*\DocTeX{Doc\TeX}
\begin{document}
\renewcommand*\listfigurename{Liste des exemples}%^^A
\renewcommand*\figurename{\textsc {Exemple}}%^^A
\maketitle
\tableofcontents
\listoffigures

\section{Introduction}
\label{sec:intro}

Le but du paquetage \texttt{makegobbler} est de faciliter l'omission conditionnelle d'une portion de document. Un exemple
valant mieux qu'un long discours :

\begin{exemple}
  \exampleframe{%^^A
    \cs{newif}\cs{ifgarde}\\
    \ldots\\
    \cs{MGBkeep*}\cs{ifgarde}\\
    \cs{LaMacroQuiGobeTout}\\
    Bla Bla bla, texte inséré conditionnellement seulement si \cs{gardetrue}.\\
    \cs{LaMacroQuiGobeTout}
  }%^^A
  \caption{Exemple introductif}
  \label{ex:intro}
\end{exemple}

Dans l'exemple ci-dessus la macro \cs{LaMacroQuiGobeTout} est ci-après désignée par \emph{délimiteur}, et on
peut utiliser n'importe quel nom \meta{délimiteur} de macro \cs{}\meta{délimiteur} au lieu de
\cs{LaMacroQuiGobeTout}. Dans le cas où \cs{gardefalse} tout ce qui est entre les deux
\cs{}\meta{délimiteur}s est supprimé (gobé), et dans le cas inverse, quand \cs{gardetrue}, c'est conservé
(dégobé).\\ Dans le premier cas, le premier \cs{}\meta{délimiteur} est défini comme une macro de gobage, ou
gobeur, gobant tout jusqu'à une marque de fin qui est le second \cs{}\meta{délimiteur} vu comme une
string\footnote{\texttt{string} en \LaTeX\ signifie une chaîne d'unités lexicales qui sont des caractères de
  catcode \texttt{other} ou \texttt{space}, dans le cas de \texttt{makegobbler} le \cs{}\meta{délimiteur} de
  fin ne comprend que des caractères de catcode \texttt{other}.}, et c'est la raison du nom
\texttt{makegobbler} du paquetage, parce qu'il fait du premier \cs{}\meta{délimiteur} un gobeur.

\section{Usage et limitations}
\label{sec:use-and-limits}

\subsection{Motivations}
\label{sec:motivations}

Le paquetage \texttt{makegobbler} n'est pas fait pour remplacer les constructions conditionnelles de \TeX\ du genre de :
\begin{exemple}
  \exampleframe{%^^A
    \cs{newcommand}*\cs{Un}\{2\}\%\\
    \ldots\\
    \cs{ifnum}\cs{Un}=1 C'est un\cs{else} C'est deux\cs{fi}
  }%^^A
  \caption{Gobage conditionnel classique à la \TeX}
\end{exemple}
\noindent ni plus la macro \cs{ifthenelse} du paquetage \LaTeX\ \texttt{ifthen} qu'on peut utiliser ainsi :
\begin{exemple}
  \exampleframe{%^^A
    \cs{newcommand}*\cs{Un}\{2\}\%\\
    \ldots\\
    \cs{ifthenelse}\{\cs{Un}=1\}\{C'est un\}\{C'est deux\}
  }%^^A
  \caption{Gobage conditionnel classique à la \LaTeX}
\end{exemple}
\noindent bien au contraire, \texttt{makegobbler} s'appuie justement sur ces constructions pour tester les conditions de
gobage ou dégobage, et son objectif est plutôt de pallier certaines limitations du gobage effectué par ces méthodes
classiques. L'exemple \ref{ex:lim-ltx-spec-car} illustre\footnote{Aux non-francophones, c'est extrait des paroles de la
  chanson \emph{Comic strip} de Serge Gainsbourg, la drôlerie des paroles vient qu'en franglais \emph{strip} n'est connu
  que dans son sens \emph{dévêtir} et non dans son sens \emph{bande}.} cela : si vous décommentez le
\cs{alternativetrue} il produit une erreur \texttt{You can\string't use \string`macro parameter character \#\string' in
  horizontal mode.}.

\begin{exemple}
  \exampleframe{%^^A
    \cs{newif}\cs{ifalternative}\\
    \%\cs{alternativetrue}\\
    \ldots\\
    Viens petite fille dans mon comic strip\\
    \ldots\\
    \cs{ifthenelse}\{\cs{boolean}\{alternative\}\}\{\cs{verb}+\#!+\}\{SHEBAM !\} POW ! BLOP ! WIZZ !
  }%^^A
  \caption{Limitation d'{\tt\cs{ifthenelse}} avec des caractères spéciaux}
  \label{ex:lim-ltx-spec-car}
\end{exemple}

Cela se produit parce que \cs{verb} fonctionne en changeant le régime de catcode de ce qui suit, mais pour que cela
fonctionne il faut que \cs{verb} soit exécuté\footnote{Le deuxième étage de \TeX, c-à-d. la gueule du lion.}. Or si on
passe \texttt{\cs{verb}+\#!+} en argument à \cs{ifthenelse} le catcode de \texttt{\#} est fixé au moment de la capture
de l'argument, car celle-ci impose de passer le premier étage\footnote{Les yeux du lion.} de \TeX, celui qui convertit
les caractères en unités lexicales, et donc \texttt{\#} conserve son catcode initial 6 (qui veut dire argument de macro)
et \cs{verb} n'y pourra rien changer.

Le paquetage \texttt{makegobbler} résout le problème de l'exemple \ref{ex:lim-ltx-spec-car} parce que les sections
dégobées ne sont pas passées en argument de macro, et d'ailleurs pour la même raison l'utilisation d'une condition à la
\TeX\ aurait aussi résolu le problème, comme dans l'exemple \ref{ex:tex-cond-spec-car} ci-dessous :

\begin{exemple}
  \exampleframe{%^^A
    \cs{newif}\cs{ifalternative}\\
    \cs{alternativetrue}\\
    \ldots\\
    Viens petite fille dans mon comic strip\\
    \ldots\\
    \cs{ifalternative}\cs{verb}+\#!+\cs{else} SHEBAM !\cs{fi}\cs{space} POW ! BLOP ! WIZZ !
  }%^^A
  \caption{Caractères spéciaux avec une condition à la \TeX}
  \label{ex:tex-cond-spec-car}
\end{exemple}

Bien sûr dans ces exemples simplistes il aurait suffit d'écrire \texttt{\cs{texttt}\{\cs{\#}!\}} au lieu de
\texttt{\cs{verb}+\#!+} et cela aurait aussi fonctionné, mais le prix de cela est d'écrire un code moins lisible.


Utiliser des conditions à la \TeX\ n'est toutefois pas une solution ultime, en effet il reste des cas qui ne
fonctionnent pas même avec les conditions à la \TeX, l'exemple \ref{ex:lim-tex-if} en illustre un :

\begin{exemple}
  \exampleframe{%^^A
    \cs{newif}\cs{ifok}\\\cs{oktrue}\\
    \ldots\\
    \cs{ifok} À minuit les carrosses redeviennent des c\cs{verb}+\cs{iftrue}+illes.\cs{fi}
  }%^^A
  \caption{Limitations d'\cs{if}\ldots}
  \label{ex:lim-tex-if}
\end{exemple}

Si vous mettez en commentaire le \cs{oktrue} alors il y aura une erreur de compilation \texttt{Incomplete \cs{iffalse};
  all text was ignored after line \ldots} La raison pour laquelle cela échoue est que le \cs{ifok} pour gober tout ce
qui suit jusqu'au \cs{fi} suivant teste tout de même s'il y a des unités lexicales de type \cs{if}\ldots, de sorte à
tomber sur le bon délimiteur de fin \cs{fi}. En faisant cela il considère par erreur que le \cs{iftrue} qui est passé
dans \texttt{\cs{verb}+\ldots+} attend un \cs{fi}, et donc il considère que le \cs{fi} suivant correspond à ce
\cs{iftrue} et non à \cs{ifok}.

Avec \texttt{makegobbler} ce problème est résolu parce que l'utilisateur donne un délimiteur \cs{}\meta{délimiteur} arbitraire, et donc en cas de gobage avec imbrications de plusieurs sections en gobage/dégobage conditionnels il suffit d'utiliser un \cs{}\meta{délimiteur} propre à chaque niveau d'imbrication.

Dans cette rubrique j'ai surtout mentionné les problèmes qu'on peut avoir avec \cs{verb} que vous n'utilisez peut-être
jamais. Sachez que c'est loin d'être le seul cas, et que toutes macros ou environnements qui jouent avec le régime de
catcode sont sujets aux mêmes types de limitations, et d'ailleurs les questions posées par les débutants sur les forums
ne concernent pas rarement la survenue de cette famille de problèmes. Notons par exemple\footnote{Cette liste n'est en aucun cas exhaustive.} que :
\begin{itemize}
\item \cs{includegraphics} avec les paquetages \texttt{graphicx,grffile} est capable de traiter correctement certains
  caractères spéciaux, comme par ex. \texttt{\~}, au sein d'un nom de fichier en changeant son régime de catcode,
\item \cs{href} et \cs{url} du paquetage \texttt{hyperref} sont également concernés pour traiter correctement certains
  caractères spéciaux au sein d'\textsc{url}s, ou encore
\item l'environnement \texttt{lstlisting} et la macro \cs{lstinline} de l'excellent paquetage \texttt{listings}, par
  exemple avec un listing en langage C on peut avoir typiquement des directives préprocesseur \texttt{\#if CONDITION}
  qui poseraient problème si vous essayez de les dégober avec \cs{ifthenelse}.
\end{itemize}

\subsection{Limitations de \protect\texttt{makegobbler}}
\label{sec:mgb-limits}

Si vous avez lu attentivement la rubrique \S\ref{sec:motivations} alors vous savez déjà qu'utiliser les macros de
\texttt{makegobbler} au sein d'un argument de macro est voué à l'échec : comme \cs{verb} les macros de
\texttt{makegobbler} jouent avec les catcodes, et donc produisent le même type de limitations.

Au sein de la plupart des environnements, cela au contraire va fonctionner. Et d'ailleurs si cela ne fonctionnait pas au
sein de l'environnement \texttt{document}, alors le paquetage serait inutilisable. Toutefois avec certains
environnements cela ne fonctionnera pas. En effet un environnement \meta{env} peut être de deux types :
\begin{itemize}
\item soit c'est un environnement \emph{fil-de-l'eau}, dans ce cas le \texttt{\cs{begin}\{\meta{env}\}} et sa
  contrepartie \texttt{\cs{end}\{\meta{env}\}} sont juste comme deux macros qui activent et désactivent certaines
  conditions de traitement de ce qu'il y a entre les deux, par exemple la police, ou bien le régime de catcode ou encore
  le paramétrage de formation de paragraphes,
\item soit c'est un environnement \emph{aspirant}, cela signifie que tout ce qui se trouve entre
  \texttt{\cs{begin}\{\meta{env}\}} et \texttt{\cs{end}\{\meta{env}\}} est préalablement aspiré comme si c'était
  l'argument d'une macro de sorte à avoir une liste d'unités lexicales, et qu'ensuite cette liste est post-traitée.
\end{itemize}
Les macros de \texttt{makegobbler} ne vont donc fonctionner correctement pour gober/dégober des sections de code entre
\texttt{\cs{begin}\{\meta{env}\}} et \texttt{\cs{end}\{\meta{env}\}} que si \meta{env} est un environnement fil-de-l'eau, mais elles ne fonctionneront pas avec un environnement aspirant, puisqu'on se retrouve dans la même situation que si le code était au sein d'un argument de macro. Voici quelques environnements aspirants :
\begin{itemize}
\item la plupart des environnements du paquetage \texttt{amsmath},
\item tous les environnements créés avec la macro \cs{NewEnviron} du paquetage \texttt{environ}, et
\item l'environnement \texttt{frame} de la classe \texttt{beamer}, sauf dans le cas où il reçoit l'argument optionnel
  \texttt{fragile}.
\end{itemize}

\section{Installation}
\label{sec:org38df004}

Ci-dessous la variable d'environnement \lstinline{TEXMF_INSTALL_DIR} pointe sur le répertoire \textsc{texmf} où l'on
désire effectuer l'installation.

\subsection{Installation à partir du CTAN}
\label{sec:orgc58fdc8}

Le script bash suivant peut être utilisé pour installer le paquetage à partir du \textsc{ctan}, vous aurez besoin
d'outils tels que \texttt{wget}, \texttt{latexmk}, \texttt{perl} (pour faire tourner \texttt{latexmk}) et d'une
distribution \LaTeX{} :

\begin{lstlisting}
# crée un répertoire temporaire pour faciliter le nettoyage
work_dir=$(mktemp -d /tmp/makegobbler-install.XXXXXX)
pushd $work_dir
# otient le paquetage
wget https://mirror.ctan.org/macros/latex/contrib/makegobbler.zip
# unzip
unzip makegobbler.zip
cd makegobbler
# set TEXMF_INSTALL_DIR to the installation target TEXMF
[ -d "$TEXMF_INSTALL_DIR" ] || TEXMF_INSTALL_DIR=$(HOME)/texmf
pdftex makegobbler.ins
mkdir -p "$TEXMF_INSTALL_DIR/tex/latex/makegobbler"
cp makegobbler.sty "$TEXMF_INSTALL_DIR/tex/latex/makegobbler"
# génère la doc, sautez cette étape pour ne pas recompiler le manuel
latexmk -pdf makegobbler.dtx
mkdir -p "$TEXMF_INSTALL_DIR/doc/latex/makegobbler"
cp makegobbler.pdf "$TEXMF_INSTALL_DIR/doc/latex/makegobbler/makegobbler-doc.pdf"
# nettoyage
popd
rm -fr $work_dir
\end{lstlisting}


\subsection{Installation à partir du dépôt SVN}
\label{sec:orga57a57e}

Si vous désirez --- à vos risques et périls --- la toute dernière version de développement possiblement encore non
plubliée sur le \textsc{ctan} alors vous pouvez utiliser le script bash suivant. Vous auez beseoin d'un client
\texttt{svn} ainsi que du \texttt{make} de GNU.

\begin{lstlisting}
# crée un répertoire temporaire pour faciliter le nettoyage
work_dir=$(mktemp -d /tmp/makegobbler-install.XXXXXX)
pushd $work_dir
# obtient les sources du paquetage
svn checkout https://svn.gnu.org.ua/sources/latex-makegobbler/trunk .
# set TEXMF_INSTALL_DIR to the installation target TEXMF
[ -d "$TEXMF_INSTALL_DIR" ] || TEXMF_INSTALL_DIR=$(HOME)/texmf
export TEXMF_INSTALL_DIR
# make est le GNUmake
make install README_EXT=org
# nettoyage
popd
rm -fr $work_dir
\end{lstlisting}


\section{Chargement du paquetage}
\label{sec:pkg-loading}


Charger le paquetage en plaçant dans votre préambule :
\begin{exemple}
  \exampleframe{%^^A
    \cs{usepackage\{makegobbler\}}
  }
\end{exemple}
\noindent pour un chargement sans options, ou bien :
\begin{exemple}
  \exampleframe{%^^A
    \cs{usepackage[}\meta{options}\texttt{]\{makegobbler\}}  
  }
\end{exemple}
\noindent pour passer \meta{options}, cf.\ \S\,\ref{sec:package-options}.

\section{Options du paquetage}
\label{sec:package-options}

Le paquetage a deux options :

\begin{description}
\item[ifthen] Juste une commodité pour charger le paquetage \texttt{ifthen}, ceci est nécessaire pour utiliser
  les macros de (dé)gobage conditionnel avec une condition à la \LaTeX.
\item[tense] Ne pas utiliser sauf si vous savez ce que vous faites. Voir la documentation du code \S \ref{descr:tense-opt} page \pageref{descr:tense-opt}, après la ligne de code \ref{ln:tense}.
\end{description}

\section{Interface utilisateur}
\subsection{Macros pour un gobage ou dégobage conditionnel}
\label{sec:conditional-macros}

Le paquetage offre quatre macros pour le (dé)gobage conditionnel d'un bout de code \LaTeX : \cs{MGBkeep},
\cs{MGBdrop}, \cs{MGBkeepelse}, et \cs{MGBdropelse}. Les deux premières utilisent deux
\cs{}\meta{délimiteur}s, et les deux dernières trois.

Chacune de ces macros a pour premier argument une condition. La syntaxe est la suivante :

\begin{exemple}
  \exampleframe{%^^A
    \cs{MGBkeep}\meta{étoile}\meta{condition}\cs{}\meta{délimiteur}\\
    \quad\meta{dégobé}\\
    \cs{}\meta{délimiteur}}%^^A
\end{exemple}
\meta{dégobé} peut être n'importe quoi entre les deux \cs{}\meta{délimiteur}s, et il est dégobé si
\meta{condition} est vraie, et gobé sinon. Avec \cs{MGBdrop} c'est le contraire, la condition de débogage
est\footnote{\enquote{$\neg C$} signifie \enquote{non $C$}.}  $\neg$\meta{condition}.

Avec les deux autres macros, \cs{MGBkeepelse} et \cs{MGBdropelse}, on a deux branches, l'une contenant
\meta{gobé} et l'autre \meta{dégobé} :

\begin{exemple}
  \exampleframe{%^^A
    \cs{MGBkeepelse}\meta{étoile}\meta{condition}\cs{}\meta{délimiteur}\\
    \quad\meta{dégobé}\\
    \cs{}\meta{délimiteur}\\
    \quad\meta{gobé}\\
    \cs{}\meta{délimiteur}}%^^A
\end{exemple}
Dans ce cas si \meta{condition} est vraie, \meta{dégobé} est dégobé, et \meta{gobé} est gobé, et sinon, si
\meta{condition} est faux, c'est le contraire. En utilisant \cs{MGBdropelse}, la branche \meta{gobé}
correspondant au gobage sous \meta{condition} est donnée en premier, et celle \meta{dégobé} correspondant au
dégobage en second.

\begin{exemple}
  \exampleframe{%^^A
    \cs{MGBdropelse}\meta{étoile}\meta{condition}\cs{}\meta{délimiteur}\\
    \quad\meta{gobé}\\
    \cs{}\meta{délimiteur}\\
    \quad\meta{dégobé}\\
    \cs{}\meta{délimiteur}}%^^A
\end{exemple}
\meta{étoile} peut être soit \texttt{*} soit vide, dans le premier cas on dit que la macro est étoilée, et
dans le second qu'elle est non-étoilée. Si la macro est non-étoilée, alors la condition est une condition à la
\LaTeX, c'est-à-dire une condition telle que la prend en premier argument la macro \cs{ifthenelse} du
paquetage \texttt{ifthen}, par exemple\footnote{\meta{condition} correspond à
  \texttt{\{}\meta{test}\texttt{\}} dans le manuel de \texttt{ifthen}.}
\texttt{\{}\cs{boolean}\texttt{\{true\}\}} ou \texttt{\{}\cs{equal}\texttt{\{}\meta{chaîne
  1}\texttt{\}\{}\meta{chaîne 2}\texttt{\}\}}.  Se reporter à la documentation de ce paquetage pour plus ample
information. Avec les formes non étoilées il faut donc que le paquetage \texttt{ifthen} ait été chargé, ce que
vous pouvez faire en passant l'option \texttt{ifthen} à \texttt{makeglobber}.

Avec la forme étoilée, le premier argument doit être une condition à la \TeX, c'est-à-dire :
\begin{itemize}
\item soit une condition\footnote{Toto a un cousin anglais complètement foo.} \cs{iftoto} instanciée
  avec une commande \cs{newif}\cs{iftoto} et pouvant être commutée avec les macros \cs{totofalse} et
  \cs{tototrue},
\item soit une condition utilisant l'un des opérateurs de branchement conditionnel prédéfini dans \TeX, par
  ex. \cs{ifmmode}, \texttt{\{}\cs{ifnum}\meta{a}=\meta{b}\vs\texttt{\}},
  \texttt{\{}\cs{ifx}\cs{}\meta{a}\cs{}\meta{b}\texttt{\}}, etc.\ Notez que dans les cas où \meta{condition}
  consiste en plusieurs unités lexicales il faut\footnote{Ceci n'a rien à voir avec le paquetage
    \texttt{makeglobber}, c'est une règle générale de \TeX, lorsqu'un argument de macro consiste en une
    séquence de plusieurs unités lexicales on le met entre accolades pour le passer d'un seul tenant à la
    macro. Lorsque il y a une seule unité lexicale, alors les accolades sont optionnelles, on peut passer
    \texttt{\{}\cs{iftoto}\texttt{\}} aussi bien que \cs{iftoto}.} l'écrire entre accolades.
\end{itemize}

\subsection{Macros pour un gobage ou dégobage inconditionnel}
\label{sec:elementary-macros}

Le paquetage fournit également deux macros de plus bas niveau \cs{makegobbler} et \cs{makeungobbler} qu'en général
l'utilisateur \emph{lambda} n'a pas besoin d'utiliser directement, et qui servent respectivement au gobage et au
dégobage inconditionnel d'un bout de code \LaTeX.

Je décris ci-après ci-après ces deux macros parce qu'elles constituent le mécanisme sous-jacent du paquetage,
c'est-à-dire que sous le capot, les macros pour le gobage et/ou dégobage conditionnel, \cs{MGBkeep},
\cs{MGBdrop}, \cs{MGBkeepelse}, et \cs{MGBdropelse}, finissent par se développer, selon la \meta{condition}
qui leur est passée, en un \cs{makegobbler} ou un \cs{makeungobbler}

Le nom du paquetage provient d'ailleurs de ce que le délimiteur \cs{}\meta{délimiteur} peut être utilisé avec
\cs{makegobbler} pour supprimer tout ce qui suit jusqu'au prochain \cs{}\meta{délimiteur}, comme ci-dessous,
où pour l'exemple \cs{}\meta{délimiteur} est nommé \cs{LaMacroQuiGobeTout} :

\begin{exemple}
  \exampleframe{%^^A
    \cs{makegobbler}\cs{LaMacroQuiGobeTout}\\
    Bla Bla bla, tout le texte ici est supprimé.\\
    \cs{LaMacroQuiGobeTout}
  }%^^A
\end{exemple}
On appelle cette suppression \emph{gobage}, et on dit que \cs{LaMacroQuiGobeTout} est un gobeur, la macro \cs{makegobbler}
sert donc à fabriquer un gobeur du nom de \cs{LaMacroQuiGobeTout} qui va tout gober jusqu'à rencontrer une marque de fin
également nommé \cs{LaMacroQuiGobeTout}, sauf que du point de vue \emph{catcodique} la première occurrence de \cs{LaMacroQuiGobeTout} est une
séquence de contrôle, alors que la seconde est une \texttt{string}, c'est-à-dire une suite de caractères de
catcode \texttt{other}.

Si on avait utilisé \cs{makeungobbler} à la place de \cs{makegobbler} alors le texte aurait été inséré au lieu d'être
supprimé :

\begin{exemple}
  \exampleframe{%^^A
    \cs{makeungobbler}\cs{LaMacroQuiGobeTout}\\
    Bla Bla bla, tout le texte ici est inséré.\\
    \cs{LaMacroQuiGobeTout}
  }%^^A
\end{exemple}

Et donc dans l'exemple ci-dessus on parle de \emph{dégobage} et on dit qu'on a défini la macro \cs{LaMacroQuiGobeTout}
comme un dégobeur, c'est-à-dire qu'elle conserve tout ce qui suit jusqu'à la prochaine occurrence de
\cs{LaMacroQuiGobeTout} qui sert de marque de fin, et que cette marque de fin est supprimée.

Il est à noter que la définition de \cs{}\meta{délimiteur} comme une macro de gobage/dégobage est transitoire. Une fois
la marque de fin consommée, \cs{}\meta{délimiteur} reprend sa valeur initiale si elle en avait une, ou sinon redevient
indéfini.

\section{Remerciements}

Un grand merci à \href{https\string://texnique.fr/osqa/users/53/quark67}{quark67} pour sa relecture attentive du manuel.


\DocInput{makegobbler.dtx}
\end{document}
%</driver>
%\fi
%\StopEventually{}
%\section{Le code}
%\iffalse
%    \begin{macrocode}
%<*makegobbler.sty>
%    \end{macrocode}
%\fi
%^^A !TEX encoding = IsoLatin9
% \subsection{Options du paquetage}
% Les déclarations habituelles pour que \LaTeX\ connaisse le paquetage.
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[2020/10/01]
\ProvidesPackage{makegobbler}
  [2026-02-15 v0.3.2 %
    Gobbling macros maker]
%    \end{macrocode}
% \DescribeMacro{\MGB@process@ifthen@option} Une option juste pour dire de charger le paquetage \texttt{ifthen} qui
% permet d'avoir des conditions à la \LaTeX. La macro \cs{MGB@process@ifthen@option} sert juste à faire le
% \cs{RequirePackage\{ifthen\}} après le \cs{ProcessOptions}, c'est-à-dire qu'on la développe à cet endroit là. Elle
% s'autodétruit assitôt sa tâche accomplie, vu qu'on n'en a plus besoin par la suite.
%    \begin{macrocode}
\DeclareOption{ifthen}{\def\MGB@process@ifthen@option
  {\RequirePackage{ifthen}\let\MGB@process@ifthen@option\@undefined}}
%    \end{macrocode}
% Si l'option \texttt{ifthen} n'est pas passée, \cs{MGB@process@ifthen@option} ne fait rien mis à part s'autodétruire.
%    \begin{macrocode}
\def\MGB@process@ifthen@option{\let\MGB@process@ifthen@option\@undefined}
%    \end{macrocode}
% N'utilisez pas l'option \texttt{tense}, sauf si vous avez lu et compris le code qui l'utilise, et si vous recherchez
% un substitut à la caféine.
%    \begin{macrocode}
\newif\ifMGB@tense
\DeclareOption{tense}{\MGB@tensetrue}
%    \end{macrocode}
%    \begin{macrocode}
\ProcessOptions*
\MGB@process@ifthen@option
%    \end{macrocode}
%
%\subsection{Interface utilisateur}
%\label{sec:user-interface}
% \subsubsection{Macros de gobage/dégobage conditionnel}
% \DescribeMacro{\MGBkeep}%
% \DescribeMacro{\MGBdrop}%
% \DescribeMacro{\MGBkeepelse}%
% \DescribeMacro{\MGBdropelse} Définition des macros d'interface utilisateur, les quatre définitions ont sensiblement
% la même gueule parce qu'en premier lieu on ne fait que sélectionner si on passe une condition à la \TeX\ en étoilant
% la macro, ou bien à la \LaTeX\ en ne l'étoilant pas.
%    \begin{macrocode}
\def\MGBkeep{\MGB@stdhooks\@ifstar{\MGBkeep@tex}{\MGBkeep@latex}}
\def\MGBdrop{\MGB@stdhooks\@ifstar{\MGBdrop@tex}{\MGBdrop@latex}}
\def\MGBkeepelse{\MGB@elsehooks\@ifstar{\MGBkeep@tex}{\MGBkeep@latex}}
\def\MGBdropelse{\MGB@elsehooks\@ifstar{\MGBdrop@tex}{\MGBdrop@latex}}
%    \end{macrocode}
% \subsubsection{Macros de gobage/dégobage inconditionnel}
% Les quatre macros de gobage/dégobage conditionnel sous le capot finissent tôt ou tard par développer l'une des deux
% macros de plus bas niveau \cs{MGB@g} dans le cas d'un gobage, ou \cs{MGB@u} dans le cas d'un dégobage. Ces deux
% dernières sont également accessible depuis l'interface utilisateur, via respetivement les macros \cs{makeglobber} et
% \cs{makeunglobber}, en effet \cs{makeglobber} pourrait être utile par exemple en \DocTeX\ pour gober la section pilote
% du document \texttt{.dtx}.\\
% \DescribeMacro{\makegobbler}\DescribeMacro{\makeungobbler}Les macros \cs{makegobbler} et \cs{makeungobbler} délèguent le
% traitement proprement dit de gobage/dégobage à respectivement \cs{MGB@g} et \cs{MGB@u} avec le préliminaire de
% développer en premier lieu \cs{MGB@stdhooks}, ce dont on verra l'utilité en \S\,\ref{sec:hooks} :
%    \begin{macrocode}
\def\makegobbler{\MGB@stdhooks\MGB@g}%
\def\makeungobbler{\MGB@stdhooks\MGB@u}%
%    \end{macrocode}
% \DescribeMacro{\MGB@u}La macro \cs{MGB@u} a juste pour effet qu'elle gobe le délimiteur, et le définit
% de sorte qu'il se redéfinisse à sa valeur initiale. Donc ce qui suit entre les deux délimiteurs n'est pas gobé.
%    \begin{macrocode}
\def\MGB@u#1{\MGB@save@mark#1\def#1{\MGB@ungobblerhook#1}}%
%    \end{macrocode}
%
% \DescribeMacro{\MGB@g}%
%La macro \cs{MGB@g} prend en argument une séquence de contrôle \cs{}\meta{delimiteur}, et gobe tout ce qui suit
%jusqu'à rencontrer la string \cs{}\meta{delimiteur} :
%    \begin{macrocode}
\def\MGB@g#1{%
  \MGB@save@mark#1%
  \begingroup
  \expandafter\MGB@\expandafter
  {\string#1}#1\MGB@set@catcoderegime#1}%
%    \end{macrocode}
% \subsection{Gestion des crochets de fin de traitement}
% \label{sec:hooks}
% Notez que les deux macros \cs{MGBkeepelse} et \cs{MGBdropelse} ne se distinguent respectivement de \cs{MGBkeep} et
% \cs{MGBdrop} que par la macro \cs{MGB@elsehooks} au lieu de \cs{MGB@stdhooks}. En fait, le c½ur du
% réacteur c'est les macros \cs{MGB@g} et \cs{MGB@u}. Chacune des ces macros développe en fin de
% traitement respectivement une macro crochet \cs{MGB@gobblerhook}, resp.\ \cs{MGB@ungobblerhook}, dont la valeur par défaut \cs{MGB@stdhook} consiste à finir le traitement.\\
% \DescribeMacro{\MGB@stdhooks} La macro \cs{MGB@stdhooks} règle les définitions de ces deux macros crochets à leur valeur
% par défaut, après avoir empilé la valeur courante :
%    \begin{macrocode}
\def\MGB@stdhooks{%
%    \end{macrocode}
% Donc  en premier lieu, avant de faire ce réglage, elle empile la valeur courante des macros crochets, ceci permettant
% de cascader plusieurs niveaux de gobage/dégobage avec leur \cs{}\meta{délimiteur} respectifs :
%    \begin{macrocode}
  \MGB@pushhooks
%    \end{macrocode}
% puis elle fait le réglage proprement dit aux valeurs par défaut des crochets en développant la
% macro\cs{MGB@resethooks} :
%    \begin{macrocode}
  \MGB@resethooks
  }
%    \end{macrocode}
% \DescribeMacro{\MGB@resethooks}La macro \cs{MGB@resethooks} règle les définitions des deux macros crochets
% à leur valeur par défaut, c'est-à-dire celle qui termine le traitement, ou en d'autres termes celle qui correspond au
% fait que le \cs{}\meta{délimiteur} est le dernier :
%    \begin{macrocode}
\def\MGB@resethooks{%
  \let\MGB@gobblerhook\MGB@stdhook
  \let\MGB@ungobblerhook\MGB@stdhook
}
%    \end{macrocode}
% \DescribeMacro{\MGB@elsehooks} La macro \cs{MGB@elsehooks} ne fait que changer les définitions de ces macros crochets pour
% qu'un dégobage soit fait à la suite d'un gobage, ou resp.\ un gobage à la suite d'un dégobage, ceci permettant de
% traiter la branche \texttt{else}.
%    \begin{macrocode}
\def\MGB@elsehooks{%
%    \end{macrocode}
% Comme avec \cs{MGB@stdhooks}, la première chose qu'on fait c'est d'empiler la valeur courante des macros crochets, de
% sorte à pouvoir les dépiler en fin de gobage.
%    \begin{macrocode}
  \MGB@pushhooks
%    \end{macrocode}
% Donc on règle le crochet de gobage\ldots
%    \begin{macrocode}
  \def\MGB@gobblerhook##1{%
%    \end{macrocode}
% pour tout d'abord écraser les valeurs courantes des crochets de gobage/dégobage par les valeurs par défaut, sans pour
% autant changer l'état de la pile\ldots
%    \begin{macrocode}
    \MGB@resethooks
%    \end{macrocode}
% et ensuite faire un dégobage :
%    \begin{macrocode}
    \MGB@u##1}%
%    \end{macrocode}
% et pour le crochet de dégobage c'est l'inverse\ldots
%    \begin{macrocode}
  \def\MGB@ungobblerhook##1{%
%    \end{macrocode}
% comme précédement on règle les macros crochets aux valeurs par défaut sans changer l'état de la pile\ldots
%    \begin{macrocode}
    \MGB@resethooks
%    \end{macrocode}
% mais ensuite on enchaîne sur un gobage au lieu d'un dégobage :
%    \begin{macrocode}
    \MGB@g##1}%
}
%    \end{macrocode}
% \DescribeMacro{\MGB@stdhook}La macro \cs{MGB@stdhook} est la valeur par défaut des macros crochets, elle finit le
% traitement de gobage/dégobage : c'est-à-dire qu'elle restaure la macro \cs{}\meta{délimiteur} à sa valeur initiale\footnote{Sa valeur avant gobage (\cs{MGB@g}) ou dégobage (\cs{MGB@u}).} :
%    \begin{macrocode}
\def\MGB@stdhook#1{%
  \MGB@pophooks
  {\def\@tempa##1{\let#1##1\let##1\@undefined}%
    \expandafter\expandafter\expandafter}\expandafter
  \@tempa\csname MGB@save\string#1\endcsname
}%
%    \end{macrocode}
% \DescribeMacro{\MGB@save@mark}La restauration de \cs{}\meta{délimiteur} se fait à partir d'une sauvegarde faite dans
% la variable\footnote{La deuxième contr'oblique est une lettre.} \cs{MGB@save\textbackslash}\meta{délimiteur}. La macro
% \cs{MGB@save@mark} sert à effectuer la sauvegarde en début de traitement :
%    \begin{macrocode}
\def\MGB@save@mark#1{%
  \expandafter\let\csname MGB@save\string#1\endcsname#1}%
%    \end{macrocode}
% \subsection{Gestion de la pile de macros crochets}
% \DescribeMacro{\MGB@hook@sd}La macro \cs{MGB@hook@sd} est un compteur qui donne la profondeur dans la pile de macros
% crochets (\texttt{sd} = \enquote{\textbf{s}tack \textbf{d}epth}) :
%    \begin{macrocode}
\newcount\MGB@hook@sd
%    \end{macrocode}
% \DescribeMacro{\MGB@pushhooks}La macro \cs{MGB@pushhooks} sert à empiler la valeur courante des macros crochets :
%    \begin{macrocode}
\def\MGB@pushhooks{%
  \expandafter\let\csname MGB@ghookstack\the\MGB@hook@sd\endcsname
    \MGB@gobblerhook
  \expandafter\let\csname MGB@uhookstack\the\MGB@hook@sd\endcsname
    \MGB@ungobblerhook
  \advance\MGB@hook@sd\@ne
}
%    \end{macrocode}
% \DescribeMacro{\MGB@pophooks}La macro \cs{MGB@pophooks} sert à dépiler les valeurs des macros crochets de sorte à
% restituer les valeurs avant le dernier empilement :
%    \begin{macrocode}
\def\MGB@pophooks{%
  \advance\MGB@hook@sd\m@ne
  \expandafter\let\expandafter\MGB@gobblerhook
    \csname MGB@ghookstack\the\MGB@hook@sd\endcsname
  \expandafter\let\expandafter\MGB@ungobblerhook
    \csname MGB@uhookstack\the\MGB@hook@sd\endcsname
}
%    \end{macrocode}
% Touche finale de la gestion de la pile, les macros crochets de gobage/dégobage sont initialisées pour produire une
% erreur indiquant un épuisement de la pile\footnote{\enquote{stack underflow} en langue anglaise}. En effet, si on ne
% fait pas cela, et que par malheur survient une situation où se produit un dépilement de plus que d'empilements, alors
% on aura un message d'erreur abscons indiquant soit que \cs{MGB@gobblerhook} n'est pas définie, soit que c'est
% \cs{MGB@ungobblerhook} qui n'est pas définie. Avec les initialisations suivantes, dans une telle situation au lieu de
% cela on a un message d'erreur beaucoup plus explicite :
%    \begin{macrocode}
\def\MGB@gobblerhook#1{%
  \PackageError{makegobbler}{\'Epuisement pile macros crochets}{%
    Une erreur a produit un d\'epilage de plus que d'empilage.%
  }
}
\let\MGB@ungobblerhook\MGB@gobblerhook
%    \end{macrocode}
% \subsection{Gobage/dégobage dans le cas d'une condition à la \TeX}
% \DescribeMacro{\MGBkeep@tex}\DescribeMacro{\MGBdrop@tex}
% On commence par le gros morceau, le cas des conditions à la \TeX. En fait on veut grosso modo que
% \cs{MGBkeep*}\cs{ifcondition} se développe en :
% \begin{verse}
% \cs{ifcondition}\\
% \meta{couic}\\
% \quad\cs{expandafter}\cs{MGB@u}\\
% \cs{else}\\
% \quad\cs{expandafter}\cs{MGB@g}\\
% \cs{fi}
% \end{verse}
% Dans le cas de \cs{MGBdrop} c'est juste l'ordre de \cs{MGB@u} et \cs{MGB@g} qui est inversé. Comme c'est un peu coton
% de mettre en clair un \cs{else} ou un \cs{fi} dans un corps de macro sans qu'il n'y ait \cs{ifcondition} également en
% clair, on va passer le \cs{else} et le \cs{fi} via des registres toks pour qu'ils ne soient pas en clair. Pour faire
% ça on se place au sein d'un groupe, et le boulot sera fait via une macro \cs{@tempa} développée en after-group.
%    \begin{macrocode}
\begingroup
%    \end{macrocode}
% Au fait, \cs{ifcondition} ça peut être n'importe quelle condition à la \TeX, par exemple
% \cs{ifnum}\meta{a}\texttt{=}\meta{b}\vs. Du coup pour éviter qu'au cas où l'utilisateur oublierait
% l'espace\footnote{Cet espace fait partie du nombre et ne génère pas une espace dans le texte.} juste après le \meta{b}
% et où donc la branche vraie serait intempestivement développée, ce qui entrainerait une erreur de type \cs{else} sans
% \cs{if}, on insère en général un \cs{relax} après le \cs{ifcondition}, sauf pour les utilisateurs qui aiment vivre
% \label{descr:tense-opt}\codelinelabel{ln:tense}^^A
% dangereusement et ont passé l'option \texttt{tense} au paquetage. Donc en général \cs{toks0} contient \cs{relax}, sauf
% si l'option \texttt{tense} est passée, auquel cas il est vide.
%    \begin{macrocode}
\edef\@tempa{\toks0{\ifMGB@tense\else\relax\fi}}\@tempa
%    \end{macrocode}
% \cs{toks1} contient \cs{else}, et
%    \begin{macrocode}
\toks1\expandafter{\csname else\endcsname}%
%    \end{macrocode}
% \cs{toks2} contient \cs{fi}.
%    \begin{macrocode}
\toks2\expandafter{\csname fi\endcsname}%
%    \end{macrocode}
% Et maintenant on définit \cs{MGBkeep@tex}, et \cs{MGBdrop@tex} dans une macro \cs{@tempa} développée en after-group.
%    \begin{macrocode}
\edef\@tempa{%
  \def\noexpand\MGBkeep@tex##1{##1\the\toks0
    \noexpand\expandafter\noexpand\MGB@u
    \the\toks1
    \noexpand\expandafter\noexpand\MGB@g
    \the\toks2
  }%
  \def\noexpand\MGBdrop@tex##1{##1\the\toks0
    \noexpand\expandafter\noexpand\MGB@g
    \the\toks1
    \noexpand\expandafter\noexpand\MGB@u
    \the\toks2
  }%
}%
\expandafter\endgroup\@tempa  
%    \end{macrocode}
% \subsection{Gobage/dégobage dans le cas d'une condition à la \LaTeX}
% \DescribeMacro{\MGBkeep@latex}\DescribeMacro{\MGBdrop@latex}
% Le cas des conditions à la \LaTeX\ est beaucoup plus simple à traiter. En fait on veut grosso modo que
% \cs{MGBkeep}\texttt{\{}\meta{condition}\texttt{\}} se développe en :
% \begin{verse}
% \cs{ifthenelse}\texttt{\{}\meta{condition}\texttt{\}}\texttt{\{\%}\\
% \quad\cs{MGB@u}\texttt{\}\{\%}\\
% \quad\cs{MGB@g}\texttt{\}}
% \end{verse}
% Pour développer \cs{MGB@u} si \meta{condition} est vraie, ou \cs{MGB@g} sinon. Et pour \cs{MGBdrop} c'est l'inverse,
% ce qu'on obtient en intervertissant \cs{MGB@u} et \cs{MGB@g}.
%    \begin{macrocode}
\def\MGBkeep@latex#1{\ifthenelse{#1}{\MGB@u}{\MGB@g}}
\def\MGBdrop@latex#1{\ifthenelse{#1}{\MGB@g}{\MGB@u}}
%    \end{macrocode}
% \subsection{Macros auxliaires de \cs{MGB@g}}
% \DescribeMacro{\MGB@set@catcoderegime}\\ La macro \cs{MGB@set@catcoderegime} sert à changer le régime de catcode
% pour que dans le cas du gobage, tout ce qui est gobé soit pris verbatim.
%    \begin{macrocode}
\def\MGB@set@catcoderegime{%
  \catcode35=12
  \catcode123=12
  \catcode125=12
  \catcode37=12
  \catcode92=12
}
%    \end{macrocode}
% \DescribeMacro{\MGB@otherize} La macro \cs{MGB@otherize} change le catcode de chacun des caractères du délimiteur
% en other. C'est pour que le délimiteur soit bien reconnu comme marque de fin.
%    \begin{macrocode}
\def\MGB@otherize#1{%
  \def\@tempa{#1}%
  \ifx\@tempa\@nnil\else
    \catcode`#1=12
    \expandafter\MGB@otherize
  \fi
}
%    \end{macrocode}
% \DescribeMacro{\MGB@}
% La macro \cs{MGB@} est l'auxiliaire de \cs{MGB@g}, elle prend deux arguments :\\
% \begin{tabular}{ll}
% \texttt{\#1}&Le délimiteur en tant que string\\
% \texttt{\#2}&Le délimiteur en tant que séquence de contrôle\\
% \end{tabular}
%    \begin{macrocode}
\def\MGB@#1#2{\MGB@otherize#1\@nil\long\def#2##1#1{\endgroup
    \MGB@gobblerhook#2}}%
%    \end{macrocode}
% E finita la comedia !
%    \begin{macrocode}
\endinput
%    \end{macrocode}
%^^A End of file `makegobbler.sty'.
%^^A Local Variables:
%^^A coding: latin-9
%^^A ispell-dictionary: "fr"
%^^A mode: DocTeX
%^^A compile-command: "make -C ../ doc"
%^^A End:
%\iffalse
%    \begin{macrocode}
%</makegobbler.sty>
%    \end{macrocode}
%\fi
%\Finale
\endinput
