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.

czuk
  • 563

4 Answers4

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)

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}
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.

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}} 
    {}
Tiago Veloso
  • 4,599
  • but it is not the same ... –  Feb 03 '11 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. – Tiago Veloso Feb 03 '11 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. –  Feb 03 '11 at 12:56
  • I see, similar to the H! option for figures? I don't think listings supports that float position. – Tiago Veloso Feb 03 '11 at 12:58