Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm working on a project where I want to display an amino acid sequence. I want to let tex decide where to put the line breaks, but it doesn't seem to work in conjunction with highlighting certain parts of the sequence using colorbox.

This is how it currently looks like

The following source code produces the above image.

\begin{lstlisting}[escapechar=!]
>unknown protein sequence
!\colorbox{red}{MELFMKNSSLWGLKFYLFCLFIILSNINRAFASHNIFLDLQSS}!SAISVKNVHRTRFHFQPPKHWINDPNAP!\colorbox{red}{MYYNG}!!\colorbox{red}{VY}!HLFYQYNPKGSVWGNIIWAHSVSKDLINWIHLEPAIY!\colorbox{red}{PSKKFDKYGTWSGSSTILPNNKPVIIYTGVVDSYNNQVQNYAIPANLSDPFLRKWIKPNNNPL}!IVPDNSINRTEFRDPTTA!\colorbox{red}{WMGQDGLWRILIASMRKHRGMALLYRSRDFMKWIKAQ}!!\colorbox{red}{HPLHSSTN}!!\colorbox{red}{TGNWECPDFFPVLFNSTNGLDVSYR}!GKNVKYVLKNSLDVARFD!\colorbox{red}{YYTIGMYHTKIDRYIPNNNSIDGWKGL}!RIDYGNFYASKTFYDPSRNRRVIWGWSNESDVLPDDEIKKGWAGIQGIPRQVWLNLSGKQLLQWPIEELE!\colorbox{red}{TLRKQKVQLNNKKLSKGEM}!FEVKGISASQADVEVLFSFSSLNEAEQFDPRWADLYAQDVCAIKG!\colorbox{red}{STIQGGLGPFGLVTLASKNLEEYTPVFFRVFKAQKSYKILM}!!\colorbox{red}{CSDARR}!SSMR!\colorbox{red}{QNEAMYKPSFAGYVDVDLEDMKKLSLRSLIDNSVVESFGAGGKTCITSRVYPTLAIYDNAHLFVFNNGSETITIETLNAWSMDACKMN}!
\end{lstlisting}

using following options

\lstset{breaklines=true,breakatwhitespace=false}

Manually adding the line break is out of the question. Any help is greatly appreciated

share|improve this question
1  
If manually adding the line break is out of the question, how are you generating the latex code? –  A.Ellett Dec 1 '12 at 19:26
    
Not directly related: you might be interested in the texshade package –  cgnieder Dec 1 '12 at 19:50
    
@A.Ellett: The code is generated using a python script. I don't know how this is relevant to my problem? I thought there might be a way to force a line break when using a colorbox. Manually line breaking while in colorbox mode also results in an error. A solution would be to also wrap the colorbox calls, but again manual work is not what I'm looking for. I have a bunch of sequences which I want to display in this manner. –  anopheles Dec 1 '12 at 19:56
1  
@anopheles, that's what I was wondering about. If it's generated by python, then why not have python create the line breaks that you need? I'm no expert in python, but I do use perl to create text like what you have, and I often have perl take care of icky details like this. I know it's not a LaTeX solution, but it might be another way to think about this. –  A.Ellett Dec 1 '12 at 19:58
2  
Even without color, lstlistings can't put line breaks in your sequence! –  Paul Gaborit Dec 2 '12 at 1:13

2 Answers 2

up vote 5 down vote accepted

See the bottom of this answer for a method not using any package.

Update: see the bottom of the bottom for a more flexible yet environment.

(the update has been updated)


Using alltt rather than listings and some modifications in your input:

  1. replace \colorbox by \ccolorbox (to use some macro defined next)
  2. replace the ! at the start of non colored segments by \!
  3. get rid of all other !

Here is the code snippet:

\documentclass{article}

\def\cccolorbox#1#2{\ifx#2\relax\let\next\allowbreak\else
       \def\next{\colorbox{#1}{#2}\allowbreak\cccolorbox{#1}}\fi\next}
\def\ccolorbox#1#2{\fboxsep0pt\cccolorbox{#1}#2\relax}

\def\!#1{\ifx#1\ccolorbox\allowbreak\expandafter\ccolorbox\else
         \ifx#1\end\expandafter\expandafter\expandafter\end\else
         #1\allowbreak\expandafter\expandafter\expandafter\!\fi\fi}

\usepackage{alltt}
\usepackage{color}
\begin{document}\pagestyle{empty}
\begin{alltt}
>unknown protein sequence
\ccolorbox{red}{MELFMKNSSLWGLKFYLFCLFIILSNINRAFASHNIFLDLQSS}\!SAISVKNVHRTRFHFQPPKHWINDPNAP\ccolorbox{red}{MYYNG}\ccolorbox{red}{VY}\!HLFYQYNPKGSVWGNIIWAHSVSKDLINWIHLEPAIY\ccolorbox{red}{PSKKFDKYGTWSGSSTILPNNKPVIIYTGVVDSYNNQVQNYAIPANLSDPFLRKWIKPNNNPL}\!IVPDNSINRTEFRDPTTA\ccolorbox{red}{WMGQDGLWRILIASMRKHRGMALLYRSRDFMKWIKAQ}\ccolorbox{red}{HPLHSSTN}\ccolorbox{red}{TGNWECPDFFPVLFNSTNGLDVSYR}\!GKNVKYVLKNSLDVARFD\ccolorbox{red}{YYTIGMYHTKIDRYIPNNNSIDGWKGL}\!RIDYGNFYASKTFYDPSRNRRVIWGWSNESDVLPDDEIKKGWAGIQGIPRQVWLNLSGKQLLQWPIEELE\ccolorbox{red}{TLRKQKVQLNNKKLSKGEM}\!FEVKGISASQADVEVLFSFSSLNEAEQFDPRWADLYAQDVCAIKG\ccolorbox{red}{STIQGGLGPFGLVTLASKNLEEYTPVFFRVFKAQKSYKILM}\ccolorbox{red}{CSDARR}\!SSMR\ccolorbox{red}{QNEAMYKPSFAGYVDVDLEDMKKLSLRSLIDNSVVESFGAGGKTCITSRVYPTLAIYDNAHLFVFNNGSETITIETLNAWSMDACKMN}
\end{alltt}
\end{document}

result of the proposal code

And to avoid having irregular boxes, use an additional \strut:

\def\cccolorbox#1#2{\ifx#2\relax\let\next\allowbreak\else
   \def\next{\colorbox{#1}{\strut #2}\allowbreak\cccolorbox{#1}}\fi\next}

result of adding a strut

(the ABC at the end is because I added \!ABC for testing purposes at the end of the protein sequence)

One may also question the need for an alltt environment. Just using a \ttfamily (with a \\ after ''unknown protein sequence'') should be enough (with some modification to the \! code which in its current version checks for an \end).


Here is now a solution along those lines. It does not use any package (apart from color). Put this in the preamble

\catcode`\?=\active\catcode`\!=\active
\newenvironment{proteinlisting}
{\fboxsep0pt\catcode`\?=\active\catcode`\!=\active
\def!##1{\ifx##1!\let\next!\else
        \ifx##1?\let\next?\else
        \ifx##1\end\let\next\end\else
        ##1\allowbreak\let\next!\fi\fi\fi\next}%
\def?##1{\ifx##1!\let\next!\else
        \ifx##1?\let\next?\else
        \ifx##1\end\let\next\end\else
        \colorbox{red}{\strut ##1}\allowbreak\let\next?\fi\fi\fi\next}%
\ttfamily}{\par}
\catcode`\?=12 \catcode`\!=12

Then prefix with ? colored segments of your sequence and with ! uncolored ones inside a proteinlisting environment:

\begin{proteinlisting}
\noindent>unknown protein sequence\\
\noindent?MELFMKNSSLWGLKFYLFCLFIILSNINRAFASHNIFLDLQSS!SAISVKNVHRTRFHFQPPKHWINDPNAP?MYYNG?VY!HLFYQYNPKGSVWGNIIWAHSVSKDLINWIHLEPAIY?PSKKFDKYGTWSGSSTILPNNKPVIIYTGVVDSYNNQVQNYAIPANLSDPFLRKWIKPNNNPL!IVPDNSINRTEFRDPTTA?WMGQDGLWRILIASMRKHRGMALLYRSRDFMKWIKAQ?HPLHSSTN?TGNWECPDFFPVLFNSTNGLDVSYR!GKNVKYVLKNSLDVARFD?YYTIGMYHTKIDRYIPNNNSIDGWKGL!RIDYGNFYASKTFYDPSRNRRVIWGWSNESDVLPDDEIKKGWAGIQGIPRQVWLNLSGKQLLQWPIEELE?TLRKQKVQLNNKKLSKGEM!FEVKGISASQADVEVLFSFSSLNEAEQFDPRWADLYAQDVCAIKG?STIQGGLGPFGLVTLASKNLEEYTPVFFRVFKAQKSYKILM?CSDARR!SSMR?QNEAMYKPSFAGYVDVDLEDMKKLSLRSLIDNSVVESFGAGGKTCITSRVYPTLAIYDNAHLFVFNNGSETITIETLNAWSMDACKMN
\end{proteinlisting}

The output is the same as in the previous proposal. The environment may be customized to use other colors and more markers, for different colors, just imitate the code.


Ok, here is one such final variant. In the preamble of the document:

\catcode`\?=\active \catcode`\!=\active
\newenvironment{proteinseqlst}[1][60]
{\fboxsep0pt \catcode`\?=\active \catcode`\!=\active
\ttfamily
\setbox0=\hbox{A}\hsize=\wd0 \multiply\hsize by #1\relax
\def!##1{\ifx##1!\let\next!\else
        \ifx##1?\let\next?\else
        \ifx##1\end\let\next\end\else
        ##1\allowbreak\let\next!\fi\fi\fi\next}%
\def?##1##2{\ifx##2!\let\next!\else
        \ifx##2?\let\next?\else
        \ifx##2\end\let\next\end\else
        \colorbox{##1}{\strut ##2}\allowbreak\def\next{?{##1}}\fi\fi\fi\next}%
}{\par}
\catcode`\?=12 \catcode`\!=12

This environment typesets the amino acid sequences with a number of letters per line indicated as an optional parameter (hence withing square brackets). The default is 60. Line breaks in the source are allowed and have no influence on the output (no empty line though, else an error will be raised on the tex run).

This environment allows arbitrary colors. One puts the desired colors within braces after a ?. One prefixes uncolored segments with a !. Note that the xcolor syntax as in ?{yellow!20} is allowed, the ! inside the braces will be treated by xcolor, not by the environment definition.

And the tex run produces no overfull boxes warnings in the log file.

With the following input (arbitrarily here 53 characters per input line, has no influence on the output):

\begin{proteinseqlst}[40]
\noindent>unknown protein sequence\\
\noindent
?{yellow}MELFMKNSSLWGLKFYLFCLFIILSNINRAFASHNIFLDLQSS!
SAISVKNVHRTRFHFQPPKHWINDPNAP?{blue}MYYNG?{green}VY!HL
FYQYNPKGSVWGNIIWAHSVSKDLINWIHLEPAIY?{red}PSKKFDKYGTWS
GSSTILPNNKPVIIYTGVVDSYNNQVQNYAIPANLSDPFLRKWIKPNNNPL!I
VPDNSINRTEFRDPTTA?{green}WMGQDGLWRILIASMRKHRGMALLYRSR
DFMKWIKAQ?{yellow}HPLHSSTN?{blue}TGNWECPDFFPVLFNSTNGL
DVSYR!GKNVKYVLKNSLDVARFD?{yellow}YYTIGMYHTKIDRYIPNNNS
IDGWKGL!RIDYGNFYASKTFYDPSRNRRVIWGWSNESDVLPDDEIKKGWAGI
QGIPRQVWLNLSGKQLLQWPIEELE?{blue}TLRKQKVQLNNKKLSKGEM!F
EVKGISASQADVEVLFSFSSLNEAEQFDPRWADLYAQDVCAIKG?{red}STI
QGGLGPFGLVTLASKNLEEYTPVFFRVFKAQKSYKILM?{blue}CSDARR!S
SMR?{red}QNEAMYKPSFAGYVDVDLEDMKKLSLRSLIDNSVVESFGAGGKT
CITSRVYPTLAIYDNAHLFVFNNGSETITIETLNAWSMDACKMN
\end{proteinseqlst}

the output is:

example with 40 letters per line

share|improve this answer
    
Adding a \strut to text being highlighted in \cccolorbox should fix the problem where lines with descenders looks wacky (see the second last line near the Q. Oh, this also produces Overfull \hbox messages. –  Peter Grill Dec 2 '12 at 21:55
    
@PeterGrill thanks for the hint! I was editing my code to this effect when you sent your comment. Will check for the overfull boxes. –  jfbu Dec 2 '12 at 21:58
    
@PeterGrill: the overfull boxes do not seem to be related to the strut's, they are overfull boxes from the paragraph breaking into horizontal lines. –  jfbu Dec 2 '12 at 22:04
    
@PeterGrill: adding \hfuzz2pt removes the overfull boxes messages to the log... (it all depends on the ratio of the text width to the width of a character from the monospaced font not being an integer) –  jfbu Dec 2 '12 at 22:11

Here's my quick & dirty solution in python

def protein_to_listing(protein_sequence, contaminated_indexes, max_line_length=50):
    lines = collections.defaultdict(str)
    ref_lines = collections.defaultdict(str)
    index = 0

    for aa_index, aa in enumerate(protein_sequence):
        contaminated = aa_index in contaminated_indexes

        if len(ref_lines[index]) == max_line_length:
            index += 1

        if contaminated:
            lines[index] += aa
        else:
            lines[index] += "!\colorbox{green}{%s}!" % aa

        ref_lines[index] += aa

    return lines

Here's the result:enter image description here

Unfortunately, the lines aren't right aligned. It seems as if the colorbox was adding a little bit of space.

share|improve this answer
    
I don't know if this is relevant but \colorbox uses the value of \fboxsep. Use \fboxsep0pt to get rid of extra space. –  jfbu Dec 2 '12 at 20:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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