10

I'm trying to compile my document but it's exploding. I've narrowed it down to this section:

\begin{figure}[h]
\caption{These are my awesome code snippets}
\subfloat[This code runs every cycle.]{
\begin{lstlisting}
    static uint64_t i = 0;
    void every_cycle()
    {
        if (i > 0)
            i--;
    }
\end{lstlisting}
}
\hfill
\subfloat[This code runs whenever.]{
\begin{lstlisting}
    uint64_t next_num()
    {
        return (i += 0x100);
    }
\end{lstlisting}
}

\label{fig:algOffset}
\end{figure}

But, when I try to compile, I get

! Argument of \lst@next has an extra }.
<inserted text> 
                \par 
l.181     }

From the lstlisting and subfloat documentation, I can't see anything I'm doing that should be disallowed. Why does this code fail to compile? Is there a better package to use than lstlisting for displaying code snippets?

Werner
  • 603,163

3 Answers3

13

It is possible to box the listings first, before using them in a \subfloat. Technically, this is probably similar to @Torbjørn's solution. Boxing is achieved via an lrbox environment.

enter image description here

\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\usepackage{subfig}% http://ctan.org/pkg/subfig
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\begin{document}

\lipsum[1]

% ======= STORE/BOX LISTINGS =======
\newsavebox{\firstlisting}
\begin{lrbox}{\firstlisting}% Store first listing
\begin{lstlisting}
static uint64_t i = 0;
void every_cycle()
{
  if (i > 0)
  i--;
}
\end{lstlisting}
\end{lrbox}
\newsavebox{\secondlisting}
\begin{lrbox}{\secondlisting}% Store second listing
\begin{lstlisting}
uint64_t next_num()
{
  return (i += 0x100);
}
\end{lstlisting}
\end{lrbox}

\begin{figure}[h]
  \caption{These are my awesome code snippets} \label{fig:algOffset}
  \subfloat[This code runs every cycle.]{\usebox{\firstlisting}} \hfill%
  \subfloat[This code runs whenever.]{\usebox{\secondlisting}}
\end{figure}

\lipsum[2]
\end{document}​
Werner
  • 603,163
8

I do not know why the lstlistingsenvironment fails, but having the code in an external file and using \lstinputlisting{filename} instead works.

The filecontents* environment will write its content to code.txt (and overwrite the file should it exist). Thanks Werner, for the suggestion.

\documentclass{article}
\usepackage{listings}
\usepackage{subfig}
\usepackage{filecontents}

\begin{filecontents*}{code.txt}
    static uint64_t i = 0;
    void every_cycle()
    {
        if (i > 0)
            i--;
    }

        uint64_t next_num()
    {
        return (i += 0x100);
    }
\end{filecontents*}
\begin{document}
\begin{figure}[h]
  \caption{These are my awesome code snippets}
  \subfloat[This code runs every cycle.]{\lstinputlisting[lastline=6]{code.txt}}
  \hfill
  \subfloat[This code runs whenever.]{\lstinputlisting[firstline=8]{code.txt}}
  \label{fig:algOffset}
\end{figure}
\end{document}

enter image description here

firstline=n and lastline=n does what you would think, it defines the first/last line in the file to be included in the listing.

Torbjørn T.
  • 206,688
  • "I do not know why the lstlistingsenvironment fails, but having the code in an external file and using \lstinputlisting{filename} instead works." I think that this is because subfloat and co do not like verbatim environments. – WaelJ Jun 14 '14 at 00:22
0

A solution that works for me was to use a parbox inside the subfloat:

\begin{figure}[h]
    \centering
    \subfloat[Example lstlisting]{%
        \parbox{6cm}{
        \lstinputlisting[language=json]{exampleJSON.json}
        }
    }
    \hfill
    \subfloat[Other Table]{%
        \begin{tabular}{l|l}
            \textbf{A} & \textbf{B} \\ \hline
            C & D
        \end{tabular}
    }
    \caption{lstlisting next to a table in subfloats}
\end{figure}
frid000
  • 21