37

I have a bunch of code in a lstlisting environment. How can I highlight (color background) just a particular chunk of code within the environment?

Ryan R. Rosario
  • 5,114
  • 9
  • 41
  • 56
  • 3
    In the future, please ask LaTeX-related questions at: https://tex.stackexchange.com. – 0 _ Dec 30 '17 at 11:47
  • 5
    @IoannisFilippidis That would have been useful to know... 8 years ago. – Ryan R. Rosario Dec 31 '17 at 05:57
  • There is a [package](http://mirror.las.iastate.edu/tex-archive/macros/latex/contrib/lstaddons/lstlinebgrd.pdf) called `lstlinebgrd` that does this, the only caveat is that it does not read the length of the texts automatically. – zyy Jul 04 '20 at 22:43
  • [This](https://tex.stackexchange.com/questions/593230/annotate-listing-with-overlays) uses overlays to highlight chunks of a listing. – Matthias Braun Apr 17 '21 at 16:50

5 Answers5

48

You can use \colorbox and an escape character inside your listing:

Add to your preamble

  \usepackage{color}

  \definecolor{light-gray}{gray}{0.80}

then use it like this in your document:

  \begin{lstlisting}[escapechar=!]
  def mult(m: Matrix[Int], n: Matrix[Int]) {
    val p = !\colorbox{light-gray}{new MatrixInt}!(m.rows, n.cols)
  }
  \end{lstlisting}
Iulian Dragos
  • 5,692
  • 23
  • 31
  • I need something extra. I am using Beamer package for my presentation and I have to highlight code present in lstlisting. The difference in my need is I can't change the code inside lstlisting, like escaping or having special comment definition. The code is present inside a different file which can't be changed. Copying the code and making modifications is not an option as there are many of them. Can we indicate from outside (i.e. in \begin{lstlisting}) which lines to highlight? – thequark Jul 20 '10 at 11:22
  • 8
    Nice but it doesn't work with multiple lines and you are losing the syntax highlighting inside a `colorbox`. – Julian Apr 26 '11 at 09:28
  • When using LaTeX Beamer I had to mark the frame as fragile with `\begin{frame}[fragile]` to make it work. – MKroehnert Feb 07 '13 at 16:30
  • 1
    Works great! Anyway, somehow I got the error `latex undefined color model` when changing colors to `\definecolor{light-green}{green}{0.80}`. That's why I switched to `\definecolor{lightgreen}{rgb}{0.8,1.0,0.8}` instead. Hope it helps anyone. – Michael Jan 18 '16 at 00:28
13

It's a bit cumbersome, but you can break the code into several lstlisting environments.

\begin{lstlisting}
line
\end{lstlisting}
\vspace{-\baselineskip}
\begin{lstlisting}[backgroundcolor=\color{pink}]
very
interesting
\end{lstlisting}
\vspace{-\baselineskip}
\begin{lstlisting}
line
line
\end{lstlisting}
0 _
  • 10,524
  • 11
  • 77
  • 109
Anton Geraschenko
  • 1,409
  • 2
  • 11
  • 20
  • 1
    Will this work if you've got, for example, line numbers, or will they get restarted? – Edd Aug 21 '09 at 19:06
  • 1
    @Edd: By default, they will get restarted, but you can use the `firstnumber` keyword to fix that. In this example, you'd use `firstnumber=2` and `firstnumber=4` in the second and third `lstlisting` environments, respectively. Using `firstnumber=last` is supposed to continue the numbering from the previous `lstlisting` environment, but when I try it, it's off by one. – Anton Geraschenko Aug 21 '09 at 19:52
  • 3
    It turns out there's an even better solution to the numbering problem: use the `name` keyword (eg `\begin{lstlisting}[name=asdf, ...`). The name doesn't get displayed, and `lstlisting` environments with the same name share a line counter by default. – Anton Geraschenko Aug 21 '09 at 20:11
  • this works with multiple lines and the syntax highlighting get preserved. Anyone knows if this can be encapsulated in a `newcommand` or `newenvironment` ? – Julian Apr 26 '11 at 11:18
  • `\vspace{-\baselineskip}` didn't work for me to suppress separation between each block. Setting options `aboveskip=0` and `belowskip=0` as needed did. – Gohu Jul 26 '11 at 16:02
  • lstlisting doesnot work with TexLive 2021 – sepideha Oct 10 '21 at 19:33
2

Here's a solution for highlighting (parts of) individual lines using tikz:

\documentclass[pdftex,11pt,a4paper]{article}

\usepackage{listings}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

% Command to place a TikZ anchor at the current position
\newcommand{\mytikzmark}[1]{%
  \tikz[overlay,remember picture,baseline] \coordinate (#1) at (0,0) {};}

\newcommand{\highlight}[2]{%
  \draw[yellow,line width=14pt,opacity=0.3]%
    ([yshift=4pt]#1) -- ([yshift=4pt]#2);%
}

\begin{document}
    \begin{lstlisting}[escapechar=@, language=C]
@\mytikzmark{hl1Start}@struct@\mytikzmark{hl1End}@ S {
    double @\mytikzmark{hl2Start}@salary_@\mytikzmark{hl2End}@;
};
    \end{lstlisting}
        
    \begin{tikzpicture}[remember picture, overlay]
        \highlight{hl1Start}{hl1End}
        \highlight{hl2Start}{hl2End}
    \end{tikzpicture}   
        
\end{document}

and you get

enter image description here

so the lstlisting's syntax highlighting is retained.

Paweł Kłeczek
  • 603
  • 1
  • 5
  • 28
1

There is a package called lstlinebgrd that does this

% !TEX encoding = UTF-8 Unicode
% !TEX TS-program = xelatex
\documentclass{article}
\usepackage[a4paper]{geometry}

\usepackage{lstlinebgrd}
\usepackage{listings, xcolor}
\lstset{tabsize = 4, showstringspaces = false, breaklines = true, numbers = left, numberstyle = \tiny, basicstyle = \small \ttfamily, keywordstyle = \color{blue}, stringstyle = \color{red}, commentstyle = \color{green}, rulecolor = \color{black}}

\begin{document}

\begin{lstlisting}[language = python, frame = tRBl, basicstyle = \ttfamily \scriptsize, linebackgroundcolor = {\ifnum \value{lstnumber} = 8 \color{yellow} \fi, \ifnum \value{lstnumber} = 10 \color{yellow} \fi, \ifnum \value{lstnumber} = 12 \color{yellow} \fi}, linebackgroundsep = 2.2 em, linebackgroundwidth = 15 em]
import numpy
from tensorflow.keras.layers import Dense, Activation, Dropout, Input
from tensorflow.keras.models import Sequential, Model, load_model
from tensorflow.keras.optimizers import Adam

model_input = Input(shape = x_train[0].shape)
x = Dense(120, activation = 'relu')(model_input)
x = Dropout(0.01)(x)
x = Dense(120, activation = 'relu')(x)
x = Dropout(0.01)(x)
x = Dense(120, activation = 'relu')(x)
x = Dropout(0.01)(x)
model_output = Dense(numpy.shape(y_train)[1])(x)
model = Model(model_input, model_output)
\end{lstlisting}

\end{document}

and you get

highlight code

it is however, still not optimized, you have to manually adjust the left and right edge of highlight bar, and setting multiple lines to highlight is cumbersome.

zyy
  • 1,271
  • 15
  • 25
  • This looks nice, although `lstlinebgrd` is currently broken https://tex.stackexchange.com/questions/451532/recent-issues-with-lstlinebgrd-package-with-listings-after-the-latters-updates – Supernormal Mar 13 '22 at 07:42
  • @Supernormal Thanks for the information, hope it will recover soon! – zyy Mar 14 '22 at 09:05
0

the listings package provides backgroundcolor=\color{} as an option, but i'm sure that makes the whole BG color, not a chunk.

you could have a look at putting it a parbox with color, or the colorbox package.

Mica
  • 18,501
  • 6
  • 46
  • 43