# Use listings in tufte-book with captions in margin

In my tufte-book document I would like to show source code listings using the listings package but with their captions in the margin. Modifying the code for typesetting the listing caption is not straightforward, and so the easiest solution is to wrap the listing in a floating environment (see the second answer to the question "combining listings and tufte-book, listings caption on tufte's margin"). However, this does not work:

• If you specify a label for the floating environment, labels for line number references (see the second answer to the question "Lstlistings reference to line number") will no longer be output to the auxiliary file, and the references will show up as "??".
• If you omit the label for the floating environment, line number references are wrong (they always reference the first line).

Here is a minimal working example illustrating the different variants for the second option:

\documentclass{tufte-book}
\makeatletter
% textwidth Tuftian float for listings
\newenvironment{listing}[1][htbp]
{\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{lstlisting}{}}
{\end{@tufte@float}}
% fullwidth Tuftian float for listings
\newenvironment{listing*}[1][htbp]%
{\ifvmode\else\unskip\fi\begin{@tufte@float}[#1]{lstlisting}{star}}
{\end{@tufte@float}}
% enable re-use of \listoflistings facility
\def\ext@lstlisting{lol}
% show listing number in caption even though \lst@@caption is empty
\def\fnum@lstlisting{\lstlistingname~\thelstlisting}
\makeatother

\usepackage{listings}
\begin{document}

% regular Tuftian figure float, wrong caption and writes to lof
\begin{figure}
\begin{lstlisting}[escapechar=|]
Dummy line
Labeled line |\label{line:test1}|
\end{lstlisting}
\caption{First test}
\end{figure}
Reference to line \ref{line:test1}

% custom Tuftian listing float, correct caption and writes to lol
\begin{listing}
\begin{lstlisting}[escapechar=|]
Dummy line
Labeled line |\label{line:test2}|
\end{lstlisting}
\caption{Second test}
\end{listing}
Reference to line \ref{line:test2}

% lstlisting float, wrong caption but writes to lol
\begin{lstlisting}[escapechar=|,float=h,caption=Third test]
Dummy line
Labeled line |\label{line:test3}|
\end{lstlisting}
Reference to line \ref{line:test3}
\end{document}


The result looks as follows:

Now I would like to go with the second approach (since I would like my listings to appear under a "List of Listings" instead of a "List of Figures"), because it provides a caption in the margin and therefore nicely integrates with the remaining floating environments. However, line number references do not work, and I have no clue why. The relevant contents of the auxiliary file follows:

\newpmemlabel{^_1}{1}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces First test}}{1}{lstnumber.-1.2}}
\newlabel{line:test1}{{1}{1}{}{lstnumber.-1.2}{}}
\newpmemlabel{^_2}{1}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}{\ignorespaces Second test}}{1}{lstnumber.-2.2}}
\newlabel{line:test2}{{1}{1}{}{lstnumber.-2.2}{}}
\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}Third test}{1}{lstlisting.0.2}}
\newlabel{line:test3}{{2}{1}{}{lstnumber.2.2}{}}

• Rather than renaming the list of figures, I would like to have both a list of figures and a list of listings in my document. By writing \contentsline commands to the lol file rather than the lof file, I can re-use the \listoflistings command provided by the listings package. However, regardless of this, line number references do not work correctly... – Michael Rudolf Dec 11 '15 at 6:33

It seems that the issue is a redefinition of the \label command in the floating environment used by the tufte-latex package for figures and tables (and in the second example of the question also for the listing). Below is the corresponding code, which already contains a hint to the solution:

\renewcommand{\label}[1]{\@tufte@label{##1}}%
% Handle subfigure package compatibility
\ifthenelse{\boolean{@tufte@packages@subfigure}}{%
% don't move the label while inside a \subfigure or \subtable command
\global\let\label\@tufte@orig@label%
}{}% subfigure package is not loaded


The tufte-latex document class detects whether the subfigure package has been loaded and sets the value of the Boolean accordingly. I came across this when using the subcaption package, which supercedes the subfig and subfigure packages - I could not reference the subfigures, because their labels were not output to the auxiliary file, just like the lables from the listings were missing. In order to retain the original behavior of the \label command also for listings and subcaption floats, I simply set the Boolean to true with the following lines in my document preamble:

\makeatletter
\setboolean{@tufte@packages@subfigure}{true}
\makeatother


This solved my problems with both listings and subfigures.

• This unfortunately breaks the labels of regular figures and tables, so this Boolean switch should probably be used on a per-float basis. – Michael Rudolf Dec 15 '15 at 14:22