## 2.1.1⁂Macro Definitions


Since many of the macros described in this section don't check for the prior existence of the command being defined, it's your responsibility to ensure you don't accidentally overwrite a core command which could mess up your document. Some class and package writers use a prefixing system for their command names to help prevent this.

If you're worried about accidentally overwriting a core command, you can get TeX to tell you the definition of a command using:

\showtoken

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

1. Suppose you're thinking about defining a command called \c but you first want to find out if it already exists:

\documentclass{article}

\show\c

\begin{document}

\end{document}


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.

2. Suppose you're now thinking about defining a command called \kern but you first want to find out if it already exists:

\documentclass{article}

\show\kern

\begin{document}

\end{document}


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.

3. Suppose you're now thinking about defining a command called \tmp but you first want to find out if it already exists:

\documentclass{article}

\show\tmp

\begin{document}

\end{document}


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:

texdef ⟨options⟩ ⟨cs name

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:

• -tformat

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

• -ccls name

This indicates that you want to check if the command is defined in a document that uses the class ⟨cls name⟩.

• -psty name

This indicates that you want to check if the command is defined in a document that uses the package ⟨sty name⟩.

For a complete list of options either use:

texdef --help

or

texdoc texdef

Example

Suppose you want to know the definition of the command \forlistloop provided by the etoolbox package:

texdef -t latex -p etoolbox forlistloop

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:

texdef -t latex figure endfigure

This displays:

\figure:
\long macro:->\@float {figure}

\endfigure:
\long macro:->\end@float

Alternatively you can use the -E switch:

texdef -t latex -E figure

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:

texdef -t latex Large endLarge

This displays:

\Large:
\long macro:->\@setfontsize \Large \@xivpt {18}

\endLarge:
undefined

This 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.

\letnew token⟩⟨token

This command makes ⟨new token⟩ have the same definition as ⟨token⟩.

Example:

\let\myemph\emph
\myemph{Test}


produces:

Note that this isn't the same as defining \myemph to use \emph. If \emph is later redefined, \myemph isn't affected.

Example:

\let\myemph\emph
\myemph{Test}.

\renewcommand{\emph}[1]{\textbf{#1}}
\myemph{Test}. \emph{Test}.


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.

\providecommand{cs}[n-args][default]{definition}


Example:

\providecommand{\emph}[1]{\textbf{#1}}%
\emph{Test}.


This produces:

Since \emph already exists, \providecommand had no effect. Compare this to:

\providecommand{\Emph}[1]{\textbf{#1}}%
\Emph{Test}.


which produces:

In this case \Emph didn't exist, so it was okay for \providecommand to define it.

\defcs⟩⟨arg syntax{definition}

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:

1. The simplest form is when you define a command that has no arguments. For example:

\def\test{This is a test.}% definition
\test


produces:

2. This example defines a command with two arguments:

\def\test#1#2{\emph{#1} \textbf{#2}}%
\test{First}{Second}


This produces:

3. This example defines a rather more complicated command that has the syntax:

\testarg1⟩-⟨arg2⟩-⟨arg3\endtest

This parameter syntax is now #1-#2-#3\endtest which is in the ⟨arg syntax⟩ part below:

\def\test#1-#2-#3\endtest{\emph{#1} \textbf{#2} \texttt{#3}} 

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

\test{First}{Second}{Third}
then you will get a runaway argument error:
Runaway argument?
{First}{Second}{Third}
! Paragraph ended before \test was complete.


Within ⟨arg syntax⟩ the parameters must appear in ascending order (for example, #2#1 is invalid); parameters can't be repeated (for example, #1#1 is invalid); intermediate parameters can't be skipped out (for example, #1#3 is invalid). This is a restriction on ⟨arg syntax⟩ not on ⟨definition⟩.

\def only has a local effect, like \newcommand. If you want to globally define a command, then you can use the analogous:

\gdefcs⟩⟨arg syntax{definition}

There are two more similar commands:

\edefcs⟩⟨arg syntax{definition}

and

\xdefcs⟩⟨arg syntax{definition}

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.

Take care when using \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:

\protected@edefcs⟩⟨arg syntax{definition}

and

\protected@xdefcs⟩⟨arg syntax{definition}

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:

\long\def\test#1{\emph{#1}} 

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.

\csdef{cs name}arg syntax{definition}

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:

\csgdef{cs name}arg syntax{definition}

analogous to \gdef,

\csedef{cs name}arg syntax{definition}

analogous to \edef,

\csxdef{cs name}arg syntax{definition}

analogous to \xdef,

\protected@csedef{cs name}arg syntax{definition}

analogous to \protected@edef, and

\protected@csxdef{cs name}arg syntax{definition}

analogous to \protected@xdef.

There are also commands analogous to \let:

\cslet{cs name}{cs}

\letcs{cs}{cs name}

and

\csletcs{cs name}{cs name}

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:

\csuse{cs name}

Remember that if the control sequence has been defined to have arguments, you need to specify these afterwards. For example:

\csuse{section}{A Sample Section} 

is equivalent to:

\section{A Sample Section} 

If the control sequence doesn't exist, \csuse{cs name} will expand to nothing. An alternative is to use TeX's primitive:

\csnamecs name⟩\endcsname

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:

\ifdef{cs}{true part}{false part}

where ⟨cs⟩ is the control sequence whose existence is being tested. Alternative you can specify the control sequence name using:

\ifcsdef{cs name}{true part}{false part}

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:

\ifundef{cs}{true part}{false part}

where ⟨cs⟩ is a control sequence and

\ifcsundef{cs name}{true part}{false part}

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:

\@ifundefined{cs name}{true part}{false part}

which is similar to \ifcsundef,

\@nameuse{cs name}

which is equivalent to

\csname ⟨cs name⟩\endcsname 

and

\@namedef{cs name}arg syntax{definition}

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).

© 2015 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.