[Tex/LaTex] Listings line numbers and figure

line-numberinglistings

I'm using listings to typeset some C inside a figure environment next to a diagram, and I have the numbers on the left. My problem is in two-column mode the line numbers appear in what should be the margin, outside the text area (i.e., numbers are not justified with the left-hand side of the column, but instead slightly to the left of the justification). The code I'm using is:

\begin{figure*}
  \begin{minipage}{.45\textwidth}
   \begin{lstlisting}[numbers=left]
    i = 0;
    j = 1;
   \end{lstlisting}
  \end{minipage}\hfill
  \begin{minipage}{.45\textwidth}
     \includegraphics{figure}
  \end{minipage}
 \caption{My caption}
 \label{fig:blah}
\end{figure*}

Is there a way to keep the line numbers from lstlisting inside the text area?

Best Answer

The listings code to write the line numbers is stored in \lst@PlaceNumber. Under numbers=left it is defined as:

\def\lst@PlaceNumber{\llap{\normalfont
  \lst@numberstyle{\thelstnumber}\kern\lst@numbersep}}%

which prints the number as a left overlap, causing the "problems" you experience. You could just push the entire lstlisting over by at least the above amount (say, 1em+\lst@numbersep) to allow the left overlap to still be within the text block boundary:

enter image description here

\documentclass[twocolumn]{article}
\usepackage[demo]{graphicx}% http://ctan.org/pkg/graphicx
\usepackage{showframe}% http://ctan.org/pkg/showframe
\usepackage{listings}% http://ctan.org/pkg/listings
\begin{document}
\begin{figure*}
  \makeatletter%
  \hspace*{\dimexpr 1em+\lst@numbersep}%
  \makeatother%
\begin{minipage}{.4\textwidth}
\begin{lstlisting}[numbers=left]
i = 0;
j = 1;
\end{lstlisting}
  \end{minipage}\hfill
  \begin{minipage}{.4\textwidth}
     \includegraphics{figure}
  \end{minipage}
 \caption{My caption}
 \label{fig:blah}
\end{figure*}
\end{document}

I've added showframe to highlight the text block boundary, and the [demo] option to graphicx in order to run the MWE. They are not needed in your final document.

Alternatively you can set the numbers to be shown left globally (using \lstset{numbers=left}) and then redefine \lst@PlaceNumber accordingly:

\makeatletter%
\def\lst@PlaceNumber{\makebox[\dimexpr 1em+\lst@numbersep][l]{\normalfont
  \lst@numberstyle{\thelstnumber}}}%
\makeatother%

The global setting is required in order to have the redefinition last beyond \begin{lstlisting}.