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 :
\begingroup
in\chord
opens a group that is closed by\endgroup
in\Xchord
; this group limits the change of category codes, which is the raison d’être of the whole exercise.Although
#
is active while\Xchord
is executed, it’s not active when it’s being defined, so that the use of#1
doesn’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).