%%\iffalse %% suffix.dtx for defining variant commands. %% Part of the critical bundle around bigfoot. %% Copyright (C) 2004 David Kastrup %% %% This program is free software; you can redistribute it and/or modify %% it under the terms of the GNU General Public License as published by %% the Free Software Foundation; either version 2 of the License, or %% (at your option) any later version. %% %% This program is distributed in the hope that it will be useful, %% but WITHOUT ANY WARRANTY; without even the implied warranty of %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the %% GNU General Public License for more details. %% %% You should have received a copy of the GNU General Public License %% along with this program; if not, write to the %% Free Software Foundation, Inc., 59 Temple Place, Suite 330, %% Boston, MA 02111-1307 USA %%\fi % \CheckSum{233} % \GetFileInfo{suffix.sty} % \author{David Kastrup\thanks{\href{mailto:dak@gnu.org}^^A % {Email: \texttt{dak@gnu.org}}}} % \title{The \texttt{suffix} Package\\Version \fileversion} % \date{\filedate} % \maketitle % \section{Basics} % The \texttt{suffix} package has the purpose of making it easy to % define and maintain command variants like |\macro*| and even % |\macro\/| or similar. It requires e\TeX\ version~2 for its work. % The suffixes are fetched with |\futurelet|, so things like |\bgroup| % and |{| ^^A} % can't be distinguished. In addition, the efficiency depends on the % complexity of the suffix' definition, so you should preferably use % characters or short commands as a suffix. A suffixed command itself % counts as short for this purpose. How does a suffix definition look % like? % % \DescribeMacro{\WithSuffix} The general form is % \begin{quote} % |\WithSuffix|\meta{prefixed definition}\meta{macro}\meta{suffix}\dots % \end{quote} % where \meta{prefixed definition} is something like |\xdef|, % |\global\let| or similar. Recognised prefixes are |\global|, % |\long|, |\protected| (the latter is rarely useful, as the original % definition already is robust), and |\expandafter| (with its % `natural' meaning), specially recognized commands are |\gdef| and % |\xdef|. Other commands can be used as long as they are suitable as % an undelimited macro argument. This means they must either be a % single token like |\newcommand| or brace-enclosed like % |{\newcommand*}|. \meta{macro} can be a macro or an active % character. It should be a single token suitable for assignment with % |\let|. \meta{suffix} can be something like a single letter such as % |*| or |[|. % % For example, assume that a command |\snarf| already exists and we % want to define a variant |\snarf|\oarg{optarg}. Then we can do this % with % \begin{quote} % \cmd\WithSuffix|\long\def\snarf[#1]{|\meta{Definition using % \texttt{\#1}}|}| % \end{quote} % That's pretty much it. Oh, only when a command is recognised as % having a prefix |\global| or being |\xdef| or |gdef| will the % corresponding redefinitions be done globally. This is rarely a % concern. % % \DescribeMacro{\SuffixName} In case you need to refer to the control % sequence name used to refer to the suffixed macro, you can access it % as % \begin{quote} % |\csname|\cmd{\SuffixName}\meta{macro}\meta{suffix}|\endcsname| % \end{quote} % \DescribeMacro{\NoSuffixName} and if you need to refer to the % original unsuffixed macro, you can access it as % \begin{quote} % |\csname|\cmd{\NoSuffixName}\meta{macro}|\endcsname| % \end{quote} % \StopEventually{} % \section{Implementation} % First we announce the package and check for e\TeX~2. % \begin{macrocode} %<*style> \def\next$#1:#2${#2} {\catcode`\-\active \def-{.} \xdef\reserved@a{\expandafter\@gobble\next$Name: $\@empty}} \def\next$#1: #2 #3${#2} \ifx\reserved@a\@empty \gdef\reserved@a{CVS-\next$Revision: 1.2 $}\fi \edef\next{\noexpand \ProvidesPackage{suffix}[\next$Date: 2004/02/19 19:49:21 $ \reserved@a\space]} \next \ifcase\ifx\eTeXversion\@undefined \@ne\fi \ifnum\eTeXversion<\tw@ \@ne\fi\z@ \else \PackageError{suffix}{This package requires eTeX version 2}% {You might try to use the `elatex' command.}% \fi % \end{macrocode} % \begin{macro}{\WithSuffix} % Then we define the \cmd{\WithSuffix} command. We use % \cmd{\@temptokena} to collect prefixes and let \cmd{\WSF@global} to % |\global| for global definitions. % % \begin{macrocode} \def\WithSuffix{\@temptokena{}\let\WSF@global\relax \WSF@sfx} % \end{macrocode} % \end{macro} % \begin{macro}{\WSF@sfx} % \begin{macro}{\WSF@append} % \begin{macro}{\WSF@gobblenext} % After checking all prefixes and stuff (we'll fill in this missing % link later), we add the defining command itself to the token list, % place \meta{macro} into \cmd{\reserved@a} and fetch \meta{suffix} % into \cmd{\reserved@b}. % \begin{macrocode} \long\def\WSF@sfx#1#2{\WSF@append{#1}\def\reserved@a{#2}% \afterassignment\WSF@decsuff \WSF@gobblenext} \def\WSF@append#1{\@temptokena\expandafter{\the\@temptokena#1}} \def\WSF@gobblenext{\let\reserved@b= } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macro}{\SuffixName} % \begin{macro}{\NoSuffixName} % While we are at it, let us define the macro names to use for % suffixed and unsuffixed \meta{macro}. % \begin{macrocode} \long\def\SuffixName#1{WSF:\string#1 \meaning} \def\NoSuffixName{WSF:\string} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\WSF@decsuff} % We first check whether the macro has already been suffixed. If it % hasn't, we save a copy of it and redefine it in terms of % \cmd{\WSF@suffixcheck}. % \begin{macrocode} \def\WSF@decsuff{\ifcsname \expandafter\NoSuffixName\reserved@a\endcsname \else \WSF@global\expandafter\let\csname \expandafter\NoSuffixName\reserved@a \expandafter\endcsname \reserved@a \long\def\reserved@c##1{\WSF@global\protected\def ##1{\WSF@suffixcheck##1}}% \expandafter\reserved@c\reserved@a \fi % \end{macrocode} % Once we have done that, we are ready for calling the definition % command on the suffixed \meta{macro}. % \begin{macrocode} \WSF@global \the\expandafter\@temptokena\csname \expandafter \SuffixName \reserved@a\reserved@b\endcsname} % \end{macrocode} % \end{macro} % \begin{macro}{\WSF@suffixcheck} % We now do the runtime code. This is % executed in a group of its own in order not to interfere with any % other macros. % \begin{macrocode} \def\WSF@suffixcheck#1{\begingroup\def\reserved@a{#1}% \futurelet\reserved@b\WSF@suffixcheckii} % \end{macrocode} % \end{macro} % \begin{macro}{\WSF@suffixcheckii} % After assigning the \meta{suffix} to \cmd{\reserved@b}, we split % into the case of known and unknown suffix. We don't code this % inline, since \cmd{\reserved@} in a false conditional might % confuse \TeX\ if it happens to be something like |\iffalse| % itself. % \begin{macrocode} \def\WSF@suffixcheckii{\ifcsname \expandafter\SuffixName \reserved@a\reserved@b\endcsname \expandafter \WSF@suffixcheckiii \else \expandafter \WSF@suffixcheckiv \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\WSF@suffixcheckiii} % \begin{macro}{\WSF@suffixcheckiv} % Calling the macros is reasonably straightforward, we just have to % take care not to close the group at the wrong time. % \begin{macrocode} \def\WSF@suffixcheckiii{% \afterassignment\endgroup \expandafter\aftergroup \csname \expandafter \SuffixName\reserved@a\reserved@b\endcsname \WSF@gobblenext} \def\WSF@suffixcheckiv{% \expandafter\endgroup \csname \expandafter\NoSuffixName\reserved@a\endcsname} % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\WSF@sfx} % Now we just augment \cmd{WSF@sfx} to recognize all prefixes and % global commands: % \begin{macrocode} \WithSuffix\def\WSF@sfx\long{\WSF@append\long\WSF@sfx} \WithSuffix\def\WSF@sfx\global{\let\WSF@global\global\WSF@sfx} \WithSuffix\def\WSF@sfx\protected{\WSF@append\protected\WSF@sfx} \WithSuffix\def\WSF@sfx\expandafter{\expandafter\WSF@sfx\expandafter} \WithSuffix\edef\WSF@sfx\gdef{\let\WSF@global\global \expandafter\noexpand\csname\NoSuffixName\WSF@sfx\endcsname\def} \WithSuffix\edef\WSF@sfx\xdef{\let\WSF@global\global \expandafter\noexpand\csname\NoSuffixName\WSF@sfx\endcsname\edef} % % \end{macrocode} %\end{macro} % \section{Various driver files} % The installer, in case it is missing. If it is to be used via % |make|, we don't specify an installation path, since % \begin{quote} % |make install| % \end{quote} % is supposed to cater for the installation itself. % \begin{macrocode} % \input docstrip % \askforoverwritefalse % \generate{ % \file{suffix.drv}{\from{suffix.dtx}{driver}} % \usedir{tex/latex/bigfoot} % \file{suffix.sty}{\from{suffix.dtx}{style}} % } % \endbatchfile % \end{macrocode} % And here comes the documentation driver. % \begin{macrocode} % \documentclass{ltxdoc} % \usepackage{hyperref} % \usepackage{suffix} % \begin{document} % \DocInput{suffix.dtx} % \end{document} % \end{macrocode} % \Finale{} % \endinput % Local Variables: % mode: latex % TeX-master: "suffix.drv" % End: