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.

Martin Scharrer posted a very elegant answer for the question "Creating a zebra effect using listings". I want to extend that code to highlight only lines given in a comma separated list. The motivations is that I want to highlight certain lines of fully functional C code inputed from a file without using any escape chars

That means that I need a command

\ifinrange{<num>}{<range>}{<TRUE>}{<FALSE>}% num>=0

where range {-2,4,8-10, 15-} is {0,1,2,4,8,9,10,15,16,...}

\ifinrange{ 0}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE
\ifinrange{ 3}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> FALSE
\ifinrange{ 4}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE
\ifinrange{ 9}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE    %% EDIT: changed 7 to 9
\ifinrange{11}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> FALSE
\ifinrange{20}{-2,4,8-10, 15-}{TRUE}{FALSE}  -> TRUE

The following code

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{beramono}
\usepackage{listings}
\usepackage{xcolor}
\makeatletter
\newcommand\realnumberstyle[1]{}
\newcommand{\HighLight}[3]{%
    {\realnumberstyle{#3}}%
    \begingroup
    \lst@basicstyle
    \ifinrange{\value{lstnumber}}{#2}{%
        \color{#1}%
        \rlap{\hspace*{\lst@numbersep}%
        \color@block{\linewidth}{\ht\strutbox}{\dp\strutbox}}}{}%
    \endgroup}
\newcommand{\ifinrange}[4]{}%%<<<<<<<<<<<<<<<<<
\makeatother
\begin{document}
\begin{lstlisting}[language=C,
                   basicstyle=\ttfamily,
                   numberstyle=\HighLight{green!35}{-3,6},
                   numbers=left]
/**
* Prints Hello World.
**/
#include <stdio.h>

int main(void) {
   printf("Hello World!");
   return 0;
}
\end{lstlisting}
\end{document}

must produce

enter image description here

share|improve this question
    
I would name this question more after the inline macro required. The exact application is only secondary here. –  Martin Scharrer May 25 '11 at 6:47
    
@Martin Scharrer: You are right. I have changed the title –  Danie Els May 25 '11 at 7:29
    
\ifinrange{ 7}{-2,4,8-10, 15-}{TRUE}{FALSE} -> TRUE should be FALSE instead. –  Martin Scharrer May 25 '11 at 8:06
add comment

1 Answer

up vote 10 down vote accepted

Here a basic solution which works with your input. It might break on spaces at the wrong positions, so avoid them.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{beramono}
\usepackage{listings}
\usepackage{xcolor}
\makeatletter
\newcommand\realnumberstyle[1]{}
\newcommand{\HighLight}[3]{%
    {\realnumberstyle{#3}}%
    \begingroup
    \lst@basicstyle
    \ifinrange{\value{lstnumber}}{#2}{%
        \color{#1}%
        \rlap{\hspace*{\lst@numbersep}%
        \color@block{\linewidth}{\ht\strutbox}{\dp\strutbox}}}{}%
    \endgroup}

\usepackage{pgf}
\usepackage{pgffor}

\newcount\rangea
\newcount\rangeb

\newcommand\ifinrange[2]{%
    \global\let\inrange\@secondoftwo
    \foreach \range in {#2} {%
        \afterassignment\getrangeb
        \rangea=0\range\relax
        \pgfmathtruncatemacro\result{ ( #1 >= \rangea) && (#1 <= \rangeb) }%
        \ifnum\result=1\relax
            \breakforeach
            \global\let\inrange\@firstoftwo
        \fi
    }%
    \inrange
}
\newcommand\getrangeb{%
    \@ifnextchar\relax
        {\rangeb=\rangea}%
        {\@getrangeb}%
}
\def\@getrangeb-#1\relax{%
    \ifx\relax#1\relax
        \rangeb=100000%   \maxdimen is too large for pgfmath
    \else
        \rangeb=#1\relax
    \fi
}

\makeatother
\begin{document}
\begin{lstlisting}[language=C,
                   basicstyle=\ttfamily,
                   numberstyle=\HighLight{green!35}{-3,6},
                   numbers=left]
/**
* Prints Hello World.
**/
#include <stdio.h>

int main(void) {
   printf("Hello World!");
   return 0;
}
\end{lstlisting}
\end{document}

Result

share|improve this answer
1  
I'd do also \global\let\inrange\@secondoftwo, to prevent save stack buildup. –  egreg May 25 '11 at 8:25
    
@egreg: Indeed. Thanks. –  Martin Scharrer May 25 '11 at 8:28
add comment

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.