4

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
    Nov 25, 2016 at 10:15
  • Is numbers=right an option, maybe together with xrightmargin=1.2em?
    – gernot
    Nov 25, 2016 at 10:21
  • @gernot numbers=right makes it really hard to see which number belongs to which line when the lines are short.
    – Cephalopod
    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
    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
  • 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
    Nov 25, 2016 at 10:18
  • I mentioned in the question that xleftmargin does not work properly.
    – Cephalopod
    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. Nov 25, 2016 at 11:11
  • Would you mind to post the complete code (i.e., a compilable document)?
    – gernot
    Nov 25, 2016 at 12:36
  • I have added the code. 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
    Nov 25, 2016 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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