Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
1  
For xelatex, see tex.stackexchange.com/questions/33855/… –  David Carlisle Apr 24 at 11:10
    
For a LuaLaTeX approach, have a look at the chickenize package. –  Martin Schröder May 1 at 19:11
add comment

2 Answers 2

up vote 19 down vote accepted

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

\documentclass{article}
\usepackage{xparse,l3regex}
\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.

share|improve this answer
    
That looks more like the correct answer actually :) But is it for LaTeX3 only? Or is l3regex available on texlive/popular LaTeX2e distributions? –  Sh3ljohn Apr 24 at 14:38
    
Could you elaborate on the functions of each line in your code a little bit more? –  azetina Apr 24 at 15:16
1  
@Sh3ljohn The expl3 suite is available on every updated TeX distribution. –  egreg Apr 24 at 16:26
1  
@azetina Done; I had only a few minutes before the LaTeX class when I wrote the answer. ;-) –  egreg Apr 24 at 16:38
    
Great! I envy your students for having such a wonderful LaTeX teacher like you. They will surely be guided on the right path :-) –  azetina Apr 24 at 16:43
add comment

This solution shows an active character approach, which (though heavy in the setup) will allow one to have cap letter automatically colorized. But because active letters will tend to break macros, I provide the means to disable it. This revised solution provides the following macros:

\capcoloron[color] turns all cap letters to this color (default red)

\capcoloroff turns off active characters and restores original cap-letter definitions

\coloron{letter}{color} turns just this [inactive] letter active and sets it to the specified color

\coloroff{letter} turns off just this active character, and restores its original definition.

The only quirk is that to change the color of a given capital letter that is already active, one must first turn the color off, and then turn it on again. Here is my MWE:

\documentclass{article}
\usepackage{xcolor}
\usepackage{stringstrings}

\let\sva A\let\svb B\let\svc C\let\svd D\let\sve E\let\svf F\let\svg G
\let\svh H\let\svi I\let\svj J\let\svk K\let\svl L\let\svm M\let\svn N
\let\svo O\let\svp P\let\svq Q\let\svr R\let\svs S\let\svt T\let\svu U
\let\svv V\let\svw W\let\svx X\let\svy Y\let\svz Z
\catcode`A=\active\catcode`B=\active\catcode`C=\active\catcode`D=\active
\catcode`E=\active\catcode`F=\active\catcode`G=\active\catcode`H=\active
\catcode`I=\active\catcode`J=\active\catcode`K=\active\catcode`L=\active
\catcode`M=\active\catcode`N=\active\catcode`O=\active\catcode`P=\active
\catcode`Q=\active\catcode`R=\active\catcode`S=\active\catcode`T=\active
\catcode`U=\active\catcode`V=\active\catcode`W=\active\catcode`X=\active
\catcode`Y=\active\catcode`Z=\active
\newcommand\colorcapon[1][red]{%
  \catcode`A=\active\def A{\textcolor{#1}{\sva}}%
  \catcode`B=\active\def B{\textcolor{#1}{\svb}}%
  \catcode`C=\active\def C{\textcolor{#1}{\svc}}%
  \catcode`D=\active\def D{\textcolor{#1}{\svd}}%
  \catcode`E=\active\def E{\textcolor{#1}{\sve}}%
  \catcode`F=\active\def F{\textcolor{#1}{\svf}}%
  \catcode`G=\active\def G{\textcolor{#1}{\svg}}%
  \catcode`H=\active\def H{\textcolor{#1}{\svh}}%
  \catcode`I=\active\def I{\textcolor{#1}{\svi}}%
  \catcode`J=\active\def J{\textcolor{#1}{\svj}}%
  \catcode`K=\active\def K{\textcolor{#1}{\svk}}%
  \catcode`L=\active\def L{\textcolor{#1}{\svl}}%
  \catcode`M=\active\def M{\textcolor{#1}{\svm}}%
  \catcode`N=\active\def N{\textcolor{#1}{\svn}}%
  \catcode`O=\active\def O{\textcolor{#1}{\svo}}%
  \catcode`P=\active\def P{\textcolor{#1}{\svp}}%
  \catcode`Q=\active\def Q{\textcolor{#1}{\svq}}%
  \catcode`R=\active\def R{\textcolor{#1}{\svr}}%
  \catcode`S=\active\def S{\textcolor{#1}{\svs}}%
  \catcode`T=\active\def T{\textcolor{#1}{\svt}}%
  \catcode`U=\active\def U{\textcolor{#1}{\svu}}%
  \catcode`V=\active\def V{\textcolor{#1}{\svv}}%
  \catcode`W=\active\def W{\textcolor{#1}{\svw}}%
  \catcode`X=\active\def X{\textcolor{#1}{\svx}}%
  \catcode`Y=\active\def Y{\textcolor{#1}{\svy}}%
  \catcode`Z=\active\def Z{\textcolor{#1}{\svz}}%
}
\def\colorcapoff{%
  \catcode`A=11\let A\sva%
  \catcode`B=11\let B\svb%
  \catcode`C=11\let C\svc%
  \catcode`D=11\let D\svd%
  \catcode`E=11\let E\sve%
  \catcode`F=11\let F\svf%
  \catcode`G=11\let G\svg%
  \catcode`H=11\let H\svh%
  \catcode`I=11\let I\svi%
  \catcode`J=11\let J\svj%
  \catcode`K=11\let K\svk%
  \catcode`L=11\let L\svl%
  \catcode`M=11\let M\svm%
  \catcode`N=11\let N\svn%
  \catcode`O=11\let O\svo%
  \catcode`P=11\let P\svp%
  \catcode`Q=11\let Q\svq%
  \catcode`R=11\let R\svr%
  \catcode`S=11\let S\svs%
  \catcode`T=11\let T\svt%
  \catcode`U=11\let U\svu%
  \catcode`V=11\let V\svv%
  \catcode`W=11\let W\svw%
  \catcode`X=11\let X\svx%
  \catcode`Y=11\let Y\svy%
  \catcode`Z=11\let Z\svz%
}
\newcommand\coloron[2]{%
  \if\sva#1\catcode`A=\active\def A{\textcolor{#2}{\sva}}\else%
  \if\svb#1\catcode`B=\active\def B{\textcolor{#2}{\svb}}\else%
  \if\svc#1\catcode`C=\active\def C{\textcolor{#2}{\svc}}\else%
  \if\svd#1\catcode`D=\active\def D{\textcolor{#2}{\svd}}\else%
  \if\sve#1\catcode`E=\active\def E{\textcolor{#2}{\sve}}\else%
  \if\svf#1\catcode`F=\active\def F{\textcolor{#2}{\svf}}\else%
  \if\svg#1\catcode`G=\active\def G{\textcolor{#2}{\svg}}\else%
  \if\svh#1\catcode`H=\active\def H{\textcolor{#2}{\svh}}\else%
  \if\svi#1\catcode`I=\active\def I{\textcolor{#2}{\svi}}\else%
  \if\svj#1\catcode`J=\active\def J{\textcolor{#2}{\svj}}\else%
  \if\svk#1\catcode`K=\active\def K{\textcolor{#2}{\svk}}\else%
  \if\svl#1\catcode`L=\active\def L{\textcolor{#2}{\svl}}\else%
  \if\svm#1\catcode`M=\active\def M{\textcolor{#2}{\svm}}\else%
  \if\svn#1\catcode`N=\active\def N{\textcolor{#2}{\svn}}\else%
  \if\svo#1\catcode`O=\active\def O{\textcolor{#2}{\svo}}\else%
  \if\svp#1\catcode`P=\active\def P{\textcolor{#2}{\svp}}\else%
  \if\svq#1\catcode`Q=\active\def Q{\textcolor{#2}{\svq}}\else%
  \if\svr#1\catcode`R=\active\def R{\textcolor{#2}{\svr}}\else%
  \if\svs#1\catcode`S=\active\def S{\textcolor{#2}{\svs}}\else%
  \if\svt#1\catcode`T=\active\def T{\textcolor{#2}{\svt}}\else%
  \if\svu#1\catcode`U=\active\def U{\textcolor{#2}{\svu}}\else%
  \if\svv#1\catcode`V=\active\def V{\textcolor{#2}{\svv}}\else%
  \if\svw#1\catcode`W=\active\def W{\textcolor{#2}{\svw}}\else%
  \if\svx#1\catcode`X=\active\def X{\textcolor{#2}{\svx}}\else%
  \if\svy#1\catcode`Y=\active\def Y{\textcolor{#2}{\svy}}\else%
  \if\svz#1\catcode`Z=\active\def Z{\textcolor{#2}{\svz}}\else%
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}
\newcommand\coloroff[1]{\catcode`#1=11%
  \edef\tmp{\detokenize{#1}}%
  \caselower[q]{\tmp}%
  \expandafter\let\expandafter#1\csname sv\thestring\endcsname%
}
\catcode`A=11\catcode`B=11\catcode`C=11\catcode`D=11\catcode`E=11
\catcode`F=11\catcode`G=11\catcode`H=11\catcode`I=11\catcode`J=11
\catcode`K=11\catcode`L=11\catcode`M=11\catcode`N=11\catcode`O=11
\catcode`P=11\catcode`Q=11\catcode`R=11\catcode`S=11\catcode`T=11
\catcode`U=11\catcode`V=11\catcode`W=11\catcode`X=11\catcode`Y=11
\catcode`Z=11

\parskip 1em

\begin{document}

\colorcapon[cyan]
\verb|\colorcapon[color]| will change all caps to the specified color\\
A Test of The Active Method (\verb|Even in \Verbatim|)

\colorcapoff
\verb|\colorcapoff| will restore all things to the original LaTeX setting\\
A Test of The Active Method

\coloron{M}{blue}\coloron{A}{red}\coloron{T}{orange}
\verb|\coloron{letter}{color}| will turn an inactive letter active with the
specified color, done here to letters ``M'', ``A'', and ``T'':\\
A Test of The Active Method

\coloroff{A}
\verb|\coloroff{letter}| will restore that letter to the original LaTeX
setting, here done to the letter ``A'':\\
A Test of The Active Method

To change The color an already active letter, one must first turn the color off
and then set the color anew, as done here to the letter ``T'':\\
\coloroff{T}\coloron{T}{green}
A Test of The Active Method
\end{document}

enter image description here


ORIGINAL SOLUTION:

This shows the traditional and dangerous active character approach. The active approach takes a fair amount of "setup" code, but then will automatically change the cap letter colors upon use.

Because it is dangerous, I provide the means to enter and exit the active approach with \colorcapon and \colorcapoff. I've only set up 3 letters... but the other 23 follow in a similar manner.

\documentclass{article}
\usepackage{xcolor}
\begin{document}
TRADITIONAL APPROACH:

\textcolor{red}{A} letter can have its color \textcolor{blue!60}{C}hanged
with the \textcolor{cyan!80}{U}se of \verb|\textcolor|.\vspace{2em}

ACTIVE CHARACTER APPROACH

\let\sva A
\let\svc C
\let\svu U
\catcode`A=\active
\catcode`C=\active
\catcode`U=\active
\def\colorcapon{%
  \catcode`A=\active\def A{\textcolor{red}{\sva}}%
  \catcode`C=\active\def C{\textcolor{blue!60}{\svc}}%
  \catcode`U=\active\def U{\textcolor{cyan!80}{\svu}}%
}
\def\colorcapoff{%
  \catcode`A=11\let A\sva%
  \catcode`C=11\let C\svc%
  \catcode`U=11\let U\svu%
}
\catcode`A=11
\catcode`C=11
\catcode`U=11

\colorcapon
A letter can have its color Changed with the Use of\\
\verb|\textcolor.  Wow.  And I can Use it in verbatim|.\vspace{2em}\colorcapoff


RESTORED TO ORIGINAL

A letter can have its color Changed with the Use of \verb|\textcolor|.

\end{document}

enter image description here

share|improve this answer
    
Impressive :) I'm going to read about these catcodes and what they do. Is there a way to select caps in a more generic manner than defining them individually? –  Sh3ljohn Apr 24 at 10:54
1  
@Sh3ljohn I'm thinking about that, but it requires another trick that I still haven't unraveled. If I obtain it, I will post. –  Steven B. Segletes Apr 24 at 10:59
    
@Sh3ljohn Please see revision. –  Steven B. Segletes Apr 24 at 13:36
    
Thanks, I'm going to mark it as the answer, but I find it a bit hackish personally. There ought to be a proper way of iterating over the chars of a string, checking for case, and modify those characters conditionally. –  Sh3ljohn Apr 24 at 14:31
    
@Sh3ljohn There may be a better way, but it gets complicated, and problems arise when the argument passed to a macro is active, but the macro was defined when that character was not active. When that happens, things that look the same in the code will actually fail a comparison test, because they possess different catcode designations. –  Steven B. Segletes Apr 24 at 14:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.