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}}
  1. The digit 1 in square brackets means that \person has one argument, so you put the whole name in a single set of curly braces, eg \person{Don Knuth}.

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

  3. But then it uses a special feature of Plain TEX macros (which use \def instead of LATEX’s \newcommand): they too can have multiple arguments but you can separate them with other characters (here a space) to form a pattern which TEX will recognise when reading the arguments.

    In this example (\reindex) it’s expecting to see a string of characters (#1) followed by a space, followed by another string of characters (#2) followed by a dummy command (\sentinel). In effect this makes it a device for splitting a name into two halves on the space between them, so the two halves can be handled separately. The \reindex command can now read the two halves of the name separately.

  4. The \person command invokes \reindex and follows it with the name you typed 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.

    It can therefore output them using \index in reverse order, 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 virtually no effort on the author’s part at all.

  1. Don’t try this at home alone, folks! This one is safe enough, but you should strictly avoid \def for a couple of years. Stick to \newcommand for now.