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.
\begin{equation}
1+1=2
\end{equation}
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
}
proofis 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:19proofis definitely a list, at least inamsthmandntheorem; in those two packages, it is atrivlist. there is a switch\if@noskipsecthat, if set to\@noskipsectruewill, 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