[Tex/LaTex] Change the color of capital letters

capitalizationcolorstrings

Is there a way to define a command that changes the colour of any capital letter in an input string?

Most of the results I find when I type "LaTeX string capital" are results about capitalizing the first letter of each word. Here I would like to process all the capital letters of a string.

I know TeX is really nice for many reasons, but when it comes to actual programming I really feel like there is nothing else like it. I hope I won't offend anyone if I say that despite how grateful I am for LaTeX to even exist, I sometimes wish TeX's syntax was more traditional when it comes to actual programming.

Best Answer

You can do it with a regular expression, if you have the input string as an argument.

\documentclass{article}
\usepackage{xparse}
%\usepackage{l3regex} % only with expl3 before June 2017
\usepackage{xcolor}


\ExplSyntaxOn
\NewDocumentCommand{\colorcap}{ O{blue} m }
 {
  \sheljohn_colorcap:nn { #1 } { #2 }
 }

\tl_new:N \l__sheljohn_colorcap_input_tl
\cs_new_protected:Npn \sheljohn_colorcap:nn #1 #2
 {
  % store the string in a variable for usage with \regex_replace_all:nnN
  \tl_set:Nn \l__sheljohn_colorcap_input_tl { #2 }
  \regex_replace_all:nnN
   { ([A-Z]+) } % search a capital letter (or more)
   { \c{textcolor}\cB\{#1\cE\}\cB\{\1\cE\} } % replace the match with \textcolor{#1}{<match>}
   \l__sheljohn_colorcap_input_tl
  \tl_use:N \l__sheljohn_colorcap_input_tl
 }
\ExplSyntaxOff

\begin{document}
\colorcap{Once Upon a Time}

\colorcap[red]{Once Upon a Time}
\end{document}

enter image description here

Note

The syntax for the replacement string is a bit convoluted, but not difficult:

  • \c{textcolor} means “the control sequence \textcolor
  • \cB\{ means “an opening brace with its normal function of B⁣egin group
  • \cE\} means “a closing brace with its normal function of E⁣nd group

Thus the replacement text can be read as

\textcolor{#1}{<match>}

where #1 is the optional argument to \colorcap.

A version that also supports accents, provided they're input in the “classical” way with a macro.

\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\colorcap}{ O{blue} m }
 {
  \sheljohn_colorcap:nn { #1 } { #2 }
 }

\tl_new:N \l__sheljohn_colorcap_input_tl
\cs_new_protected:Npn \sheljohn_colorcap:nn #1 #2
 {
  % store the string in a variable
  \tl_set:Nn \l__sheljohn_colorcap_input_tl { #2 }
  \regex_replace_all:nnN
    % search a capital letter (or more)
    { ([A-Z]+|\cC.\{?[A-Z]+\}?) }
    % replace the match with \textcolor{#1}{<match>}
    { \c{textcolor}\cB\{#1\cE\}\cB\{\1\cE\} }
    \l__sheljohn_colorcap_input_tl
  \tl_use:N \l__sheljohn_colorcap_input_tl
 }
\ExplSyntaxOff

\begin{document}
\colorcap{\`Once \r{U}pon a Time}

\colorcap[red]{Once Upon a Time}
\end{document}

enter image description here

Here \cC. matches any control sequence, \{? zero or one open brace, \}? zero or one closed brace, so both \`O and \r{U} inputs are caught.