Colorear letras o patrones automáticamente

Colorear letras o patrones automáticamente

Estoy tratando con algunos datos a los que me gustaría aplicar un formateador automático. Estoy intentando utilizar el paquete de listados para definir un "lenguaje" que se ajuste a mi modelo, pero no lo consigo.

Por ejemplo, me gustaría formatear esto:

3 HHHHHHHHHHHHHHLLLHH  21
        |||  |   |   
3 LLHHHHHHHHHHHHLLLLL  21

A algo como esto:

ingrese la descripción de la imagen aquí

Es decir, la letra H con un color concreto, la letra L con otro color y así sucesivamente. Sería bastante sencillo si hubiera espacios entre las letras, ya que

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

Reconocería H, L y E como palabras clave, pero en mi caso no hay espacios entre esos caracteres. Quizás estoy usando el paquete incorrecto para hacer esto, así que pregunto si hay alguna manera de hacerlo. Si usara expresiones regulares para especificar los patrones, sería mejor. Podría escribir un programa para traducir este código a uno formateado usando \textcolor, pero me gustaría dejar que el compilador haga esto por mí.

Respuesta1

ingrese la descripción de la imagen aquí

\documentclass{article}
\usepackage{color}

{
\catcode`H\active
\catcode`L\active
\catcode`\ \active
\gdef\foo{%
\catcode`H\active
\catcode`L\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}

Respuesta2

UsarlistingsLa literateopción de especificar una búsqueda y reemplazo para cada una de las letras que desea colorear:

ingrese la descripción de la imagen aquí

\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}

Respuesta3

Un poco complejo, pero con una interfaz mucho más amigable para definir los colores:

\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}

ingrese la descripción de la imagen aquí

información relacionada