[Tex/LaTex] Keep text together with minipage; leave space at end of previous page

page-breaking

I have a document that includes text with block of source code interspersed. Here's a minimal example:

\documentclass[twocolumn,twoside]{article}
\flushbottom

\begin{document}

... lots of text ...

To find the primes less than $n$, we use the
ancient Sieve of Eratosthenes:

\vspace*{\fill}
\begin{minipage}{\linewidth}\begin{verbatim}
(define (primes n)
  (let ((bits (make-vector (+ n 1) #t)))
    (let loop ((p 2) (ps (list)))
      (cond ((< n p) (reverse ps))
            ((vector-ref bits p)
              (do ((i p (+ i p))) ((< n i))
                (vector-set! bits i #f))
              (loop (+ p 1) (cons p ps)))
            (else (loop (+ p 1) ps))))))
\end{verbatim}\end{minipage}
\vspace{\baselineskip}

... more text ...

\end{document}

This keeps the source code together on a single column, preventing it from splitting across a column or page break. But what happens when it would normally split is the last line of text in the previous column (before the \vspace) is placed at the top of the new column, before the block of source code, and the previous column is stretched vertically, with extra space between paragraphs.

I want to eliminate that extra vertical space and just leave an empty space at the end of the previous column; it's ugly, but less ugly than the stretched text. As you can see above, I tried to add vertical fill, but that doesn't work. How can I get what I want?

Best Answer

There's an undocumented feature in LaTeX which directly comes from Plain TeX:

\filbreak

This is an abbreviation for

\par\vfil\penalty-200\vfilneg

which does exactly what you need. First it issues \par to ensure vertical mode; then it issues \vfil and \penalty-200. A page break can be taken either at \vfil or at \penalty-200, but not at \vfilneg (because it's preceded by a penalty).

In any case, if the three items end together in a page, the two glues will cancel each other (and the penalty will do nothing). If instead a break is taken at the penalty, the \vfil will fill the page and the \vfilneg will disappear because it's at the top of a new page.

The -200 penalty denotes a good place where breaking a page.