2

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:

enter image description here

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.

3

enter image description here

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

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

enter image description here

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

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}

enter image description here

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

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.