Your support for our advertisers helps cover the cost of hosting, research, and maintenance of this document

Formatting Information — An introduction to typesetting with LATEX

Chapter 7: Programmability

Section 7.4: Nested macros

Here’s a slightly more complex example, where one macro calls another. It’s common in normal text to refer to people by their forename and surname (in that order), for example Donald Knuth, but to have them indexed as surname, forename. This pair of macros, \person and \reindex, automates that process to minimise typing and indexing.

\newcommand{\person}[1]{#1\reindex #1\sentinel}
\def\reindex #1 #2\sentinel{\index{#2, #1}}

The digit 1 in square brackets means that the \person command has one argument, so you put the whole name in a single set of curly braces, eg \person{Don Knuth}.

  1. The first thing the macro does is output #1, which is the value of the argument, what you typed, just as it stands, so the whole name gets typeset exactly as you typed it.

  2. Next, it uses the \reindex command defined underneath. This uses a special feature of Plain TEX macros, which use \def instead of the LATEX \newcommand (see the sidebar ‘Plain TEX’s \def vs LATEX’s \newcommand below): they too can have multiple arguments but you can separate them with other characters to forma pattern.

    In this example (\reindex), TEX is expecting to see a string of characters (#1) followed by a space, followed by another string of characters (#2) followed by a command (\sentinel), which is a dummy to terminate the second string. In effect this pattern makes this command a function for splitting a name into two halves on the space between them, so the two halves can be handled separately. The rest of the \reindex command can now deal with the two halves of the name separately.

  3. The \person command invokes \reindex and follows it with the name you typed (which of course contains a space) plus the dummy command \sentinel (which is just there to signal the end of the name). Because \reindex is expecting two arguments separated by a space and terminated by a \sentinel, it sees ‘Don’ and ‘Knuth’ as two separate arguments.

  4. Finally, \reindex outputs the second argument followed by the first argument, using \index, so that it indexes the name in reverse order, surname first, which is exactly what we want.

A book or report with a large number of personal names to print and index could make significant use of this to allow them to be typed as \person{Leslie Lamport} and printed as Leslie Lamport, but have them indexed as ‘Lamport, Leslie’ with no additional effort on the author’s part at all.