I'm trying to finish my attempt at having good looking unlimited line annotations for the listing environments, using tikz. The original problem was that indentation caused shifts in the positioning, so I changed the code to use the overlay feature.
My original question is here: How to add numerical (ala No Starch Press) listing notes without XeTeX?
Unfortunately, I'm still unable to figure out how to properly align them:
Update: the code is merged with Werner's version.
\documentclass{article}
\usepackage{libertine}
\usepackage[log-declarations=false]{xparse}
\usepackage[quiet]{fontspec}
\setromanfont[Ligatures={Common,TeX}]{Linux Libertine O}
\setmainfont[Ligatures={Common,TeX}]{Linux Libertine O}
\setmonofont[SmallCapsFont={Latin Modern Mono Caps}]{Latin Modern Mono Light}
\setsansfont{Linux Biolinum O}
\usepackage{xunicode}
\usepackage[x11names, rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{snakes,arrows,shapes}
\usepackage{amsmath}
\usepackage{listings}
\newcommand{\mynumold}[1]{{\oldstylenums{#1}}}
\newcounter{lstNoteCounter}
\newcommand*\lnnum[2][,]{\tikz[baseline=(char.base), overlay]{
\node[shape=circle,draw,inner sep=0.8pt,
fill=black, text=white, #1] (char) {\rmfamily\bfseries\footnotesize#2};}}
\newcommand*{\lnote}{\stepcounter{lstNoteCounter}\llap{{\lnnum{\thelstNoteCounter}}\hskip 4em}}
\newcommand*{\linenum}[1]{%
\setbox0=\hbox{\rmfamily\bfseries\footnotesize#1}%
\lnnum[anchor=west]{#1}\hspace*{\dimexpr1ex+\wd0\relax}%
}
\lstnewenvironment{annotatedcsource}[1][]
{
\setcounter{lstNoteCounter}{0}
\lstset{
basicstyle=\ttfamily,
frame=lines,
framexleftmargin=0.5em,
framexrightmargin=0.5em,
basicstyle=\ttfamily\footnotesize,
numberstyle=\normalsize\itshape\mynumold,
backgroundcolor=\color{LemonChiffon1},
showstringspaces=false,
numbers=left,
numbersep=2.5em,
escapeinside={(*@}{@*)},#1}
}
{}
\begin{document}
\pagestyle{empty}
\begin{annotatedcsource}[caption={RC4 blues}]
void
rc4_init(struct rc4_state *const state, const u_char *key, int keylen)
{
u_char j;
int i, k;
/* Initialize state with identity permutation */
for (i = 0; i < 256; i++)
(*@\lnote@*)state->perm[i] = (u_char)i;
state->index1 = 0;
(*@\lnote@*)state->index2 = 0;
/* Randomize the permutation using key data */
for (j = i = k = 0; i < 256; i++) {
j += state->perm[i] + key[k];
(*@\lnote@*)swap_bytes(&state->perm[i], &state->perm[j]);
if (++k >= keylen)
(*@\lnote@*)k = 0;
}
\end{annotatedcsource}
Some source code doing whatever \linenum{1}, with line numbers and annotations \linenum{2}.
\begin{annotatedcsource}[caption={Hello blues}]
void hello(int times)
{
int i;
(*@\lnote@*)if (times > 4) {
printf("Feeling chatty today?\n");
return;
}
/* foobar */
(*@\lnote@*)for (i = 0; i < times; i++) {
printf("Hello %d!\n", i);
}
printf("Adios!\n");
(*@\lnote@*)return;
}
\end{annotatedcsource}
Some source code doing whatever \linenum{1}, with line numbers and annotations \linenum{2}.
\end{document}
Output:

Desired output:
- Properly aligned circled numbers to the left or right margins along the line numbers.
- In other words, the circled numbers must appear outside of the code block box, to the right or left of the line numbers.
- Any kind of source code listing should work fine, no indentation assumptions (please).
- Properly spaced circled numbers for the actual references embedded in the text.
Like this:




anchor=west,option to the tikzpicture and using saySome source code doing whatever \lnnum{1}\quad, with line numbers and annotations \lnnum{2}\quad.solves the second problem. Frankly, I couldn't understand what your first problem is. Note thatsnakeslibrary is deprecated and replaced with decorations. – percusse Apr 13 '12 at 19:53