41

Is it possible to prevent lstlisting from splitting a code between pages if it does not fit on one page? Instead splitting I would like to have the code on the next page.

I tried to put all lstlisting inside \begin{figure}[h!]...\end{figure} but the order of code and header is lost.

1

4 Answers 4

30

Define your own listing environment which doesn't allow page breaks

\documentclass[a4paper]{article}
\usepackage{listings}
\usepackage{lipsum}

\lstnewenvironment{code}[1][]%
  {\noindent\minipage{\linewidth}\medskip 
   \lstset{basicstyle=\ttfamily\footnotesize,frame=single,#1}}
  {\endminipage}

\begin{document}

\lipsum[1-4] % some dummy text to get to the bottom of the page

\begin{code}[caption={This is my code. There are many like it, but this one is mine.},
         language=Python]
def jacobian(function, variablelist):
    """
    Calculates symbolically the Jacobian of the vector with respect to 
    the provided variables. Returns a square matrix
    """
    n=len(variablelist)
    J=np.asmatrix(np.zeros((n,n)),dtype=sy.Symbol)

    for i in range(n):
        for k in range(n):
            J[i,k]=function[i,0].diff(variablelist[k])
    return J

def vector(*arglist):
    """
    A shorthand for defining a symbolic column vector. Arguments are 
    supplied as a normal comma-separated list.
    """
    return np.asmatrix(np.array(arglist), dtype=sy.Symbol).transpose()
\end{code}

\end{document}

or use the float option from the package (see documentation)

1
  • This solution has two potential problems which are fixed by Jesse Doherty answer
    – lanoxx
    Jun 29, 2014 at 0:25
15

I found Herbert's answer gave me two problems.

  1. Since the code has to be in its own paragraph, the minipage/listing gets indented.
  2. The listing seems to now ignore the baselinestretch for some reason. Which is a problem when the listing is not pushed onto a new page and the baselineskip is something other than 1.

I fixed these by adding to Herbert's solution:

\lstnewenvironment{code}[1][]%
{
   \noindent
   \minipage{\linewidth} 
   \vspace{0.5\baselineskip}
   \lstset{basicstyle=\ttfamily\footnotesize,frame=single,#1}}
{\endminipage}
0
12

The easiest way to go is to create a custom float using the float package, and put the lstlistings environment inside it. Here's a quick-and-dirty example:

\documentclass[a4paper]{article}
\usepackage{listings}
\usepackage{float}
\usepackage{lipsum} % used to insert dummy text; not required

\floatstyle{plain} % optionally change the style of the new float
\newfloat{Code}{H}{myc}
\lstloadlanguages{Python}

\begin{document}
\lstset{basicstyle=\ttfamily\tiny}

\lipsum[1-4] % some dummy text to get to the bottom of the page

\begin{Code}
    \centering
    \begin{lstlisting}[language=Python]
    def jacobian(function, variablelist):
        """
        Calculates symbolically the Jacobian of the vector with respect to 
        the provided variables. Returns a square matrix
        """

        n=len(variablelist)
        J=np.asmatrix(np.zeros((n,n)),dtype=sy.Symbol)

        for i in range(n):
            for k in range(n):
                J[i,k]=function[i,0].diff(variablelist[k])
        return J

    def vector(*arglist):
        """
        A shorthand for defining a symbolic column vector. Arguments are 
        supplied as a normal comma-separated list.
        """
        return np.asmatrix(np.array(arglist), dtype=sy.Symbol).transpose()

    \end{lstlisting}
    \caption{This is my code. There are many like it, but this one is mine.}
\end{Code}

\end{document}

You can use captions, labels, list of code samples, etc. in the same way you would with normal figures. Check the float package for some extra information about customizing those.

1
  • Note that you don't need \centering because listings are in full width anyway.
    – Nux
    Mar 12, 2014 at 11:31
7

I would try out the float option of the listings package. See section 4.3 of the package documentation.

Edit: I have used it with success, but it has to be defined listing-by-listing, it ignores the float option if set in the global lstset.

Edit #2: For completeness sake I have defined an environment to achieve exactly this, I like mine better than the one provided by Herbert simply because it seems simpler:

% Snippet Listings
\lstnewenvironment{snippet}[1][]
    {\lstset{float=htpb,#1}} 
    {}
4
  • but it is not the same ...
    – user2478
    Feb 3, 2011 at 11:10
  • 1
    Ok, I may be missing something, but doesn't my environment produce floating listings as your own? Or isn't the float option appropriate? I really want to know if I did something wrong. Feb 3, 2011 at 11:14
  • 3
    no, with your setting it is a real floating object. If the OP wants this, than your solution is ok. If he wants his listings exactly at the text position where it is defined, than he cannot use the optional argument float.
    – user2478
    Feb 3, 2011 at 12:56
  • I see, similar to the H! option for figures? I don't think listings supports that float position. Feb 3, 2011 at 12:58

You must log in to answer this question.

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