From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/xargs/README | 49 + macros/latex/contrib/xargs/xargs-fr.pdf | Bin 0 -> 78571 bytes macros/latex/contrib/xargs/xargs.dtx | 1559 +++++++++++++++++++++++++++++++ macros/latex/contrib/xargs/xargs.pdf | Bin 0 -> 150220 bytes macros/latex/contrib/xargs/xargs.sty | 361 +++++++ 5 files changed, 1969 insertions(+) create mode 100644 macros/latex/contrib/xargs/README create mode 100644 macros/latex/contrib/xargs/xargs-fr.pdf create mode 100644 macros/latex/contrib/xargs/xargs.dtx create mode 100644 macros/latex/contrib/xargs/xargs.pdf create mode 100644 macros/latex/contrib/xargs/xargs.sty (limited to 'macros/latex/contrib/xargs') diff --git a/macros/latex/contrib/xargs/README b/macros/latex/contrib/xargs/README new file mode 100644 index 0000000000..3df0eb23b1 --- /dev/null +++ b/macros/latex/contrib/xargs/README @@ -0,0 +1,49 @@ + + The xargs package + + Defining commands with many optional arguments made easy + + Manuel P\'egouri\'e-Gonnard + + +Presentation +------------ + +Defining commands with an optional argument is easy in LaTeXe. There is, +however, two limitations: only one argument can be optional and it must +be the first one. The xargs package provide extended variants of +\newcommand & friends, for which these limitations no longer hold. It +allows to control what happens with many consecutive optional arguments. +It also provide a way of making the definition global. + +Some features of xargs are similar to those provided by the experimental +`xparse' package, which also allows more flexible argument syntaxes, +though the approach and syntax are different. However, xargs is not +experimental, so I hope it can be useful while waiting for a stable +LaTeX3 release. + +Contents +-------- + +xargs.sty: the package itself +xargs.pdf: the (English) documentation and documented code +xargs-fr.pdf: the French documentation + +xargs.dtx: source for both documentations and package + +Version info +------------ + +2007-10-20 v1.0 First release +2008-03-08 v1.09 Added the usedefault and addprefix keys, not + documented yet... +2008-03-22 v1.1 Updated the documentation and fixed a bug in + \DeclareRobustCommandx, introduced in v1.09. + +License +------- + +This material is subject to the LaTeX Project Public License. See +http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html for the +details of that license. + diff --git a/macros/latex/contrib/xargs/xargs-fr.pdf b/macros/latex/contrib/xargs/xargs-fr.pdf new file mode 100644 index 0000000000..da3eaf0f16 Binary files /dev/null and b/macros/latex/contrib/xargs/xargs-fr.pdf differ diff --git a/macros/latex/contrib/xargs/xargs.dtx b/macros/latex/contrib/xargs/xargs.dtx new file mode 100644 index 0000000000..a8eb4cb8a4 --- /dev/null +++ b/macros/latex/contrib/xargs/xargs.dtx @@ -0,0 +1,1559 @@ +% +% \iffalse /!\ this file contains non-ascii -- encoding is utf-8 /!\ +% +% xargs package by Manuel P\'egouri\'e-Gonnard +% ------------------------------------------------------------- +% +% This work may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, either version 1.3c of this license +% or (at your option) any later version. The latest version of this +% license is in: +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.3c or later is part of all distributions of LaTeX +% version 2006/05/20 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The current maintainer of this work is Manuel P\'egouri\'e-Gonnard. +% +% This work consists of the file xargs.dtx and the derived files +% xargs.sty, xargs.pdf and xargs-fr.pdf. +% +% +%<*gobble> +\ProvidesFile{xargs.dtx} +% +%\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{xargs} +%<*package> +% \fi +% \ProvidesFile{xargs.dtx} + [2008/03/22 v1.1 \space extended macro definitions \space (mpg)] +% \iffalse +% +% \fi +% \CheckSum{782} +% \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 \~} +% \iffalse +%<*gobble> +\begingroup +% +%<*batchfile> +\input docstrip +\keepsilent +\preamble + +xargs package by Manuel P\string\'egouri\string\'e-Gonnard % + +This is a generated file. See xargs.dtx for license information. + +\endpreamble +\askforoverwritefalse +%\generate{\file{xargs.ins}{\from{xargs.dtx}{batchfile}}} +%\generate{\file{xargs.drv}{\from{xargs.dtx}{driver}}} +\generate{\file{xargs.sty}{\from{xargs.dtx}{package}}} +\generate{\file{xargs-fr.drv}{\from{xargs.dtx}{pilote}}} +% +%<*gobble> +\endgroup +% +%<*driver|pilote> +\documentclass[oneside, a4paper]{ltxdoc} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{fixltx2e, mparhack} +\usepackage[babel=true, expansion=false]{microtype} +\usepackage{xargs} +\expandafter\newif\csname iffrenchdoc\endcsname % cachez ce if que je ne... +%\frenchdoctrue +% +%<*gobble> +\iffrenchdoc +% +%<*pilote> +\usepackage[lmargin=4.5cm, rmargin=3cm]{geometry} +\OnlyDescription +\usepackage[english, frenchb]{babel} +\FrenchFootnotes \AddThinSpaceBeforeFootnotes +\newcommand*\eng[1]{\emph{\foreignlanguage{english}{#1}}} +\usepackage[colorlinks=true, bookmarks=true, + bookmarksnumbered=true, bookmarksopen=true, bookmarksopenlevel=3, + pdfauthor={Manuel Pégourié-Gonnard}, + pdftitle={L'extension xargs}, + pdfsubject={Définitions de macros étendues pour LaTeX2e}, + ]{hyperref} +% +%<*gobble> +\else +% +%<*driver> +\AlsoImplementation +\usepackage[english]{babel} +\usepackage[colorlinks=true, bookmarks=true, + bookmarksnumbered=true, bookmarksopen=true, bookmarksopenlevel=3, + pdfauthor={Manuel Pégourié-Gonnard}, + pdftitle={The xargs package}, + pdfsubject={Extended macro definitions for LaTeX2e}, + ]{hyperref} +\settowidth\MacroIndent{\rmfamily\scriptsize 000\ } +\setlength\MacroTopsep{0pt} +\usepackage[nohints, english]{minitoc} +\mtcsetpagenumbers{secttoc}{off} +\mtcsetrules{secttoc}{off} +\mtcsetdepth{secttoc}{3} +\setlength{\stcindent}{0pt} +\mtcsetfont{secttoc}{subsection}{\normalfont} +\newcommand\tocwithmini{% + \dosecttoc[n] + \setcounter{tocdepth}{1}\tableofcontents + \setcounter{tocdepth}{3}\faketableofcontents} +% +%<*gobble> +\fi +% +%<*driver|pilote> +\newcommand\pf{\textsf} +\newcommand\optstar{\meta{$*$}} +\newcommand\topcs[1]{\texorpdfstring{\cs{#1}}{#1}} +\newcommand\eTeX{$\varepsilon$-\TeX} +\begin{document} + \DocInput{xargs.dtx} +\end{document} +% +%<*package> +% \fi +% +% \GetFileInfo{xargs.dtx} +% +% \title{\iffrenchdoc L'extension \pf{xargs}\else The \pf{xargs} package\fi} +% \author{Manuel Pégourié-Gonnard\\ +% \href{mailto:mpg@elzevir.fr}{mpg@elzevir.fr}} +% \date{\fileversion\ (\filedate)} +% +% \maketitle +% \iffrenchdoc\else \tocwithmini \fi +% +% \iffrenchdoc\else +% \medskip +% \emph{Important note for French users}: a French version of the user +% documentation is included in the \nolinkurl{xargs-fr.pdf} file. +% \fi +% +% \section{Introduction} +% +% \iffrenchdoc +% +% \LaTeXe{} permet de définir facilement des commandes ayant un argument +% optionel. Cependant, il y a deux restrictions : il peut y avoir au plus un +% argument optionel, et ce doit être le premier. L'extension \pf{xargs} +% fournit des versions étendues de \cs{newcommand} et de ses analogues +% standard, qui ne présentent pas ces restrictions : il est désormais +% facile de définir des commandes avec plusieurs arguments optionnels, +% placés où l'on veut, par une syntaxe agréable du style +% \meta{clé}=\meta{valeur}. Par exemple, voici comment définir une +% commande avec deux arguments optionnels. +% +% \begin{center} +% |\newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})}| +% \newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})} +% \par\medskip +% \begin{tabular}{ll} +% |$\coord{x}$| & $\coord{x}$ \\ +% |$\coord[0]{y}$| & $\coord[0]{y}$ \\ +% |$\coord{z}[m]$| & $\coord{z}[m]$ \\ +% |$\coord[0]{t}[m]$| & $\coord[0]{t}[m]$ \\ +% \end{tabular} +% \end{center} +% +% \else +% +% Defining commands with an optional argument is easy in \LaTeXe{}. +% There is, however, two limitations: you can make only one argument +% optional and it must be the first one. The \pf{xargs} package provide +% extended variants of \cs{newcommand} \& friends, for which these +% limitations no longer hold: It is now easy to define commands with +% many (and freely placed) optional arguments, using a nice +% \meta{key}=\meta{value} syntax. For example, the following defines a +% command with two optional arguments. +% +% \begin{center} +% |\newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})}| +% \newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})} +% \par\medskip +% \begin{tabular}{ll} +% |$\coord{x}$| & $\coord{x}$ \\ +% |$\coord[0]{y}$| & $\coord[0]{y}$ \\ +% |$\coord{z}[m]$| & $\coord{z}[m]$ \\ +% |$\coord[0]{t}[m]$| & $\coord[0]{t}[m]$ \\ +% \end{tabular} +% \end{center} +% +% \fi +% +% \section{Usage} +% +% \iffrenchdoc +% +% \subsection{Les bases} +% +% L'extension \pf{xargs} fournit des analogues de toutes les macros de +% \LaTeXe{} relatives à la définition de macros. Les macros de \pf{xargs} ont +% le même nom que leur analogue standard, mais avec un |x| supplémentaire à la +% fin. En voici la liste complète. +% +% \begin{center} +% \begin{tabular}{ll} +% \cs{newcommandx} & \cs{renewcommandx} \\ +% \cs{newenvironmentx} & \cs{renewenvironmentx} \\ +% \cs{providecommandx} & \cs{DeclareRobustCommandx} \\ +% \cs{CheckCommandx} +% \end{tabular} +% \end{center} +% +% Si vous ne connaissez pas toutes ces commandes, ne vous inquiétez pas. +% Vous pouvez utiliser seulement les analogues des macros que vous +% connaissez ; ou apprendre les autres par exemple dans le livre de +% \bsc{Lamport}, le \LaTeX{} Companion, ou tout autre manuel sur \LaTeXe. +% +% \medskip +% +% Ces commandes partageant toutes la même syntaxe, je parlerai seulement +% de |\newcommandx| par la suite, mais gardez à l'esprit que les +% explications sont valables pour les autres commandes. (Bien sûr, pour +% les environnements, il y a un dernier argument en plus, pour la +% définition de fin.) Voici la syntaxe complète de |\newcommand|. +% +% \begin{center} +% \cs{newcommandx}\optstar\marg{commande}\oarg{nombre}\oarg{liste}^^A +% \marg{définition} +% \end{center} +% +% Rappelons brièvement tout ce qui est commun avec la syntaxe usuelle, à +% savoir tout sauf \meta{liste}. Si une $*$ est présente, elle signifie +% que la macro crée est \emph{courte} au sens de \TeX{}, c'est-à-dire +% que ses arguments ne peuvent pas contenir de saut de paragraphe +% (\cs{par} ou ligne vide). La \meta{commande} est n'importe quelle +% séquence de contrôle, que vous pouvez ou non entourer d'accolades +% suivant vos goûts. Le \meta{nombre} définit le nombre total d'argument +% de la \meta{commande}, c'est un entier compris entre $0$ et $9$. La +% \meta{définition} est un texte équilibré en accolades, et où chaque +% caractère |#| est suivi soit d'un chiffre représentant un des +% arguments, soit d'un autre caractère |#|. Les arguments \meta{nombre} +% et \meta{liste} sont optionnels. +% +% \medskip +% +% La partie intéressante maintenant. La \meta{liste} est une\ldots{} +% liste (!) d'éléments de la forme \meta{chiffre}=\meta{valeur}, séparés +% par des virgules. Le \meta{chiffre} doit être un entier compris entre +% $1$ et le nombre d'arguments, donné par \meta{nombre}. La +% \meta{valeur} est n'importe quelle texte équilibré en accolades. Il +% peut être vide si vous le souhaitez : le signe égal qui le précède +% peut alors être omis. Tous les arguments dont le numéro figure en tant +% que \meta{chiffre} dans la \meta{liste} seront optionnels, avec pour +% valeur par défaut celle donnée par la \meta{valeur} correspondante. +% +% Quelques remarques supplémentaires sur la syntaxe de la \meta{liste}, +% que vous pouvez sauter si vous êtes familiers avec la syntaxe fournie +% par \pf{xkeyval}. Vu que les éléments sont séparés par des virgules, +% si une \meta{valeur} doit contenir une virgule, il faut entourer la +% valeur par des accolades pour protéger la virgule. (Cette précaution +% est également indispensable si la \meta{valeur} contient une accolade +% fermante.) Ne vous inquiétez pas, cette parie d'accolade sera retirée +% ultérieurement. D'ailleurs, jusqu'à trois paires d'accolades seront +% retirées ainsi, et si vous voulez vraiment que votre valeur reste +% entourée d'accolades, il vous faudra écrire quelque chose +% comme~|1={{{{\large blabla}}}}|. +% +% \medskip +% +% C'est tout pour les bases : vous en savez maintenant assez pour +% utiliser \pf{xargs}, et vous pouvez laisser la fin de la documentation +% pour plus tard si vous voulez. Si, au contraire, vous vous demandez ce +% qui se passe avec plusieurs arguments optionnels à la suite, que vous +% voulez effectuer des définitions globales, ou que vous aves besoin de +% connaître les limites précises de \pf{xargs}, vous pouvez lire les +% sections suivantes. +% +% \subsection{La clé \texttt{usedefault}} +% +% Voyons donc se qui se passe quand plusieurs arguments optionnels se +% suivent. Le comportement par défaut est calqué sur celui de commandes +% \LaTeX{} comme \cs{makebox} et \cs{parbox} : on ne peut spécifier une +% valeur pour le troisième argument optionnel que si on l'a fait pour +% les deux premiers. Par exemple, dans l'exemple du début, remarquez +% comment j'avais pris soin de placer l'argument obligatoire au milieu +% pour séparer les arguments optionnels. +% +% Cependant, ce n'est pas très pratique, et on aimerait pouvoir choisir +% l'ordre des arguments plutôt selon leur sens, sans se poser de +% questions. Bien, la clé |usedefault| est justement là pour ça : +% incluez-la dans la \meta{liste}, et vous pouvez désormais utiliser +% |[]| pour sauter un argument optionnel, en utilisant sa valeur par +% défaut. +% +% \begin{center} +% |\newcommandx*\coord[3][2=1,3=n,usedefault]{(#2_{#1},\ldots,#2_{#3})}| +% \newcommandx*\coord[3][2=1, 3=n, usedefault]{(#2_{#1},\ldots,#2_{#3})} +% \par\medskip +% \begin{tabular}{ll} +% |$\coord{x}$| & $\coord{x}$ \\ +% |$\coord{y}[0]$| & $\coord{y}[0]$ \\ +% |$\coord{z}[][m]$| & $\coord{z}[][m]$ \\ +% |$\coord{t}[0][m]$| & $\coord{t}[0][m]$ \\ +% \end{tabular} +% \end{center} +% +% Bien sûr, sur cet exemple simple, c'est surtout une histoire de goût, +% mais parfois |usedefault| peut vous épargner pas mal de frappe +% inutile, car la valeur par défaut d'un argument est parfois longue, et +% qu'on a pas toujours assez d'arguments obligatoires pour séparer les +% arguments optionnels comme plus haut. +% +% Cette utilisation simple de |usedefault| présente un inconvénient : +% vous ne pouvez plus spécifier la valeur vide pour un argument +% optionnel. En fait, il faut nécessairement une valeur spéciale de +% l'argument pour dire \og utiliser la valeur par défaut \fg{}, mais ce +% n'est pas nécessairement la chaîne vide : en fait, on peut choisir +% cette valeur en disant |usedefault=|\meta{valeur}. L'exemple suivant +% ne sert à rien, à part illustrer ceci. +% +% \begin{center} +% |\newcommandx*\test[2][1=A, 2=B, usedefault=@]{(#1,#2)}| +% \newcommandx*\test[2][1=A, 2=B, usedefault=@]{(#1,#2)} +% \par\medskip +% \begin{tabular}{ll} +% |\test[b]| & \test[b] \\ +% |\test[][b]| & \test[][b] \\ +% |\test[@][b]| & \test[@][b] \\ +% \end{tabular} +% \end{center} +% +% \subsection{Ajouter un préfixe} +% +% La commande |\newcommand| standard permet de définir au choix des +% macros \og longues \fg{} (dont les arguments peuvent contenir des +% \cs{par}) ou \og courtes \fg{} (les \cs{par} ou lignes vides sont +% interdits dans les arguments) au moyen de l'étoile optionnelle. C'est +% une partie de ce que \TeX{} appelle un préfixe, plus précisément la +% composante \cs{long}. Les autres composantes d'un préfixe peuvent être +% \cs{global}, \cs{outer}, ou (avec \eTeX) \cs{protected}. Il n'y a pas +% de moyen d'utiliser ces composantes avec \cs{newcommand}, bien que, +% par exemple, \cs{global} puisse être utile pour qu'une définition +% faite à l'intérieur d'un groupe (comme un environnement) ne soit pas +% \og oubliée \fg{} à la fin. (Pour des détails sur les autres, voir le +% \TeX book ou le manuel d'\eTeX.) +% +% Avec \pf{xargs}, vous pouvez utiliser la clé |addprefix|, \emph{sauf} +% pour la composante \cs{outer}, qui n'est pas et ne sera pas supportée +% (et, à ma connaissance n'est jamais utilisée dans \LaTeXe). Remarquons +% que cette clé \emph{ajoute} une préfixe à celui en cours, elle +% n'écrase rien. Au début, le préfixe par défaut est \cs{long}, ou vide +% si une étoile a été utilisée. Par exemple, les deux instructions +% suivantes ont exactement le même effet. +% +% \begin{quote} +% |\newcommandx*\truc[0][addprefix=\global, addprefix=\long,|\\ +% | addprefix=\protected]{machin}|\\ +% |\newcommandx\truc[0][addprefix=\global\protected]{machin}| +% \end{quote} +% +% En passant, les macros avec au moins un argument optionnel sont +% définies de façon robuste au sens que \LaTeXe{} donne à ce mot, je ne +% sais donc pas si le préfixe \cs{protected} est très utile. Je pense +% que la possibilité d'effectuer des définitions globales est l'usage +% principale de la clé |usedefault|. +% +% \subsection{Compatibilité et limitations connues} +% +% La mauvaise nouvelle (les limitations) en premier. Il y en a +% essentiellement une : on ne peut pas utiliser dans la \meta{liste} +% certaines choses, qui ne sont pas gérées correctement par +% \pf{xkeyval}. Précisément, il s'agit des signes |#| (les lexèmes de +% \cs{catcode} $6$) et des lexèmes \cs{par}. Aussi, aucune composante +% de la \meta{liste} ne doit avoir l'air mal équilibrée en \cs{if}s aux +% yeux de \TeX. Seule la première de ces limitations est partagée pas le +% \cs{newcommand} standard, qui n'accepte pas non plus de |#| dans les +% valeurs par défaut. Autrement, vous pouvez utiliser ce que vous +% voulez, où vous voulez (autant que je sache). +% +% Maintenant les bonnes nouvelles. J'ai pris grand soin que les macros +% définies avec \pf{xargs} ressemblent autant que possibles à celles +% définies avec les commandes standard de \LaTeX. En fait, quand on +% demande à \cs{newcommandx} d'effectuer une définition que +% \cs{newcommand} aurait pu faire, la commande sera définie exactement +% comme si on avait utilisé ce dernier. Plus précisément, le code +% suivant (et les tests similaires) ne renvoie pas d'avertissement. +% +% \begin{quote} +% |\newcommandx\truc[2][1=default]{def-truc}|\\ +% |\CheckCommand\truc[2][default]{def-truc}|\\ +% |\newcommand\chose{def-chose}|\\ +% |\CheckCommandx*\chose[0][addprefix=\long]{def-chose}| +% \end{quote} +% +% De plus, il y a seulement trois points (à ma connaissance) sur +% lesquels les commandes d'\pf{xargs} diffèrent de celles de \LaTeX{}. +% Le premier a déjà été évoqué, c'est la limitation sur le \meta{liste} +% due à \pf{xkeyval}. Les deuxièmes et troisièmes points, par contre, +% sont censés être positifs. Le deuxième est donc, que j'ai essayé +% d'éviter de reproduire dans \cs{CheckCommandx} deux +% problèmes\footnote{% +% \url{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/3971}} +% dont souffre l'implémentation actuelle de \cs{CheckCommand} dans +% \LaTeX. +% +% Le dernier point concerne la gestion des espaces, lors de la recherche +% du prochain caractère, pour déterminer s'il s'agit ou non d'un crocher +% carré, quand on teste la présence d'un argument optionnel. Pour ceci, +% je n'utilise ni la version du noyau, ni celle d'\pf{amsmath}, de +% \cs{@ifnextchar}, mais la mienne, qui a le comportement suivant : elle +% avale les espaces jusqu'à trouver le prochain caractère, puis les +% restitue si ce n'était pas le début d'un argument optionnel. Je ne +% suis plus tout à fait sûr que ce soit la bonne façon de faire, et il +% est probable que je ferai une option à ce sujet dans une prochaine +% version, afin que l'utilisateur puisse choisir son comportement +% préféré. +% +% \bigskip +% +% \begin{quote} +% Vous savez maintenant absolument tout ce qu'il y a à savoir sur +% l'utilisation de \pf{xargs}. Si vous souhaitez vous pencher sur son +% implémentation, il vous faudra lire les commentaires en anglais car je +% n'ai pas eu le courage de commenter mon code en deux langues. +% \end{quote} +% +% \begin{center}\large +% C'est tout pour cette fois ! \\ +% Amusez-vous bien avec \LaTeX{} ! +% \end{center} +% +% \else +% +% \subsection{Basics} +% +% ^^A \DescribeMacro{\newcommandx} +% ^^A \DescribeMacro{\renewcommandx} +% ^^A \DescribeMacro{\newenvironmentx} +% ^^A \DescribeMacro{\renewenvironmentx} +% ^^A \DescribeMacro{\providecommandx} +% ^^A \DescribeMacro{\DeclareRobustCommandx} +% ^^A \DescribeMacro{\CheckCommandx} +% The \pf{xargs} package defines an extended variant for every \LaTeX{} +% macro related to macro definition. \pf{xargs}'s macro are named after +% their \LaTeX{} counterparts, just adding an |x| at end (see the list +% in the margin). Here is the complete list: +% +% \begin{center} +% \begin{tabular}{ll} +% \cs{newcommandx} & \cs{renewcommandx} \\ +% \cs{newenvironmentx} & \cs{renewenvironmentx} \\ +% \cs{providecommandx} & \cs{DeclareRobustCommandx} \\ +% \cs{CheckCommandx} +% \end{tabular} +% \end{center} +% +% If you are not familiar with all of them, you can either just keep +% using the commands you already know, or check Lamport's book or the +% \LaTeX{} Companion (or any \LaTeXe{} manual) to learn the others. +% +% \medbreak +% +% Since these commands all share the same syntax, I'll always use +% \cs{newcommandx} in the following, but remember it works the same for +% all seven commands. (Of course, command about environments take one +% more argument, for the end definition.) Here is |\newcommandx|'s +% complete syntax. +% +% \begin{center} +% \cs{newcommandx}\optstar\marg{command}\oarg{number}\oarg{list}^^A +% \marg{definition} +% \end{center} +% +% Everything here is the same as the usual \cs{newcommand} syntax, +% except \meta{list}. Let's recall this briefly. The optional $*$ make +% \LaTeX{} define a ``short'' macro, that is a macro that won't accept a +% paragraph break (\cs{par} or an empty line) inside its argument; if +% you don't put it, the macro will be long. \meta{command} is any +% control sequence, and can but need not be enclosed in braces, as you +% like. The \meta{number} specifies how many arguments your macro will +% take (including optional ones): it should be a non-negative integer, +% and at most $9$. The macro's \meta{definition} is a balanced text, +% where every |#| sign must be followed by a number, thus representing +% an argument, or by another |#| sign. The two arguments \meta{number} +% and \meta{list} are optionals. +% +% \medskip +% +% Now comes the new and funny part. \meta{list} is a coma-separated list +% of element \meta{digit}=\meta{value}. Here, \meta{digit} should be +% non-zero, and at most \meta{number} (the total number of arguments). +% The \meta{value} is any balanced text, and can be empty. If so, the +% |=| sign becomes optional: You only need to write \meta{digit} if you +% want the \meta{digit}th argument to be optional, with empty default +% value. Of course, every argument whose number is a \meta{digit} in the +% \meta{list} becomes optional, with \meta{value} as its default value. +% +% If you are not very familiar with some aspects of the syntax provided +% by the \pf{xkeyval} package, you may be interested in the following +% remarks about the syntax of \meta{list}. Since \meta{list} is +% coma-separated, if you want to use a coma inside a \meta{value}, you +% need to enclose it (either the coma or the whole \meta{value}) in +% braces. The same applies if you want to use a closing square bracket +% inside the \meta{list}. Don't worry about those unwanted braces, they +% will be removed later. Actually, \pf{xkeyval} removes up to $3$ braces +% set: If you really want braces around a value, you need to type +% something like |1={{{{\large stuff}}}}|. +% +% \medskip +% +% That's all for the basics: you are now ready to use \pf{xargs}, and +% can stop reading this doc now if you want. If, however, you are +% wondering about what happens if you have many successive optional +% arguments, or care about doing global definitions, or even need to +% know precisely the limitations of \pf{xargs}, go on with the next +% subsections. +% +% \subsection{The \texttt{usedefault} key} +% +% So, what happens with many successive optional arguments? The default +% behaviour is that of \LaTeX's commands like \cs{makebox} or +% \cs{parbox}: you can't specify the third argument if you didn't +% specify the first two ones. For example, in my first example, please +% notice how I used the mandatory argument to separate the two optional +% ones. +% +% However, maybe you don't like this and prefer choosing your argument's +% order as you want, according to their logical meaning. Ok. That's +% exactly what the |usedefault| key is for. Just include it in the +% \meta{list}, and you can now use |[]| to skip one optional argument +% (using its default value) and go to the next one. +% +% \begin{center} +% |\newcommandx*\coord[3][2=1,3=n,usedefault]{(#2_{#1},\ldots,#2_{#3})}| +% \newcommandx*\coord[3][2=1, 3=n, usedefault]{(#2_{#1},\ldots,#2_{#3})} +% \par\medskip +% \begin{tabular}{ll} +% |$\coord{x}$| & $\coord{x}$ \\ +% |$\coord{y}[0]$| & $\coord{y}[0]$ \\ +% |$\coord{z}[][m]$| & $\coord{z}[][m]$ \\ +% |$\coord{t}[0][m]$| & $\coord{t}[0][m]$ \\ +% \end{tabular} +% \end{center} +% +% Of course, on this simple example, this is merely a matter of +% taste, but sometimes the |usedefault| key can save you a lot of +% typing, since the optional value for an argument can be rather long, +% and you don't always have enough mandatory arguments to separate the +% optional ones. +% +% This simple way of using |usedefault| has one problem: you can no more +% specify an empty value for an optional argument. Of course you need a +% special value of the argument to mean ``please use the default value +% there'', but it doesn't need to be always the empty string. Actually, +% you can say |usedefaut=|\meta{flag} to choose this special value. The +% following example has no other purpose that illustrating this. +% +% \begin{center} +% |\newcommandx*\test[2][1=A, 2=B, usedefault=@]{(#1,#2)}| +% \newcommandx*\test[2][1=A, 2=B, usedefault=@]{(#1,#2)} +% \par\medskip +% \begin{tabular}{ll} +% |\test[b]| & \test[b] \\ +% |\test[][b]| & \test[][b] \\ +% |\test[@][b]| & \test[@][b] \\ +% \end{tabular} +% \end{center} +% +% \subsection{Using a prefix} +% +% Standard |\newcommand| allows you to define so-called ``long'' (i. e. +% the arguments may contain a \cs{par} token) or ``short'' (they +% may not) macros with the optional star. This is part of what \TeX{} +% calls a ``prefix'' for the definition, namely the \cs{long} prefix. +% Other components of the prefix are \cs{global}, \cs{outer}, and +% \eTeX's \cs{protected}. There is no way to use them with +% |\newcommand|, though \cs{global} can be specially interesting in +% order to avoid definitions made inside a group (e. g. an environment) +% ``disappear'' at the end of the group. (For details about the other +% possible components, see the \TeX book and \eTeX's manual.) +% +% With \pf{xargs}, you can use the |addprefix| key, \emph{except} for +% the \cs{outer} prefix, which is not and will not be supported (and not +% used anywhere I know in \LaTeXe, either). Please note that it +% \emph{adds} a prefix to the current one, which by default is \cs{long} +% for the unstarred form, and empty for the starred form. You can also +% use this key many times: all prefixes will be merged together. For +% example, the following two instructions do the exactly the same thing. +% +% \begin{quote} +% |\newcommandx*\foo[0][addprefix=\global, addprefix=\long,|\\ +% | addprefix=\protected]{bar}|\\ +% |\newcommandx\foo[0][addprefix=\global\protected]{bar}| +% \end{quote} +% +% By the way, macros with at least one optional argument are already +% robust in \LaTeXe's meaning of the word, so I don't know if the +% \cs{protected} prefix is very interesting there. Maybe the ability to +% perform global definitions is the main use of the |addprefix| key. +% +% \subsection{Compatibility and known limitations} +% +% Okay, let's see the bad things (the limitations) first. There is +% essentially one: you cannot use in the \meta{list} some elements, +% because \pf{xkeyval} won't handle them properly. Namely, hash signs +% (tokens with \cs{catcode} $6$), and \cs{par} tokens are forbidden, and +% any part of the list should look properly \cs{if}-balanced to \TeX. +% Only the first limitation is shared by the standard \cs{newcommand}: +% it accepts no hash signs in a default value. Apart from this, you can +% use anything you want, everywhere you want, as far as I know. +% +% Now the ``good'' features. I've tried hard to make macros defined with +% \pf{xargs} as much similar as possible with those defined with +% standard \LaTeX's commands. Actually, when \cs{newcommandx} is asked +% to perform a definition which \cs{newcommand} can do, the resulting +% macro will be defined exactly as the latter would have done. More +% precisely, the following code (and similar tests) issues no warning. +% +% \begin{quote} +% |\newcommandx\foo[2][1=default]{def-foo}|\\ +% |\CheckCommand\foo[2][default]{def-foo}|\\ +% |\newcommand\baz{def-baz}|\\ +% |\CheckCommandx*\baz[0][addprefix=\long]{def-baz}| +% \end{quote} +% +% Moreover, there are only three points (to my knowledge) where +% \pf{xargs}'s commands differ from the kernel ones. The first one was +% already mentioned, it is due to using \pf{xkeyval} for precessing the +% \meta{list}. The second and third points are meant to be good one. +% Second point is: There is a bug\footnote{% +% \url{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/3971}} +% in the current implementation of \cs{CheckCommand}, that I obviously +% tried to avoid. +% +% Last, I don't use kernel's (nor \pf{amsmath}'s) version of +% \cs{@ifnextchar}. Indeed, a problem arises when the last argument of a +% command is optional: we have to make a choice about what to do with +% spaces while scanning ahead for a left square bracket. I chose to scan +% over them, and the put them back in the text in there were no +% optional argument. I'm no more sure it is the right thing to do, and +% I'll probably make an option to let the user decide in a future +% version. +% +% \fi +% +% \StopEventually{} +% +% \section{Implementation} +% +% First, I'd like to recall the way \LaTeXe{} handles optional +% arguments. For example, a command \cs{foo} defined with +% |\newcommand*\foo[2][bar]{baz}| is implemented as the pair: +% \begin{quote} +% |\foo=macro:->\@protected@testopt\foo\\foo{bar}| \\ +% |\\foo=macro:[#1]#2->baz| +% \end{quote} +% There is one ``external'' macro \cs{foo}, which is merely an argument +% grabber or a parser, and an internal macro \cs{\string\foo}, which is +% the ``real'' one. In \pf{xargs} this is quite the same, except that +% the external macro is a bit more sophisticated. This idea of the +% external macro being a parser, giving the arguments to the internal +% one in a standard form, reflects in the name of \LaTeX3's experimental +% package for extended argument syntax: \pf{xparse}. +% +% Here the approach is a bit different. Of course, the idea is still to +% build a parser for the specified syntax, but since \cs{newcommandx} +% user syntax is based on \pf{xkeyval}, we also have to care about keys +% and there default values, and to put the whole thing in the correct +% order before we build up the parser. We also seek for compatibility +% with existing \LaTeXe{} commands, which adds a few tests. The +% organisation is as follows. +% +% \begingroup \def\leaders#1#2{} +% \secttoc[n] +% \endgroup +% +% Before we really begin, just a few preliminaries. +% First, load the \pf{xkeyval} package for it's nice key=value syntax. +% \begin{macrocode} +\RequirePackage{xkeyval} +% \end{macrocode} +% +% \begin{macro}{\xargs@max} +% \begin{macro}{\xargs@temp} +% \begin{macro}{\xargs@toksa} +% \begin{macro}{\xargs@toksb} +% Then allocate a few registers and make sure the name of our private scratch +% macro is free for use. Note that for certain uses, we really need a +% \cs{toks} register because the string used can possibly contain |#| +% characters. Sometimes I also use a \cs{toks} register instead of a macro +% just for ease of use (writing less \cs{expandafter}s). +% \begin{macrocode} +\@ifdefinable\xargs@max{\newcount\xargs@max} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@temp\relax +\@ifdefinable\xargs@toksa{\newtoks\xargs@toksa} +\@ifdefinable\xargs@toksb{\newtoks\xargs@toksb} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Parser} +% +% Let's begin with a simple, concrete example. Recall that we defined a +% command \cs{vect} with +% |\newcommandx\vect[3]{1=0,3=n}{(#2_{#1},\ldots,#2_{#3}}| and have a +% look at its implementation. +% \begin{quote} +% |\vect=macro:->\@protected@testopt@xargs\vect\\vect|\\ +% \hspace*{1em}|{\xargs@test@opt{0},\xargs@put@arg,\xargs@test@opt{n},}|\\ +% |\\vect=macro:[#1]#2[#3]->(#2_{#1},\ldots ,#2_{#3})| +% \end{quote} +% +% As you can see, the parser is stored as a coma-separated list of +% ``actions''. Here the only actions are to grab a mandatory argument or +% to check for the presence of of an optional one. In this case, special +% care is taken about spaces. Actually, there can be one more action, +% associated with the |usedefaut| user key: \cs{xargs@setdefflag}, which +% specifies the flag that says ``use the default value''. +% +% The parsing is done by a loop that read and executes each action from +% the originating list, and concurrently builds an argument list such as +% |[0]{x}[m]| to be passed to |\\vect| for example. All of this happens +% inside a group. +% +% \begin{macro}{\@protected@testop@xargs} +% This first macro closely resembles kernel's \cs{@protected@testopt} +% (similarity in their names is intentional, see \cs{CheckCommandx}). It +% just checks the protection context and call the real argument grabbing +% macro. +% \begin{macrocode} +\newcommand*\@protected@testopt@xargs[1]{% + \ifx\protect\@typeset@protect + \expandafter\xargs@read + \else + \@x@protect#1% + \fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@read} +% Initiate the loop. \cs{xargs@toksa} will become the call to the +% internal macro with all arguments, \cs{xargs@toksb} contains the +% actions list for arguments grabbing. +% \begin{macrocode} +\newcommand*\xargs@read[2]{% + \begingroup + \xargs@toksa{#1}% + \xargs@toksb{#2}% + \xargs@continue} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@continue} +% \begin{macro}{\xargs@pick@next} +% Each iteration of the loop consist of two steps: pick the next action +% (and remove it from the list), and execute it. When there is no more +% action in the list, it means the arguments grabbing stage is over, and +% it's time to execute the internal macro by expanding the contents of +% \cs{xargs@toksa}. +% \begin{macrocode} +\newcommand\xargs@continue{% + \expandafter\xargs@pick@next\the\xargs@toksb,\@nil + \xargs@temp} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@pick@next{% + \def\xargs@pick@next#1,#2\@nil{% + \def\xargs@temp{#1}% + \xargs@toksb{#2}% + \ifx\xargs@temp\empty + \def\xargs@temp{\expandafter\endgroup\the\xargs@toksa}% + \fi}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\xargs@set@defflag} +% Let's begin with the most simple action. +% \begin{macrocode} +\newcommand*\xargs@set@defflag[1]{% + \def\xargs@default@flag{#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@put@arg} +% \begin{macro}{\xargs@test@opt} +% \begin{macro}{\xargs@put@opt} +% Now have a look at the argument grabbing macros. The first one, +% \cs{xargs@put@arg}, just reads an undelimited argument in the input stack +% and add it to the arguments list. \cs{xargs@testopt} checks if the next +% non-space token is a square bracket to decide if it have to read an argument +% from the input or use the default value, and takes care to enclose it in +% square brackets. +% \begin{macrocode} +\newcommand\xargs@put@arg[1]{% + \xargs@toksa\expandafter{\the\xargs@toksa{#1}}% + \xargs@continue} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@test@opt[1]{% + \xargs@ifnextchar[%] + {\xargs@grab@opt{#1}}% + {\xargs@put@opt{#1}}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\xargs@put@opt[1]{% + \xargs@toksa\expandafter{\the\xargs@toksa[{#1}]}% + \xargs@continue} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@grab@opt{% + \long\def\xargs@grab@opt#1[#2]{% + \toks@{#2}\edef\xargs@temp{\the\toks@}% + \ifx\xargs@temp\xargs@default@flag + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi{% + \xargs@put@opt{#1}% + }{% + \xargs@put@opt{#2}}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\xargs@ifnextchar} +% \begin{macro}{\xargs@ifnch} +% \begin{macro}{\xargs@xifnch} +% Here comes a modified version of \cs{@ifnextchar}, that works like +% kernel's one, except that it remembers how many spaces it gobbles and +% puts them back in case the next non-space character isn't a match. Not +% sure whether this is the better way to do, may change in future +% versions. +% \begin{macrocode} +\newcommand\xargs@ifnextchar[3]{% + \let\xargs@temp\empty + \let\reserved@d=#1% + \def\reserved@a{#2}% + \def\reserved@b{#3}% + \futurelet\@let@token\xargs@ifnch} +% \end{macrocode} +% \begin{macrocode} +\newcommand\xargs@ifnch{% + \ifx\@let@token\@sptoken + \edef\xargs@temp{\xargs@temp\space}% + \let\reserved@c\xargs@xifnch + \else + \ifx\@let@token\reserved@d + \let\reserved@c\reserved@a + \else + \def\reserved@c{\expandafter\reserved@b\xargs@temp}% + \fi + \fi + \reserved@c} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@xifnch{% + \expandafter\def\expandafter\xargs@xifnch\space{% + \futurelet\@let@token\xargs@ifnch}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Keys} +% +% Okay, we are done with the parsing related macros. Now define stuff +% for the definition of macros. In this part we use \pf{xkeyval}. Let's +% start with the particular keys for options |addprefix| and |default|. +% Like all \pf{xargs} key, we use the prefix |xargs| and the familly +% |key|. The |addprefix| key can be used many times : each value is +% appended at the end of the current prefix. Actually, we also construct +% a ``short'' prefix (without any \cs{long}), for the external macro. We +% define them globally, since key processing will happen inside a group, +% and the definition outside. +% \begin{macrocode} +\@ifdefinable\xargs@key@addprefix{% + \define@key[xargs]{key}{addprefix}[]{% + \global\expandafter\def\expandafter\xargs@prefix\expandafter{% + \xargs@prefix#1}% + \xargs@makeshort#1\long\@nil}} +% \end{macrocode} +% The \cs{long} tokens are removed from the prefix in a fast and easy +% way, assuming the input is a correct prefix. (It will crash e.g. if +% the input contains an undefined CS or braces, but this will make all +% crash later anyway. By the way, we also assume the prefix contains no +% macro parameter token\ldots) +% \begin{macrocode} +\@ifdefinable\xargs@makeshort{% + \def\xargs@makeshort#1\long#2{% + \expandafter\gdef\expandafter\xargs@shortpref\expandafter{% + \xargs@shortpref#1}% + \ifx#2\@nil \else + \expandafter\xargs@makeshort\expandafter#2% + \fi}} +% \end{macrocode} +% The initial prefixes will be fixed by \cs{newcommandx} and its friends +% when they check the star: empty in the stared version, \cs{long} +% otherwise. For this, they use \pf{xargs}'s variant or +% \cs{@star@or@long}: +% \begin{macrocode} +\newcommand\xargs@star@or@long[1]{% + \global\let\xargs@shortpref\@empty + \@ifstar{\gdef\xargs@prefix{}#1}{\gdef\xargs@prefix{\long}#1}} +% \end{macrocode} +% +% Now, another particular key is the |usedefault| key. When used, it +% just sets \cs{xargs@default@flag} and the corresponding boolean. Later +% on, this will be used to possibly introduce a \cs{xargs@set@default} +% action at the beginning of the actions list. +% \begin{macrocode} +\define@key[xargs]{key}{usedefault}[]{% + \xargs@toksa{#1}\edef\xargs@default@flag{\the\xargs@toksa}} +% \end{macrocode} +% +% \medskip +% +% Let's continue with the more important keys. We have to collect +% through \pf{xkeyval} at most 9 actions numbered 1 to \cs{xargs@max} +% (the total number of arguments), each of them being +% \cs{xargs@test@opt} or \cs{xargs@put@arg}. Latter, we will use them to +% build up the parser. +% +% \begin{macro}{\@namenewc} \begin{macro}{\xargs@action@1} +% \begin{macro}{\xargs@action@2} \begin{macro}{\xargs@action@3} +% \begin{macro}{\xargs@action@4} \begin{macro}{\xargs@action@5} +% \begin{macro}{\xargs@action@6} \begin{macro}{\xargs@action@7} +% \begin{macro}{\xargs@action@8} \begin{macro}{\xargs@action@9} +% So our first task is to define container macros for the at most nine +% actions which represent arguments parsing, with default value +% \cs{xargs@put@arg} since every argument is mandatory unless specified. +% \begin{macrocode} +\providecommand\@namenewc[1]{% + \expandafter\newcommand\csname #1\endcsname} +% \end{macrocode} +% \begin{macrocode} +\@namenewc{xargs@action@1}{\xargs@put@arg} +\@namenewc{xargs@action@2}{\xargs@put@arg} +\@namenewc{xargs@action@3}{\xargs@put@arg} +\@namenewc{xargs@action@4}{\xargs@put@arg} +\@namenewc{xargs@action@5}{\xargs@put@arg} +\@namenewc{xargs@action@6}{\xargs@put@arg} +\@namenewc{xargs@action@7}{\xargs@put@arg} +\@namenewc{xargs@action@8}{\xargs@put@arg} +\@namenewc{xargs@action@9}{\xargs@put@arg} +% \end{macrocode} +% \end{macro} \end{macro} +% \end{macro} \end{macro} +% \end{macro} \end{macro} +% \end{macro} \end{macro} +% \end{macro} \end{macro} +% \begin{macro}{\xargs@def@key} +% The next macro will define the keys. Its first argument is the key's +% number. The second argument will be discussed later. +% \begin{macrocode} +\newcommand*\xargs@def@key[2]{% + \expandafter\@ifdefinable\csname xargs@key@#1\endcsname{% + \define@key[xargs]{key}{#1}[]{% +% \end{macrocode} +% The first thing do to, before setting any action, is to check whether +% this key can be used for this command, and complain if not. +% \begin{macrocode} + \ifnum\xargs@max<#1 + \PackageError{xargs}{% + Illegal argument label in\MessageBreak + optional arguments description% + }{% + You are trying to make optional an argument whose label (#1) + \MessageBreak is higher than the total number (\the\xargs@max) + of parameters. \MessageBreak This can't be done and your + demand will be ignored.}% + \else +% \end{macrocode} +% If the key number is correct, it may be that the user is trying to use +% it twice for the same command. Since it's probably a mistake, issue a +% warning in such case. +% \begin{macrocode} + \expandafter\expandafter\expandafter + \ifx\csname xargs@action@#1\endcsname\xargs@put@arg \else + \PackageWarning{xargs}{% + Argument #1 was allready given a default value.\MessageBreak + Previous value will be overriden.\MessageBreak}% + \fi +% \end{macrocode} +% If everything looks okay, define the action to be \cs{xargs@test@opt} +% with the given value, and execute the (for now) mysterious second +% argument. +% \begin{macrocode} + \@namedef{xargs@action@#1}{\xargs@test@opt{##1}}% + #2% + \fi}}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifxargs@firstopt@} +% \begin{macro}{\ifxargs@otheropt@} +% \begin{macro}{\xargs@key@1} +% \begin{macro}{\xargs@key@2} \begin{macro}{\xargs@key@3} +% \begin{macro}{\xargs@key@4} \begin{macro}{\xargs@key@5} +% \begin{macro}{\xargs@key@6} \begin{macro}{\xargs@key@7} +% \begin{macro}{\xargs@key@8} \begin{macro}{\xargs@key@9} +% The second argument is used to set the value for some \cs{if} which +% will keep track of the existence of an optional argument other than +% the first one, and the of the possibly optional nature of the first. +% Such information will be useful when we will have to decide if we use +% the \LaTeXe{} standard way or \pf{xargs} custom one to define the +% macro. +% \begin{macrocode} +\newif\ifxargs@firstopt@ +\newif\ifxargs@otheropt@ +% \end{macrocode} +% Now actually define the keys. +% \begin{macrocode} +\xargs@def@key1\xargs@firstopt@true +\xargs@def@key2\xargs@otheropt@true \xargs@def@key3\xargs@otheropt@true +\xargs@def@key4\xargs@otheropt@true \xargs@def@key5\xargs@otheropt@true +\xargs@def@key6\xargs@otheropt@true \xargs@def@key7\xargs@otheropt@true +\xargs@def@key8\xargs@otheropt@true \xargs@def@key9\xargs@otheropt@true +% \end{macrocode} +% \end{macro} \end{macro} \end{macro} +% \end{macro} \end{macro} \end{macro} +% \end{macro} \end{macro} \end{macro} +% \end{macro} \end{macro} +% \begin{macro}{\xargs@setkeys} +% \begin{macro}{\xargs@check@keys} +% We set the keys with the starred version of \cs{setkeys}, so we can +% check if there were some strange keys we cannot handle, and issue a +% meaningful warning if there are some. +% \begin{macrocode} +\newcommand\xargs@setkeys[1]{% + \setkeys*[xargs]{key}{#1}% + \xargs@check@keys} +% \end{macrocode} +% \begin{macrocode} +\newcommand\xargs@check@keys{% + \ifx\XKV@rm\empty \else + \xargs@toksa\expandafter{\XKV@rm}% + \PackageError{xargs}{% + Illegal key or argument label in\MessageBreak + optional arguments description% + }{% + You can only use non-zero digits as argument labels.\MessageBreak + Other allowed keys are usedefault and addprefix.\MessageBreak + You wrote: "\the\xargs@toksa".\MessageBreak + I can't understand this and I'm going to ignore it.}% + \fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Definition} +% +% \begin{macro}{\xargs@add@args} +% Now our goal is to build two lists from our up to nine argument +% grabbers, the special action |\xargs@setdefflag| and not forgetting +% the prefix. The first list is the coma-separated list of actions +% already discussed. The second is the parameter text for use in the +% definition on the internal macro, for example |[#1]#2[#3]|. The next +% macro takes the content of a \cs{xargs@action@X} macro for argument +% and adds the corresponding items to this lists. It checks if the first +% token of its parameter is \cs{xargs@testopt} in order to know if the +% |#n| has to be enclosed in square brackets. +% \begin{macrocode} +\newcommand\xargs@add@args[1]{% + \xargs@toksa\expandafter{\the\xargs@toksa #1,}% + \expandafter + \ifx\@car#1\@nil\xargs@put@arg + \xargs@toksb\expandafter\expandafter\expandafter{% + \the\expandafter\xargs@toksb\expandafter##\the\count@}% + \else + \xargs@toksb\expandafter\expandafter\expandafter{% + \the\expandafter\xargs@toksb\expandafter + [\expandafter##\the\count@]}% + \fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@process@keys} +% Here comes the main input processing macro, which prepares the +% information needed to define the final macro, and expands it to the +% defining macro. +% \begin{macrocode} +\@ifdefinable\xargs@process@keys{% + \long\def\xargs@process@keys#1[#2]{% +% \end{macrocode} +% Some initialisations. We work inside a group so that the default +% values for the \cs{xargs@action@X} macros and the \cs{xargs@XXXopt@} +% be automatically restored for the next time. +% \begin{macrocode} + \begingroup + \xargs@setkeys{#2}% + \xargs@toksa{}\xargs@toksb{}% +% \end{macrocode} +% Let's begin with the |usedefault| part. +% \begin{macrocode} + \@ifundefined{xargs@default@flag}{}{% + \xargs@toksa\expandafter{% + \expandafter\xargs@set@defflag\expandafter{% + \xargs@default@flag}}} +% \end{macrocode} +% Then the main loop actually builds up the two lists in the correct +% order. +% \begin{macrocode} + \count@\z@ + \@whilenum\xargs@max>\count@ \do{% + \advance\count@\@ne + \expandafter\expandafter\expandafter\xargs@add@args + \expandafter\expandafter\expandafter{% + \csname xargs@action@\the\count@\endcsname}}% +% \end{macrocode} +% Then we need to address a special case: if only the first argument is +% optional, we use \LaTeXe's standard \cs{newcommand} construct, and we +% dont need an actions list like the one just build, but only the +% default value for the first argument. In this case, we extract this +% value from \cs{xargs@action@1} by expanding it two times with a +% modified \cs{xargs@testopt} (and one more expansion step for the +% |\csname| gives $3$, hence the $2^3-1 = 7$ \cs{expandafter}s). +% \begin{macrocode} + \ifxargs@otheropt@ \else + \ifxargs@firstopt@ + \let\xargs@test@opt\@firstofone + \xargs@toksa\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter\expandafter{% + \csname xargs@action@1\endcsname}% + \fi + \fi +% \end{macrocode} +% Finally expand the stuff to the next macro and, while we're at it, +% choose the next macro : depending of the existence and place of an +% optional argument, use \LaTeX's or \pf{xargs}'s way. In the \LaTeX{} +% case, however, we don't use \cs{@argdef} or \cs{xargdef} since we want +% to be able to use a prefix (and we have more work done allready, too). +% \begin{macrocode} + \edef\xargs@temp{% + \ifxargs@otheropt@ \noexpand\xargs@xargsdef \else + \ifxargs@firstopt@ \noexpand\xargs@xargdef \else + \noexpand\xargs@argdef + \fi\fi + \noexpand#1% + \expandafter\noexpand\csname\string#1\endcsname + {\the\xargs@toksa}{\the\xargs@toksb}}% +% \end{macrocode} +% Now we can close the group and forget all about key values, etc. Time +% to conclude and actually define the macro. (The only thing not passed +% as an argument is the prefix, which is globally set.) We also take +% care to execute \cs{xargs@drc@hook} just outside the group. +% \begin{macrocode} + \expandafter\endgroup + \expandafter\xargs@drc@hook + \xargs@temp}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@argdef} +% \begin{macro}{\xargs@xargdef} +% \begin{macro}{\xargs@xargsdef} +% The first two next macros are modified versions of kernel's +% \cs{@argdef} and \cs{@xargdef}, that do the same work, but use the +% prefix we built, and also are simpler since they get the internal name +% as an argument. The last one is the only new macro. +% \begin{macrocode} +\newcommand\xargs@argdef[5]{% + \@ifdefinable#1{% + \xargs@prefix\def#1#4{#5}}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\xargs@xargdef[5]{% + \@ifdefinable#1{% + \xargs@shortpref\def#1{\@protected@testopt#1#2{#3}}% + \xargs@prefix\def#2#4{#5}}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\xargs@xargsdef[5]{% + \@ifdefinable#1{% + \xargs@shortpref\def#1{\@protected@testopt@xargs#1#2{#3}}% + \xargs@prefix\def#2#4{#5}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{User macros} +% +% \begin{macro}{\newcommandx} +% \begin{macro}{\xargs@newc} +% All the internal macros are ready. It's time to define the user +% commands, beginning with \cs{newcommandx}. Like its standard version, +% it just checks the star and call the next macro wich grabs the number +% of arguments. +% \begin{macrocode} +\newcommand\newcommandx{% + \xargs@star@or@long\xargs@newc} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@newc[1]{% + \@testopt{\xargs@set@max{#1}}{0}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\xargs@set@max} +% Set the value of \cs{xargs@max}. If no optional arguments description +% follows, simply call \cs{argdef} because all the complicated stuff is +% useless here. +% \begin{macrocode} +\@ifdefinable\xargs@set@max{% + \def\xargs@set@max#1[#2]{% + \kernel@ifnextchar[%] + {\xargs@max=#2 \xargs@check@max{#1}}% + {\@argdef#1[#2]}}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@check@max} +% To avoid possible problems later, check right now that \cs{xargs@max} +% value is valid. If not, warn the user and treat this value as zero. +% Then begin the key processing. +% \begin{macrocode} +\newcommand\xargs@check@max{% + \ifcase\xargs@max \or\or\or\or\or\or\or\or\or\else + \PackageError{xargs}{Illegal number, treated as zero}{The total + number of arguments must be in the 0..9 range.\MessageBreak + Since your value is illegal, i'm going to use 0 instead.} + \xargs@max0 + \fi + \xargs@process@keys} +% \end{macrocode} +% \end{macro} +% +% \medskip +% +% The other macros (\cs{renewcommandx} etc.) closely resemble their kernel +% homologues, since they are mostly wrappers around some call to +% \cs{xargs@newc}. There is however two exceptions: \cs{CheckCommand} +% and \cs{DeclareRobustCommandx}. Indeed, the current implementation of +% \cs{CheckCommand} in the kernel suffers from two bugs (see +% \href{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/3971} +% {PR/3971}) which I'm trying to avoid. For \cs{DeclareRobustCommandx}, +% the problem is to handle the prefix correctly: for that we use a hook, +% in order to delay the external macro's definition until we get the +% prefix right. So, let's see those two commands first. +% +% \begin{macro}{\CheckCommandx} +% We begin as usual detecting the possible star. +% \begin{macrocode} +\newcommand\CheckCommandx{% + \xargs@star@or@long\xargs@CheckC} +\@onlypreamble\CheckCommandx +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xargs@CheckC} +% \begin{macro}{\xargs@check@a} +% \begin{macro}{\xargs@check@b} +% First, we don't use the |#2#| trick from the kernel, since it can fail +% if there are braces in the default values. Instead, we follow the +% argument grabing method used for \cs{new@environment}, ie calling +% \cs{kernel@ifnextchar} explicitly. +% \begin{macrocode} +\newcommand\xargs@CheckC[1]{% + \@testopt{\xargs@check@a#1}0} +\@onlypreamble\xargs@CheckC +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@check@a{% + \def\xargs@check@a#1[#2]{% + \kernel@ifnextchar[%] + {\xargs@check@b#1[#2]}% + {\xargs@check@c#1{[#2]}}}} +\@onlypreamble\xargs@check@a +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@check@b{% + \def\xargs@check@b#1[#2][#3]{% + \xargs@check@c{#1}{[#2][{#3}]}}} +\@onlypreamble\xargs@check@b +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\xargs@CheckC} +% Here comes the major difference with the kernel version. If +% |\\reserved@a| is defined, we not only check that it is equal to +% |\\foo| (assuming \cs{foo} is the macro being tested), we also check +% that \cs{foo} makes something sensible, with \cs{xargs@check@d}. +% \begin{macrocode} +\newcommand\xargs@check@c[3]{% + \xargs@toksa{#1}% + \expandafter\let\csname\string\reserved@a\endcsname\relax + \xargs@renewc\reserved@a#2{#3}% + \@ifundefined{\string\reserved@a}{% + \ifx#1\reserved@a \else + \xargs@check@complain + \fi + }{% + \expandafter + \ifx\csname\string#1\expandafter\endcsname + \csname\string\reserved@a\endcsname + \xargs@check@d + \else + \xargs@check@complain + \fi}} +\@onlypreamble\xargs@check@c +% \end{macrocode} +% \end{macro} +% So, what do we want \cs{foo} to do? If |\\foo| is defined, \cs{foo} +% should begin with one of the followings: +% \begin{quote} +% |\@protected@testopt \foo \\foo| \\ +% |\@protected@testopt@xargs \foo \\foo| +% \end{quote} +% Since I'm to lazy to really check this, the \cs{xargs@check@d} macro +% only checks if the \cs{meaning} of \cs{foo} begins with +% \cs{@protected@test@opt} (without a space after it). It does this +% using a macro with delimited argument. Here are preliminaries to this +% definition: We need to have this string in \cs{catcode} 12 tokens. +% \begin{macrocode} +\def\xargs@temp{\@protected@testopt} +\expandafter\xargs@toksa\expandafter{\meaning\xargs@temp} +\def\xargs@temp#1 {\def\xargs@temp{#1}} +\expandafter\xargs@temp\the\xargs@toksa +% \end{macrocode} +% \begin{macro}{\xargs@check@d} +% \begin{macro}{\xargs@check@e} +% Now, \cs{xargs@check@c} just pass the \cs{meaning} of the command +% \cs{foo} being checked to the allready mentionned macro with delimited +% arguments, which will check if its first argument is empty (ie, if +% \cs{foo}'s \cs{meaning} starts with what we want) and complain +% otherwise. +% \begin{macrocode} +\expandafter\newcommand\expandafter\xargs@check@d\expandafter{% + \expandafter\expandafter\expandafter\xargs@check@e + \expandafter\meaning\expandafter\reserved@a\xargs@temp\@nil} +\@onlypreamble\xargs@check@d +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@check@e{% + \expandafter\def\expandafter\xargs@check@e + \expandafter#\expandafter1\xargs@temp#2\@nil{% + \ifx\empty#1\empty \else + \xargs@check@complain + \fi}} +\@onlypreamble\xargs@check@e +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\xargs@check@complain} +% The complaining macro uses the name saved by \cs{xargs@check@c} in +% \cs{xargs@toksa} in order to complain about the correct macro. +% \begin{macrocode} +\newcommand\xargs@check@complain{% + \PackageWarningNoLine{xargs}{Command \the\xargs@toksa has changed. + \MessageBreak Check if current package is valid}} +\@onlypreamble\xargs@check@complain +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareRobustCommandx} +% \begin{macro}{\xargs@DRC} +% The \pf{xargs} version of \cs{DeclareRobustCommand}, and related +% internal macros. +% \begin{macrocode} +\newcommand\DeclareRobustCommandx{% + \xargs@star@or@long\xargs@DRC} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@DRC[1]{% + \ifx#1\@undefined\else\ifx#1\relax\else + \PackageInfo{xargs}{Redefining \string#1}% + \fi\fi + \edef\reserved@a{\string#1}% + \def\reserved@b{#1}% + \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}% +% \end{macrocode} +% Here is the difference from kernel's code: instead of doing the +% definition of the user macro now, we just set the hook to do it +% latter, when the correct prefix will be set, then disable itself for +% next time. +% \begin{macrocode} + \edef\xargs@drc@hook{% + \noexpand\xargs@shortpref\def\noexpand#1{% + \ifx\reserved@a\reserved@b + \noexpand\x@protect + \noexpand#1% + \fi + \noexpand\protect + \expandafter\noexpand\csname + \expandafter\@gobble\string#1 \endcsname}% + \expandafter\let\noexpand\xargs@drc@hook\relax}% + \let\@ifdefinable\@rc@ifdefinable + \expandafter\xargs@newc\csname + \expandafter\@gobble\string#1 \endcsname} +% \end{macrocode} +% And finally set a default empty hook. +% \begin{macrocode} +\let\xargs@drc@hook\relax +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \medskip +% +% From now on, there is absolutely nothing to comment, since the next +% macros are mainly wrappers around \cs{xargs@newc}, just as kernel's +% ones are wrappers around \cs{new@command}. So the code below is only +% copy/paste with search\&replace from the kernel code. +% +% \begin{macro}{\renewcommandx} +% \begin{macro}{\xargs@renewc} +% The \pf{xargs} version of \cs{renewcommand}, and it's related internal +% macro. +% \begin{macrocode} +\newcommand\renewcommandx{% + \xargs@star@or@long\xargs@renewc} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@renewc[1]{% + \begingroup\escapechar\m@ne + \xdef\@gtempa{{\string#1}}% + \endgroup + \expandafter\@ifundefined\@gtempa{% + \PackageError{xargs}{\noexpand#1undefined}{% + Try typing \space \space to proceed.\MessageBreak + If that doesn't work, type \space X \space to quit.}}% + \relax + \let\@ifdefinable\@rc@ifdefinable + \xargs@newc#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\providecommandx} +% \begin{macro}{\xargs@providec} +% The \pf{xargs} version of \cs{providecommand}, and the related +% internal macro. +% \begin{macrocode} +\newcommand\providecommandx{% + \xargs@star@or@long\xargs@providec} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@providec[1]{% + \begingroup\escapechar\m@ne + \xdef\@gtempa{{\string#1}}% + \endgroup + \expandafter\@ifundefined\@gtempa + {\def\reserved@a{\xargs@newc#1}}% + {\def\reserved@a{\renew@command\reserved@a}}% + \reserved@a} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\newenvironment} +% \begin{macro}{\xargs@newenv} +% \begin{macro}{\xargs@newenva} +% \begin{macro}{\xargs@newenvb} +% \begin{macro}{\xargs@new@env} +% The \pf{xargs} version of \cs{newenvironment}, and related internal +% macros. +% \begin{macrocode} +\newcommand\newenvironmentx{% + \xargs@star@or@long\xargs@newenv} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@newenv[1]{% + \@testopt{\xargs@newenva#1}0} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@newenva{% + \def\xargs@newenva#1[#2]{% + \kernel@ifnextchar[%] + {\xargs@newenvb#1[#2]}% + {\xargs@new@env{#1}{[#2]}}}} +% \end{macrocode} +% \begin{macrocode} +\@ifdefinable\xargs@newenvb{% + \def\xargs@newenvb#1[#2][#3]{% + \xargs@new@env{#1}{[#2][{#3}]}}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\xargs@new@env[4]{% + \@ifundefined{#1}{% + \expandafter\let\csname#1\expandafter\endcsname + \csname end#1\endcsname}% + \relax + \expandafter\xargs@newc + \csname #1\endcsname#2{#3}% + \xargs@shortpref\expandafter\def\csname end#1\endcsname{#4}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\renewenvironment} +% \begin{macro}{\xargs@renewenv} +% The \pf{xargs} version of \cs{renewenvironment}, and the related +% internal macro. +% \begin{macrocode} +\newcommand\renewenvironmentx{% + \xargs@star@or@long\xargs@renewenv} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\xargs@renewenv[1]{% + \@ifundefined{#1}{% + \PackageError{xargs}{\noexpand#1undefined}{% + Try typing \space \space to proceed.\MessageBreak + If that doesn't work, type \space X \space to quit.}}% + \relax + \expandafter\let\csname#1\endcsname\relax + \expandafter\let\csname end#1\endcsname\relax + \xargs@newenv{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \bigskip +% \begin{center}\Large +% That's all folks!\\ +% Happy \TeX ing! +% \end{center} +% +% \Finale +% +% \iffalse +% +%<*batchfile> +% \fi +% \typeout{**************************************************} +% \typeout{*} +% \typeout{* To finish the installation you have to move the} +% \typeout{* following file into a directory searched by TeX:} +% \typeout{*} +% \typeout{* \space\space\space\space xargs.sty} +% \typeout{*} +% \typeout{* Documentation is in xargs.dvi or xargs.pdf} +% \typeout{*} +% \typeout{* To produce french documentation, run} +% \typeout{* \space\space \space\space (pdf)latex xargs-fr.drv} +% \typeout{*} +% \typeout{* Happy TeXing!} +% \typeout{*} +% \typeout{**************************************************} +% \iffalse +% +% \fi +\endinput diff --git a/macros/latex/contrib/xargs/xargs.pdf b/macros/latex/contrib/xargs/xargs.pdf new file mode 100644 index 0000000000..66f8ad371f Binary files /dev/null and b/macros/latex/contrib/xargs/xargs.pdf differ diff --git a/macros/latex/contrib/xargs/xargs.sty b/macros/latex/contrib/xargs/xargs.sty new file mode 100644 index 0000000000..a523e8abc6 --- /dev/null +++ b/macros/latex/contrib/xargs/xargs.sty @@ -0,0 +1,361 @@ +%% +%% This is file `xargs.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% xargs.dtx (with options: `package') +%% +%% xargs package by Manuel P\'egouri\'e-Gonnard +%% This is a generated file. See xargs.dtx for license information. +%% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{xargs} + [2008/03/22 v1.1 \space extended macro definitions \space (mpg)] +\RequirePackage{xkeyval} +\@ifdefinable\xargs@max{\newcount\xargs@max} +\@ifdefinable\xargs@temp\relax +\@ifdefinable\xargs@toksa{\newtoks\xargs@toksa} +\@ifdefinable\xargs@toksb{\newtoks\xargs@toksb} +\newcommand*\@protected@testopt@xargs[1]{% + \ifx\protect\@typeset@protect + \expandafter\xargs@read + \else + \@x@protect#1% + \fi} +\newcommand*\xargs@read[2]{% + \begingroup + \xargs@toksa{#1}% + \xargs@toksb{#2}% + \xargs@continue} +\newcommand\xargs@continue{% + \expandafter\xargs@pick@next\the\xargs@toksb,\@nil + \xargs@temp} +\@ifdefinable\xargs@pick@next{% + \def\xargs@pick@next#1,#2\@nil{% + \def\xargs@temp{#1}% + \xargs@toksb{#2}% + \ifx\xargs@temp\empty + \def\xargs@temp{\expandafter\endgroup\the\xargs@toksa}% + \fi}} +\newcommand*\xargs@set@defflag[1]{% + \def\xargs@default@flag{#1}} +\newcommand\xargs@put@arg[1]{% + \xargs@toksa\expandafter{\the\xargs@toksa{#1}}% + \xargs@continue} +\newcommand*\xargs@test@opt[1]{% + \xargs@ifnextchar[%] + {\xargs@grab@opt{#1}}% + {\xargs@put@opt{#1}}} +\newcommand\xargs@put@opt[1]{% + \xargs@toksa\expandafter{\the\xargs@toksa[{#1}]}% + \xargs@continue} +\@ifdefinable\xargs@grab@opt{% + \long\def\xargs@grab@opt#1[#2]{% + \toks@{#2}\edef\xargs@temp{\the\toks@}% + \ifx\xargs@temp\xargs@default@flag + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi{% + \xargs@put@opt{#1}% + }{% + \xargs@put@opt{#2}}}} +\newcommand\xargs@ifnextchar[3]{% + \let\xargs@temp\empty + \let\reserved@d=#1% + \def\reserved@a{#2}% + \def\reserved@b{#3}% + \futurelet\@let@token\xargs@ifnch} +\newcommand\xargs@ifnch{% + \ifx\@let@token\@sptoken + \edef\xargs@temp{\xargs@temp\space}% + \let\reserved@c\xargs@xifnch + \else + \ifx\@let@token\reserved@d + \let\reserved@c\reserved@a + \else + \def\reserved@c{\expandafter\reserved@b\xargs@temp}% + \fi + \fi + \reserved@c} +\@ifdefinable\xargs@xifnch{% + \expandafter\def\expandafter\xargs@xifnch\space{% + \futurelet\@let@token\xargs@ifnch}} +\@ifdefinable\xargs@key@addprefix{% + \define@key[xargs]{key}{addprefix}[]{% + \global\expandafter\def\expandafter\xargs@prefix\expandafter{% + \xargs@prefix#1}% + \xargs@makeshort#1\long\@nil}} +\@ifdefinable\xargs@makeshort{% + \def\xargs@makeshort#1\long#2{% + \expandafter\gdef\expandafter\xargs@shortpref\expandafter{% + \xargs@shortpref#1}% + \ifx#2\@nil \else + \expandafter\xargs@makeshort\expandafter#2% + \fi}} +\newcommand\xargs@star@or@long[1]{% + \global\let\xargs@shortpref\@empty + \@ifstar{\gdef\xargs@prefix{}#1}{\gdef\xargs@prefix{\long}#1}} +\define@key[xargs]{key}{usedefault}[]{% + \xargs@toksa{#1}\edef\xargs@default@flag{\the\xargs@toksa}} +\providecommand\@namenewc[1]{% + \expandafter\newcommand\csname #1\endcsname} +\@namenewc{xargs@action@1}{\xargs@put@arg} +\@namenewc{xargs@action@2}{\xargs@put@arg} +\@namenewc{xargs@action@3}{\xargs@put@arg} +\@namenewc{xargs@action@4}{\xargs@put@arg} +\@namenewc{xargs@action@5}{\xargs@put@arg} +\@namenewc{xargs@action@6}{\xargs@put@arg} +\@namenewc{xargs@action@7}{\xargs@put@arg} +\@namenewc{xargs@action@8}{\xargs@put@arg} +\@namenewc{xargs@action@9}{\xargs@put@arg} +\newcommand*\xargs@def@key[2]{% + \expandafter\@ifdefinable\csname xargs@key@#1\endcsname{% + \define@key[xargs]{key}{#1}[]{% + \ifnum\xargs@max<#1 + \PackageError{xargs}{% + Illegal argument label in\MessageBreak + optional arguments description% + }{% + You are trying to make optional an argument whose label (#1) + \MessageBreak is higher than the total number (\the\xargs@max) + of parameters. \MessageBreak This can't be done and your + demand will be ignored.}% + \else + \expandafter\expandafter\expandafter + \ifx\csname xargs@action@#1\endcsname\xargs@put@arg \else + \PackageWarning{xargs}{% + Argument #1 was allready given a default value.\MessageBreak + Previous value will be overriden.\MessageBreak}% + \fi + \@namedef{xargs@action@#1}{\xargs@test@opt{##1}}% + #2% + \fi}}} +\newif\ifxargs@firstopt@ +\newif\ifxargs@otheropt@ +\xargs@def@key1\xargs@firstopt@true +\xargs@def@key2\xargs@otheropt@true \xargs@def@key3\xargs@otheropt@true +\xargs@def@key4\xargs@otheropt@true \xargs@def@key5\xargs@otheropt@true +\xargs@def@key6\xargs@otheropt@true \xargs@def@key7\xargs@otheropt@true +\xargs@def@key8\xargs@otheropt@true \xargs@def@key9\xargs@otheropt@true +\newcommand\xargs@setkeys[1]{% + \setkeys*[xargs]{key}{#1}% + \xargs@check@keys} +\newcommand\xargs@check@keys{% + \ifx\XKV@rm\empty \else + \xargs@toksa\expandafter{\XKV@rm}% + \PackageError{xargs}{% + Illegal key or argument label in\MessageBreak + optional arguments description% + }{% + You can only use non-zero digits as argument labels.\MessageBreak + Other allowed keys are usedefault and addprefix.\MessageBreak + You wrote: "\the\xargs@toksa".\MessageBreak + I can't understand this and I'm going to ignore it.}% + \fi} +\newcommand\xargs@add@args[1]{% + \xargs@toksa\expandafter{\the\xargs@toksa #1,}% + \expandafter + \ifx\@car#1\@nil\xargs@put@arg + \xargs@toksb\expandafter\expandafter\expandafter{% + \the\expandafter\xargs@toksb\expandafter##\the\count@}% + \else + \xargs@toksb\expandafter\expandafter\expandafter{% + \the\expandafter\xargs@toksb\expandafter + [\expandafter##\the\count@]}% + \fi} +\@ifdefinable\xargs@process@keys{% + \long\def\xargs@process@keys#1[#2]{% + \begingroup + \xargs@setkeys{#2}% + \xargs@toksa{}\xargs@toksb{}% + \@ifundefined{xargs@default@flag}{}{% + \xargs@toksa\expandafter{% + \expandafter\xargs@set@defflag\expandafter{% + \xargs@default@flag}}} + \count@\z@ + \@whilenum\xargs@max>\count@ \do{% + \advance\count@\@ne + \expandafter\expandafter\expandafter\xargs@add@args + \expandafter\expandafter\expandafter{% + \csname xargs@action@\the\count@\endcsname}}% + \ifxargs@otheropt@ \else + \ifxargs@firstopt@ + \let\xargs@test@opt\@firstofone + \xargs@toksa\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter\expandafter{% + \csname xargs@action@1\endcsname}% + \fi + \fi + \edef\xargs@temp{% + \ifxargs@otheropt@ \noexpand\xargs@xargsdef \else + \ifxargs@firstopt@ \noexpand\xargs@xargdef \else + \noexpand\xargs@argdef + \fi\fi + \noexpand#1% + \expandafter\noexpand\csname\string#1\endcsname + {\the\xargs@toksa}{\the\xargs@toksb}}% + \expandafter\endgroup + \expandafter\xargs@drc@hook + \xargs@temp}} +\newcommand\xargs@argdef[5]{% + \@ifdefinable#1{% + \xargs@prefix\def#1#4{#5}}} +\newcommand\xargs@xargdef[5]{% + \@ifdefinable#1{% + \xargs@shortpref\def#1{\@protected@testopt#1#2{#3}}% + \xargs@prefix\def#2#4{#5}}} +\newcommand\xargs@xargsdef[5]{% + \@ifdefinable#1{% + \xargs@shortpref\def#1{\@protected@testopt@xargs#1#2{#3}}% + \xargs@prefix\def#2#4{#5}}} +\newcommand\newcommandx{% + \xargs@star@or@long\xargs@newc} +\newcommand*\xargs@newc[1]{% + \@testopt{\xargs@set@max{#1}}{0}} +\@ifdefinable\xargs@set@max{% + \def\xargs@set@max#1[#2]{% + \kernel@ifnextchar[%] + {\xargs@max=#2 \xargs@check@max{#1}}% + {\@argdef#1[#2]}}} +\newcommand\xargs@check@max{% + \ifcase\xargs@max \or\or\or\or\or\or\or\or\or\else + \PackageError{xargs}{Illegal number, treated as zero}{The total + number of arguments must be in the 0..9 range.\MessageBreak + Since your value is illegal, i'm going to use 0 instead.} + \xargs@max0 + \fi + \xargs@process@keys} +\newcommand\CheckCommandx{% + \xargs@star@or@long\xargs@CheckC} +\@onlypreamble\CheckCommandx +\newcommand\xargs@CheckC[1]{% + \@testopt{\xargs@check@a#1}0} +\@onlypreamble\xargs@CheckC +\@ifdefinable\xargs@check@a{% + \def\xargs@check@a#1[#2]{% + \kernel@ifnextchar[%] + {\xargs@check@b#1[#2]}% + {\xargs@check@c#1{[#2]}}}} +\@onlypreamble\xargs@check@a +\@ifdefinable\xargs@check@b{% + \def\xargs@check@b#1[#2][#3]{% + \xargs@check@c{#1}{[#2][{#3}]}}} +\@onlypreamble\xargs@check@b +\newcommand\xargs@check@c[3]{% + \xargs@toksa{#1}% + \expandafter\let\csname\string\reserved@a\endcsname\relax + \xargs@renewc\reserved@a#2{#3}% + \@ifundefined{\string\reserved@a}{% + \ifx#1\reserved@a \else + \xargs@check@complain + \fi + }{% + \expandafter + \ifx\csname\string#1\expandafter\endcsname + \csname\string\reserved@a\endcsname + \xargs@check@d + \else + \xargs@check@complain + \fi}} +\@onlypreamble\xargs@check@c +\def\xargs@temp{\@protected@testopt} +\expandafter\xargs@toksa\expandafter{\meaning\xargs@temp} +\def\xargs@temp#1 {\def\xargs@temp{#1}} +\expandafter\xargs@temp\the\xargs@toksa +\expandafter\newcommand\expandafter\xargs@check@d\expandafter{% + \expandafter\expandafter\expandafter\xargs@check@e + \expandafter\meaning\expandafter\reserved@a\xargs@temp\@nil} +\@onlypreamble\xargs@check@d +\@ifdefinable\xargs@check@e{% + \expandafter\def\expandafter\xargs@check@e + \expandafter#\expandafter1\xargs@temp#2\@nil{% + \ifx\empty#1\empty \else + \xargs@check@complain + \fi}} +\@onlypreamble\xargs@check@e +\newcommand\xargs@check@complain{% + \PackageWarningNoLine{xargs}{Command \the\xargs@toksa has changed. + \MessageBreak Check if current package is valid}} +\@onlypreamble\xargs@check@complain +\newcommand\DeclareRobustCommandx{% + \xargs@star@or@long\xargs@DRC} +\newcommand*\xargs@DRC[1]{% + \ifx#1\@undefined\else\ifx#1\relax\else + \PackageInfo{xargs}{Redefining \string#1}% + \fi\fi + \edef\reserved@a{\string#1}% + \def\reserved@b{#1}% + \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}% + \edef\xargs@drc@hook{% + \noexpand\xargs@shortpref\def\noexpand#1{% + \ifx\reserved@a\reserved@b + \noexpand\x@protect + \noexpand#1% + \fi + \noexpand\protect + \expandafter\noexpand\csname + \expandafter\@gobble\string#1 \endcsname}% + \expandafter\let\noexpand\xargs@drc@hook\relax}% + \let\@ifdefinable\@rc@ifdefinable + \expandafter\xargs@newc\csname + \expandafter\@gobble\string#1 \endcsname} +\let\xargs@drc@hook\relax +\newcommand\renewcommandx{% + \xargs@star@or@long\xargs@renewc} +\newcommand*\xargs@renewc[1]{% + \begingroup\escapechar\m@ne + \xdef\@gtempa{{\string#1}}% + \endgroup + \expandafter\@ifundefined\@gtempa{% + \PackageError{xargs}{\noexpand#1undefined}{% + Try typing \space \space to proceed.\MessageBreak + If that doesn't work, type \space X \space to quit.}}% + \relax + \let\@ifdefinable\@rc@ifdefinable + \xargs@newc#1} +\newcommand\providecommandx{% + \xargs@star@or@long\xargs@providec} +\newcommand*\xargs@providec[1]{% + \begingroup\escapechar\m@ne + \xdef\@gtempa{{\string#1}}% + \endgroup + \expandafter\@ifundefined\@gtempa + {\def\reserved@a{\xargs@newc#1}}% + {\def\reserved@a{\renew@command\reserved@a}}% + \reserved@a} +\newcommand\newenvironmentx{% + \xargs@star@or@long\xargs@newenv} +\newcommand*\xargs@newenv[1]{% + \@testopt{\xargs@newenva#1}0} +\@ifdefinable\xargs@newenva{% + \def\xargs@newenva#1[#2]{% + \kernel@ifnextchar[%] + {\xargs@newenvb#1[#2]}% + {\xargs@new@env{#1}{[#2]}}}} +\@ifdefinable\xargs@newenvb{% + \def\xargs@newenvb#1[#2][#3]{% + \xargs@new@env{#1}{[#2][{#3}]}}} +\newcommand\xargs@new@env[4]{% + \@ifundefined{#1}{% + \expandafter\let\csname#1\expandafter\endcsname + \csname end#1\endcsname}% + \relax + \expandafter\xargs@newc + \csname #1\endcsname#2{#3}% + \xargs@shortpref\expandafter\def\csname end#1\endcsname{#4}} +\newcommand\renewenvironmentx{% + \xargs@star@or@long\xargs@renewenv} +\newcommand*\xargs@renewenv[1]{% + \@ifundefined{#1}{% + \PackageError{xargs}{\noexpand#1undefined}{% + Try typing \space \space to proceed.\MessageBreak + If that doesn't work, type \space X \space to quit.}}% + \relax + \expandafter\let\csname#1\endcsname\relax + \expandafter\let\csname end#1\endcsname\relax + \xargs@newenv{#1}} +\endinput +%% +%% End of file `xargs.sty'. -- cgit v1.2.3