2.1.1 ⁂Macro Definitions
Volume 1
described how to define new commands
using \newcommand
and how to redefine them using
\renewcommand
. However there are times when these commands are
too limited for the task in hand.
[Optional arguments like \section
] For example, these commands only have a local effect, which means that if you
use them to define a command within a group (see Volume 1) they cease
to be defined when the group ends. There are also cases where you might
want to define a command without checking if it has already been
defined. For example, suppose you want to define a “scratch” command
that's used for temporary storage. If you use \renewcommand
,
then you must first initialise the scratch command with
\newcommand
, but if it turns out you never need to use the
scratch command, then this definition is redundant and a waste of
resources. In this case it's better to define the scratch command
only when it's needed without the existence checks imposed by
\newcommand
and \renewcommand
.
If you're worried about accidentally overwriting a core command, you can get TeX to tell you the definition of a command using:
This will interrupt the document build (as though an error had been encountered) and display the definition of ⟨token⟩ in the transcript. This command can be used for testing purposes but it should be removed once it's provided you with the information you require. The token may be a control sequence or a character, including special characters.
Examples
- Suppose you're thinking about defining a command called
\c
but you first want to find out if it already exists:When you run LaTeX on this document, the transcript will show:
> \c=macro: ->\OT1-cmd \c \OT1\c . l.3 \show\c ?
This tells you that\c
is a macro (first line of the above) and it then gives you the definition (second line of the above between->
and the terminating full stop). The rest of the message is just the regular error message prompt, including the line number. If you type h at the prompt for help, it will tell you that this isn't actually an error message. - Suppose you're now thinking about defining a command called
\kern
but you first want to find out if it already exists:The transcript now shows:
> \kern=\kern. l.3 \show\kern ?
This may seem a bit strange as it's not showing you a definition, but in this case (La)TeX is telling you that\kern
is a primitive (a core command that's not defined in terms of any other command). If you try redefining this particular command, the results will be disastrous. - Suppose you're now thinking about defining a command called
\tmp
but you first want to find out if it already exists:The transcript now shows:
> \tmp=undefined. l.3 \show\tmp ?
This means that\tmp
is undefined.
There's a convenient Perl script called texdef that will
display the definition of a command without the need for you to use
\show
in your document. Syntax:
where ⟨cs name⟩ is the name of the command you want to check without the leading backslash. There are a number of options you can use. For example:
- -t ⟨format⟩
This indicates the TeX format. For example, -t latex means you're checking a LaTeX command. On some systems, there's a convenient shortcut script:
$ latexdef ⟨options⟩ ⟨cs name⟩which is equivalent to:
$ texdef -t latex ⟨options⟩ ⟨cs name⟩ - -c ⟨cls name⟩
This indicates that you want to check if the command is defined in a document that uses the class ⟨cls name⟩.
- -p ⟨sty name⟩
This indicates that you want to check if the command is defined in a document that uses the package ⟨sty name⟩.
or
Example
Suppose you want to know the definition of the command
\forlistloop
provided by the etoolbox package:
This displays:
\forlistloop: macro:#1#2->\expandafter \etb@forlistloop \expandafter {#2}{#1}This means that
\forlistloop
is a macro that has two
arguments (indicated by macro:#1#2
) and the code after the arrow
->
indicates the definition of \forlistloop
.
What about environments? The start of an environment ⟨envname⟩,
issued by the command \begin
{
⟨envname⟩}
, performs some
checks, starts a group, stores the environment name in \@currenvir
and does \⟨envname⟩
. The end of the environment
\end
{
⟨envname⟩}
checks that ⟨envname⟩ matches
\@currenvir
, does \end⟨envname⟩
if that command
exists, and then closes the group. (This, incidentally, is why
\newcommand
won't allow you to define a command where the name
starts with end as it may interfere with the environment
end mechanism.)
Example
Suppose you want to know the definition of the figure
environment:
This displays:
\figure: \long macro:->\@float {figure} \endfigure: \long macro:->\end@floatAlternatively you can use the -E switch:
which produces the same output.
Recall from Volume 1
that the font declarations can also
be used as environments. In this case, \end⟨envname⟩
doesn't exist so \end
{
⟨envname⟩}
skips it.
Example
Suppose you want to know the definition of the Large
environment:
This displays:
\Large: \long macro:->\@setfontsize \Large \@xivpt {18} \endLarge: undefinedThis shows the definition of
\Large
but shows that
\endLarge
is undefined, which means \Large
can also be
used as a declaration.
Now that you know how to check that your chosen macro name doesn't already exist, so you won't accidentally cause a perplexing catastrophic error in your document, the rest of this section will look at defining commands, while the next section (§2.1.2 Hook Management) will look at modifying existing commands.
This command makes ⟨new token⟩ have the same definition as ⟨token⟩.
Example:
produces:
Note that this isn't the same as defining \myemph
to use
\emph
. If \emph
is later redefined, \myemph
isn't affected.
Example:
produces:
The command \let
may be prefixed with \global
to make the
assignment have a global effect.
Example:
\newcommand{\myemph}[1]{\texttt{#1}} \myemph{Test}. \emph{Test}. {% start a group \global\let\myemph\emph \myemph{Test}. \renewcommand{\emph}[1]{\textbf{#1}}% \myemph{Test}. \emph{Test}. }% end the group \myemph{Test}. \emph{Test}.
produces:
In this case, \myemph
has retained its new definition
after the end of the group, but the original definition of
\emph
has been restored, because the effect of
\renewcommand
only lasted until the end of the group.
This is like \newcommand
except that it will only define the
command if it doesn't already exist. If ⟨cs⟩ already
exists, no change will be made to it. The syntax is the same as for
\newcommand
.
Example:
This produces:
Since \emph
already exists, \providecommand
had no
effect. Compare this to:
which produces:
In this case \Emph
didn't exist, so it was okay for
\providecommand
to define it.
This defines ⟨cs⟩ without checking if it already exists. The
⟨definition⟩ part is the same as that for \newcommand
, but
with \def
you don't just specify the number of arguments.
Instead you declare the argument syntax in ⟨arg syntax⟩ where
each parameter is identified by #⟨n⟩ (where
⟨n⟩ is a number from 1 to 9).
Examples:
- The simplest form is when you define a command that has no
arguments. For example:
produces:
- This example defines a command with two arguments:
This produces:
- This example defines a rather more complicated command that has the
syntax:
\test
⟨arg1⟩-⟨arg2⟩-⟨arg3⟩\endtest
This parameter syntax is now #1-#2-#3
\endtest
which is in the ⟨arg syntax⟩ part below:Note that this doesn't define a command called
\endtest
. The\endtest
token merely forms part of the argument syntax. This\test
command can now be used but only with the correct syntax:\test First-Second-Third\endtest
This produces:
If you attempt to use incorrect syntax, for example, if you try
then you will get a runaway argument error:Runaway argument? {First}{Second}{Third} ! Paragraph ended before \test was complete.
\def
only has a local effect, like \newcommand
. If you want to
globally define a command, then you can use the analogous:
There are two more similar commands:
and
In both cases, the command being defined is set to the full expansion
of ⟨definition⟩. The first, \edef
, only has a local
effect. The second, \xdef
, has a global effect.
Example:
This example illustrates the difference between the non-expansion
\gdef
and the expansion \xdef
:
\def\abc{abc} \def\xyz{xyz} {% start group \def\abc{ABC} \def\xyz{XYZ} \gdef\test{\abc; \xyz} \xdef\etest{\abc; \xyz} \test. \etest. }% \test. \etest.
This produces:
In this example, \test
was just defined in terms of \abc
and \xyz
, so when \test
is executed, it uses the
current definitions of those commands. On the other hand, \etest
was defined as the full expansion of \abc
and \xyz
.
This means that if the definitions of \abc
and \xyz
later change, \etest
is unaffected.
\edef
and \xdef
that the definition
doesn't contain fragile commands, as that can cause an error.
If you want to protect against fragile commands, LaTeX provides additional
commands analogous to \edef
and \xdef
:
and
Note that these are internal commands, so if you need to use them in your
document (rather than in a class or package), you need \makeatletter
and \makeatother
. [\@
and @ in macro
names]
Note that \def
, \gdef
, \edef
and \xdef
all define short
commands, unless the prefix \long
is used. For example:
This now allows a paragraph break within the argument of \test
.
For further details see The TeXbook [46].
(Both \protected@edef
and \protected@xdef
also define short
commands, but they can't be prefixed with \long
.)
In addition to the TeX primitives and core LaTeX commands described above, the etoolbox package [51] also provides ways of defining commands.
This is analogous to \def
except that you supply the control sequence
name ⟨cs name⟩ (without the leading backslash) instead of the actual
control sequence. Note that ⟨cs name⟩ must be fully expandable. The
⟨arg syntax⟩ is the same as for \def
.
Defining a control sequence by its name in this manner means that you
can have control sequences that include punctuation or digits or
you can form the control sequence name on the fly. This is the way that
commands with labels work. For example, recall the \newglossaryentry
command from Volume 2. The first argument is a label,
and this label is used in the name of the internal control sequences that store
the entry details. The datatool package's database commands
described later in this chapter also use a similar technique.
The etoolbox package also provides:
analogous to \gdef
,
analogous to \edef
,
analogous to \xdef
,
analogous to \protected@edef
, and
analogous to \protected@xdef
.
There are also commands analogous to \let
:
and
where ⟨cs name⟩ is the name of a control sequence and ⟨cs⟩ is a control sequence.
You can use a control sequence by its name with:
Remember that if the control sequence has been defined to have arguments, you need to specify these afterwards. For example:
is equivalent to:
If the control
sequence doesn't exist, \csuse
{
⟨cs name⟩}
will expand to nothing.
An alternative is to use TeX's primitive:
If the control sequence doesn't exist, \csname
will define
the control sequence to \relax
before using it.
The etoolbox package also provides ways of determining if a command already exists using:
where ⟨cs⟩ is the control sequence whose existence is being tested. Alternative you can specify the control sequence name using:
In both cases, if the command has been defined, ⟨true part⟩ will be processed, otherwise ⟨false part⟩ will be processed. You can also use the logically opposite commands which check for non-existence:
where ⟨cs⟩ is a control sequence and
where ⟨cs name⟩ is a control sequence name. Although logically
opposite, these commands differ slightly from their existence
counterparts as these commands will consider a control sequence
undefined if its definition is \relax
.
If you don't want to use the etoolbox package, the LaTeX kernel provides the internal commands:
which is similar to \ifcsundef
,
which is equivalent to
\csname ⟨cs name⟩\endcsname
and
which is similar to \csdef
.
This book is also available as A4 PDF or 12.8cm x 9.6cm PDF or paperback (ISBN 978-1-909440-07-4).