# How to write a command to format different letters?

I hope I can have a command MyFormatter, which can make letters p and k bold and make letters m and t italic.

For example:

\MyFormatter{Supermarket}

will output as follows:

Supermarket

How to write the command \MyFormatter in LaTeX?

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{\CCp=\AC  \CCk=\AC  \CCm=\AC  \CCt=\AC }
\def\CODESOFF{\CCp=11 \CCk=11 \CCm=11 \CCt=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}

• Try \mbox{\MyFormatter{Supermarket}} – egreg Jun 30 '16 at 11:00
• @egreg DRAT! Again, I say DRAT! – Steven B. Segletes Jun 30 '16 at 11:03
• @egreg Of course, since \MyFormatter{Supermarket} doesn't hyphenate, why would one need to put it into an \mbox? ;^) – Steven B. Segletes Jun 30 '16 at 11:14
• But \hbox{\MyFormater{Supermarket}} works. This is LaTeX problem that \mbox is defined as macro with parameter. It needs not. – wipet Jun 30 '16 at 11:20
• Advertising \hbox is best service to them because they come to know that there are other approaches than only LaTeX. :-). Or they can define \def\mbox{\leavevmode\hbox} – wipet Jun 30 '16 at 12:09

For example using OPmac:

\input opmac

\def\MyFormatter{\afterassignment\MyFormatterA \def\tmpb}
\def\MyFormatterA{\replacestrings{p}{{\bf p}}\replacestrings{k}{{\bf k}}%
\replacestrings{m}{{\it m}\/}\replacestrings{t}{{\it t}\/}\tmpb}

\MyFormatter{Supermarket}

\bye