1

Is it possible to draw an tikz arc (arrow) between to letters (numbers) in a Latex document? If yes, how to define the nodes in that case?

  • I don't understand, whether a TikZ node contains a number or a letter, the way you define it is exactly the same. – Torbjørn T. Sep 15 '17 at 13:47
  • Assuming that you want to connect arbitray characters in the page via a overlayed arc, the answer would be to use \tikzmark command to mark the characters and tikz's remember picture, overlay options to draw connections between them. See this for example. The details depend on what you specifically want to do. – JLDiaz Sep 15 '17 at 14:51
  • I have few listings with \lstlisting and I need arrows that point from one line of the code to the other. – Drimades Boy Sep 15 '17 at 15:59

1 Answers1

3

The general approach to add graphics on top of already typeset text in the page is to use TikZ remember picture and overlay options. An invisible tikz node can be placed next to the points of interest, so that the point receives a name, and then another tikzpicture draws connections between those nodes.

Andrew Stacey had this idea of adding invisible nodes to mark points in the page, called them "tizkmarks", and wrote the tikzmark package.

In your case, since you aim is to draw on top of code listings (as expressed in a comment after the question), it gets a bit more complex, because inside a listing environment you cannot enter latex commands (and thus \tikzmark) without escaping them somehow.

Depending on the language you use in your code listings, an easy way could be to use the option mathescape, which allows the use of the dollar sign inside the listings to escape to math mode. Once in math mode you can use \tikzmark. However, if your listings are PHP or Perl scripts, in which the dollar appears frequently, this approach is not valid. You can use escapechar to choose another special character to escape to latex.

The following example uses mathescape to enter latex in the listings, and put the tikz marks, and then, after the listing, a tikzpicture draws a cuved arrow between these marks.

\documentclass{article}
\usepackage{tikz}
\usepackage{listings}
\newcommand{\tikzmark}[1]{%
  \tikz[overlay,remember picture] \coordinate (#1) {};}
\begin{document}

\lstset{
    basicstyle=\ttfamily,
    keywordstyle=\color[rgb]{0.13,0.29,0.53}\bfseries,
    stringstyle=\color[rgb]{0.31,0.60,0.02},
    commentstyle=\color[rgb]{0.56,0.35,0.01}\itshape,
    backgroundcolor=\color[RGB]{248,248,248},
    showspaces=false,
    showstringspaces=false,
    linewidth=\textwidth,
    basewidth=0.5em,
    mathescape,
}

\begin{lstlisting}[language=C]
int main(int argc, char *argv[])
{
  char who="world";

  printf("Hello %$\tikzmark{s}$s\n", who$\tikzmark{who}$);
  return 0;
}
\end{lstlisting}
\begin{tikzpicture}[remember picture, overlay]
  \draw[red, ->, shorten >=5pt, shorten <=5pt] 
        (who) to[bend left] node[midway, below] {replaces} (s);
\end{tikzpicture}

\end{document}

This is the result:

Result

Note that this approach can fail if the listing is inside a float, because this can lead to the listing to appear in a different page than the annotated arrow. In this case you have to put the tikzpicture inside the same float than the listing. This would require to use the escapeinside option of listings, to define two chars to delimite a block of latex code inside the lstlistings environment.

JLDiaz
  • 55,732
  • This is more or less what I wanted, but from one line of code to another. I managed to do that by changing the position of the nodes. How can I 'curve' the arrow a little more? – Drimades Boy Sep 16 '17 at 00:12