[Tex/LaTex] How to put a curly brace inside a listing to group code lines

listingstikz-pgf

I am using the listing package. Is it possible to use curly braces to group some lines in the listing so as to be able to put an explanation to the right?

I'm trying to use the code given in Peter Grill's excellent answer to How can I put a curly brace inside an algorithm to group code lines? but passing the markers given by tikzmark's listings capability to AddNote doesn't seem to work.

Here's my code so far:

\documentclass{article}
\usepackage{tikz}
\usepackage{listings}
\usetikzlibrary{decorations.pathreplacing,calc,tikzmark}
\usetikzmarklibrary{listings}

\newcommand*{\AddNote}[4]{%
    \begin{tikzpicture}[overlay, remember picture]
        \draw [decoration={brace,amplitude=0.5em},decorate,ultra thick,red]
            ($(#3)!(#1.north)!($(#3)-(0,1)$)$) --  
            ($(#3)!(#2.south)!($(#3)-(0,1)$)$)
                node [align=center, text width=2.5cm, pos=0.5, anchor=west] {#4};
    \end{tikzpicture}
}%

\begin{document}
\begin{lstlisting}[name=listing]
  Example code line 1
  Example code line 2
  Example code line 3
  Example code line 4
  Example code line 5
  Example code line 6
  Example code line 7
  Example code line 8
  Example code line 9
  Example code line 10
\end{lstlisting}

\AddNote{pic cs:line-listing-4-end}{pic cs:line-listing-7-end}{pic cs:line-listing-4-end}{Example annotation.}
\end{document}

And here's what that outputs:

Best Answer

Many things have likely changed since this question was asked. I'm not entirely sure why your usage is not working, since it matches what is listed in the documentation. Maybe some incompatibility cropped up in recent updates.

Anyway, here is a workaround using listings' mathescape feature, but maybe someone will come along with a real answer, and I will delete this answer then.

Code

\documentclass{article}
\usepackage{tikz}
\usepackage{listings}
\usetikzlibrary{decorations.pathreplacing,calc}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\newcommand*{\AddNote}[4]{%
    \begin{tikzpicture}[overlay, remember picture]
        \draw [decoration={brace,amplitude=0.5em},decorate,ultra thick,red]
            ($(#3)!([yshift=1.5ex]#1)!($(#3)-(0,1)$)$) --  
            ($(#3)!(#2)!($(#3)-(0,1)$)$)
                node [align=center, text width=2.5cm, pos=0.5, anchor=west] {#4};
    \end{tikzpicture}
}%

\begin{document}
\begin{lstlisting}[mathescape]
  Example code line 1
  Example code line 2
  Example code line 3
  Example code line 4 $\tikzmark{listing-4-end}$
  Example code line 5
  Example code line 6
  Example code line 7   $\tikzmark{listing-7-end}$
  Example code line 8
  Example code line 9
  Example code line 10
\end{lstlisting}

\AddNote{listing-4-end}{listing-7-end}{listing-4-end}{Example annotation.}
\end{document}

Remember that these math escapes are placed literally (whitespace matters). So the horizontal position is still controlled by the third argument to \AddNote, but you must add/remove whitespace before the math escape to change the position.

Output

enter image description here