Colorir letras ou padrões automaticamente

Colorir letras ou padrões automaticamente

Estou lidando com alguns dados que gostaria de aplicar um formatador automático. Estou tentando utilizar o pacote lists para definir uma "linguagem" que caiba no meu modelo, mas não estou tendo sucesso.

Por exemplo, eu gostaria de formatar isto:

3 HHHHHHHHHHHHHHLLLHH  21
        |||  |   |   
3 LLHHHHHHHHHHHHLLLLL  21

Para algo assim:

insira a descrição da imagem aqui

Ou seja, a letra H com uma cor específica, a letra L com outra cor e assim por diante. Seria bem simples se houvesse espaços entre as letras, já que

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

Reconheceria H, L e E como palavras-chave, mas no meu caso não há espaços entre esses caracteres. Talvez eu esteja usando o pacote errado para fazer isso, então estou perguntando se existe uma maneira de fazer isso. Se eu usasse regex para especificar os padrões, seria melhor. Eu poderia escrever um programa para traduzir esse código para um código formatado usando \textcolor, mas gostaria de deixar o compilador fazer isso por mim.

Responder1

insira a descrição da imagem aqui

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

Responder2

UsarlistingsA opção de literateespecificar uma pesquisa e substituição para cada uma das letras que você deseja colorir:

insira a descrição da imagem aqui

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

Responder3

Um pouco complexo, mas com uma interface bem mais amigável para definição das cores:

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

insira a descrição da imagem aqui

informação relacionada