Active characters in command arguments#
Occasionally, it’s nice to make one or two characters active in the argument of a command, to make it easier for authors to code the arguments.
Active characters can be used safely in such situations; but care is needed.
An example arose while this answer was being considered : an aspirant macro writer posted to comp.text.tex asking for help to make # and b produce musical sharp and flat signs, respectively, in a macro for specifying chords.
The first problem is that both # and b have rather important uses elsewhere in TeX (to say the least!), so that the characters can only be made active while the command is executing.
Using the techniques discussed in « Active characters in command arguments », we can define :
\begingroup
\catcode`\#=\active
\gdef#{$\sharp$}
\endgroup
and :
\begingroup
\lccode''\~=''\b
\lowercase{\endgroup
\def~{$\flat$}%
}
The second problem is one of timing : the command has to make each character active before its arguments are read : this means that the command can’t actually « have arguments itself, but must be split in two. So we write :
\def\chord{%
\begingroup
\catcode`\#=\active
\catcode`\b=\active
\Xchord
}
\def\Xchord#1{%
\chordfont#1%
\endgroup
}
and we can use the command as \chord{F#} or \chord{Bb minor}.
Two features of the coding are important :
\begingroupin\chordopens a group that is closed by\endgroupin\Xchord; this group limits the change of category codes, which is the raison d’être of the whole exercise.Although
#is active while\Xchordis executed, it’s not active when it’s being defined, so that the use of#1doesn’t require any special attention.
Note that the technique used in such macros as \chord, here, is analogous to that used in such commands as \verb; and, in just the same way as \verb (see « Pourquoi le mode verbatim ne marche pas toujours ? »), \chord won’t work inside the argument of another command (the error messages, if they appear at all, will probably be rather odd).