# Coloring letters, or patterns, automatically

I'm dealing with some data that I would like to apply a automatic formatter. I'm trying to use the listings package in order to define a "language" that fits in my model, but I'm not having success.

For example, I would like to format this:

3 HHHHHHHHHHHHHHLLLHH  21
|||  |   |
3 LLHHHHHHHHHHHHLLLLL  21


To something like this:

I.e., the letter H with a specific color, letter L with another color and so on. It would be pretty simple if there is spaces between the letters, since

\lstdefinelanguage{MyKindOfLanguage}
{morekeywords={H,L,E},
sensitive=true,
}


Would recognize H, L and E as keywords, but in my case there is not spaces between those characters. Maybe I'm using the wrong package to do this, so I'm asking if there is a way to do this. If I would use regex to specify the patters it would be better. I could write a program to translate this code to a formated one using \textcolor, but I would like to let the compiler do this for me.

\documentclass{article}
\usepackage{color}

{
\catcodeH\active
\catcodeL\active
\catcode\ \active
\gdef\foo{%
\catcodeH\active
\catcodeL\active
\catcode\ \active
\ttfamily\obeylines\obeyspaces
\def {\ }%
\defH{\textcolor{magenta}{\stringH}}%
\defL{\textcolor{yellow}{\stringL}}%
}%
}%
\def\endfoo{\par}
\begin{document}

\begin{foo}
3 HHHHHHHHHHHHHHLLLHH  21
|||  |   |
3 LLHHHHHHHHHHHHLLLLL  21
\end{foo}

\end{document}

• Thanks! It works pretty well, but I'm getting this error: Undefined control sequence. ...2009/10/30 v1.6 Font defs for Latin Modern] – davidbuzatto Nov 17 '16 at 22:14
• @davidbuzatto oh just typeset anything before you start the environment, so the lmodern .fd file doesn't get loaded while L is active. – David Carlisle Nov 17 '16 at 22:30

Use listings's literate option to specify a search-and-replace for each of the letters you want to colour:

\documentclass{article}

\usepackage{listings,xcolor}
\lstnewenvironment{foo}[1][]
{\lstset{
basicstyle=\ttfamily,
literate={H}{{{\color{red!20!blue}H}}}1
{L}{{{\color{yellow!20!green}L}}}1,
#1
}}
{}

\begin{document}

\begin{foo}
3 HHHHHHHHHHHHHHLLLHH  21
|||  |   |
3 LLHHHHHHHHHHHHLLLLL  21
\end{foo}

\end{document}


A bit complex, but with a much friendlier interface for defining the colors:

\documentclass{article}
\usepackage{xparse,l3regex,xcolor}
\usepackage{lipsum}

\ExplSyntaxOn
\NewDocumentCommand{\foo}{}
{
\begin{flushleft}\ttfamily
% we need to make spaces active, so we let them to a skip
% the change is local to the flushleft environment
\char_set_active_eq:nN { \  } \buzatto_foo_space:
\char_set_catcode_active:n { \  }
\buzatto_foo_process:n
}
\NewDocumentCommand{\definefoocolor}{mm}
{
% store in a property list: <letter> -> <color>
\prop_gput:Nnn \g_buzatto_foo_prop { #1 } { #2 }
}

\tl_new:N \l_buzatto_foo_arg_tl
\prop_new:N \g_buzatto_foo_prop

\cs_new_protected:Nn \buzatto_foo_space:
{
\hspace*{.5em}
}
\cs_new_protected:Nn \buzatto_foo_process:n
{
\tl_set:Nn \l_buzatto_foo_arg_tl { #1 }
% process all the keys in the property list
\prop_map_inline:Nn \g_buzatto_foo_prop
{
% any run of the current letter is changed into
% \textcolor{<color>}{<run of letters>}
\regex_replace_all:nnN
{ (##1+) }
{ \c{textcolor}\cB\{##2\cE\}\cB\{\1\cE\} }
\l_buzatto_foo_arg_tl
}
% use the returned token list
\tl_use:N \l_buzatto_foo_arg_tl
\end{flushleft}
}
\ExplSyntaxOff

\definefoocolor{H}{red!20!blue}
\definefoocolor{L}{yellow!20!green}

\begin{document}

\lipsum[2]

\foo{
3 HHHHHHHHHHHHHHLLLHH  21 \\
|||  |   |        \\
3 LLHHHHHHHHHHHHLLLLL  21
}

\lipsum[3]

\end{document}


• Pretty nice! Worked like a charm too ;) – davidbuzatto Nov 18 '16 at 17:36