# How to annotate listings in Latex

I have three listings in Latex and I want to be able to annotate them: I was thinking something like this:

How can I achieve this, and if it's not a listing but a simple annotated text then, again, how to do it?

Thank you!

It's possible to define listings styles that put their stuff inside TikZ nodes. This allows for the framing effect, and linking them afterwards.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/419759/86}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\newcounter{tmlistings}

\newcommand\makenode[2]{%
\tikz[baseline=0pt, remember picture] { \node[fill=gray!50,thick,rounded corners,anchor=base,#1/.try] (listings-\the\value{tmlistings}) {#2}; }%
\stepcounter{tmlistings}%
}

\tikzset{
keyword/.style={
fill=gray!75,
draw=black
}
}

\lstset{
keywordstyle=\makenode{keyword},
stringstyle=\makenode{string},
identifierstyle=\makenode{identifier},
}

\begin{document}

\begin{lstlisting}[language=c]
int gilligan (int j) {
for (int i = 1; i < j; i++) {
if (i % 2 == 0) {
cout << i
}
}
}
\end{lstlisting}

\begin{tikzpicture}[remember picture,overlay,>=Latex]
\draw[->] (listings-8) to[out=45,in=45,looseness=2] (listings-3);
\draw[->] (listings-13) -- (listings-11);
\draw[->] (listings-11) -- (listings-6);
\draw[->] (listings-6) to[out=-45,in=-135] (listings-7);
\draw[->] (listings-7) to[out=-45,in=-135] (listings-9);
\end{tikzpicture}

\end{document}


(I don't know how to get the symbols into nodes, unfortunately. I'm not that experienced with listings.)

• thanks a lot for this. I didn't know this option, at all, and I haven't seen it somewhere before! Seems to be closer to my question. I added one more thing (see my Edit., let me know if I have to move in a new question, if there is a way of doing it.) – user4712458 Mar 15 '18 at 19:14

You can continue adding lines at the bottom

\documentclass[tikz, border = 4pt]{standalone}

\usetikzlibrary{shapes.geometric}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{document}

\begin{tikzpicture}[
font = \ttfamily,
node distance = 1ex,
minimum height = 13pt,
outer sep = 0pt,
sq code/.style = {draw, fill = gray!20, opacity = 0.7},
ci code/.style = {draw, rounded corners, opacity = 0.7},
]

% line 1
\path node (function type) [sq code] {int}
node (function name) [right = of function type] {gilligan (}
node (argument j type) [sq code, right = of function name] {int}
node (argument j name) [ci code, right = of argument j type] {j}
node (function open) [right = of argument j name] {) \{};
\begin{pgfonlayer}{background}
\draw[sq code] ($(function type.south west) + (-0.1, -0.1)$) rectangle (function
open.north east);
\end{pgfonlayer}

% line 2
\path node (for) [sq code, below right = of function type]{for}
node (open parenthesis) [right = of for]{(}
node (i type) [sq code, right = of open parenthesis]{int}
node (i init) [ci code, right = of i type]{i}
node (i init assign) [sq code, right = of i init]{=}
node (i init value) [right = of i init assign]{1;}
node (i stop) [ci code, right = of i init value]{i}
node (i stop assign) [sq code, right = of i stop]{<}
node (i stop value) [ci code, right = of i stop assign]{j}
node (i stop sep) [right = of i stop value]{;}
node (i step) [right = of i stop sep]{i}
node (i step value) [sq code, right = of i step]{++}
node (close parenthesis) [right = of i step value]{) \{};
\begin{pgfonlayer}{background}
\draw[sq code] ($(i step.south west) + (-0.1, -0.1)$) rectangle
($(i step value.north east) + (0.1, 0.1)$);
\end{pgfonlayer}

% line ...

\path (i stop value) edge[out = 90, in = 90, ->] (argument j name)
(i init) edge[out = -50, in = -140, ->] (i stop)
(i stop) edge[out = -50, in = -140, ->] (i step value);

\end{tikzpicture}

\end{document}


• Thanks a looot for this solution!!! Because the annotations I needed to be inside listings, and the next answer shows something closer to my question, I'll accept that one. Thnx a ton! – user4712458 Mar 15 '18 at 19:08
• @user4712458 LoopSpace's solution is definitely better than mine, you should accept that one :) – caverac Mar 15 '18 at 19:25