This is easily doable using, what else, but \tikzmark
. You need to have a way within the verbatim environment to escape back to LaTeX temporarily in order to place the \tikzmark
within the verbatim environment. Below I used the verbatim environment provided by the listings
package, and escapeinside
to provide a way to execute LaTeX macros.
Arrow:
Box and Arrow:
You can extend this to draw the box as well. I have extended \DrawArrow
to \DrawBoxAndArrow
in the same macro (but perhaps you want a separate macro for that):
Notes:
This does require two runs. First one to determine the locations, and the second to do the drawing.
The \tikzmark
is from Adding a large brace next to a body of text.
To ensure that the arrow does not cross over the text, you will need to choose the in=
, and out=
angles which are provided as the first optional parameter to the \DrawArrow
macro. Using out=-60
was enough to get the arrow to curve around the verbatim text at the end of the line.
Code (arrow):
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{listings}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand*{\DrawArrow}[3][]{%
% #1 = draw options
% #2 = left point
% #3 = right point
\begin{tikzpicture}[overlay,remember picture]
\draw [-latex, #1] ($(#2)+(0.1em,0.5ex)$) to ($(#3)+(0,0.5ex)$);
\end{tikzpicture}%
}%
\begin{document}
Here is some text from which I want to draw an arrow from here\tikzmark{start} into the verbatim environment below.
\begin{lstlisting}[escapeinside={(*}{*)}]
verbatim line 1
Here is a verbatim line and I want the arrow to
point here(*\tikzmark{end}*)
verbatim line 3
\end{lstlisting}
\DrawArrow[red, thick, out=-60, in=0]{start}{end}
\end{document}
Code: (box and arrow):
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{listings}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand*{\DrawBoxAndArrow}[4][]{%
% #1 = draw options
% #2 = left point, start of box
% #3 = right point, end of box
% #4 = point where arrow ends
\begin{tikzpicture}[overlay,remember picture]
\draw [#1] ($(#2)-(0.1em,0.25ex)$) rectangle ($(#3)+(0.1em,1.5ex)$);
\draw [-latex, #1] ($(#3)+(0.1em,0.5ex)$) to ($(#4)+(0,0.5ex)$);
\end{tikzpicture}%
}%
\begin{document}
Here is some text from which I want to draw an arrow from \tikzmark{startBox}here\tikzmark{endBox} into the verbatim environment below.
\begin{lstlisting}[escapeinside={(*}{*)}]
verbatim line 1
Here is a verbatim line and I want the arrow to
point here(*\tikzmark{endArrow}*)
verbatim line 3
\end{lstlisting}
\DrawBoxAndArrow[red, thick, out=-60, in=0]{startBox}{endBox}{endArrow}
\end{document}