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.3: Macros with arguments

But macros are not limited to text expansion or the reproduction of previously-stored values. They can take arguments of their own, so you can define a command to do something with specific text you give it. This makes them much more powerful and generic, as you can write a macro to do something a certain way, and then use it hundreds of times with a different value each time.

We mentioned earlier (in the para ‘This sensitivity to logic is programmed …’ in § 6.2) the idea of making new commands to put specific classes of words into certain fonts, such as \foreign or \product. Here’s an example for a new command \tmproduct, which also indexes the product name and adds a trademark sign:

\newcommand{\tmproduct}[1]{%
        \textit{#1}\texttrademark%
        \index{#1@\textit{#1}}%
}
      

If I now type \tmproduct{Velcro}, I get Velcro™ typeset, and if you look in the index, you’ll find this page referenced under Velcro. Let’s examine what this does:

  1. The macro is specified as having one argument (that’s the [1] in the definition). This will be the product name you type in curly braces when you use \product. Macros can have up to nine arguments.

  2. The expansion of the macro is contained in the second set of curly braces, spread over several lines (see the last listitem ‘Typing this macro over several lines …’ for why).

  3. It prints the value of the first argument (that’s the #1) in italics, which is conventional for product names, and adds the \texttrademark command.

  4. Finally, it creates an index entry using the same value (#1), making sure that it’s italicised in the index (see list item ‘Font changes’ to remind yourself of how indexing something in a different font works).

  5. Typing this macro over several lines makes it easier for humans to read. I could just as easily have typed

    \newcommand{\product}[1]{\textit{#1}\index{#1@\textit{#1}}}
              

    but it wouldn’t have been as clear what I was doing.

    One thing to notice is that to prevent unwanted spaces creeping into the output when LATEX reads the macro, I ended each line with a comment character (%). LATEX normally treats newlines as spaces when formatting (remember list item ‘%), so this stops the end of line being turned into an unwanted space when the macro is used. LATEX usually ignores spaces at the start of macro lines anyway, so indenting lines for readability is fine.

In § 1.9.2 we mentioned the problem of frequent use of unbreakable text leading to poor justification or to hyphenation problems. A solution is to make a macro which puts the argument into an \mbox with the appropriate font change, but precedes it all with a conditional \linebreak which will make it more attractive to TEX to start a new line.

\newcommand{\var}[1]{\linebreak[3]\mbox{\ttfamily#1}}
      

This only works effectively if you have a reasonably wide setting and paragraphs long enough for the differences in spacing elsewhere to get hidden. If you have to do this in narrow journal columns, you may have to adjust wording and spacing by hand occasionally.