Tell me more ×
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 want to highlight either a whole line of code in a listing, or a part of line (a subexpression) using background color (to not interfere with syntax highlighting).

I use lstlistings environment from 'listings' package.

share|improve this question
1  
(to not interfere with syntax highlighting) Does it have to be a background-color solution or would you also be happy with some text style applied "on top" of syntax highlighting (e.g., make the text color red while keeping boldface for keywords). – Daniel Dec 2 '11 at 16:26

2 Answers

Listings allow escaping to TeX, so you can put a box in the background:

\documentclass{standalone}
\usepackage{listings,xcolor}
\lstset{language=c,escapechar=|}
\begin{document}
\begin{lstlisting}
int main (int argc, char ** argv)
{
  |\makebox[0pt]{\color{yellow}\rule[-0.1ex]{30em}{2ex}}|printf("Hello, world\n");
  exit(0);
}
\end{lstlisting}
\end{document}

enter image description here

share|improve this answer

Here is one easy-to-use solution built on posts from this site.

Sources :

  1. Creating a zebra effect using listings
  2. Listing, zebra effect and broken lines
  3. Highlighting line ranges in a lstlisting: partial solution, but expansion issues

The code:

\documentclass[10pt,a4paper]{article}
    \usepackage[utf8x]{inputenc}
    \usepackage{ucs}
    \usepackage{amsmath}
    \usepackage{amsfonts}
    \usepackage{amssymb}

    \usepackage{xcolor}
    \usepackage{listings}

    \usepackage{pgf}
    \usepackage{pgffor}

% Define backgroundcolor
    \usepackage[
        style=1,
        skipbelow=\topskip,
        skipabove=\topskip
    ]{mdframed}

    \definecolor{bggray}{rgb}{0.85, 0.85, 0.85}
    \mdfsetup{
        leftmargin = 20pt,
        rightmargin = 20pt,
        backgroundcolor = bggray,
        middlelinecolor = black,
        roundcorner = 15
    }
    \BeforeBeginEnvironment{lstlisting}{\begin{mdframed}\vskip-.5\baselineskip}
    \AfterEndEnvironment{lstlisting}{\end{mdframed}}

    \makeatletter
%
% \btIfInRange{number}{range list}{TRUE}{FALSE}
%
% Test if int number <number> is element of a (comma separated) list of ranges
% (such as: {1,3-5,7,10-12,14}) and processes <TRUE> or <FALSE> respectively
%
        \newcount\bt@rangea
        \newcount\bt@rangeb

        \newcommand\btIfInRange[2]{%
            \global\let\bt@inrange\@secondoftwo%
            \edef\bt@rangelist{#2}%
            \foreach \range in \bt@rangelist {%
                \afterassignment\bt@getrangeb%
                \bt@rangea=0\range\relax%
                \pgfmathtruncatemacro\result{ ( #1 >= \bt@rangea) && (#1 <= \bt@rangeb) }%
                \ifnum\result=1\relax%
                    \breakforeach%
                    \global\let\bt@inrange\@firstoftwo%
                \fi%
            }%
            \bt@inrange%
        }

        \newcommand\bt@getrangeb{%
            \@ifnextchar\relax%
            {\bt@rangeb=\bt@rangea}%
            {\@getrangeb}%
        }

        \def\@getrangeb-#1\relax{%
            \ifx\relax#1\relax%
                \bt@rangeb=100000%   \maxdimen is too large for pgfmath
            \else%
                \bt@rangeb=#1\relax%
            \fi%
        }

%
% \btLstHL{range list}
%
        \newcommand{\btLstHL}[1]{%
            \btIfInRange{\value{lstnumber}}{#1}%
            {\color{blue!30}}%
            {\def\lst@linebgrd}%
        }%

%
% \btInputEmph[listing options]{range list}{file name}
%
        \newcommand{\btLstInputEmph}[3][\empty]{%
            \lstset{%
                linebackgroundcolor=\btLstHL{#2}%
                \lstinputlisting{#3}%
            }% \only
        }

% 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


\begin{document}

\begin{lstlisting}[
    language = C,
    linebackgroundcolor = {\btLstHL{4-6,9}},
]
/**
* Prints Hello World.
**/
#include <stdio.h>
}
int main(void) {
    printf("Hello World!");  
    return 0;
}
\end{lstlisting}

\end{document}

enter image description here

share|improve this answer
Was thinking about a similar solution, but realized that it will work only with highlighting full lines, not partial lines. Still very useful to have. One suggestion: can you make the sources on this site as part of the text (as opposed to part of the code) so that they are click able links, and post an image. – Peter Grill Dec 2 '11 at 18:16

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.