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:
This is an abbreviation for
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.