The moredefs package

more defining commands (Frankenstein’s brain)

                 Matt Swift <swift@bu.edu>

Version: v1.01 Documentation revision: 1996/03/25

Abstract

A delightful collection of defining, expansion, and debugging commands that make elegant programming in L^{A}TEX fun and easy.

Part I

Discussion

These macros were written in response to practical programming needs. I wouldn’t write a package without them now.

1 Naming conventions

The convention is that a capital E means the macro expands something just once. A lowercase e, as in \edef, means the macro expands something all the way to unexpandable tokens.

The specification ⟨“csname⟩ means a control sequence with a preceding backslash; the specification ⟨csname⟩ means a control sequence without a preceding backslash. ⟨csname⟩ arguments are expanded. Commands which take ⟨csname⟩ arguments have Name in their names.

When I write package in this documentation, I mean L^{A}TEX package or class.

2 Defining commands

\InitCS \InitCS and \InitCS* take one argument, ⟨“csname⟩, and initialize it to {}. The \InitCS* non-*-form is long; the *-form is not. \InitName \InitName and \InitName* are the same but take an argument ⟨csname⟩ \InitName* without a backslash. \ShortEmpty To make it easier to avoid the problem of comparing long and non-long macros

\LongEmpty with \ifx, compare macros with \ShortEmpty and \LongEmpty.

\ReserveCS \ReserveCS {⟨“csname⟩} reserves ⟨“csname⟩ for the current package’s use. \ReserveName \ReserveName {⟨csname⟩} does the same for a ⟨csname⟩.

\requirecommand      \requirecommand is like \providecommand, but if the control sequence is

already defined, \CheckCommand is called to make sure it’s defined identically, whereas \providecommand assumes that if it’s already defined, the definition is appropriate. Using \requirecommand guarantees that a control sequence will have the given definition; or an error will occur.

\newtokens      \newtokens{⟨“csname⟩}, \newlet{⟨“csname⟩}{⟨“csname⟩}, and \newboolean
\newlet
\newboolean

{⟨csname⟩} give an error if their control sequence argument is already defined. \newtokens creates a token variable. \newlet does a \let assignment. \newboolean {⟨csname⟩} creates three new control sequences: two switches,

\csnametrue and \csnamefalse, and a test, \ifcsname. \newtokens is not

outer. Is there any reason this really matters?

\providetokens  Like the kernel’s \providecommand, the commands \providetokens{⟨“csname⟩},
\provideboolean
\providesavebox
\providecounter
\providelength

\provideboolean{⟨csname⟩}, \providesavebox{⟨“csname⟩}, \providecounter

{⟨csname⟩}, and \providelength {⟨“csname⟩} will create a new object (or objects) based on the name ⟨“csname⟩ or ⟨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 \providecommand, however, these commands will write a record to the log file if their argument was already defined (\providecommand does nothing at all in this case).

\Undefine \Undefine {⟨“csname⟩} causes ⟨“csname⟩ to be undefined. \UndefineName \UndefineName does the same for a ⟨csname⟩. Use with caution. \global works before it.

\defcommand \defcommand{⟨“csname⟩}[⟨# of args⟩][⟨default for an optarg⟩] defines ⟨“csname⟩ \defcommand* in the same manner as \newcommand except no warning or error is issued if

⟨“csname⟩ is already defined.

\defcommand is very similar to the primitive \def, so why would you want to use it? For one thing, the syntax is the same as all the other L^{A}TEX defining commands, so it is easier to read, and easier to change the word defcommand to one of the other defining commands. Second, \defcommands 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 \defcommand whenever the command to be defined is taking an argument. When it does not take an argument, there is no difference between \def and \defcommand except that \def is faster.

I see very little reason to every use \renewcommand. It causes an error when the control sequence is 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 \renewcommand might raise is inappropriate and a problem.

\NewName \NewName {⟨csname⟩}{⟨template⟩}{⟨body⟩} defines ⟨csname⟩ to expand to \NewName* ⟨body⟩ using a TEX-style argument ⟨template⟩, e.g. #1#2\@nil or simply #1#2.

The *-form is not long. If ⟨csname⟩ is already defined, an error will be signalled.

\DefName \DefName is like \NewName but no error is signalled if ⟨csname⟩ is already

\DefName* defined.

\Global If the command \Global immediately precedes \NewName or \DefName, then

the definition will be global.

To do: Get something like \Global going for all the new commands, not just

\DefName and \NewName.

\CheckName \CheckName is like \NewName but instead of defining the control sequence, it

\CheckName*

checks whether the control sequence has the given definition. If so, no action is taken; if not, a warning is given.

\RequireName      \RequireName is to \requirecommand as \NewName is to \newcommand. The

\RequireName* syntax is \RequireName {⟨csname⟩}{⟨template⟩}{⟨body⟩}.

\NewTextFontCommand      \NewTextFontCommand and \NewRobustCommand are just like the kernel’s
\NewRobustCommand  \DeclareTextFontCommand and \DeclareRobustCommand, but give an error in-

stead of just a warning if their first argument is already defined. \Elet \Elet expands the second token after it once and then \lets the first token to \EElet the second token. \global works before it. \EElet expands the two tokens that

come after it once each, and then \lets the first to the second. \global works before it.

\NewUserInfo \NewUserInfo {⟨variable⟩}[⟨user-cmd⟩], where ⟨variable⟩ has some capital \NewUserInfo* letters, will define the lowercase version of ⟨variable⟩ to be a user command that

redefines ⟨variable⟩ to its argument. An optional argument ⟨user-cmd⟩ is used for the user command if supplied, overriding the default of the a lowercased ⟨variable⟩.

   For example, \NewUserInfo*\Subtitle defines a user command \subtitle

{⟨text⟩} which does the equivalent of \defcommand\Subtitle{⟨text⟩}.

3 Controlling expansion

\EExpand...\In A common construction is to \edef a scratch variable to something and then

\EExpand*...\In
\eExpand...\In
\eExpand*...\In
\eExecute
\eExecute*

execute the scratch variable. The \eExecute macro takes a single argument, expands it fully, then executes it.

\eExpand {⟨first tokens⟩}\In {⟨second tokens⟩} expands the ⟨first tokens⟩ inside ⟨second tokens⟩ wherever #1 occurs. \EExpand expands the first token of ⟨first tokens⟩ only once. The *-versions make each argument short. These commands can nest.

For example,

%␣␣␣     \def\a {\b}
     \def\b {Hello }
     \eExpand\a world\In {
       \def\c {This is a good way to avoid lots of noexpands and
               expandafters.  #1.  And I continue.}
       \c
     }
     \EExpand\a BLOOB\In {
       \edef#1{\b world}
       This is a good way to avoid lots of noexpands and
       expandafters.  \a BLOOB.  And I continue.
     }

LOOKS LIKE:

This is a good way to avoid lots of noexpands and expandafters. Hello world. And I continue. This is a good way to avoid lots of noexpands and expandafters. Hello world. And I continue.

The two commands expand to the same three sentences.

4 Gobbling

\Gobble It occurs fairly often that you want to gobble things while \makeatother is in

\GobbleM
\GobbleO
\GobbleMM
\GobbleMO
\GobbleOM

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[⟨optarg⟩]{⟨marg⟩}. If you \let\foo\GobbleOM, then the arguments to \foo will be gobbled appropriately.

\Gobble is the same as \GobbleM, in imitation of the internal \@gobble.

5 Debugging

I have plans for expanding this section in the next release with some API commands for controlling the level of debugging output.

\VerboseErrors L^{A}TEX by default gives very little context for errors. \VerboseErrors [⟨number⟩] causes L^{A}TEX to give ⟨number⟩ lines of context, or the maximum by default.

\Debug \Debug {⟨number⟩} sets a debugging parameter to ⟨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 \typeout, call \VerboseErrors, and use the

parameter to assign values to \tracingoutput, \tracingpages, \tracingmacros,
and \tracingcommands.
\MonsterError  The commands \MonsterError, \MonsterWarning, and \MonsterInfo are de-
\MonsterWarning
\MonsterInfo
\MonsterDebug

fined here for use by other Frankenstein packages and classes. They are simply wrappers for the obvious kernel commands.

6 Miscellaneous internals

\@ifundefined@cs \@ifundefined@cs{⟨“csname⟩}{⟨true⟩}{⟨false⟩} executes the ⟨true⟩ clause if

⟨“csname⟩ is not defined, and the ⟨else⟩ clause otherwise.

\addto@macro \addto@macro{⟨“csname⟩}{⟨tokens⟩} adds ⟨tokens⟩ to the end of {⟨“csname⟩}. \lg@addto@macro The redefinition of {⟨“csname⟩} is local. The kernel provides the global equivalent,

\g@addto@macro. \lg@addto@macro is both long and global.

\prependto@macro \prependto@macro{⟨“csname⟩}{⟨tokens⟩} adds ⟨tokens⟩ to the beginning of

\g@prependto@macro
\lg@prependto@macro

{⟨“csname⟩}. The redefinition of {⟨“csname⟩} is local. The global equivalent is

\g@prependto@macro. \lg@prependto@macro is both long and global.

\E@car...\@nil Let T be the sequence of tokens between \E@car and \@nil. The first token of \E@cdr...\@nil T is expanded once, and \E@car...\@nil expands to the first token of the result.

\E@cdr...\@nil is similar, but expands to the entire result except its first token.

For example, after

     \def\a {Hello}
     \def\b { world}
   \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.)

Part II

Implementation

7 Version control

\fileinfo \fileversion \filedate \docdate \PPOptArg These definitions must be the first ones in the file.
 1 \def\fileinfo{more defining commands (Frankenstein's brain)}
 2 \def\fileversion{v1.01}
 3 \def\filedate{1996/03/25}
 4 \def\docdate{1996/03/25}
 5 \edef\PPOptArg {%
 6 \filedate\space \fileversion\space \fileinfo
 7 }

Stop right here if we’re just loading the file’s information, and don’t want to load this code for typesetting its documentation (only makes sense for certain packages). The JuStLaAdInFoRmAtIoN flag will be set by the documentation driver; the DoXNeeDME flag will be set in the dtx file, and will appear above if it’s set.

 8 \makeatletter
 9 \@ifundefined{JuStLoAdInFoRmAtIoN} {%
10 }{%
11 \@ifundefined{DoXNeeDME} {%
12  }{%
13  \usepackage{moredefs}%

14 }

15 \makeatother
16 \endinput

17 }

Now we check for L^{A}TEX2e and declare the package.

18 \NeedsTeXFormat{LaTeX2e}
19 \ProvidesPackage{moredefs}[\PPOptArg]

8 Getting started

We will begin to use commands as we define them.

\@ifundefined@cs We want this macro to make other macros easier to read.

20 \newcommand*\@ifundefined@cs [1] {%
21 \edef\reserved@a{%
22  \expandafter\@gobble\string #1%
23 }%
24 \@ifundefined\reserved@a
25  \@firstoftwo
26  \@secondoftwo

27 }

9 Defining commands

\sc@star@or@long \sc@star@nothing The macros \sc@star@or@long and \sc@star@nothing are parallel to the kernel’s

\@star@or@long and \l@ngrel@x, which control whether definitions are long or

not. \sc@star@or@long causes the value of \sc@star@nothing to be either * or

empty, depending on whether it finds a * when it is called. It also sets the kernel’s \l@ngrel@x to nothing or \long, respectively. (We need both flags at least once.)

28 \newcommand*\sc@star@nothing{}
29 \newcommand*\sc@star@or@long [1] {% args: defining-command
30 \@ifstar {%
31  \let\l@ngrel@x\relax
32  \def\sc@star@nothing {*}#1%
33  }{% ELSE
34  \let\l@ngrel@x\long
35  \def\sc@star@nothing {}%
36  #1%
37 }%

38 }

\requirecommand \requirecommand* \require@command A typical application of the star mechanisms is \requirecommand.
39 \newcommand\requirecommand {%
40 \sc@star@or@long\require@command

41 }

42 \newcommand\require@command [1] {% args: \csname
43 \@ifundefined@cs{#1} {%
44  \expandafter\newcommand\sc@star@nothing
45  }{% ELSE
46  \expandafter\CheckCommand\sc@star@nothing
47 }%
48 {#1}%

49 }

\InitCS
\InitCS*
\InitName
\InitName*
\ReserveCS
\ReserveName
\ShortEmpty
\LongEmpty

50 \newcommand\InitCS {%
51 \@star@or@long\Init@CS

52 }

53 \newcommand\Init@CS [1] {% args: \csname
54 \l@ngrel@x\def#1{}%

55 }

56 \newcommand\InitName {%
57 \sc@star@or@long\Init@Name

58 }

59 \newcommand\Init@Name [1] {% args: csname
60 \expandafter\DefName\sc@star@nothing{#1}{}{}%

61 }

62 \newcommand\ReserveCS [1] {% args: \csname
63 \newcommand{#1} {}%

64 }

65 \newcommand\ReserveName [1] {% args: csname
66 \NewName{#1}{} {}%

67 }

68 \InitCS*\ShortEmpty
69 \InitCS\LongEmpty

\sc@t@a \sc@t@b \sc@t@c \sc@t@d \sc@t@e \sc@t@f \sc@t@g Scratch variables.
70 \ReserveCS\sc@t@a
71 \ReserveCS\sc@t@b
72 \ReserveCS\sc@t@c
73 \ReserveCS\sc@t@d
74 \ReserveCS\sc@t@e
75 \ReserveCS\sc@t@f
76 \ReserveCS\sc@t@g

\newtokens \newlet Because \newtoks is \outer, we have to fool \def into allowing it to be in its argument by using \@nameuse.

77 \newcommand\newtokens [1] {% args: \csname
78 \@ifdefinable #1 {%
79  \@nameuse{newtoks}#1%
80 }%

81 }

82 \newcommand*\newlet [2] {% args: \csname-a \csname-b
83 \@ifdefinable #1 {%
84  \let#1#2%
85 }%

86 }

\providetokens \providelength \providesavebox \providecounter \newboolean \provideboolean The \newboolean command is the same as the one in the ifthen package; so that

packge won’t clash with this one. Isn’t \requirecommand nice?

87 \newcommand*\providetokens [1] {% args: \csname
88 \@ifundefined@cs{#1} {%
89  \@nameuse{newtokens}#1%
90  }{% ELSE
91  \MonsterInfo{moredefs}{\protect\providetokens\space is not reallocating
92  token variable \protect#1.\MessageBreak
93  The existing contents are [\the#1]}%
94 }%

95 }

96 \newcommand*\providelength [1] {% args: \csname
97 \@ifundefined@cs{#1} {%
98  \newlength{#1}%
99  }{% ELSE
100  \MonsterInfo{moredefs}{\protect\providelength\space is not reallocating
101  \protect#1.\MessageBreak
102  The existing value is [\the#1]}%

103 }% 104 }

105 \newcommand*\providesavebox [1] {% args: \csname
106 \@ifundefined@cs{#1} {%
107  \newsavebox{#1}%
108  }{% ELSE
109  \MonsterInfo{moredefs}{\protect\providesavebox\space is not reallocating
110  box \protect#1.}%

111 }% 112 }

113 \newcommand*\providecounter [1] {% args: string
114 \@ifundefined{c@#1} {%
115  \newcounter{#1}%
116  }{% ELSE

117  \MonsterInfo{moredefs}{\protect\providecounter\space is not reallocating
118  counter #1.\MessageBreak
119  The existing value is [\expandafter\number\csname c@#1\endcsname]}%

120 }% 121 }

122 \requirecommand*\newboolean [1] {% args: string
123 \csname newif\expandafter\endcsname\csname if#1\endcsname

124 }

125 \newcommand*\provideboolean [1] {% args: string
126 \@ifundefined {if#1} {%
127  \newboolean{#1}%
128  }{% ELSE
129  \MonsterInfo{moredefs}{\protect\provideboolean\space is not reallocating
130  \protect#1.\MessageBreak
131  The value is [\@nameuse{if#1}TRUE\else FALSE\fi]}%

132 }% 133 }

\sc@toks@a \addto@macro \lg@addto@macro \prependto@macro \g@prependto@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 moredefs.cfg.

134 \newtokens\sc@toks@a

135

136 \newcommand\addto@macro [2] {%
137 \sc@toks@a=\expandafter{#1#2}%
138 \edef#1{%
139  \the\sc@toks@a

140 }% 141 }

142 \newcommand\lg@addto@macro [2] {%
143 \sc@toks@a=\expandafter{#1#2}%
144 \long\xdef#1{%
145  \the\sc@toks@a

146 }% 147 }

148 \newcommand\prependto@macro [2] {%
149 \sc@toks@a=\expandafter{#1#2}%
150 \edef#1{%
151  \the\sc@toks@a

152 }% 153 }

154 \newcommand\g@prependto@macro [2] {%
155 \sc@toks@a=\expandafter{#1#2}%
156 \global\edef#1{%
157  \the\sc@toks@a

158 }% 159 }

160 \newcommand\lg@prependto@macro [2] {%
161 \sc@toks@a=\expandafter{#1#2}%
162 \long\xdef#1{%
163  \the\sc@toks@a

164 }% 165 }

\Undefine \UndefineName  \global works before it.

166 \newcommand\Undefine [1] {% args: \csname
167 \let#1\@undefined

168 }

169 \newcommand\UndefineName [1] {% args: csname
170 \expandafter\let\csname#1\endcsname\@undefined

171 }

\defcommand \defcommand* \def@command See the user documentation for a discussion of when to use this insteae of \def.

172 \newcommand\defcommand {%
173 \@star@or@long\def@command

174 }

175 \newcommand\def@command {%
176 \let\@ifdefinable\@rc@ifdefinable
177 \new@command

178 }

\DefName \DefName* \def@name \NewName \NewName* \new@name \Global \sc@global  \Global works before \DefName and \NewName only!
179 \newcommand\DefName {%
180 \@star@or@long\def@name

181 }

182 \newcommand\def@name [3] {% args: arglist csname body
183 \sc@global\l@ngrel@x\@namedef{#1}#2{#3}%

184 }

185 \newcommand\NewName {%
186 \@star@or@long\new@name

187 }

188 \newcommand\new@name [3] {% args: arglist csname body
189 \@ifundefined{#1} {%
190  \sc@global\l@ngrel@x\@namedef{#1}#2{#3}%
191  }{% ELSE
192  \defcommand\reserved@a {%
193  #1%

194 }%

195  \@notdefinable

196 }% 197 }

198 \newcommand\sc@global {%
199 \relax

200 }

201 \newcommand\Global {%
202 \def\sc@global {%
203  \global\let\sc@global\relax\global

204 }% 205 }

\CheckName
\CheckName*
\check@name
\RequireName
\RequireName*
\require@name

206 \newcommand\CheckName {%
207 \@star@or@long\check@name

208 }

209 \newcommand\check@name [3] {% args: arglist csname body
210 \expandafter\DefName\sc@star@nothing{reserved@a}{#2}{#3}%
211 \expandafter\@check@eq\csname #1\endcsname\reserved@a

212 }

213 \newcommand\RequireName {%

214 \sc@star@or@long\require@name

215 }

216 \newcommand\require@name [3] {% args: arglist csname body
217 \@ifundefined{#1} {%
218  \expandafter\DefName\sc@star@nothing{#1}{#2}{#3}%
219  }{% ELSE
220  \expandafter   \expandafter
221  \expandafter \CheckName
222  \expandafter \sc@star@nothing
223  \csname #1\endcsname
224  {#2}{#3}%

225 }% 226 }

\NewTextFontCommand
\NewRobustCommand
\new@robustcommand
\new@@robustcommand

227 \newcommand\NewTextFontCommand [2] {% args: \csname font-command
228 \ReserveCS{#1}%
229 \DeclareTextFontCommand{#1}{#2}%

230 }

231 \newcommand\NewRobustCommand {%
232 \@star@or@long\new@robustcommand

233 }

We need \new@@robustcommand to escape weird expansion troubles inside \@

 ifdefinable.
234 \newcommand\new@robustcommand [1] {%
235 \InitCS\sc@t@a
236 \@ifdefinable #1 {%
237  \def\sc@t@a {\new@@robustcommand#1}%

238 }%

239 \sc@t@a

240 }

241 \newcommand\new@@robustcommand [1] {%
242 \edef\reserved@a {\string#1}%
243 \def\reserved@b {#1}%
244 \edef\reserved@b {%
245  \expandafter\strip@prefix\meaning\reserved@b

246 }%

247 \edef#1{%
248  \ifx\reserved@a\reserved@b
249  \noexpand\x@protect
250  \noexpand#1%
251  \fi
252  \noexpand\protect
253  \expandafter\noexpand\csname
254  \expandafter\@gobble\string#1 \endcsname

255 }%

256 \let\@ifdefinable\@rc@ifdefinable
257 \expandafter\new@command\csname
258  \expandafter\@gobble\string#1 \endcsname

259 }

\Elet
260 \newcommand\Elet {%

261 \expandafter\let\expandafter

262 }

\EElet
263 \newcommand*\EElet {%
264 \expandafter\expandafter\expandafter\let\expandafter\expandafter

265 }

\NewUserInfo \NewUserInfo* \new@userinfo Using \lowercase in this macro is tricky, since it gets expanded only in TEX’s stomach.

266 \newcommand\NewUserInfo {%
267 \sc@star@or@long\new@userinfo

268 }

269 \newcommand*\new@userinfo [2][] {%
270 \expandafter\InitCS\sc@star@nothing{#2}%
271 \def\sc@t@b {#1}%
272 \ifx\sc@t@b\ShortEmpty
273  \edef\sc@t@a {%
274  \edef\noexpand\sc@t@b{%
275  \E@cdr\string#2\@nil

276 }% 277 }%

278  \lowercase\expandafter{\sc@t@a}%
279 \else
280  \edef\sc@t@b {\E@cdr\string#1\@nil}%
281 \fi
282 \edef\sc@t@a {%
283  \noexpand\NewName\sc@star@nothing{\sc@t@b}{####1}
284  {\noexpand\renewcommand\sc@star@nothing\noexpand#2{####1}}

285 }%

286 \sc@t@a

287 }

10 Controlling expansion

\EExpand...\In \EExpand*...\In \sc@EExpand \eExpand...\In \eExpand*...\In \sc@eExpand \eExecute \eExecute* Uses \sc@t@a, \sc@t@b, \sc@t@c.
288 \newcommand\eExpand {%
289 \sc@star@or@long\sc@eExpand

290 }

291 \NewName{sc@eExpand} {#1\In#2} {% args: object body
292 \l@ngrel@x\edef\sc@t@a{#1}%
293 \expandafter\defcommand\sc@star@nothing\sc@t@b [1] {#2}%
294 \expandafter   \sc@t@b
295  \expandafter {\sc@t@a}%

296 }

297 \newcommand\EExpand {%
298 \sc@star@or@long\sc@EExpand

299 }

When this is short, both the two args are short. \sc@star@nothing gets reset by the first \defcommand, so we save it in \sc@t@c.

300 \NewName{sc@EExpand}{#1\In#2} {% args: object body
301 \let\sc@t@c\sc@star@nothing

302 \expandafter   \expandafter
303  \expandafter \defcommand
304  \expandafter \sc@t@c
305  \expandafter \sc@t@a
306  \expandafter {#1}%
307 \expandafter\defcommand\sc@t@c\sc@t@b [1] {#2}%
308 \expandafter\sc@t@b
309  \expandafter{\sc@t@a}%

310 }

311 \newcommand\eExecute[1] {% args: body
312 \eExpand#1\In{##1}%

313 }

\E@car \E@cdr
314 \NewName{E@cdr} {#1\@nil} {%
315 \expandafter\@cdr #1\@nil

316 }

317 \NewName{E@car} {#1\@nil} {%
318 \expandafter\@car #1\@nil

319 }

11 Gobbling

\Gobble \GobbleM \GobbleO \GobbleMM \GobbleMO \GobbleOM \sc@gobbleOM M for mandatory arg, i.e., one token. O for optional arg, i.e., a square-brace pair.

320 \newlet\Gobble\@gobble
321 \newlet\GobbleM\@gobble
322 \NewName{GobbleO} {[#1]}

323 {}

324 \newlet\GobbleMM\@gobbletwo
325 \newcommand\GobbleOM {%
326 \@ifnextchar [
327  \sc@gobbleOM
328  \Gobble

329 }

330 \NewName{sc@gobbleOM} {[#1]#2}

331 {}

332 \newcommand\GobbleMO [1] {%
333 \@ifnextchar [
334  \GobbleO
335  {}%

336 }

12 Debugging

\VerboseErrors We do not use \setcounter but rather set these counters locally.

337 \newcommand*\VerboseErrors [1][\@M] {% args: [number]
338 \c@errorcontextlines #1%
339 \showboxbreadth #1%
340 \showboxdepth #1%

341 }

\Debug Set \debug to 0, 1, or 2.

342 \newcommand*\Debug[1] {% args: debug-level
343 \ifnum #1 > 0%
344  \let\sc@t@a\@M
345 \else
346  \let\sc@t@a\m@ne
347 \fi
348 \VerboseErrors[\sc@t@a]%
349 \tracingoutput#1 %
350 \tracingpages#1 %
351 \tracingmacros#1 %
352 \tracingcommands#1 %
353 \typeout{++++ Debugging [#1] \on@line}%

354 }

\MonsterError
\MonsterWarning
\MonsterInfo

355 \newcommand\MonsterWarning [2] {% args: package warning
356 \GenericWarning  % continuation message
357  {(#1)\@spaces\@spaces\@spaces\@spaces\@spaces}
358  {Frankenstein (#1) WARNING: #2}%

359 }

360 \newcommand\MonsterError [3] {% args: package error-message help-text
361 \GenericError % args: continuation message where-help what-help
362  {(#1)\@spaces\@spaces\@spaces\@spaces\@spaces}
363  {Frankenstein (#1) error: #2}
364  {See the documenation for the #1 package for more information.}
365  {#3}%

366 }

367 \newcommand\MonsterInfo [2] {% args: package info
368 \GenericInfo    % continuation message
369  {(#1)\@spaces\@spaces\@spaces\@spaces\@spaces}
370  {Frankenstein (#1) says: #2}%

371 }