17

I’d like to show you a nice technique used in this book to describe code listings (see pag. 6 and 7 of the PDF -- 116 and 117 of the book), in which relevant statement are labeled with special “markers”.

Can you tell me how to replicate such technique in Latex?

I know that the packet listings allows escaping (so it is possible to insert Latex code within code listings) but I cannot figure out how to typeset the markers (hopefully with auto numbering within the listing itself) -- in the book, the numbering for the markers wraps around at each listing.

I was thinking to something like the following:

% preamble
\lstset{
    (...)
    escapechar=§,
}

% Definition for the command `mycoderef`

(...) 
% begin document

% Marked listing
\begin{lstlisting}[language=c,label=src-hello-c]
    #include <stdio.h>

    int
    main(int argc, char *argv[])
    {
        §\mycoderef{mylabel1}§printf("Hello, World!\n");
        return 0;
    }
\end{lstlisting}

% The text refers to the marked statement
The hello message is printed with the statement printf\autoref{mylabel1}.

Thanks,
Giorgio

  • Personally I think those special markers distracts, from real content. I you need a reference to the corresponding code I strongly suggest numbering every line, or every second or every fith. This way even small mistakes can be referenced exactly by proof-readers. See page 33 of the manual: ftp.tex.ac.uk/tex-archive/macros/latex/contrib/listings/… – math Sep 23 '13 at 14:43
18

Here's how you could do it. I didn't go into the trouble of printing the markers exactly as in your book, but I think this will be quite easy. Notice that the counter is initialized once; if you have more listings, it will keep the previous value. This should be fixed too.

\documentclass[11pt]{article}
\usepackage{listings}

\lstset{basicstyle=\normalsize\ttfamily,
        showstringspaces=false,
        basewidth=1.2ex,
        fontadjust=true,
        escapechar=§}

\newcount\mymark
\makeatletter
\def\mycoderef#1{%
  \global\advance\mymark by 1%
  \protected@write \@auxout {}{\string \newlabel {#1}{{\the\mymark}{}}}%
  \makebox[0pt][r]{{\scriptsize\bfseries \the\mymark~}}%
}
\makeatother

\begin{document}
\begin{lstlisting}[language=c,label=src-hello-c]
#include <stdio.h>

int main(int argc, char *argv[])
{
    §\mycoderef{mylabel1}§printf("Hello world!\n");
    printf("Love, peace and harmony!\n");
    §\mycoderef{mylabel2}§return 0;
}
\end{lstlisting}

The hello message is printed with the statement printf at \ref{mylabel1}.
Yet another message is printed similarly.
Then, the program returns with \ref{mylabel2}.
\end{document}

Addendum

This is a very basic approach with TikZ to recreate boxed numbers.

\documentclass[11pt]{article}
\usepackage{tikz}
\usepackage{listings}

\lstset{basicstyle=\normalsize\ttfamily,
        showstringspaces=false,
        basewidth=1.2ex,
        fontadjust=true,
        escapechar=§}

\newcommand{\roundbox}[1]{%
  \tikz[baseline=-1ex]%
  \node[%
  inner sep=1.5pt,
  draw=black,
  fill=black,
  text=white,
  rounded corners=2.5pt]{#1};}

\newcommand{\boxref}[1]{%
  \begingroup%
  \scriptsize\ttfamily%
  \roundbox{\ref{#1}}%
  \endgroup%
}

\newcount\mymark
\makeatletter
\def\mycoderef#1{%
  \global\advance\mymark by 1%
  \protected@write \@auxout {}{\string \newlabel {#1}{{\the\mymark}{}}}%
  \makebox[0pt][r]{{\scriptsize\roundbox{\the\mymark}~}}%
}
\makeatother

\begin{document}
\begin{lstlisting}[language=c,label=src-hello-c]
#include <stdio.h>

int main(int argc, char *argv[])
{
    §\mycoderef{mylabel1}§printf("Hello world!\n");
    printf("Love, peace and harmony!\n");
    §\mycoderef{mylabel2}§return 0;
}
\end{lstlisting}

The hello message is printed with the statement printf at \boxref{mylabel1}.
Yet another message is printed similarly.
Then, the program returns with \boxref{mylabel2}.
\end{document} 

enter image description here

  • Very nice. Can I add some code to make numbers look similar to the ones in the document mentioned by the OP? – karlkoeller Sep 8 '13 at 9:45
  • --EDITED-- @karlkoeller It would be nice. I tried with tikz, but I cannot make it. OK for the consent, thanks. – Giorgio B. Sep 8 '13 at 10:57
  • Guys, sorry, I'm out of town. I can't work on this today or tomorrow. Feel free to edit what you need. Cheers... – nickie Sep 8 '13 at 15:08
  • 1
    @nickie I've added some code for boxed numbers. I'm not a TikZ expert, so this is just a very basic approach. Adjust it as you want (or delete it). – karlkoeller Sep 8 '13 at 16:20
  • @GiorgioB. I've added some very basic code. Take a look. – karlkoeller Sep 8 '13 at 16:20

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.