4

I was wondering if it was possible to color every second letter in a text string in LaTeX. I'm writing a report on decrypting a Vigenere cipher, and have a text string that I would like to have every alternate letter be colored differently.

So for example the string might be 'abcdefg', and I would like the output to show 'aceg' in blue and 'bdf' in red, or something like that. Is this easily feasible in LaTeX?

Thank you guys!

  • 1
    Did you mean automatically? The simple-but-tedious way with color package is just to do \textcolor{red}{a}\textcolor{blue}{b} etc – Thruston Jan 4 '16 at 18:35
  • 1
    Did you mean to use the luatex tag? Are you looking for a lua solution? – Thruston Jan 4 '16 at 18:37
  • And while I'm at it... Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. – Thruston Jan 4 '16 at 18:39
  • @Thruston Yes -- I advised OP to post this question here. It was originally posted on reddit where there are far fewer LuaTeX users. – Sean Allred Jan 4 '16 at 19:34
  • In ciphertext spaces are usually ignored. Is this your case? – egreg Jan 4 '16 at 23:30
8

Here's an expl3 version for alternating colours, but not for strings with whitespace (so far)

\documentclass{article}
\usepackage{xparse}

\usepackage[x11names]{xcolor}
\ExplSyntaxOn
\newcommand{\colorstring}[3]{% 
  \str_set:Nn \l_tmpa_str {#3}% store the string to a string variable
  % Now loop through the string variable and get each 'letter' 
  \int_step_inline:nnnn {1} {1} {\str_count:N \l_tmpa_str } {%
    \int_if_odd:nTF{##1}{% Is the number odd → use the first colour
      \textcolor{#1}{\str_item:Nn \l_tmpa_str {##1}}
    }{% No, use the 2nd colour
      \textcolor{#2}{\str_item:Nn \l_tmpa_str {##1}}
    }%
  }%
}
\ExplSyntaxOff

\begin{document}

\bfseries
\huge \colorstring{blue}{red}{abcdefgh}


\huge \colorstring{brown}{Green4}{ABCEDEFGH}

\end{document}

enter image description here

Another version, with alternating colours

... and providing more than two colours, as well as using in an environment. However, no empty lines are allowed! No real tests on printable characters are done so far.

\documentclass{article}
\usepackage{xparse}
\usepackage{environ}

\usepackage[x11names]{xcolor}
\ExplSyntaxOn

\NewDocumentCommand{\colorstring}{O{blue,red}+m}{%
  \clist_set:Nn \l_tmpa_clist {#1}%
  \int_zero:N \l_tmpa_int%
  \str_set:Nx \l_tmpa_str {#2}%
  \int_step_inline:nnnn {1} {1} {\str_count:N \l_tmpa_str } {%
    \str_case_x:nnF {\str_item:Nn \l_tmpa_str {##1}} {%
      {\space}{\space}
    }{%
      \int_compare:nNnTF {\l_tmpa_int } < {\clist_count:N \l_tmpa_clist } {
        \int_incr:N \l_tmpa_int
      }{%
        \int_set:Nn \l_tmpa_int {\c_one}
      }
      \textcolor{\clist_item:Nn \l_tmpa_clist {\l_tmpa_int }}{\str_item:Nn \l_tmpa_str {##1}}
    }
  }
}



\ExplSyntaxOff

\NewEnviron{ColorLettersInternal}[1]{\colorstring[#1]{\BODY}} % Internal environment for `\Body`

\NewDocumentEnvironment{ColorLetters}{O{blue,red}}{%
  \ttfamily%
  \ColorLettersInternal{#1}%
}{%
  \endColorLettersInternal%
}


\parindent=0pt
\begin{document}


\bfseries
\huge \colorstring{abcdefgh}
\huge \colorstring[brown,Green4,Aquamarine4]{ABCEDEFGH}

\colorstringnew[violet,Green4,Red4,Blue2]{TCGATGGAGGGACCAT}

\begin{ColorLetters}[Blue4,Red4,Green4,LightBlue4]
And now for something completely different
Number Three -- the Larch!
\end{ColorLetters}

\end{document}

enter image description here

  • Could this be adaptable to use as an environment? – Sean Allred Jan 4 '16 at 19:46
  • And couldn't you use \exp_args: to say \textcolor{\int_if_odd: ...}? – Sean Allred Jan 4 '16 at 19:47
  • @SeanAllred: I am still new to expl3 .... thanks for any suggestion. About the environment: Well, I must grab the environment body then, I assume? – user31729 Jan 4 '16 at 20:22
  • This works with color I guess, as well as xcolor. – Thruston Jan 4 '16 at 21:03
  • @Thruston: Of course, but the colornames may be different (I am not sure color provides the x11names` etc. color names sets) – user31729 Jan 4 '16 at 21:09
4

Here, I use a simple recursion, until the end of the string is reached.

\documentclass{article}
\usepackage{xcolor}
\newcommand\colorstring[3]{\def\colorA{#1}\def\colorB{#2}\colorstringhelp#3%
  \relax\relax\relax}
\def\colorstringhelp#1#2#3\relax{\textcolor{\colorA}{#1}\textcolor{\colorB}{#2}%
  \ifx\relax#3\else\colorstringhelp#3\relax\relax\fi}
\begin{document}%
\colorstring{blue}{red}{abcdef}\par
\colorstring{green}{orange}{abcdefg}
\end{document}

enter image description here

2

Since ciphertext is usually typeset without spaces, doing a mapping on the input is simple (and automatically gobbles spaces). With environ we can define an environment that collects its body.

\documentclass{article}
\usepackage{xparse}
\usepackage{environ}

\usepackage[x11names]{xcolor}

\ExplSyntaxOn

\seq_new:N \l_kaddon_colors_seq
\int_new:N \l_kaddon_color_int

\cs_new_protected:Nn \kaddon_color_string:nn
 {
  \seq_set_from_clist:Nn \l_kaddon_colors_seq { #1 }
  \int_zero:N \l_kaddon_color_int
  \tl_map_inline:nn { #2 } { \kaddon_color:n { ##1 } }
 }
\cs_generate_variant:Nn \kaddon_color_string:nn { nV }

\cs_new_protected:Nn \kaddon_color:n
 {
  \int_incr:N \l_kaddon_color_int
  \int_compare:nT { \l_kaddon_color_int > \seq_count:N \l_kaddon_colors_seq }
   { % exhausted colors, restart
    \int_set:Nn \l_kaddon_color_int { 1 }
   }
  \str_if_eq:nnTF { #1 } { \par }
   {
    \int_decr:N \l_kaddon_color_int
    \par
   }
   {
    \textcolor{\seq_item:Nn \l_kaddon_colors_seq { \l_kaddon_color_int } } { #1 }
    \hspace{0pt plus 0.1pt }
   }
 }

\NewDocumentCommand{\colorstring}{ O{red,blue} m }
 {
  \kaddon_color_string:nn { #1 } { #2 }
  \unskip % remove the last \hspace
 }

\NewEnviron{colorpar}[1][red,blue]
 {
  \begin{quote}
  \kaddon_color_string:nV { #1 } \BODY
  \end{quote}
 }
\ExplSyntaxOff

\begin{document}

\colorstring{abcdefgh}

\colorstring[red,red,blue]{abcd efgh}

\colorstring[brown,Green4,Aquamarine4]{ABCEDEFGH abcdef}

\begin{colorpar}[Blue4,Red4,Green4,LightBlue4]
And now for something completely different
And now for something completely different
And now for something completely different
And now for something completely different
\end{colorpar}

\begin{colorpar}
And now for something completely different
And now for something completely different

And now for something completely different
And now for something completely different
\end{colorpar}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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