You can use m4 to generate common text whenever necessary, but care must be taken to distinguish between macros to be expanded and literal text.
All literal text should be enclosed in ` and ' to avoid it being interpreted as a macro by m4. In several cases, literal arguments to macros must be quoted that way twice, because m4 expands them once before they enter the macro, and once after they come out. Only some operands to built-in macros need only one pair of quotes: those which do not come out.
As an example, here is the definition of a trivial macro to create a paragraph using one of its arguments as the content:
define(`P', ``<P>'$1`</P>'')dnl
Only one set of quotes is needed around the macro name
because it doesn't pass through
the definition.
However, the definition itself (the second argument) needs
two for literal text — the outer pair delimits the argument
and is stripped away before the definition is made, so
doesn't ultimately form part of the definition. If you
leave off one pair of quotes, the enclosed P
will be expanded recursively, when you use
the macro!
In summary, here are the arguments that need to be double-quoted:
Macro definitions, e.g.:
define(`name',``value'')dnl pushdef(`name',``new value'')dnl
Conditional text, e.g.:
ifelse($1,$2,``yes' $1', ``no' $2') ifdef(`CONTEXT',``defined'',``not defined'')
…but not the condition itself.
The format format string, e.g.:
define(`xxx',``yyy'')dnl format(``xxx'') format(`xxx')
which yields:
xxx yyy
For reasons which I forget right now, I dequote each $ argument reference within a definition, e.g.:
define(`P', ``<p>'$1`</p>'')dnl
This means that in uses of the macro, you must pass literal text quoted twice, for example:
P(``Hello, world!'')
You can probably get away with just using a single pair of quotes, but I'll leave that as an exercise for the reader. At least, I know that double-quoting works.
If anyone can shed light on this, do please contact me!
Ah! Here's a reason: you can avoid unnecessary macro expansions. Consider this single-quote example:
define(`test',`ifelse(`$1',`$2',``<p>Yes: $3</p>'', ``<p>No!</p>'')')dnl define(`floop',``the words'errprint(`Macro floop used ')')dnl test(1,0,`These are 'floop` of me')
…which yields:
<p>No!</p>
…but also prints out:
Macro floop used
…on the error output. The double-quote version:
define(`test',`ifelse(`$1',`$2',``<p>Yes: '$3`</p>'', ``<p>No!</p>'')')dnl define(`floop',``the words'errprint(`Macro floop used ')')dnl test(1,0,``These are 'floop` of me'')
…yields the same, but without the error message, because floop did not need to be expanded. This may have some value(?).
The following macros mainly involve XML character entities/references, so I keep them in a file include/xml.m4 which I include from etc/site.xml.m4.
m4 uses the characters
'
(apostrophe), `
(grave), ,
(comma) and
$
(dollar) for special purposes. If you
want to use them literally, these macros express them
without m4
interpretation:
define(`APOS',``''') define(`GRAV',```'') define(`COMM',``,'') define(`DOLL',``$'')
HTML Tidy will convert these into normal characters after leaving m4.
Only APOS and GRAV are usually necessary. Use them this way:
`It'APOS`s a nice day!'
…to produce:
It's a nice day!
Another possibility is to use the built-in macro
changequote to change the quote
strings to something less commonly encountered, possibly of
more than one character, but you would still have to
provide escapes for them. Or you could use changeword to change the syntax of macros so
you don't have to quote everything, but that would make
built-ins harder to access.
You may be uncertain about how you should use (consistently) common terms or abbrieviations. If you define macros for them, you can change all uses at once.
For example, you might anticipate changing the title of a website, which appears on every page:
define(`SITENAME', ``My Excellent Website'')dnl define(`SITEABBR', ``MEW'')dnl
We can use m4 to quote text with the right quotation marks. The macro below, Qx, wraps its first argument between its second and third (the quotation marks):
define(`Qx',`$2`'$1`'$3')
(You may want to override this for specific media types. For example, see the HTML version of Qx.)
Here are some particular types of quotation marks:
define(`Q69',`Qx(`$1',``‘'',``’'',shift($@))') define(`DQ69',`Qx(`$1',``“'',``”'',shift($@))') define(`QA',`Qx(`$1',``‹'',``›'',shift($@))') define(`DQA',`Qx(`$1',``«'',``»'',shift($@))')
In XML, you can express any character by its Unicode number, so if you cannot enter, for example, an accented character such as ‘ĥ’ directly, you can use Ĥ.
Here are some macros for accented Esperanto characters:
define(`Cx',``Ĉ'') define(`cx',``ĉ'') define(`Gx',``Ĝ'') define(`gx',``ĝ'') define(`Hx',``Ĥ'') define(`hx',``ĥ'') define(`Jx',``Ĵ'') define(`jx',``ĵ'') define(`Sx',``Ŝ'') define(`sx',``ŝ'') define(`Ux',``Ŭ'') define(`ux',``ŭ'')
Now you can write ‘eĥoŝanĝo ĉiuĵaŭde’ as `e'hx`o'sx`an'gx`o 'cx`iu'jx`a'ux`de'.
Some such characters break down into a base character and a combining one. For example, ‘ĥ’ can be expressed as ĥ. So, with these macros:
define(`x',``̂'') define(`w',``̆'')
…you can write ‘eĥoŝanĝo ĉiuĵaŭde’ as `eh'x`os'x`ang'x`o c'x`iuj'x`au'w`de'.
This form may help some browsers which cannot display the correct characters, because they may appear like this: ‘eh^os^ang^o c^iuj^au˘de’ or ‘eh?os?ang?o c?iuj?au?de’ instead of ‘e?o?an?o ?iu?a?de’.
Updated: 2008-Apr-04 11:46 GMT
Contact
Steven Simpson
Ĉi tiu paĝo disponeblas ĉi-lingve, laŭ via krozila agordo.