thmtools: How to prevent pagebreak between theorem and proof?

I am using thmtools to format a collection of theorems and their proofs.

Is there any way to prevent a pagebreak from happening between the last line of a theorem statement and the first line of the proof?

I tried inserting \nopagebreak, like this

\end{thorem}
\nopagebreak[4]
\begin{proof}


...but it failed to suppress the pagebreak.

The first line of the first proof on any one page should be preceded by at least two lines from the theorem statement. (The proof always follows immediately after the statement; there never is intervening text not belonging to either environment).

FWIW: I searched for multiple variants of "pagebreak", "page break", "nopagebreak" in the thmtools docs, but got no hits.

Thanks!

-
I think proof is pretty much always a list and lists tend to insert a negative penalty before they start (i.e., a break between theorem and proof is made more favourable than a break after the first line of the proof). –  Ulrich Schwarz Sep 12 '11 at 12:19
proof is definitely a list, at least in amsthm and ntheorem; in those two packages, it is a trivlist. there is a switch \if@noskipsec that, if set to \@noskipsectrue will, after an ordinary section heading, suppress a break. whether this would work to suppress a break between theorem and proof is unknown; haven't tested. but it's the only plausible approach i can see. ugly. –  barbara beeton Sep 12 '11 at 12:55

Given that the theorem and proof environments are quite separate, it's indeed a bit tricky to forbid categorically all pagebreaks between them. All I can suggest is that you load the package needspace and insert the command

\Needspace{3\baselineskip}


close to the end of the statement of the theorem/corollary/whatever; note the uppercase N at the start of the macro. According to the manual of the needspace package, the command "\Needspace{} is less efficient [than \needspace{}] but reserves the requested space exactly. It should only be used between paragraphs." Given that you're basically facing this situation, you may want to give it a try.

You'll probably have to practice a bit to determine the best placement of this command and the number of baseline skips you require in order to always get at least two lines of the proof statement to show up on the same page as the associated theorem.

-
Thanks++, this gets the job done, and it comes in handy in many other situations. BTW, my theorem statements tend to be pretty short, which means that, to prevent the pagebreak between statement and proof usually I need to put the Needspace{} command right before the former. –  kjo Sep 24 '11 at 15:08
One potential difficulty here: the \Needspace command is only supposed to be used between paragraphs, and its cousin the \needspace command will automatically introduce a paragraph break. So if you want to use this in the middle of a paragraph near the end of the theorem, you will at least want to use something like \linebreak\needspace{4\baselineskip}\noindent, and also be careful about the placement to avoid a bad line break. –  Charles Staats Dec 10 '12 at 23:06

The following creates a command, \reservespace. If the (entire) theorem is passed in as an argument, it will use the \needspace command to make sure that there is not a page break right after the theorem.

\usepackage{needspace,calc}
\newlength{\heightRecaller}
\newcommand{\reservespace}[1]{%
\let \oldstepcounter \stepcounter%
\renewcommand{\stepcounter}[1]{}%
\settototalheight{\heightRecaller}{\parbox{\textwidth}{#1}}%
\let \stepcounter \oldstepcounter%
\needspace{\heightRecaller+4\baselineskip}%
#1%
}


There's a complete working example below, using amsthm. Here are some caveats:

• Without the temporary redefinition of \stepcounter, any counters incremented will be incremented twice--once during the "phantom pass" used only to compute the height, and again during the actual typesetting of the theorem. However, this redefinition may well have unpleasant side effects that go beyond my limited knowledge, so it may be safer simply to reset by hand all the counters you expect to be used. There's a "safer version" at the very bottom of my answer.
• With this command, it is not possible to split the theorem statement across pages, which may be problematic if there is a long statement.
• The command appears to increase the space before a theorem statement on which it is used. (Note that the same appears to happen if a \needspace or \Needspace command is used right before the theorem statement, so this difficulty is not specific to this answer.)

The complete working example, which illustrates the need that led me to study this question--namely, that my students found it confusing when a solution box was not on the same page as the problem statement:

\documentclass[letterpaper]{article}
\usepackage{lipsum}

\usepackage{amsthm}
\theoremstyle{plain}
\newtheorem{exercise}{Exercise}

\usepackage{xcolor}
\newcommand{\blank}[1]{\textcolor{white}{#1}}
%\newcommand{\blank}[1]{#1}

\usepackage{framed}
\newenvironment{solution}%
{\begin{proof}[Solution]\begin{oframed}}%
{\end{oframed}\end{proof}}

\usepackage{needspace,calc}
\newlength{\heightRecaller}
\newcommand{\reservespace}[1]{%
\let \oldstepcounter \stepcounter%
\renewcommand{\stepcounter}[1]{}%
\settototalheight{\heightRecaller}{\parbox{\textwidth}{#1}}%
\let \stepcounter \oldstepcounter%
\needspace{\heightRecaller+4\baselineskip}%
#1%
}

\begin{document}
\lipsum[1-4]
\reservespace{
\begin{exercise}
This is an exercise that involves an equation, which is printed below.
$$1+1=2$$
Please study the equation and somehow do something in the Solution box,
which may or may not be filled in depending on which line is commented out.
Please study the equation and somehow do something in the Solution box,
which may or may not be filled in depending on which line is commented out.
\end{exercise}
}
\begin{solution}
\blank{%
\lipsum[5-6]\qedhere%
}
\end{solution}
%
%
\reservespace{
\begin{exercise}
Another exercise goes here.
\end{exercise}
}
\begin{solution}
\blank{%
\lipsum[7]\qedhere%
}
\end{solution}
\end{document}


Here's a "safer version" of the \reservespace command that could be used for the working example above. (It resets the equation and exercise counters by hand, rather than temporarily redefining \stepcounter.)

\usepackage{needspace,calc}
\newlength{\heightRecaller}
\newcounter{temp_exercise}
\newcounter{temp_equation}
\newcommand{\reservespace}[1]{
\setcounter{temp_exercise}{\value{exercise}}
\setcounter{temp_equation}{\value{equation}}
\settototalheight{\heightRecaller}{\parbox{\textwidth}{#1}}
\setcounter{exercise}{\value{temp_exercise}}
\setcounter{equation}{\value{temp_equation}}
\needspace{\heightRecaller+4\baselineskip}
#1
}

-