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.
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
define(foo,bar-bar-b'ra-$1)define(act,`
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
fictions.
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.
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.
define(Unname,Undef)Unname(ine)d sources
would produce output
Undefined sources
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.