# How to add numerical (ala No Starch Press) listing notes without XeTeX?

I've been following the instructions and code available at: https://zuttobenkyou.wordpress.com/2010/12/05/latex-saner-source-code-listings-no-starch-press-style/

I would like to add notes (and style) to lstlisting environments similar to those in No Starch Press publications:

Unfortunately it depends on XeTeX and I've added conditional support for it in my document, but this is problematic with pgf/tikx since the xetex driver isn't very complete, and I also have issues with monospace fonts such as DejaVu Sans Mono, which results in (very) weird invalid kerning.

How can I avoid the xetex dependency using a similar approach for notes and pdftex?

Update: Check my answer for tikz-based solution with support for unlimited sidenotes.

Thanks to Mike Renfro for the input!

-

Not perfect, but it works on a subset that may be sufficient for you. Using The Comprehensive LaTeX Symbol List to scan for the circled numbers and such:

\documentclass{article}
\usepackage[x11names]{xcolor} % for a set of predefined color names, like LemonChiffon1
\usepackage{listings}
\usepackage{textcomp}
\newcommand{\numold}[1]{\oldstylenums{#1}}

% Allow "No Starch Press"-like custom line numbers (essentially, bulleted line
% numbers for only those lines the author will address)
\usepackage{pifont}
\usepackage{ifthen}
\newcounter{lstNoteCounter}
\newcommand{\lnnum}[1]{% Print pifont circled number for line label
\ifcase#1%
% nothing for 0
\or\ding{202}%
\or\ding{203}%
\or\ding{204}%
\or\ding{205}%
\or\ding{206}%
\or\ding{207}%
\or\ding{208}%
\or\ding{209}%
\or\ding{210}%
\or\ding{211}%
\else{NUM TOO HIGH}%
\fi%
}
\newcommand*{\lnote}{%
\stepcounter{lstNoteCounter}\vbox{\llap{{\lnnum{\thelstNoteCounter}}\hskip 1em}}%
}
\lstnewenvironment{csource2}[1][]
{
\setcounter{lstNoteCounter}{0}
\lstset{basicstyle=\ttfamily,language=C,numberstyle=\numold,numbers=right,
frame=lines,framexleftmargin=0.5em,framexrightmargin=0.5em,
backgroundcolor=\color{LemonChiffon1},showstringspaces=false,
escapeinside={(*@}{@*)},#1}
}
{}

\begin{document}
\section{Hello, world!}
The following program \texttt{hello.c} simply prints Hello, world!'':

\begin{csource2}
(*@\lnote@*)#include <stdio.h>

/* This is a comment. */
(*@\lnote@*)int main()
{
(*@\lnote@*)    printf("Hello, world!\n");
(*@\lnote@*)    return 0;
}
\end{csource2}

We first include the \texttt{stdio.h} header file \lnnum{1}. We then declare
the \texttt{main} function \lnnum{2}. We then print Hello, world!'' to
standard output (a.k.a., \textit{STDOUT}) \lnnum{3}. Finally, we return value
0 to let the caller of this program know that we exited safely without any
errors \lnnum{4}.
\end{document}


It won't handle more than 10 circled number labels, but does work with regular pdflatex. Someone else can make TikZ code for those labels and extend it past the 20 labels in the original.

-
Let's hope someone comes up with the tikz version, but many thanks for all the effort :) (I'm actually having trouble using the original code too, seems something is wrong with my global listings lset catch-all). – soze Apr 12 '12 at 1:54
Any chance for something with better resolution? (so the numbers inside the circles are a bit more "crisp" to the eye) – soze Apr 12 '12 at 2:28
Please check my update. Does \oldstylenums work fine on both xetex and pdftex? – soze Apr 12 '12 at 3:44
In an attempt to duplicate the shown example, you could use numbers=left,numbersep=3em to push the regular line numbers further left. – Werner Apr 12 '12 at 5:08
Werner, I've detected problems with both versions (mine and yours). For instance, depending on the identation level of the annotated level, the corresponding circle is placed erroneously in the margin. So spaces affect its placement. I don't know what's causing it. – soze Apr 13 '12 at 18:51

I've decided to do my own tikz-based version, mostly because the actual quality of the output is better even compared to a properly scalable glyph. It has no limitations as to how many "annotated lines" you can add, and you get fine-grained support for the typography inside each circle.

%\newcommand{\mynumold}[1]{{\addfontfeature{Numbers=OldStyle}#1}}
\newcommand{\mynumold}[1]{{\oldstylenums{#1}}}

\newcounter{lstNoteCounter}

\newcommand*\lnnum[1]{\tikz[baseline=(char.base)]{
\node[shape=circle,draw,inner sep=0.8pt,
fill=black, text=white] (char) { \rmfamily\bfseries\footnotesize#1};}}

\newcommand*{\lnote}{\stepcounter{lstNoteCounter}\llap{{\lnnum{\thelstNoteCounter}}\hskip 6em}}

\lstnewenvironment{annotatedcsource}[1][]
{
\setcounter{lstNoteCounter}{0}
\lstset{
frame=lines,
framexleftmargin=0.5em,
framexrightmargin=0.5em,
basicstyle=\ttfamily\footnotesize,
numberstyle=\normalsize\itshape\mynumold,
backgroundcolor=\color{LemonChiffon1},
showstringspaces=false,
numbers=left,
escapeinside={(*@}{@*)},#1}
}
{}


This is the output:

Currently it has some issues:

• The size of the circle might break the way the background is displayed. This won't show up if it's white, but the spacing between the affected line and others is affected either way. One workaround is to make it larger to accommodate more space, choose a smaller font size for the circle text or some such.

Also, sorry about the garbled code block. See for yourself and adjust the hline spacing.

Update: I have posted the following question looking for answers on how to properly solve the alignment problems (so far I've solved the background display through the overlay feature): Position tikz pictures at left margin of a listing code block

-