How to write a command to format different letters?
Here's a straightforward solution using expl3. If you need it to work in subgroups \MyFormatter{Supermarket and \MakeUppercase{Supermarket}}
you can check this solution.
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \myformatter { +m } { \xmllmx_myformatter:n { #1 } }
\cs_new_protected:Npn \xmllmx_myformatter:n #1
{
\tl_set:Nn \l_tmpa_tl { #1 }
\tl_replace_all:Nnn \l_tmpa_tl { p } { \textbf{p} }
\tl_replace_all:Nnn \l_tmpa_tl { k } { \textbf{k} }
\tl_replace_all:Nnn \l_tmpa_tl { m } { \textit{m} }
\tl_replace_all:Nnn \l_tmpa_tl { t } { \textit{t} }
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
It's easy and flexible with regular expressions:
\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\myformatter}{m}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_all:nnN
{ ([kp]+) } { \c{textbf}\cB\{ \1 \cE\} }
\l_tmpa_tl
\regex_replace_all:nnN
{ ([mt]+) } { \c{textit}\cB\{ \1 \cE\} }
\l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff
\begin{document}
\myformatter{Supermarket}
\end{document}
An approach using catcodes that works if the \MyFormatter
appears in the clear and is not part of an argument. As egreg pointed out in this regard, \mbox{\MyFormatter{Supermarket}}
fails.
However, I jokingly retort in my comment that the way to get around the fail-case is to put the \mbox
inside the MyFormatter
, not the other way around. Of course, the new drawback with this "fix" is that the "m" of \mbox
is now active, and so an additional \let
is required: \let\MBOX\mbox\MyFormatter{\MBOX{Supermarket}}
.
Finally, wipet comments that one could argue that the problem lies in the definition of \mbox
, in that \hbox{\MyFormatter{Supermarket}}
does not suffer the same problem.
\documentclass{article}
\let\BB\textbf
\let\II\textit
\let\CC\catcode
\let\AC\active
\let\SVP p \let\SVK k \let\SVM m \let\SVT t
\def\CODESON{\CC`p=\AC \CC`k=\AC \CC`m=\AC \CC`t=\AC }
\def\CODESOFF{\CC`p=11 \CC`k=11 \CC`m=11 \CC`t=11 }
\CODESON
\def p{\BB{\SVP}}
\def k{\BB{\SVK}}
\def m{\II{\SVM}}
\def t{\II{\SVT}}
\CODESOFF
\newcommand\MF[1]{#1\CODESOFF}
\newcommand\MyFormatter{\CODESON\MF}
\begin{document}
Supermarket \MyFormatter{Supermarket} Supermarket
\mbox{\MyFormatter{Supermarket}} fails, but
\let\MBOX\mbox\MyFormatter{\MBOX{Supermarket}} works
\end{document}