Thomas A. Alspaugh

A macro is a named unit of text; a macro processor replaces each occurrence of a macro name with its definition. Because the definition is usually longer than the name, this process is called macro expansion.

(The term macro is also used to refer to named units that are not obviously text, for example a macro representing a sequence of actions to be performed as a unit by a spreadsheet program.)

The prototypical macro processor for the purposes of this page is m4, by Brian Kernighan and Dennis Ritchie. m4 extends the earlier m3 macro processor, thus the name. A free GNU m4, slightly expanded from the standard m4, is available from the Free Software Foundation and is documented online.

The output in examples on this page was produced automatically by m4 from the input in those examples.

Basics of m4 macro processing

Macros are defined by putting the definition in the input text. The m4 command define defines a macro.

Individual words are examined to see if they are macro names. If a macro name is part of a larger word, it won't be expanded — for example, if there is a macro named con and a word in the input scone, the con in scone won't be expanded.

The command define(foo,bar) defines a macro named foo whose definition is bar. The input

define(foo,bar)define(con,pro)Don't be
foo-led by words that are
con-tradicted by actions.
Have a scone instead of a s-con-e!

results in the output

Don't be
bar-led by words that are
pro-tradicted by actions.
Have a scone instead of a s-pro-e!

Each define command is replaced by the empty string.

Macro expansion can be prevented by quoting the macro name, or text that includes the macro name (or even just part of the macro name). m4 uses ` and ' by default as its quotes (the quote characters can be changed to any strings if necessary).

The input

define(foo,bar)define(con,pro)`Don't be
foo`'led by words' that are `c'on`'tradicted by actions.
Have a scone instead of a s`'con`'e!

results in the output

Dont be
barled by words' that are contradicted by actions.
Have a scone instead of a sproe!

The initial backquote ` was closed by the apostrophe in Don't, so foo was not quoted after all (and the quote after words was interpreted as a literal quote character rather than an end quote). Note that empty quotes `' were used to divide the macro names as separate words, rather than -s as in the previous example, and that quotes are paren-nested.

Macros can be given parameters. Formal parameters in definitions are represented by $1, $2, etc., and actual parameters in calls are separated by commas and enclosed in (). The first actual parameter in the list is used to replace $1, the second to replace $2, and so on. If there aren't n actual parameters, then formal parameter $n is replaced by the empty string.

The input

fi$1ct$2')Don't be
foo(Ann,marie)led by
words that are contradicted by act`'ions.

results in the output

Don't be
bar-bar-b'ra-Annled by
words that are contradicted by 

The actual parameter Marie wasn't used because there was no $2 in the definition. Note how the newline in the definition of act ended up in the output.

Macro language design choices

Under Construction

There are many design choices involved in the design of a macro language (how the names to be expanded are presented in the input to the macro processor, etc.) and the actions of the corresponding macro processor. In this discussion we will assume that macro name has been defined with definition def.

How is a macro call (the presentation of a name to be expanded) presented?
  1. The name is expanded, in whatever context it is encountered.
  2. The name is expanded only if it is preceded and followed by word-boundary characters, such as [ \t\n.,:;!?()\[\]{}<>].
  3. The name is expanded only if it is preceded by a specific command or character and followed by its parameters in (), for example !name().
How are parameters expressed?
A typical approach is to use $1, $2, etc. in the macro definition as the formal parameters to be replaced, and to enclose the actual parameters that are to replace them in (), separated by commas, after the macro name. For example, input
    define(Unname,Undef)Unname(ine)d sources 

would produce output

    Undefined sources 
How can the expansion of a name be prevented?
Sometimes the string that makes up the macro name appears in the macro processor input, but is not intended to be expanded.

The usual approach is to quote any string that is not to be expanded. m4 uses `' for this purpose; input

    define(Unnamed,Undefined)`Unnamed sources' 

would produce output

    Unnamed sources 

Typically, a pair of quotes is used up when the text they are part of is scanned looking for macros to expand, and they are removed at that point. If for some reason a section of text will be scanned n times, it will need to be enclosed in n levels of quotes.

Can the input define macros?
When is a macro's definition expanded: once when the macro is defined, or each time it is expanded?

flip bgunflip