Remember text in LaTeX

June 2, 2010

programming

After reading the Android Book from O’Reilly I saw some nice use of bullets alongside source code which allowed for extra explanation to be given after the code. I thought only one thing: I want to use that too, but then in LaTeX. After fiddling around for an evening it finally looked like this:

Nice bullets in LaTeX

There are two ways you can do this. The easy way is to write a few macros which create numbered bullets in the code and then use these numbers manually after the code to add your explanation. There are however problems with this approach; You need to manually keep the numbers in sync and thus it distracts you from focussing on the text.

This is not the LaTeX way.

In LaTeX you want your remark to be typed right away and remembered, so that later it can just be rendered. This means LaTeX must somehow remember your text. This is what I came up with.

%% Code Remarks -- Miek Gieben
% define 2 commands
% \longremark[1] where you can say something about the code/whatever
% \showremarks - displays all remarks in a list after the code or where
%            you put the command
\usepackage{ifthen}
\usepackage{tikz}

Some counters we will be needing

\newcounter{coderemarks}
\setcounter{coderemarks}{1}
\newcounter{codevar}
\setcounter{codevar}{1}

And now the crux of the code. With \global and \def you define a global new command. This command has to be global otherwise it is only visible inside the environment where you defined it and you can not use it later on when the explanation is to be rendered. With csname codebox\the\value{coderemarks}\endcsname I generate a string for LaTeX to interpret. The string will become something like codebox1 or codebox2. Those will be the names of the commands to are to be defined and hold the text.

The tikz stuff is a very nice picture environment which draws a black circle with a number rendered in white in it.

\newcommand{\longremark}[1]{%
\tikz\node[text=white,font=\sffamily\bfseries,inner sep=0.2mm,draw,circle,fill=black]{\arabic{coderemarks}};%
\global \expandafter\def \csname codebox\the\value{coderemarks}\endcsname{#1}%
\stepcounter{coderemarks}%
}

And now the code to display your remarks later on. Basically this is a while-loop that renders an item list. In the body of the loop the command names are also constructed in the same way as in \longremark, but now they are not defined, but called. The bullets used are drawn in the same way with \tikz.

\newcommand{\showremarks}{%
\begin{list}{%
\tikz\node[text=white,font=\sffamily\bfseries,inner sep=0.2mm,draw,
circle,fill=black]% 
{\arabic{codevar}};}{\setlength{\labelsep}{2.0\labelsep}}
\whiledo{\value{codevar} < \value{coderemarks}}{
\item \expandafter\csname codebox\the\value{codevar}\endcsname
\stepcounter{codevar}%
}
\end{list}
\setcounter{coderemarks}{1}%
\setcounter{codevar}{1}%
}

The usage of these commands in your code should be quite transparent. (I could turn this into a proper package – and maybe something like this already exists — don’t know).

The following is an example of how to use it. We define a code listing using the lstlisting package. At interesting spots in the listing we use \longremark and give our remark.

\begin{lstlisting}
type stack struct { |\longremark{\emph{stack} is not exported}|
i    int 
data [10]int  |\longremark{Meer gezeur wat in dit geval ook %
            djskdjkd sjd skjfk fjdkf jdkf jfk dfj d TODO %
            djskdjkd sjd skjfk fjdkf jdkf jfk dfj d TODO %
            \newline %
            djskdjkd sjd skjfk fjdkf jdkf jfk dfj d TODO %
over meerdere regels heen gaat, oh waar moet dat }|
}
\end{lstlisting}

And when we want to see our remarks we just give

\showremarks

to render it.

LaTeX