7

In Creating a zebra effect using listings, I've found one solution to produce a zebra effect for listing. Unfortunately, this only works if the lines are not broken. Is there a way to fix this?

Here is a code with an example showing the problem:

\documentclass[10pt,a4paper]{article}
    \usepackage[utf8x]{inputenc}
    \usepackage{ucs}
    \usepackage[T1]{fontenc}
    \usepackage{lmodern}
    \usepackage[frenchb]{babel}
    \usepackage[x11names, svgnames]{xcolor}
    \usepackage{graphicx}
    \usepackage{listings}
    \usepackage{amsfonts}
    \usepackage{amssymb}

    \makeatletter
        % Patch line number key to call line background macro
        \lst@Key{numbers}{none}{%
            \def\lst@PlaceNumber{\lst@linebgrd}%
            \lstKV@SwitchCases{#1}%
            {none&\\%
             left&\def\lst@PlaceNumber{\llap{\normalfont
                        \lst@numberstyle{\thelstnumber}\kern\lst@numbersep}\lst@linebgrd}\\%
             right&\def\lst@PlaceNumber{\rlap{\normalfont
                        \kern\linewidth \kern\lst@numbersep
                        \lst@numberstyle{\thelstnumber}}\lst@linebgrd}%
            }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}}

        % New keys
        \lst@Key{linebackgroundcolor}{}{%
            \def\lst@linebgrdcolor{#1}%
        }
        \lst@Key{linebackgroundsep}{0pt}{%
            \def\lst@linebgrdsep{#1}%
        }
        \lst@Key{linebackgroundwidth}{\linewidth}{%
            \def\lst@linebgrdwidth{#1}%
        }
        \lst@Key{linebackgroundheight}{\ht\strutbox}{%
            \def\lst@linebgrdheight{#1}%
        }
        \lst@Key{linebackgrounddepth}{\dp\strutbox}{%
            \def\lst@linebgrddepth{#1}%
        }
        \lst@Key{linebackgroundcmd}{\color@block}{%
            \def\lst@linebgrdcmd{#1}%
        }


        % Line Background macro
        \newcommand{\lst@linebgrd}{%
            \ifx\lst@linebgrdcolor\empty\else
            \rlap{%
                \lst@basicstyle
                \color{-.}% By default use the opposite (`-`) of the current color (`.`) as background
                \lst@linebgrdcolor{%
                \kern-\dimexpr\lst@linebgrdsep\relax%
                \lst@linebgrdcmd{\lst@linebgrdwidth}{\lst@linebgrdheight}{\lst@linebgrddepth}%
                }%
            }%
            \fi
        }
    \makeatother

    \lstset{
%    * Number for lines
        numbers=left,                   % Where to put the line-numbers
        numberstyle=\footnotesize,      % Size of the fonts used for the line-numbers
        stepnumber=1,                   % Step between two numbers
        numbersep=5pt,                  % How far the line-numbers are from the code
%
%    * Back returns for long lines
        breaklines=true,                % Sets automatic line breaking
        breakatwhitespace=false,        % Automatic breaks only happen at whitespace ?
        breakindent=0pt,                % Space before the text of a break
        postbreak=\mbox{                % Character used at the begining of a break
            \rotatebox[y=0.9ex]{180}{\color{Red} $\Lsh$}%
        },
    }

\begin{document}

\begin{lstlisting}[language=Python,linebackgroundcolor={\ifodd\value{lstnumber}\color{gray}\fi}]
for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5):
    sum += i**3
print sum

print('Fin de la boucle...')
\end{lstlisting}

\end{document}
2
  • 1
    I think this has nothing to do with the zebra. The cause seems to be the \rotatebox inside the postbreak= definition. Try to provide a minimal working example before asking. Commented Jul 25, 2011 at 12:44
  • Ah sorry! I understand the problem now. I have another issue on my side. Commented Jul 25, 2011 at 12:53

1 Answer 1

7

You can add a second colored bar as part of the postbreak code as shown below. However, I couldn't get the \color{-.} command working there, so I used \color{white} which works fine in this particular example, but should be replaced by a variable in the general case.

\documentclass[10pt,a4paper]{article}
    \usepackage[utf8x]{inputenc}
    \usepackage{ucs}
    \usepackage[T1]{fontenc}
    \usepackage{lmodern}
    \usepackage[frenchb]{babel}
    \usepackage[x11names, svgnames]{xcolor}
    \usepackage{graphicx}
    \usepackage{listings}
    \usepackage{amsfonts}
    \usepackage{amssymb}

    \makeatletter
        % Patch line number key to call line background macro
        \lst@Key{numbers}{none}{%
            \def\lst@PlaceNumber{\lst@linebgrd}%
            \lstKV@SwitchCases{#1}%
            {none&\\%
             left&\def\lst@PlaceNumber{\llap{\normalfont
                        \lst@numberstyle{\thelstnumber}\kern\lst@numbersep}\lst@linebgrd}\\%
             right&\def\lst@PlaceNumber{\rlap{\normalfont
                        \kern\linewidth \kern\lst@numbersep
                        \lst@numberstyle{\thelstnumber}}\lst@linebgrd}%
            }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}}

        % New keys
        \lst@Key{linebackgroundcolor}{}{%
            \def\lst@linebgrdcolor{#1}%
        }
        \lst@Key{linebackgroundsep}{0pt}{%
            \def\lst@linebgrdsep{#1}%
        }
        \lst@Key{linebackgroundwidth}{\linewidth}{%
            \def\lst@linebgrdwidth{#1}%
        }
        \lst@Key{linebackgroundheight}{\ht\strutbox}{%
            \def\lst@linebgrdheight{#1}%
        }
        \lst@Key{linebackgrounddepth}{\dp\strutbox}{%
            \def\lst@linebgrddepth{#1}%
        }
        \lst@Key{linebackgroundcmd}{\color@block}{%
            \def\lst@linebgrdcmd{#1}%
        }


        % Line Background macro
        \newcommand{\lst@linebgrd}{%
            \ifx\lst@linebgrdcolor\empty\else
            \rlap{%
                \lst@basicstyle
                \color{-.}% By default use the opposite (`-`) of the current color (`.`) as background
                \lst@linebgrdcolor{%
                \kern-\dimexpr\lst@linebgrdsep\relax%
                \lst@linebgrdcmd{\lst@linebgrdwidth}{\lst@linebgrdheight}{\lst@linebgrddepth}%
                }%
            }%
            \fi
        }
        \newcommand{\lst@linebreakbgrd}{%
            \ifx\lst@linebgrdcolor\empty\else
            \rlap{{%
               \lst@basicstyle
               \color{white}% By default use the opposite (`-`) of the current color (`.`) as background
               \lst@linebgrdcolor{%
               \lst@linebgrdcmd{\lst@linebgrdwidth}{\lst@linebgrdheight}{\lst@linebgrddepth}%
               }%
            }}%
            \fi
        }
    \makeatother

    \lstset{
%    * Number for lines
        numbers=left,                   % Where to put the line-numbers
        numberstyle=\footnotesize,      % Size of the fonts used for the line-numbers
        stepnumber=1,                   % Step between two numbers
        numbersep=5pt,                  % How far the line-numbers are from the code
%
%    * Back returns for long lines
        breaklines=true,                % Sets automatic line breaking
        breakatwhitespace=false,        % Automatic breaks only happen at whitespace ?
        breakindent=0pt,                % Space before the text of a break
        postbreak={%
           \mbox{%               % Character used at the begining of a break
               \lst@linebreakbgrd
               \rotatebox[y=0.9ex]{180}{\color{Red} $\Lsh\,$}%
           }},
    }

\begin{document}

\begin{lstlisting}[language=Python,linebackgroundcolor={\ifodd\value{lstnumber}\color{gray}\fi}]
for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5):
for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5):
for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5):
for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5): for i in range(5):
    sum += i**3
print sum

print('Fin de la boucle...')
\end{lstlisting}

\end{document}

Result

3
  • Do you get the same alignment of the shaded areas, when the numbers on the left of each line go from 9 to 10, and from 99 to 100 or from 999 to 1000, mine get pushed across. Commented May 11, 2013 at 10:49
  • awesome code! But when I use it in my diploma thesis, the grey Background starts after the postbreak sign and runs over the right edge of the listing: !enter image description here Any help would be appreciated
    – user37183
    Commented Sep 24, 2013 at 11:44
  • @PatrickA.: I would need a compilable minimal working example (MWE) from you to identify that issue in order to fix it. You could either post it as part of a follow-up question here or, better, sent it me by email. See scharrer-online.de/wiki/MySelf for the address. Commented Sep 25, 2013 at 17:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .