5

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}
3
  • Use xleftmargin = <a sensible length>
    – AboAmmar
    Commented Nov 25, 2016 at 10:15
  • Is numbers=right an option, maybe together with xrightmargin=1.2em?
    – gernot
    Commented Nov 25, 2016 at 10:21
  • 1
    @gernot numbers=right makes it really hard to see which number belongs to which line when the lines are short.
    – Cephalopod
    Commented Nov 25, 2016 at 10:30

3 Answers 3

5

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}
1
  • 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
    Commented Nov 25, 2016 at 12:14
8

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.

\documentclass[english,conference]{IEEEtran}

\usepackage{lmodern}
\usepackage{listings}
\usepackage{float}
\newfloat{listing}{tbp}{lol}
\floatname{listing}{Listing}
\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}
\lstset{xleftmargin=2em}

\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{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}
\blindtext
\end{document}

enter image description here

5
  • 2
    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
    Commented Nov 25, 2016 at 10:18
  • I mentioned in the question that xleftmargin does not work properly.
    – Cephalopod
    Commented Nov 25, 2016 at 10:32
  • Sorry, I overlooked that. Now I have updated my answer with a solution that keeps the caption to the left. Commented Nov 25, 2016 at 11:11
  • Would you mind to post the complete code (i.e., a compilable document)?
    – gernot
    Commented Nov 25, 2016 at 12:36
  • I have added the code. Commented Nov 25, 2016 at 17:20
2

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}
1
  • Looks good, but still moves the caption so that it does not align with the caption of figures. See the updated mwe.
    – Cephalopod
    Commented Nov 25, 2016 at 10:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .