20

I need nice drawing in lstlisting C/C++ code. I'm trying to make something like this printf function explanation

This is what i have made so far

enter image description here

\documentclass[11pt]{article}
\usepackage{listingsutf8}
\usepackage{tikz}
\usetikzlibrary{decorations.text}
 \newcommand{\tikzmark}[2]{%
     \tikz[overlay,remember picture] \node[text=black,
           inner sep=2pt] (#1) {#2};}
\begin{document}
\begin{lstlisting}[language=c,escapeinside={(*@}{@*)}]
#include <stdio.h>
int main (void)
{
int value1, value2, sum;//declaring
value1 = 50;//assign values
value2 = 25;
sum = value1 + value2;//sum them
//output
printf ("%d(*@\tikzmark{a}{} @*)+%d(*@\tikzmark{b}{} @*)= %d(*@\tikzmark{c}{} @*)\n", value1(*@\tikzmark{a1}{} @*), value2(*@\tikzmark{b1}{} @*), sum(*@\tikzmark{c1}{} @*));
 (*@
\begin{tikzpicture}[overlay,remember picture]
 \node (a) at (a.{east}) {};
\node  (a1) at (a1.{north west}) {};
\node  (b) at (b.{east}) {};
\node  (b1) at (b1.{north west}) {};
\node  (c) at (c.{east}) {};
\node  (c1) at (c1.{north west}) {};        
\draw[->,red,in=120,out=100] (a1) to (a);
\draw[->,red,in=120,out=100] (b1) to (b);
\draw[->,red,in=120,out=100] (c1) to (c);
\end{tikzpicture}
 @*)
    return 0;
 }
 \end{lstlisting}
\end{document}

How to make tikz nodes and arrows more nice?

26
+100

You can adjust the in and out angles as well as shift the location of the start and end points:

enter image description here

Notes:

  • I also added basicstyle=\ttfamily to have a more listings like output.
  • A \tikzmark was added on the left and right of each mark to simplify the computations of the midpoints.

Code:

\documentclass[11pt]{article}
\usepackage{listingsutf8}
\usepackage{tikz}
\usetikzlibrary{decorations.text,calc}
 \newcommand{\tikzmark}[2]{%
     \tikz[overlay,remember picture] \node[text=black,
           inner sep=2pt] (#1) {#2};}


\newcommand{\VerticalShiftForArrows}{0.0em,+2.75ex}%
\newcommand{\VerticalShiftForBar}{0.0em,+2.0ex}%
\newcommand{\Stub}{0.0em,-0.6ex}%
\newcommand{\DrawOverBar}[3][]{%
        \coordinate (top left)  at ($(#2)       +(\VerticalShiftForBar)$);
        \coordinate (start)     at ($(top left) +(\Stub)$);
        \coordinate (top right) at ($(#3)       +(\VerticalShiftForBar)$);
        \coordinate (end)       at ($(top right)+(\Stub)$);
        \draw [#1] (start) -- (top left) -- (top right) -- (end);
}%
\newcommand{\DrawArrows}[3][]{%
    \coordinate (Start Mid) at ($(#2Left)!0.5!(#2Right) + (\VerticalShiftForArrows)$);
    \coordinate (End Mid)   at ($(#3Left)!0.5!(#3Right) + (\VerticalShiftForArrows)$);

    \draw[-stealth, thick, #1] (Start Mid) to (End Mid);
}

\begin{document}
\begin{lstlisting}[language=c,escapeinside={(*@}{@*)},basicstyle=\ttfamily]
#include <stdio.h>
int main (void)
{
int value1, value2, sum;//declaring
value1 = 50;//assign values
value2 = 25;
sum = value1 + value2;//sum them
//output
printf ("(*@\tikzmark{aLeft}{}@*)%d(*@\tikzmark{aRight}{}@*)+(*@\tikzmark{bLeft}{}@*)%d(*@\tikzmark{bRight}{}@*)= (*@\tikzmark{cLeft}{}@*)%d(*@\tikzmark{cRight}{}@*)\n", (*@\tikzmark{value1Left}{}@*)value1(*@\tikzmark{value1Right}{}@*), (*@\tikzmark{value2Left}{}@*)value2(*@\tikzmark{value2Right}{}@*), (*@\tikzmark{sumLeft}{}@*)sum(*@\tikzmark{sumRight}{}@*));
 (*@
\begin{tikzpicture}[overlay,remember picture]
    \foreach \x/\y in {a/red, c/blue, value1/red, sum/blue} {
        \DrawOverBar[-, \y, thick]{\x Left.north}{\x Right.north}
    }

    \foreach \x/\y in {b/brown, value2/brown} {% Needs special handling as we are putting this below
        \renewcommand{\VerticalShiftForBar}{0.0em,-0.8ex}%
        \renewcommand{\Stub}{0.0em,+0.6ex}%
        \DrawOverBar[-, \y, thick]{\x Left.south}{\x Right.south}
    }

    \DrawArrows[red,   in=20,  out=160]{value1}{a}
    \DrawArrows[blue,  in=30,  out=150, distance=6.5ex]{sum}{c}

    \renewcommand{\VerticalShiftForArrows}{0.0em,-2.0ex}%Needs special handling as we are putting this below
    \DrawArrows[brown, in=-30, out=-150]{value2}{b}

\end{tikzpicture}
 @*)
    return 0;
 }
 \end{lstlisting}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.