0

I'm using \lstinputlisting to include sections of source code. Instead of adding line numbers to be able to refer to some specific parts, I'd like to include unique symbols that are visibly not part of the source coude itself, namely numbered circles - just like in this screenshot, for example:

enter image description here

This is from Effective C by Robert C. Seacord, no starch press. I have seen similar in other programming-centric books from different publishers, too.

How can I set and refer to these circle markers? I'd of course prefer to keep using the listings package, but are not strictly bound to it. Most importantly, I do not want to modify the source files themselves.

  • If you only want it "in print", i.e. without hyperlinks, use e.g. Circled Numerals, Table 386 from https://tug.ctan.org/info/symbols/comprehensive/symbols-a4.pdf . // However, very likely you'll need to define your own code-environment, i.e. probably won't be able to use the listings package or similar: https://mirror.marwan.ma/ctan/macros/latex/contrib/listings/listings.pdf // A workaround might be using tables (left circle, right lstlisting), parcol or similar. – MS-SPO Feb 03 '23 at 09:13

1 Answers1

4

You can extend Suppress line numbering for specific lines in listings package to use the circledsteps package (see https://tex.stackexchange.com/a/496665/) for the line numbers:

\documentclass{article}
\usepackage{circledsteps}
\pgfkeys{/csteps/inner color=white}
\pgfkeys{/csteps/fill color=black}
\usepackage{listings}

\lstset{numbers=left,numberblanklines=false,escapeinside=||} \def\origthelstnumber{\Circled{\arabic{lstnumber}}} \makeatletter \newcommand*\Suppressnumber{% \lst@AddToHook{OnNewLine}{% \let\thelstnumber\relax% \advance\c@lstnumber-@ne\relax% }% }

\newcommand*\Reactivatenumber{% \lst@AddToHook{OnNewLine}{% \let\thelstnumber\origthelstnumber% \advance\c@lstnumber@ne\relax}% }

\makeatother \begin{document} \Suppressnumber \begin{lstlisting}[language=C] void func(int arr[5]); int main(void) {|\Reactivatenumber| unsigned int i = 0;|\Suppressnumber| unsigned int j = 0; int arr[3][5];|\Reactivatenumber| func(arr[i]);|\label{someline}| int x = arr[i][j];|\label{otherline}\Suppressnumber| return 0; } \end{lstlisting} Interesting lines are \Circled{\ref{someline}} and \Circled{\ref{otherline}}. \end{document}

enter image description here

Of course this only works for inline listings and not for \lstinputlisting, given that you need to insert the LaTeX code for switching the numbers on and off and setting the labels manually into the listing.


If you want the source to be unchanged then you can use the following brilliantly engineered solution based on Skip line numbers and resume from specific number in Minted? (which is for Minted, but for Listings it works more or less the same). Here you need to manually set which line gets which number and also number the references by hand.

\begin{filecontents*}{matrices.c}
void func(int arr[5]);
int main(void) {
  unsigned int i = 0;
  unsigned int j = 0;
  int arr[3][5];
  func(arr[i]);
  int x = arr[i][j];
  return 0;
}
\end{filecontents*}

\documentclass{article} \usepackage{circledsteps} \pgfkeys{/csteps/inner color=white} \pgfkeys{/csteps/fill color=black} \usepackage{listings}

\lstset{numbers=left} \let\origlstnumber\thelstnumber

\def\thelstnumber{% \ifnum\value{lstnumber}=6\Circled{1}\fi% \ifnum\value{lstnumber}=7\Circled{2}\fi% } \begin{document} \section*{Selected circled numbers} \lstinputlisting[language=C]{matrices.c}

Interesting lines are \Circled{1} and \Circled{2}.

\let\thelstnumber\origlstnumber \section*{Normal numbers} \lstinputlisting[language=C]{matrices.c} \end{document}

Note that the C code is contained in this file as well but only in a filecontents environment for demonstration purposes, if you have the original file then this is not necessary.

enter image description here

Marijn
  • 37,699
  • Well I thought this would work great for my purposes. Then I included the next source file and found that the same line numbers would be highlighted there as in the previous one. Is there a way to undefine/redefine thelstnumber? – UnbescholtenerBuerger Feb 04 '23 at 16:15
  • 1
    @UnbescholtenerBuerger Yes, for this reason I put the 'reset' code in my example above but probably I should have explained that a bit, sorry for that. The code above restores the normal line numbering after \let\thelstnumber\origlstnumber (4 lines from the bottom). If you want to keep the special numbering but number different lines, then you should copy the definition \def\thelstnumber{% and the lines below that just above the next listing (and adjust the if statements accordingly). – Marijn Feb 04 '23 at 19:50
  • Ah, of course! Totally missed that line. Thank you! – UnbescholtenerBuerger Feb 05 '23 at 21:22