TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm using listings with line numbers in a two-column document. When the listing is in the right column, the numbers are too close to the text on the left.

I tried using xleftmargin, but that option also moves the caption to the right.

How can I move only the code and the line numbers to the right, so that they are no longer in the margin?

enter image description here

MWE (ieeetran.cls):

\documentclass[english,conference]{IEEEtran}

\usepackage{lmodern}
\usepackage{listings}

\lstset{captionpos=b}
\lstset{basicstyle=\small\ttfamily}
\lstset{showstringspaces=false, columns=flexible, keepspaces=true}
\lstset{tabsize=2, gobble=2}
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt, numberfirstline=true, firstnumber=1, stepnumber=5}

\usepackage{blindtext}

\begin{document}

\title{The Title}
\author{author}

\maketitle

\begin{abstract}
\blindtext
\end{abstract}

\blindtext[4]

\begin{figure}
    \centering
    mah figure
    \caption{This is a very long caption, it is so long that it spans two lines.}
    \label{myfig}
\end{figure}

\begin{lstlisting}[float,caption={This is a very long caption, it is so long that it spans two lines.},label=mylisting]
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
\end{lstlisting}

\end{document}
share|improve this question
    
Use xleftmargin = <a sensible length> – AboAmmar 4 hours ago
    
Is numbers=right an option, maybe together with xrightmargin=1.2em? – gernot 4 hours ago
    
@gernot numbers=right makes it really hard to see which number belongs to which line when the lines are short. – Cephalopod 4 hours ago
up vote 2 down vote accepted

To shift the numbers but not the caption requires to dig deeper into the listings package.

Instead of the \lst@PlaceNumber command without arguments we define \lst@FormatNumber which takes the number as an argument. This allows us to print also nothing but occupying the same space. We define a new value for the option numbers called LEFT for numbers not in the margin; most of the code is a copy of the original code.

\lst@Key{numbers}{none}{%
    \def\lst@FormatNumber##1{\relax}%   <<<<<<<<<<<<<<<<<<
    \lstKV@SwitchCases{#1}%
    {none&\\%
     left&\def\lst@FormatNumber##1{\llap{\normalfont % <<<<<<<<<<<<<
                \lst@numberstyle{##1}\kern\lst@numbersep}}\\%
     right&\def\lst@FormatNumber##1{\rlap{\normalfont % <<<<<<<<<<<<<
                \kern\linewidth \kern\lst@numbersep
                \lst@numberstyle{##1}}}\\%
     LEFT&\def\lst@FormatNumber##1{\makebox[\lst@LEFTmargin][r]{\normalfont  % <<<<<<<<<<<<<<<<<<<<<<<<<<
                \lst@numberstyle{##1}\kern\lst@numbersep}}% <<<<<<<<<<
    }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}}

Moreover, we have to extend the printing of the number by an else branch such that an 'empty' number is printed in unnumbered lines.

\gdef\lst@SkipOrPrintLabel{%
    \ifnum\lst@skipnumbers=\z@
        \global\advance\lst@skipnumbers-\lst@stepnumber\relax
        \lst@FormatNumber{\thelstnumber}%     <<<<<<<<<<<<<<<<<
        \lst@numberfirstlinefalse
    \else
        \lst@ifnumberfirstline
            \lst@FormatNumber{\thelstnumber}% <<<<<<<<<<<<<<<<<
            \lst@numberfirstlinefalse
        \else                               % <<<<<<<<<<<<<<<<<
            \lst@FormatNumber{}%              <<<<<<<<<<<<<<<<<
        \fi
    \fi
    \global\advance\lst@skipnumbers\@ne
}

Finally, to control the width reserved for the number, we introduce a new key LEFTmargin with default value 2em.

\lst@Key{LEFTmargin}{2em}{\def\lst@LEFTmargin{#1}}

If these definitions are included in the preamble instead of in a file loaded by \usepackage, they have to be enclosed by \makeatletter and \makeatother.

Here is the sample code from the original posting.

enter image description here

\documentclass[english,conference]{IEEEtran}
\usepackage{lmodern}
\usepackage{listings}
\lstset{captionpos=b}
\lstset{basicstyle=\small\ttfamily}
\lstset{showstringspaces=false, columns=flexible, keepspaces=true}
\lstset{tabsize=2, gobble=2}
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt,
   numberfirstline=true, firstnumber=1, stepnumber=5}
\usepackage{blindtext}

\makeatletter
\lst@Key{numbers}{none}{%
    \def\lst@FormatNumber##1{\relax}%
    \lstKV@SwitchCases{#1}%
    {none&\\%
     left&\def\lst@FormatNumber##1{\llap{\normalfont
                \lst@numberstyle{##1}\kern\lst@numbersep}}\\%
     right&\def\lst@FormatNumber##1{\rlap{\normalfont
                \kern\linewidth \kern\lst@numbersep
                \lst@numberstyle{##1}}}\\%
     LEFT&\def\lst@FormatNumber##1{\makebox[\lst@LEFTmargin][r]{\normalfont
                \lst@numberstyle{##1}\kern\lst@numbersep}}%
    }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}}
\gdef\lst@SkipOrPrintLabel{%
    \ifnum\lst@skipnumbers=\z@
        \global\advance\lst@skipnumbers-\lst@stepnumber\relax
        \lst@FormatNumber{\thelstnumber}%
        \lst@numberfirstlinefalse
    \else
        \lst@ifnumberfirstline
            \lst@FormatNumber{\thelstnumber}%
            \lst@numberfirstlinefalse
        \else
            \lst@FormatNumber{}%
        \fi
    \fi
    \global\advance\lst@skipnumbers\@ne
}
\lst@Key{LEFTmargin}{2em}{\def\lst@LEFTmargin{#1}}
\makeatother

\begin{document}
\title{The Title}
\author{author}
\maketitle
\begin{abstract}
\blindtext
\end{abstract}
\blindtext[4]
\begin{figure}
    \centering
    mah figure
    \caption{This is a very long caption, it is so long that it spans two lines.}
    \label{myfig}
\end{figure}

\begin{lstlisting}[numbers=LEFT,LEFTmargin=1.2em,numbersep=2pt,float,caption={This is a very long caption, it is so long that it spans two lines.},label=mylisting]
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
\end{lstlisting}
\end{document}
share|improve this answer
    
Wow. Thank you. (I just noticed that this problem does not occur with ACM two-column layouts. I wonder what they are doing different...) – Cephalopod 2 hours ago

I think the only way to shift the code to the right is using xleftmargin.

\lstset{xleftmargin=2em} % or some other value

If you want the caption to stay unshifted, I would suggest not to use the float parameter, but to use a separate float environment.

\usepackage{float}
\newfloat{listing}{htbp}{lol}
\floatname{listing}{Listing}

\begin{listing}
\begin{lstlisting}
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
\end{lstlisting}
\caption{This is a very long caption, it is so long that it spans two lines.}
\label{mylisting}
\end{listing}

enter image description here

share|improve this answer
1  
I came up with the same 'solution' but found that this parameter shifts the whole float including the caption, which then protrudes into the right margin. – gernot 4 hours ago
    
I mentioned in the question that xleftmargin does not work properly. – Cephalopod 4 hours ago
    
Sorry, I overlooked that. Now I have updated my answer with a solution that keeps the caption to the left. – Piet van Oostrum 3 hours ago
    
Thank you for this solution – Cephalopod 2 hours ago
    
Would you mind to post the complete code (i.e., a compilable document)? – gernot 2 hours ago

Use xleftmargin=1em or something like that and reduce the columnwidth for the listing by the same amount.

enter image description here

\documentclass[english,conference]{IEEEtran}
\usepackage{lmodern}
\usepackage{listings}
\lstset{captionpos=b}
\lstset{basicstyle=\small\ttfamily}
\lstset{showstringspaces=false, columns=flexible, keepspaces=true}
\lstset{tabsize=2, gobble=2}
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt,
  numberfirstline=true, firstnumber=1, stepnumber=5}
\usepackage{blindtext}
\begin{document}
\title{The Title}
\author{author}
\maketitle
\begin{abstract}
\blindtext
\end{abstract}
\Blindtext

{\advance\columnwidth-1em%
\begin{lstlisting}[xleftmargin=1em,float,caption={This is a very long caption, it is so long that it spans two lines.},label=mylisting]
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
  teh c0dez
\end{lstlisting}}
\end{document}
share|improve this answer
    
Looks good, but still moves the caption so that it does not align with the caption of figures. See the updated mwe. – Cephalopod 4 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.