3

I'd like to draw a rectangle (outline only, not filled) around a few words inside an lstlisting environment. I've tried the following, but it doesn't treat the text inside the box as "verbatim" as lstlisting does. (so, for example, "%" is interpreted as beginning a comment.) Ideally, I'd like a solution that I can use with "moredelim" so I can easily draw these boxes whenever I need one. Here's what I've done so far:

\documentclass{article}

\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,calc,shapes,positioning}

\newcommand\tbox[1]{\tikz[overlay]\node[inner sep=2pt, draw=red, ultra thick, anchor=text, rectangle] {#1};\phantom{#1}}

\begin{document}

\begin{lstlisting}[escapechar=!]
#include <stdio.h>
#include <math.h>

int main () {
  double c=-1;
  double z=0;
  int i;

  printf (``For c = %lf:\n'', c );
  for ( i=0; i<10; i++ ) {
      printf ( !\tbox{``z %d = %lf\n''}!, i, z );
      z = pow(z,2) + c;
  }
 }
 \end{lstlisting}


\end{document}
1

2 Answers 2

4

Thanks to Ignasi, above, for pointing me to this:

Frame a line in an environnement lstlisting

Based on the example there, I've re-worked my sample code as shown below. This is a nice solution, since it lets me write the code naturally, and then add marks as needed to indicate where the box goes.

\documentclass{article}

\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,calc,shapes,positioning,tikzmark}


\begin{document}

\begin{lstlisting}[escapechar=!]
#include <stdio.h>
#include <math.h>

int main () {
  double c=-1;
  double z=0;
  int i;

  printf (``For c = %lf:\n'', c );
  for ( i=0; i<10; i++ ) {
    printf ( !\tikzmark{a}!``z %d = %lf\n''!\tikzmark{b}!, i, z );
    z = pow(z,2) + c;
  }
}
\end{lstlisting}

\begin{tikzpicture}[remember picture,overlay]
\draw[red,rounded corners]
  ([shift={(-3pt,2ex)}]pic cs:a) 
    rectangle 
  ([shift={(3pt,-0.65ex)}]pic cs:b);
\end{tikzpicture}


\end{document}

enter image description here

1

Even \savebox{\tempbox}{\verb...} didn't work. I had to use the plain TeX version.

\documentclass{article}

\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,calc,shapes,positioning,tikzmark}

\newcommand\tbox[1]{\tikz[baseline]{\node[inner sep=2pt, draw=red, ultra thick, anchor=text, rectangle] {#1};}}

\newsavebox{\tempbox}

\begin{document}

\setbox\tempbox=\hbox{\verb$``z %d = %lf\n''$}

\begin{lstlisting}[escapechar=!]
#include <stdio.h>
#include <math.h>

int main () {
  double c=-1;
  double z=0;
  int i;

  printf (``For c = %lf:\n'', c );
  for ( i=0; i<10; i++ ) {
      printf ( !\tbox{\usebox{\tempbox}}!, i, z );
      z = pow(z,2) + c;
  }
 }
 \end{lstlisting}


\end{document}

savebox with verbatim

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .