diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/frankenstein/moredefs.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/frankenstein/moredefs.sty | 1478 |
1 files changed, 1478 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/frankenstein/moredefs.sty b/Master/texmf-dist/tex/latex/frankenstein/moredefs.sty new file mode 100644 index 00000000000..28c26446c3c --- /dev/null +++ b/Master/texmf-dist/tex/latex/frankenstein/moredefs.sty @@ -0,0 +1,1478 @@ +%^^A* legal notices +% \iffalse +% +% This program is part of the Frankenstein bundle for LaTeX. +% +% Copyright 1995-2001 Matt Swift <swift@alum.mit.edu>. +% +% This file contains both the code and documentation for the +% moredefs LaTeX package. It will work ONLY if it is placed in a +% proper directory. Files called README, INSTALL, moredefs.tex +% and moredefs.ins should have also been distributed to you +% with this file. See them for more information on how to typeset +% the documentation with LaTeX and how to generate a version of this +% file that will work faster than this one. +% +% This program is free software; you may redistribute it and/or +% modify it under the conditions of the LaTeX Project Public +% License, either version 1.2 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.2 or later is +% part of all distributions of LaTeX version 1999/12/01 or later. +% +% 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 +% LaTeX Project Public License for more details. +% +% \fi +% +%^^A* checks +% +%^^A NOTE: The character table, with two %'s, will get written to all files. +%% \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 \~} +% +% \CheckSum{793} +% +% \begin{abstract} +% A delightful collection of defining, expansion, and debugging commands that +% make elegant programming in \LaTeX{} fun and easy. +% \end{abstract} +% \tableofcontents +% +% \part{Discussion} +% +% These macros were written in response to practical programming needs. Most +% of the packages I have written, whether distributed or not, depend on this +% package. Using these constructs has saved me a lot of time and made my code +% much more readable---that is, maintainable and improvable. For examples of +% these macros in useful applications, see the packages in the \Frankenstein +% bundle. +% +% \section{Naming conventions} +% +% The convention is that a capital \emph{E} means the macro expands something +% just once. A lowercase \emph{e}, as in \cs\edef, means the macro expands +% something all the way to unexpandable tokens. +% +% The specification \meta{\\csname} means a control sequence with a preceding +% backslash; the specification \meta{csname} means a control sequence without a +% preceding backslash. \meta{csname} arguments are expanded. Commands which +% take \meta{csname} arguments have |Name| in their names. +% +% When I write \word{package} in this documentation, I mean \LaTeX{} package or +% class. +% +% \section{Conditionals} +% +% \DescribeMacro{\@ifundefined@cs} +% \cname{@ifundefined@cs}\marg{\\csname}\marg{true}\marg{false} executes the +% \meta{true} clause if \meta{\\csname} is not defined, and the \meta{else} +% clause otherwise. +% +% \DescribeMacro{\IfElement...\string\In} +% To check whether a token \meta{thingma} is \cs\ifx-equal to any token in a +% list of tokens stored in a macro \meta{list}, use +% \cs\IfElement\meta{thingma}\cs\In\meta{list}\marg{true}\marg{false}. The +% top-level expansion of \meta{list} must be a list of tokens to compare with +% \meta{thingma} with \cs\ifx. If the \meta{thingma} is in the \meta{list}, +% the \meta{true} clause is executed; otherwise, the \meta{false} clause is +% executed. +% +% \section{Defining commands} +% \subsection{\protect\code{*} and no-\protect\code{*} forms} +% The naming convention of most defining commands in the \LaTeX{} kernel and +% in \package{moredefs} is that the no-|*| form of the command is |long| and +% the |*|-form is not |long|. +% +% \subsection{User commands} +% +% \DescribeMacro\InitCS +% \DescribeMacro{\InitCS*} +% \cs\InitCS and \cname{InitCS*} take one argument, \meta{\\csname}, and +% initialize it to |{}|. +% +% \DescribeMacro\InitName +% \DescribeMacro{\InitName*} +% \cs\InitName and \cname{InitName*} are the same but take an argument +% \meta{csname} without a backslash. +% +% \DescribeMacro\ShortEmpty +% \DescribeMacro\LongEmpty +% To make it easier to avoid the problem of comparing |long| and +% non-|long| macros with \cname{ifx}, compare macros with \cs\ShortEmpty +% and \cs\LongEmpty. +% +% \DescribeMacro\ReserveCS +% \DescribeMacro{\ReserveCS*} +% \cs\ReserveCS\marg{\\csname} reserves \meta{\\csname} for the current +% package's use. The variable is also initialized with the \cs\InitCS or +% \cs\InitCS* as appropriate. +% +% \DescribeMacro\ReserveName +% \DescribeMacro{\ReserveName*} +% \cs\ReserveName and \cname{ReserveName*} are the same but take an argument +% \meta{csname} without a backslash. +% +% \DescribeMacro\SaveCS +% \DescribeMacro\RestoreCS +% \cs\SaveCS\marg{\\csname} saves the present value of \meta{\\csname} in a +% macro (\cname{MDSaved}\meta{csname}). The saved value is restored to +% \meta{\\csname} by \cs\RestoreCS\marg{\\csname}. +% +% \DescribeMacro\SaveName +% \DescribeMacro\RestoreName +% \cs\SaveName and \cname{RestoreName} are the same but take an argument +% \meta{csname} without a backslash. +% +% \DescribeMacro\requirecommand +% \DescribeMacro{\requirecommand*} +% \cs\requirecommand takes arguments like \cs\newcommand and behaves like +% \cs\providecommand (defined in the kernel) with the following difference: +% if the control sequence is already defined, \cs\requirecommand calls +% \cs\CheckCommand to make sure that the new and existing definitions are +% identical, whereas \cs\providecommand assumes that if the control sequence +% is already defined, the existing definition is appropriate. +% \cs\requirecommand, like \cs\defcommand, \emph{guarantees} that a control +% sequence will have the given definition, but \cs\requirecommand also warns +% you if there was a previous and different existing definition. +% +% \DescribeMacro\newtokens +% \DescribeMacro\newlet +% \DescribeMacro\newboolean +% \cs\newtokens\marg{\\csname}, \cs\newlet\marg{\\csname}\marg{\\csname}, +% and \cs\newboolean\marg{csname} give an error if their control sequence +% argument is already defined. \cs\newtokens creates a token variable. +% \cs\newlet does a \cs\let assignment. \cs\newboolean\marg{csname} creates +% three new control sequences: two switches, |\csnametrue| and +% |\csnamefalse|, and a test, |\ifcsname|. \cs\newtokens is \emph{not} +% |outer|. Is there any reason this really matters? +% +% \begin{warning} +% Limitation: You can't use \cs\newlet to \cs\let a command sequence +% to a character with a catcode not equal to 10 (space), 11 (letter), 12 +% (other), or 13 (active). For example, you can't say |\newlet\foo#|. +% Also, you cannot use |=| with \cs\newlet like you can with \cs\let. +% \end{warning} +% +% \DescribeMacro\providetokens +% \DescribeMacro\provideboolean +% \DescribeMacro\providesavebox +% \DescribeMacro\providecounter +% \DescribeMacro\providelength +% Like the kernel's \cs\providecommand, the commands +% \cs\providetokens\marg{\\csname}, \cs\provideboolean\marg{csname}, +% \cs\providesavebox\marg{\\csname}, \cs\providecounter\marg{csname}, and +% \cs\providelength\marg{\\csname} will create a new object (or objects) +% based on the name \meta{\\csname} or \meta{csname} only if they are not +% already defined. See the corresponding commands that begin with |\new| +% instead of |\provide| for a description of what kind of object is created. +% In contrast with \cs\providecommand, however, these commands will write a +% record to the log file if their argument was already defined +% (\cs\providecommand does nothing at all in this case). +% +% \DescribeMacro\UndefineCS +% \DescribeMacro\UndefineName +% \cs\UndefineCS\marg{\\csname} causes \meta{\\csname} to be undefined. +% \cs\UndefineName does the same for a \meta{csname}. Use with caution. +% \cs\global works before them. +% +% \DescribeMacro\defcommand +% \DescribeMacro{\defcommand*} +% \cs\defcommand\marg{\\csname}\oarg{\# of args}\oarg{default for an optarg} +% defines \meta{\\csname} in the same manner as \cs\newcommand except no +% warning or error is issued if \meta{\\csname} is already defined. +% +% \cs\defcommand is very similar to the primitive \cs\def, so why would you +% want to use it? For one thing, the syntax is the same as all the other +% \LaTeX{} defining commands, so it is easier to read, and easier to change +% the word \code{defcommand} to one of the other defining commands. Second, +% \cs\defcommand{}s that take arguments have simpler syntax when defining +% commands are nested. You still have to double the |#| characters in the +% definition body, but the argument specification (e.g., |[n]|) is the same +% as if not nested. +% +% There is a performance-syntax tradeoff; I choose to use \cs\defcommand +% whenever the command to be defined is taking an argument. When it does not +% take an argument, there is no difference between \cs\def and \cs\defcommand +% except that \cs\def is faster. +% +% I see very little reason to ever use \cs\renewcommand. It causes an error +% when the control sequence is \emph{not} already defined. Conceivably this +% is useful during development to catch programming mistakes, but much more +% often I find that I don't care whether the control sequence was defined or +% not, and therefore the error \cs\renewcommand might raise is inappropriate +% and a problem. +% +% \DescribeMacro\NewName +% \DescribeMacro{\NewName*} +% \cs\NewName\marg{csname}\marg{template}\marg{body} defines \meta{csname} to +% expand to \meta{body} using a \TeX-style argument \meta{template}, +% e.g. |#1#2\@nil| or simply |#1#2|. +% If \meta{csname} is already defined, an error will be signalled. +% +% \DescribeMacro\DefName +% \DescribeMacro{\DefName*} +% \cs\DefName is like \cs\NewName but no error is signalled if \meta{csname} +% is already defined. +% +% \DescribeMacro\Global +% If the command \cs\Global immediately precedes \cs\NewName, \cs\DefName, or +% \cs\ToggleBoolean, then the definition will be global. +% +% \todo{Get something like \cs\Global going for all the new commands, not +% just \cs\DefName and \cs\NewName.} +% +% \DescribeMacro\CheckName +% \DescribeMacro{\CheckName*} +% \cs\CheckName is like \cs\NewName but instead of defining the control +% sequence, it checks whether the control sequence has the given definition. +% If so, no action is taken; if not, a warning is given. +% +% \DescribeMacro\RequireName +% \DescribeMacro{\RequireName*} +% \cs\RequireName is to \cs\requirecommand as \cs\NewName is to +% \cs\newcommand. The syntax is +% \cs\RequireName\marg{csname}\marg{template}\marg{body}. +% +% \DescribeMacro\NewTextFontCommand +% \DescribeMacro\NewRobustCommand +% \cs\NewTextFontCommand and \cs\NewRobustCommand are just like the kernel's +% \cs\DeclareTextFontCommand and \cs\DeclareRobustCommand, but they signal an +% error instead of just a warning if their first argument is already defined. +% +% \DescribeMacro\Elet +% \DescribeMacro\EElet +% \cs\Elet expands the second token after it once and then \cs\let{}s the +% first token to the second token. \cs\global works before it. \cs\EElet +% expands the two tokens that come after it once each, and then \cs\let{}s +% the first to the second. \cs\global works before it. +% +% \DescribeMacro\NewUserInfo +% \DescribeMacro{\NewUserInfo*} +% \cs\NewUserInfo\oarg{user-cmd}\marg{variable}, where \meta{variable} has +% some capital letters, will define the lowercase version of \meta{variable} +% to be a user command that redefines \meta{variable} to its argument. The +% argument \meta{user-cmd}, if supplied, is used for the user command, +% overriding the default of the lowercased \meta{variable}. +% +% For example, |\NewUserInfo*\Subtitle| defines a user command +% |\subtitle|\marg{text} which does the equivalent of +% |\defcommand\Subtitle{|\meta{text}|}|. +% +% \cs\NewUserInfo uses \cs\ReserveCS to initialize \meta{variable}; +% \cs\NewUserInfo** uses \cs\ReserveCS*. +% +% These have |@| in their names because they are modelled after kernel +% commands. \todo{Sort out naming comventions and write them down.} +% +% \DescribeMacro{\addto@macro} +% \DescribeMacro{\lg@addto@macro} +% \cname{addto@macro}\marg{\\csname}\marg{tokens} adds \meta{tokens} to the +% end of \marg{\\csname}. The redefinition of \marg{\\csname} is local. The +% kernel provides the global equivalent, \cname{g@addto@macro}. +% \cname{lg@addto@macro} is both |long| and global. +% \caveat{These commands won't work with a \meta{\\csname} that takes +% arguments.} +% \begin{todo} +% Probably it would not be too hard to handle that case. Here is how you would +% do it by hand for one example: +% \begin{codeexample} +% % something like: \def\@chapter[#1]#2{...} +% +% \typeout{\meaning\@chapter} +% +% \renewcommand\addto@macro [2] {% +% \sc@toks@a=\expandafter{#1[##1]{##2}#2}% +% \edef#1[##1]##2{% +% \the\sc@toks@a +% }% +% } +% +% \def\doodie#1{bobo \textsc{#1}} +% \tracingonline1 +% +% \Debug2 +% \addto@macro\@chapter {\doodie blorful} +% \Debug0 +% +% \typeout{\meaning\@chapter} +% \end{codeexample} +% \end{todo} +% +% \DescribeMacro{\prependto@macro} +% \DescribeMacro{\g@prependto@macro} +% \DescribeMacro{\lg@prependto@macro} +% \cname{prependto@macro}\marg{\\csname}\marg{tokens} adds \meta{tokens} to +% the beginning of \marg{\\csname}. The redefinition of \marg{\\csname} is +% local. The global equivalent is \cname{g@prependto@macro}. +% \cname{lg@prependto@macro} is both |long| and global. +% +% \section{Controlling expansion} +% +% \DescribeMacro{\EExpand...\string\In} +% \DescribeMacro{\EExpand*...\string\In} +% \DescribeMacro{\eExpand...\string\In} +% \DescribeMacro{\eExpand*...\string\In} +% \DescribeMacro\eExecute +% \DescribeMacro{\eExecute*} +% A common construction is to \cs\edef a scratch variable to something and +% then execute the scratch variable. The \cs\eExecute macro takes a single +% argument, expands it fully, then executes it. +% +% \cs\eExpand\marg{first tokens}\cs\In\marg{second tokens} expands the +% \meta{first tokens} inside \meta{second tokens} wherever |#1| occurs. +% \cs\EExpand expands the first token of \meta{first tokens} only once. +% These commands can nest. +% +% For example, +% \begin{bothexample} +% \def\a {\b} +% \def\b {Hello } +% \def\x {d} +% \eExpand\a worl\x\In {% +% \def\c {This is a good way to avoid lots of noexpands and +% expandafters. #1. And I continue.}% +% \def\x {boogaloo}% \x is already expanded in the def of \c +% \c +% } +% +% \EExpand\a BLOOB\x\In {% +% \def\x{avoid } +% \edef#1{\b world}% BLOOB\x is syntactic sugar +% This is a good way to \x lots of noexpands and +% expandafters. \a BLOOB\x. And I continue.% +% } +% \end{bothexample} +% The two commands expand to the same three sentences. Here is one more +% example, showing (again) how \cs\EExpand expands only the first token of its +% argument only once:: +% \begin{bothexample} +% \def\x{XXX} +% \def\a{AAA\x} +% \def\b{BBB} +% \EExpand\a\b\In{% +% \def\x{xxx} +% \def\a{aaa} +% \def\b{YYY} +% #1 +% } +% \end{bothexample} +% +% \begingroup +% \catcode`\ =11\relax +% \DescribeMacro{\E@car...\string\@nil } +% \DescribeMacro{\E@cdr...\string\@nil } +% \endgroup +% Let $T$ be the sequence of tokens between \cname{E@car} and \cname{@nil}. +% The first token of $T$ is expanded once, and \cs{\E@car...\@nil} +% expands to the first token of the result. +% +% \cname{E@cdr...\@nil} is similar, but expands to the entire result +% \emph{except} its first token. +% +% For example, after +% \begin{codeexample} +% \def\a {Hello} +% \def\b { world} +% \end{codeexample} +% |\E@car \a there\b.\@nil| would expand first of all to +% |H|\@. And |\E@cdr \a there\b.\@nil| would expand first of all to +% |ellothere\b.|, and then eventually expand fully to |ellothere world.|. +% +% The example is more complicated than you would normally use. Usually you +% want to |car| and |cdr| a sequence of tokens contained in macro |\foo|, and +% this is easy enough with |\E@car\foo\@nil|. To chop off the first token of +% |\foo|, |\edef\foo {\E@cdr\foo\@nil}|. (If you're wondering, the space +% after |\foo| is irrelevant.) +% +% \section{Gobbling} +% +% \DescribeMacro{\Gobble} +% \DescribeMacro{\GobbleM} +% \DescribeMacro{\GobbleO} +% \DescribeMacro{\GobbleMM} +% \DescribeMacro{\GobbleMO} +% \DescribeMacro{\GobbleOM} +% It occurs fairly often that you want to gobble things while \cs\makeatother +% is in effect, so these command names have no |@|'s. The |M| stands for a +% mandatory argument, and the |O| stands for an optional argument. For +% example, suppose there is a command |\foo|\oarg{optarg}\marg{marg}. If you +% |\let\foo\GobbleOM|, then the arguments to |\foo| will be gobbled +% appropriately. +% +% \cs\Gobble is the same as \cs\GobbleM, in imitation of the internal +% \cname{@gobble}. +% +% \section{Option declaration} +% +% The follwing two commands may be used in packages before the +% \cs\ProcessOptions command is issued. +% +% \DescribeMacro\DeclareBooleanOptions +% \cs\DeclareBooleanOptions\marg{on}\marg{off} declares a new boolean +% variable |@|\meta{on}|@| and makes it |true| if the option +% \option{\meta{on}} is given to the package, and |false| if the option +% \option{\meta{off}} is given, or if neither is given. I think it is good +% programming style not to rely on the default, always declaring either +% \meta{on} or \meta{off} with an \cs\ExecuteOptions statement. +% +% \DescribeMacro\DeclareBooleanUserOptions +% \cs\DeclareBooleanUserOptions\marg{on}\marg{off} is like +% \cs\DeclareBooleanOptions, but additionally declares two user commands +% \meta{\\on} and \meta{\\off} which are \cs\let to |\@|\meta{on}|@true| and +% |\@|\meta{off}|@false|, respectively. Use this command when it is sensible +% to change the status of the option after the package has been loaded. +% +% \section{Toggle a boolean} +% +% \DescribeMacro\ToggleBoolean +% \cs\ToggleBoolean\marg{boolean} changes the state of \meta{boolean} from +% |false| to |true| or vice versa. The argument \meta{boolean} should not +% include an initial |if| or final |true| or |false|. The redefinition is +% local unless \cs\Global precedes \cs\ToggleBoolean. +% +% \section{Debugging} +% +% \DescribeMacro\VerboseErrors +% \LaTeX{} by default gives very little context for errors. +% \cs\VerboseErrors\oarg{number} causes \LaTeX{} to give \meta{number} lines +% of context, or the maximum by default. +% +% \DescribeMacro\GVerboseErrors +% Like \cs\VerboseErrors but effective globally. +% +% \DescribeMacro\Debug +% \cs\Debug\marg{number} sets a debugging parameter to \meta{number}. I have +% plans to turn this into a bitwise parameter like many C programs, but right +% now the behavior is to issue a message with \cs\typeout, call +% \cs\VerboseErrors, and use the parameter to assign values to +% \cs\tracingoutput, \cs\tracingpages, \cs\tracingmacros, and +% \cs\tracingcommands. +% +% \DescribeMacro\GDebug +% \cs\GDebug\marg{number} is as \cs\Debug but its assignments are +% \cs\global. +% +% \DescribeMacro\DTypeout +% \DescribeMacro\DDTypeout +% \DescribeMacro\DDDTypeout +% \cs\DTypeout expands to \cs\typeout when \cs\Debug is 1 or greater, and +% \cs\GobbleM otherwise. \cs\DDTypeout is \cs\GobbleM unless \cs\Debug is 2 +% or greater; \cs\DDDTypeout is \cs\GobbleM unless \cs\Debug is 3 or greater. +% +% \DescribeMacro\DGobbleM +% Like \cs\GobbleM but when \cs\Debug is 1 or greater, tells you what it's +% gobbling with a \cs\typeout. +% +% \DescribeMacro\FrankenError +% \DescribeMacro\FrankenWarning +% \DescribeMacro\FrankenInfo +% The commands \cs\FrankenError, \cs\FrankenWarning, and \cs\FrankenInfo are +% defined here for use by other \Frankenstein packages and classes. They are +% simply wrappers for the obvious kernel commands (i.e., substitute +% ``Generic'' for ``Franken''). +% +% \StopEventually{} +% +% \part{Implementation} +% +% \section{Version control} +% +% \begin{macro}{\fileinfo} +% \begin{macro}{\DoXUsepackagE} +% \begin{macro}{\HaveECitationS} +% \begin{macro}{\fileversion} +% \begin{macro}{\filedate} +% \begin{macro}{\docdate} +% \begin{macro}{\PPOptArg} +% These definitions must be the first ones in the file. +% \begin{macrocode} +\def\fileinfo{more defining commands (Frankenstein's brain)} +\def\DoXPackageS {} +\def\fileversion{v1.8} +\def\filedate{2001/08/31} +\def\docdate{2001/08/31} +\edef\PPOptArg {% + \filedate\space \fileversion\space \fileinfo +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% If we're loading this file from a \cs\ProcessDTXFile command (see the +% \package{compsci} package), then \cs\JusTLoaDInformatioN will be defined; +% othewise we assume it is not (that's why the FunkY NamE). +% +% If we're loading from \cs\ProcessDTXFile, we want to load the packages listed +% in \cs\DoXPackageS (needed to typeset the documentation for this file) and +% then bail out. Otherwise, we're using this file in a normal way as a +% package, so do nothing. \cs\DoXPackageS, if there are any, are declared in +% the \ext{dtx} file, and, if you're reading the typeset documentation of this +% package, would appear just above. (It's OK to call \cs\usepackage with an +% empty argument or \cs\relax, by the way.) +% \begin{macrocode} +\makeatletter% A special comment to help create bst files. Don't change! +\@ifundefined{JusTLoaDInformatioN} {% + }{% ELSE (we know the compsci package is already loaded, too) + \UndefineCS\JusTLoaDInformatioN + \SaveDoXVarS + \eExpand\csname DoXPackageS\endcsname\In {%use \csname in case it's undefined + \usepackage{#1}% + }% + \RestoreDoXVarS + \makeatother + \endinput +}% A special comment to help create bst files. Don't change! +% \end{macrocode} +% +% Now we check for \LaTeX2e and declare the LaTeX package. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{moredefs}[\PPOptArg] +% \end{macrocode}^^A special comment to help create bst files. Don't change! +% +% ^^A NOTE: We have to compensate for the above backslashes, which are not +% ^^A actually in the .dtx file the author works on, by adding to the +% ^^A CheckSum. +%% +% \AddToCheckSum{17}^^A `dtx-update-checksum' automatically handles this. +% \AddToCheckSum{7}^^A The half a macrocode env. at the top is missed, however... +% \AddToCheckSum{10}^^A ... and so are the 5 \defs from the .dtx file +% ^^A that precede it. +% \IfCitations {% +% \AddToCheckSum{2}^^A When \initelyHavECitationS is defined in +% } ^^A the .dtx file, we need 2 more in the CheckSum. +% +% +% \section{Conditionals} +% We start with the conditionals section because we want to use +% \cname{@ifundefined@cs} in this package to make some of the subsequent +% definitions easier to read. +% +% \begin{macro}{\@ifundefined@cs} +% \mbox{} +% \begin{macrocode} +\newcommand*\@ifundefined@cs [1] {% + \edef\reserved@a{% + \expandafter\@gobble\string #1% + }% + \@ifundefined\reserved@a + \@firstoftwo + \@secondoftwo +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IfElement...\In} +% \mbox{} +% \begin{macrocode} +\newcommand\IfElement{} +\def\IfElement #1\In#2{% + \@tempswafalse + \expandafter \@tfor + \expandafter \sc@t@a + \expandafter :% + \expandafter =#2\do {% + \ifx #1\sc@t@a +% \DTypeout{[\meaning #1] matches element [\meaning\sc@t@a] +% in [\string#2].}% + \@tempswatrue + \@break@tfor + \else +% \DTypeout{[\meaning #1] matches NO elements in [\string #2].}% + \fi + }% + \if@tempswa + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} +% \end{macrocode} +% \end{macro} +% +% \section{Defining commands} +% +% \begin{macro}{\sc@star@or@long} +% \begin{macro}{\sc@star@nothing} +% The macros \cname{sc@star@or@long} and \cname{sc@star@nothing} are parallel +% to the kernel's \cname{@star@or@long} and \cname{l@ngrel@x}, which control +% whether definitions are |long| or not. \cname{sc@star@or@long} causes the +% value of \cname{sc@star@nothing} to be either |*| or empty, depending on +% whether it finds a |*| when it is called. It also sets the kernel's +% \cname{l@ngrel@x} to nothing or \cs\long, respectively. (We need both +% flags at least once.) +% \begin{macrocode} +\newcommand*\sc@star@nothing{} +\newcommand*\sc@star@or@long [1] {% args: defining-command + \@ifstar {% + \let\l@ngrel@x\relax + \def\sc@star@nothing {*}% + #1% + }{% ELSE + \let\l@ngrel@x\long + \def\sc@star@nothing {}% + #1% + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\md@check@star} +% Looks for a star with \cname{@ifstar} and sets \cname{sc@star@nothing} to +% |*| if there is a star and \cs\ShortEmpty if not. +% \begin{macrocode} +\newcommand\md@check@star {% + \@ifstar {% + \def\sc@star@nothing {*}% + }{% ELSE + \let\sc@star@nothing \ShortEmpty + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\requirecommand} +% \begin{macro}{\requirecommand*} +% \begin{macro}{\require@command} +% A typical application of the star mechanisms is \cs\requirecommand. +% \begin{macrocode} +\newcommand\requirecommand {% + \sc@star@or@long\require@command +} +\newcommand\require@command [1] {% args: \csname + \@ifundefined@cs{#1} {% + \expandafter\newcommand\sc@star@nothing + }{% ELSE + \expandafter\CheckCommand\sc@star@nothing + }% + {#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\InitCS} +% \begin{macro}{\InitCS*} +% \begin{macro}{\InitName} +% \begin{macro}{\InitName*} +% \begin{macro}{\ReserveCS} +% \begin{macro}{\ReserveCS*} +% \begin{macro}{\ReserveName} +% \begin{macro}{\ReserveName*} +% \begin{macro}{\ShortEmpty} +% \begin{macro}{\LongEmpty} +% \mbox{} +% \begin{macrocode} +\newcommand\InitCS {% + \@star@or@long\Init@CS +} +\newcommand\Init@CS [1] {% args: \csname + \l@ngrel@x\def#1{}% +} +\newcommand\InitName {% + \sc@star@or@long\Init@Name +} +\newcommand\Init@Name [1] {% args: csname + \expandafter\DefName\sc@star@nothing{#1}{}{}% +} +\newcommand\ReserveCS {% + \sc@star@or@long\Reserve@CS +} +\newcommand\Reserve@CS [1] {% args: \csname + \expandafter\newcommand\sc@star@nothing{#1} {}% +} +\newcommand\ReserveName {% + \sc@star@or@long\Reserve@Name +} +\newcommand\Reserve@Name [1] {% args: csname + \expandafter\NewName\sc@star@nothing{#1}{} {}% +} +\InitCS*\ShortEmpty +\InitCS\LongEmpty +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\sc@t@a} +% \begin{macro}{\sc@t@b} +% \begin{macro}{\sc@t@c} +% \begin{macro}{\sc@t@d} +% \begin{macro}{\sc@t@e} +% \begin{macro}{\sc@t@f} +% \begin{macro}{\sc@t@g} +% Scratch variables. ^^A FIX +% \begin{macrocode} +\ReserveCS\sc@t@a +\ReserveCS\sc@t@b +\ReserveCS\sc@t@c +\ReserveCS\sc@t@d +\ReserveCS\sc@t@e +\ReserveCS\sc@t@f +\ReserveCS\sc@t@g +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\newtokens} +% \begin{macro}{\newlet} +% Because \cs\newtoks is \cs\outer, we have to fool \cs\def into allowing it +% to be in its argument by using \cname{@nameuse}. +% \begin{macrocode} +\newcommand\newtokens [1] {% args: \csname + \@ifdefinable #1 {% + \@nameuse{newtoks}#1% + }% +} +\newcommand*\newlet [2] {% args: \csname-a \csname-b + \@ifdefinable #1 {% + \let #1#2% + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\providetokens} +% \begin{macro}{\providelength} +% \begin{macro}{\providesavebox} +% \begin{macro}{\providecounter} +% \begin{macro}{\newboolean} +% \begin{macro}{\provideboolean} +% The \cs\newboolean command is the same as the one in the \package{ifthen} +% package; so that package won't clash with this one. Isn't +% \cs\requirecommand nice? +% \begin{macrocode} +\newcommand*\providetokens [1] {% args: \csname + \@ifundefined@cs{#1} {% + \@nameuse{newtokens}#1% + }{% ELSE + \FrankenInfo{moredefs}{\protect\providetokens\space is not reallocating + token variable \protect#1.\MessageBreak + The existing contents are [\the#1]}% + }% +} +\newcommand*\providelength [1] {% args: \csname + \@ifundefined@cs{#1} {% + \newlength{#1}% + }{% ELSE + \FrankenInfo{moredefs}{\protect\providelength\space is not reallocating + \protect#1.\MessageBreak + The existing value is [\the#1]}% + }% +} +\newcommand*\providesavebox [1] {% args: \csname + \@ifundefined@cs{#1} {% + \newsavebox{#1}% + }{% ELSE + \FrankenInfo{moredefs}{\protect\providesavebox\space is not reallocating + box \protect#1.}% + }% +} +\newcommand*\providecounter [1] {% args: string + \@ifundefined{c@#1} {% + \newcounter{#1}% + }{% ELSE + \FrankenInfo{moredefs}{\protect\providecounter\space is not reallocating + counter #1.\MessageBreak + The existing value is [\expandafter\number\csname c@#1\endcsname]}% + }% +} +% \end{macrocode} +% The following definition follows the one in the \package{ifthen} package: +% \begin{macrocode} + +% \ProvidesPackage{ifthen} +% [1999/01/07 v1.1a Standard LaTeX ifthen package (DPC)] + +\requirecommand*\newboolean [1] {% args: string + \expandafter + \@ifdefinable\csname if#1\endcsname {% + \expandafter\newif\csname if#1\endcsname + }% +} + +% old def of \cs\newboolean I had before 15 Feb 00: +% \csname newif\expandafter\endcsname\csname if#1\endcsname +% \end{macrocode} +% Notice that \cs\defcommand is not defined yet. +% +% If the \package{ifthen} package is loaded \emph{either} before or +% after this package, the \cs\provideboolean command will be the one defined in +% \package{ifthen}. Otherwise, it will be the one defined here. +% +% There are two minor differences between this definition and the one in the +% \package{ifthen} package: (1) my command will barf on undefined but +% ``undefinable'' commands, e.g., ones that begin with \cs\end, which \LaTeX{} +% reserves; (2) my command writes an informational message to the log file when +% the boolean variable is already defined. I'm not sure how useful the +% informational message is, but the first difference should I think also be in +% the \package{ifthen} package, so \todo{I'm putting it on my list to write the +% \LaTeX{} team requesting this change.} +% \begin{macrocode} +\@ifpackageloaded{ifthen} {% + }{% ELSE + \requirecommand*\provideboolean [1] {% args: string + \@ifundefined {if#1} {% + \newboolean{#1}% + }{% ELSE + \FrankenInfo{moredefs}{\protect\provideboolean\space is not reallocating + \protect#1.\MessageBreak + The value is [\@nameuse{if#1}TRUE\else FALSE\fi]}% + }% + }% +} +% \end{macrocode} +% The following definition is what's in the \package{ifthen} package, for +% reference. +% \begin{macrocode} +% \requirecommand*\provideboolean [1] {% args: string +% \@ifundefined{if#1}{% +% \expandafter +% \newif\csname if#1\endcsname}\relax +% } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\sc@toks@a} +% \begin{macro}{\sc@toks@b} +% \begin{macro}{\addto@macro} +% \begin{macro}{\lg@addto@macro} +% \begin{macro}{\prependto@macro} +% \begin{macro}{\g@prependto@macro} +% \begin{macro}{\lg@prependto@macro} +% There are still missing a couple of the permutations, but I won't add them +% until I need them. You can add them yourself in the configuration file +% \file{moredefs.cfg}. +% \begin{macrocode} +\newtokens\sc@toks@a +\newtokens\sc@toks@b + +\newcommand\addto@macro [2] {% + \sc@toks@a=\expandafter{#1#2}% + \edef#1{% + \the\sc@toks@a + }% +} +\newcommand\lg@addto@macro [2] {% + \sc@toks@a=\expandafter{#1#2}% + \long\xdef#1{% + \the\sc@toks@a + }% +} +\newcommand\prependto@macro [2] {% + \sc@toks@a={#2}% + \sc@toks@b=\expandafter{#1}% + \edef#1{% + \the\sc@toks@a\the\sc@toks@b + }% +} +\newcommand\g@prependto@macro [2] {% + \sc@toks@a={#2}% + \sc@toks@b=\expandafter{#1}% + \xdef#1{% + \the\sc@toks@a\the\sc@toks@b + }% +} +\newcommand\lg@prependto@macro [2] {% + \sc@toks@a={#2}% + \sc@toks@b=\expandafter{#1}% + \long\xdef#1{% + \the\sc@toks@a\the\sc@toks@b + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\UndefineCS} +% \begin{macro}{\UndefineName} +% \cs\global works before them. +% \begin{macrocode} +\newcommand\UndefineCS [1] {% args: \csname + \let#1\@undefined +} +\newcommand\UndefineName [1] {% args: csname + \expandafter\let\csname#1\endcsname\@undefined +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\defcommand} +% \begin{macro}{\defcommand*} +% \begin{macro}{\def@command} +% See the user documentation for a discussion of when to use this insteae of \cs\def. +% \begin{macrocode} +\newcommand\defcommand {% + \@star@or@long\def@command +} +\newcommand\def@command {% + \let\@ifdefinable\@rc@ifdefinable + \new@command +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\DefName} +% \begin{macro}{\DefName*} +% \begin{macro}{\def@name} +% \begin{macro}{\NewName} +% \begin{macro}{\NewName*} +% \begin{macro}{\new@name} +% \begin{macro}{\Global} +% \begin{macro}{\sc@global} +% \cs\Global works before \cs\DefName, \cs\NewName, and \cs\ToggleBoolean +% only! +% \begin{macrocode} +\newcommand\DefName {% + \@star@or@long\def@name +} +\newcommand\def@name [3] {% args: arglist csname body + \sc@global\l@ngrel@x\@namedef{#1}#2{#3}% +} +\newcommand\NewName {% + \@star@or@long\new@name +} +\newcommand\new@name [3] {% args: arglist csname body + \@ifundefined{#1} {% + \sc@global\l@ngrel@x\@namedef{#1}#2{#3}% + }{% ELSE + \defcommand\reserved@a {% + #1% + }% + \@notdefinable + }% +} +\newcommand\sc@global {% + \relax +} +\newcommand\Global {% + \def\sc@global {% + \global\let\sc@global\relax\global + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\CheckName} +% \begin{macro}{\CheckName*} +% \begin{macro}{\check@name} +% \begin{macro}{\RequireName} +% \begin{macro}{\RequireName*} +% \begin{macro}{\require@name} +% \mbox{} +% \begin{macrocode} +\newcommand\CheckName {% + \@star@or@long\check@name +} +\newcommand\check@name [3] {% args: arglist csname body + \expandafter\DefName\sc@star@nothing{reserved@a}{#2}{#3}% + \expandafter\@check@eq\csname #1\endcsname\reserved@a +} +\newcommand\RequireName {% + \sc@star@or@long\require@name +} +\newcommand\require@name [3] {% args: arglist csname body + \@ifundefined{#1} {% + \expandafter\DefName\sc@star@nothing{#1}{#2}{#3}% + }{% ELSE + \expandafter \expandafter + \expandafter \CheckName + \expandafter \sc@star@nothing + \csname #1\endcsname + {#2}{#3}% + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\NewTextFontCommand} +% \begin{macro}{\NewRobustCommand} +% \begin{macro}{\new@robustcommand} +% \begin{macro}{\new@@robustcommand} +% \mbox{} +% \begin{macrocode} +\newcommand\NewTextFontCommand [2] {% args: \csname font-command + \NewRobustCommand#1[1]{% + \ifmmode + \nfss@text{#2##1}% + \else + \leavevmode + {\text@command{##1}% + #2\check@icl ##1\check@icr + \expandafter}% + \fi + }% +} +\newcommand\NewRobustCommand {% + \@star@or@long\new@robustcommand +} +% \end{macrocode} +% We need a second level here because otherwise the \cs\fi that closes +% \cname{@ifdefinable} will become the definition of the closing +% \cname{new@command}. We could use a chain of \cs\expandafter{}s but that +% would be confusing. +% \begin{macrocode} +\newcommand\new@robustcommand [1] {% + \let\sc@t@a\relax + \@ifdefinable #1 {% + \def\sc@t@a {% + \new@@robustcommand #1% + }% + }% + \sc@t@a +} +\newcommand\new@@robustcommand [1] {% + \edef\reserved@a {\string#1}% + \def\reserved@b {#1}% + \edef\reserved@b {% + \expandafter\strip@prefix\meaning\reserved@b + }% + \edef#1{% + \ifx\reserved@a\reserved@b + \noexpand\x@protect + \noexpand#1% + \fi + \noexpand\protect + \expandafter\noexpand\csname + \expandafter\@gobble\string#1 \endcsname + }% + \let\@ifdefinable\@rc@ifdefinable + \expandafter\new@command\csname + \expandafter\@gobble\string#1 \endcsname +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\Elet} +% \mbox{} +% \begin{macrocode} +\newcommand\Elet {% + \expandafter\let\expandafter +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\EElet} +% \mbox{} +% \begin{macrocode} +\newcommand*\EElet {% + \expandafter\expandafter\expandafter\let\expandafter\expandafter +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\NewUserInfo} +% \begin{macro}{\NewUserInfo*} +% \begin{macro}{\new@userinfo} +% Using \cs\lowercase in this macro is tricky, since it gets expanded only in +% \TeX's stomach. +% \begin{macrocode} +\newcommand\NewUserInfo {% + \sc@star@or@long\new@userinfo +} +\newcommand*\new@userinfo [2][] {% args: [\csname] \csname + \expandafter\ReserveCS\sc@star@nothing{#2}% + \def\sc@t@b {#1}% +% \end{macrocode} +% If we were not given the optional user-cmd, define scratch |b| to be a +% lowercase version of the variable, without the backslash. Otherwise use the +% user-cmd given, without the backslash. +% \begin{macrocode} + \ifx\sc@t@b\ShortEmpty + \edef\sc@t@a {% + \edef\noexpand\sc@t@b{% + \E@cdr\string#2\@nil + }% + }% + \lowercase\expandafter{\sc@t@a}% + \else + \edef\sc@t@b {\E@cdr\string#1\@nil}% + \fi +% \end{macrocode} +% Now define the user-cmd to be a redefinition of the variable. +% \begin{macrocode} + \edef\sc@t@a {% + \noexpand\NewName\sc@star@nothing{\sc@t@b}{####1} + {\noexpand\renewcommand\sc@star@nothing\noexpand#2{####1}} + }% + \sc@t@a +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\SaveCS} +% \begin{macro}{\RestoreCS} +% \begin{macro}{\SaveName} +% \begin{macro}{\RestoreName} +% \mbox{} +% \begin{macrocode} +\newcommand\SaveCS [1] {% args: \csname + \expandafter\newlet\csname MDSaved\E@cdr\string#1\@nil\endcsname#1% +} +\newcommand\RestoreCS [1] {% args: \csname + \Elet#1\csname MDSaved\E@cdr\string#1\@nil\endcsname + \UndefineName{MDSaved\E@cdr\string#1\@nil}% +} +\newcommand\SaveName [1] {% args: csname + \ReserveName{MDSaved#1}% + \EElet\csname MDSaved#1\endcsname + \csname #1\endcsname +} +\newcommand\RestoreName [1] {% args: csname + \EElet\csname #1\endcsname + \csname MDSaved#1\endcsname + \UndefineName{MDSaved#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \section{Controlling expansion} +% +% \begin{macro}{\EExpand...\In} +% \begin{macro}{\EExpand*...\In} +% \begin{macro}{\sc@EExpand} +% \begin{macro}{\eExpand...\In} +% \begin{macro}{\eExpand*...\In} +% \begin{macro}{\sc@eExpand} +% \begin{macro}{\eExecute} +% \begin{macro}{\eExecute*} +% \begin{macro}{\sc@eExecute} +% Uses \cname{sc@t@a}, \cname{sc@t@b}, \cname{sc@t@c}. +% \begin{macrocode} +\newcommand\eExpand {% + \sc@star@or@long\sc@eExpand +} +\NewName{sc@eExpand} {#1\In#2} {% args: object body + \l@ngrel@x\edef\sc@t@a{#1}% + \expandafter\defcommand\sc@star@nothing\sc@t@b [1] {#2}% + \expandafter \sc@t@b + \expandafter {\sc@t@a}% +} +\newcommand\EExpand {% + \sc@star@or@long\sc@EExpand +} +% \end{macrocode} +% When this is |short|, both the two args are |short|. \cname{sc@star@nothing} +% gets reset by the first \cs\defcommand, so we save it in \cname{sc@t@c}. +% \begin{macrocode} +\NewName{sc@EExpand}{#1\In#2} {% args: object body + \let\sc@t@c\sc@star@nothing + \expandafter \expandafter + \expandafter \defcommand + \expandafter \sc@t@c + \expandafter \sc@t@a + \expandafter {#1}% + \expandafter\defcommand\sc@t@c\sc@t@b [1] {#2}% + \expandafter\sc@t@b + \expandafter{\sc@t@a}% +} +\newcommand\eExecute {% + \sc@star@or@long\sc@eExecute +} +\newcommand\sc@eExecute [1] {% args: body + \l@ngrel@x\edef\sc@t@a {#1}% + \sc@t@a +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\E@car} +% \begin{macro}{\E@cdr} +% \mbox{} +% \begin{macrocode} +\NewName{E@cdr} {#1\@nil} {% + \expandafter\@cdr #1\@nil +} +\NewName{E@car} {#1\@nil} {% + \expandafter\@car #1\@nil +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \section{Gobbling} +% +% \begin{macro}{\Gobble} +% \begin{macro}{\GobbleM} +% \begin{macro}{\GobbleO} +% \begin{macro}{\GobbleMM} +% \begin{macro}{\GobbleMO} +% \begin{macro}{\GobbleOM} +% \begin{macro}{\sc@gobbleO} +% \begin{macro}{\sc@gobbleOM} +% \textsf{M} for mandatory arg, i.e., one token. \textsf{O} for optional arg, +% i.e., a square-brace pair. +% \begin{macrocode} +\newlet\Gobble\@gobble +\newlet\GobbleM\@gobble +\newcommand\GobbleO {% + \@ifnextchar [ + \sc@gobbleO + \relax +} +\newlet\GobbleMM\@gobbletwo +\newcommand\GobbleOM {% + \@ifnextchar [ + \sc@gobbleOM + \Gobble +} +\newcommand\GobbleMO [1] {% + \@ifnextchar [ + \sc@gobbleO + \relax +} +\NewName{sc@gobbleOM} {[#1]#2} + {} +\NewName{sc@gobbleO} {[#1]} + {} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \section{Option declaration} +% +% \begin{macro}{\DeclareBooleanOptions} +% \begin{macro}{\DeclareBooleanUserOptions} +% \mbox{} +% \begin{macrocode} +\newcommand\DeclareBooleanOptions [2] {% args: on off + \newboolean{@#1@}% + \DeclareOption{#1} {% + \@nameuse{@#1@true} + }% + \DeclareOption{#2} {% + \@nameuse{@#1@false} + }% +} +\newcommand\DeclareBooleanUserOptions [2] {% args: on off + \DeclareBooleanOptions{#1}{#2}% + \ReserveName{#1}% + \ReserveName{#2}% + \EElet \csname#1\endcsname\csname @#1@true\endcsname + \EElet \csname#2\endcsname\csname @#1@false\endcsname +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \section{Toggle a boolean} +% +% \begin{macro}{\ToggleBoolean} +% \mbox{} +% \begin{macrocode} +\newcommand\ToggleBoolean [1] {% arg: boolean + \csname if#1\endcsname + \sc@global\csname #1false\endcsname + \else + \sc@global\csname #1true\endcsname + \fi +} +% \end{macrocode} +% \end{macro} +% +% \section{Debugging} +% +% \begin{macro}{\VerboseErrors} +% \begin{macro}{\GVerboseErrors} +% We do not use \cs\setcounter but rather set these counters locally. +% \begin{macrocode} +\newcommand*\VerboseErrors [1][\@M] {% args: [number] + \c@errorcontextlines #1% + \showboxbreadth #1% + \showboxdepth #1% +} +\newcommand*\GVerboseErrors [1][\@M] {% args: [number] + \global\c@errorcontextlines #1% + \global\showboxbreadth #1% + \global\showboxdepth #1% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\Debug} +% \begin{macro}{\GDebug} +% \begin{macro}{\md@maybe@global} +% Set \cs\debug to 0, 1, or~2. ^^A remember \cs\showlists +% \begin{macrocode} +\ReserveCS\md@maybe@global +\newcommand*\Debug {% + \let\md@maybe@global\relax + \md@debug +} +\newcommand*\GDebug {% + \let\md@maybe@global\global + \md@debug +} +\newcommand*\md@debug [1] {% args: debug-level + \ifnum #1 > 0% + \let\sc@t@a\@M + \md@maybe@global\def\DTypeout ##1{% + \typeout{##1}% + }% + \md@maybe@global\def\DGobbleM ##1{% + \typeout{DGobbleM: [##1]}% + }% + \ifnum #1 > 1% + \md@maybe@global\def\DDTypeout ##1{% + \typeout{##1}% + }% + \ifnum #1 > 2% + \md@maybe@global\def\DDDTypeout ##1{% + \typeout{##1}% + }% + \fi + \fi + \else + \let\sc@t@a\m@ne + \md@maybe@global\let\DTypeout\GobbleM + \md@maybe@global\let\DDTypeout\GobbleM + \md@maybe@global\let\DDDTypeout\GobbleM + \md@maybe@global\let\DGobbleM\GobbleM + \fi + \md@maybe@global\tracingoutput#1 % + \md@maybe@global\tracingpages#1 % + \md@maybe@global\tracingmacros#1 % + \md@maybe@global\tracingcommands#1 % + \ifx\md@maybe@global\relax + \VerboseErrors[\sc@t@a]% + \typeout{++++ Debugging [#1]\on@line}% + \else + \GVerboseErrors[\sc@t@a]% + \typeout{++++ Global debugging [#1]\on@line}% + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\DTypeout} +% \begin{macro}{\DTypeout} +% \begin{macro}{\DTypeout} +% \begin{macro}{\DGobbleM} +% When the debugging parameter is not set, these commands gobble their +% argument. \todo{Streamline dox about ``debugging parameter''; should be +% something checkable, no?} +% \begin{macrocode} +\newlet\DTypeout\GobbleM +\newlet\DDTypeout\GobbleM +\newlet\DDDTypeout\GobbleM +\newlet\DGobbleM\GobbleM +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\FrankenError} +% \begin{macro}{\FrankenWarning} +% \begin{macro}{\FrankenInfo} +% \mbox{} +% \begin{macrocode} +\newcommand\FrankenWarning [2] {% args: package warning + \GenericWarning % continuation message + {(#1)\@spaces\@spaces\@spaces\@spaces\@spaces} + {Frankenstein (#1) WARNING: #2}% +} +\newcommand\FrankenError [3] {% args: package error-message help-text + \GenericError % args: continuation message where-help what-help + {(#1)\@spaces\@spaces\@spaces\@spaces\@spaces} + {Frankenstein (#1) error: #2} + {See the documenation for the #1 package for more information.} + {#3}% +} +\newcommand\FrankenInfo [2] {% args: package info + \GenericInfo % continuation message + {(#1)\@spaces\@spaces\@spaces\@spaces\@spaces} + {Frankenstein (#1) says: #2}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \Finale |