Execute condition in “last” environment typeset of it's type

I am trying to write some code that will clean up some future notes for me. In essence I want to be able to "turn on" or "turn off" an environment (proofs of results) via a simple command. I managed this with the environ package easily enough, but without the proof environments the theorems are all too close together and get cluttered. Thus I wanted to inject some space and a hrule to separate them, just for a nice visual. Again, accomplishing this was trivial, just adding the relevent code at the end of my new environment code, but this would put space and a hrule after every theorem... including the last one. Is there a way to know if the given environment is the "last" environment to be typeset, and then not put the line there? I was thinking about trying to do some kind of stepcounter system where it would expand at the end and thus know that the one that had "counter 17" is the last one and expand a macro only there (or everywhere but there).

Here is my MWE that has the undesired hrule at the end:

\documentclass{article}

% Packages
\usepackage{amsmath}
\usepackage{environ}% Used to hide proofs for condensed version of what we want to see.
\newcommand{\hideproofs}{%
\RenewEnviron{proof}{%
\vspace{1cm}
\hrule%

\vspace{1cm}
}%
}%

\begin{document}

\hideproofs% Comment this out to show proofs.

\begin{theorem}
This is theorem 1!
\end{theorem}
\begin{proof}
This is the first proof! It should be hidden when the hideproof command is on
and instead have the spacing and the hrule,
but it should show when hideproof is commented out.
\end{proof}

\begin{theorem}
This is theorem 2!
\end{theorem}
\begin{proof}
This is the second proof! It should also be hidden when the hideproof command is on
and instead have the spacing and the hrule,
but it should show when hideproof is commented out.
\end{proof}

\begin{theorem}
This is theorem 3! The last thoerem!
\end{theorem}
\begin{proof}
This is the third proof! It should be hidden when the hideproof command is on
and instead NOT have the spacing OR the hrule,
but it should still show when hideproof is commented out.
\end{proof}

\end{document}

• You would need to write to the .aux file for that since an environment at the time it is processed can not know if it is the last one or not. Maybe totcount can help you (it does the .aux writing for you). – moewe Aug 26 '18 at 16:59

Suggestion: Use zref's abspage-modul and have LaTeX place a label both at the beginning and at the end of the theorem.

Have LaTeX draw the line above the theorem only if the end of the previous theorem and the beginning of the current theorem are on the same page.

In case there is some text between theorems on the same page, you can use \suppressline.

\documentclass{article}

% Packages
\usepackage{amsmath}
\usepackage{environ}% Used to hide proofs for condensed version of what we want to see.
\usepackage[abspage]{zref}%
\usepackage[english]{fnumprint}%
\usepackage{lipsum}%

\newcounter{absthms}%

\newif\ifproofs\global\proofstrue
\newcommand{\hideproofs}{%
\RenewEnviron{proof}{}%
\global\proofsfalse
}%

\newif\ifsuppressline\global\suppresslinefalse
\newcommand\suppressline{\global\suppresslinetrue}%

\makeatletter

\newtheorem{theorem}{Theorem:\zref@labelbyprops{absthmsstrt\number\value{absthms}}{abspage}}%
\newtheorem{proof}{Proof:}

\newcommand\MySavedTheorem{}%
\newcommand\MySavedEndTheorem{}%
\let\MySavedTheorem=\theorem
\let\MySavedEndTheorem=\endtheorem
\def\theorem{%
\global\stepcounter{absthms}%
\ifproofs\else
\ifsuppressline\global\suppresslinefalse\else
\vspace{1cm}%
\hrule
\ifnum\number\numexpr\number
\zref@extractdefault{absthmsend\number\numexpr\number\value{absthms}-1\relax}{abspage}{0}-%
\number\zref@extractdefault{absthmsstrt\number\value{absthms}}{abspage}{0}\relax=0 %
\else
width 0pt
\fi
\vspace{1cm}%
\fi\fi
\MySavedTheorem
}%
\def\endtheorem{\zref@labelbyprops{absthmsend\number\value{absthms}}{abspage}\MySavedEndTheorem}%

\makeatother

\begin{document}

\hideproofs% Comment this out to show proofs.

\def\tmpcnt{1}
\loop
\begin{theorem}
This is theorem \tmpcnt!
\end{theorem}
\begin{proof}
This is proof number \fnumprint{\tmpcnt}! It should be hidden when the hideproof command is on
and instead NOT have the spacing OR the hrule,
but it should still show when hideproof is commented out.
\end{proof}
\ifnum\tmpcnt<8 %
\edef\tmpcnt{\number\numexpr\tmpcnt+1\relax}
\repeat

\lipsum[1]

\suppressline
\def\tmpcnt{9}
\loop
\begin{theorem}
This is theorem \tmpcnt!
\end{theorem}
\begin{proof}
This is proof number \fnumprint{\tmpcnt}! It should be hidden when the hideproof command is on
and instead NOT have the spacing OR the hrule,
but it should still show when hideproof is commented out.
\end{proof}
\ifnum\tmpcnt<20 %
\edef\tmpcnt{\number\numexpr\tmpcnt+1\relax}
\repeat

\end{document}


You can use totcount:

\documentclass{article}

% Packages
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{environ}
\usepackage{totcount}

\newtheorem{theorem}{Theorem}

\newtotcounter{proof}

\newcommand{\hideproofs}{%
\RenewEnviron{proof}{%
\stepcounter{proof}
\ifnum\value{proof}=\totvalue{proof}%
\else
\vspace{1cm}
\hrule
\vspace{1cm}
\fi
}%
}

\begin{document}

\hideproofs% Comment this out to show proofs.

\begin{theorem}
This is theorem 1!
\end{theorem}
\begin{proof}
This is the first proof! It should be hidden when the hideproof command is on
and instead have the spacing and the hrule,
but it should show when hideproof is commented out.
\end{proof}

\begin{theorem}
This is theorem 2!
\end{theorem}
\begin{proof}
This is the second proof! It should also be hidden when the hideproof command is on
and instead have the spacing and the hrule,
but it should show when hideproof is commented out.
\end{proof}

\begin{theorem}
This is theorem 3! The last theorem!
\end{theorem}
\begin{proof}
This is the third proof! It should be hidden when the hideproof command is on
and instead NOT have the spacing OR the hrule,
but it should still show when hideproof is commented out.
\end{proof}

\end{document}


This needs two runs to synchronize.

• Within the question it was not asked, but what are the best ways for ensuring that the \hrule does not wind up at the top or at the bottom of a page/column? (What I did in my own answers to the question occurs like bumbling around to me. ;-) ) – Ulrich Diez Aug 27 '18 at 11:36
• @UlrichDiez I would not bother. I don’t think this is an effective method. – egreg Aug 27 '18 at 14:10

One more suggestion:

Via \vskip insert \cleaders at the begin of each theorem. Vertical glue/a \vskip and thus the \cleaders will be removed in case that glue would occur at the beginning of the next page as it does not fit on the current page any more.

In order to get exactly one instance of \cleaders, the vertical skip must fit the height and width of the vertical leader-box.

There is the edge case of having space at the bottom of the page for the vertical gaps and the rule but nothing else. Perhaps this can woked around by decreasing the penalty for (page)breaks before the vertical gap, thus encouraging (La)TeX to do the pagebreak before inserting the vertical skip with the \cleaders for the line.

\documentclass{article}

% Packages
\usepackage{amsmath}
\usepackage{environ}% Used to hide proofs for condensed version of what we want to see.
\usepackage[english]{fnumprint}%
\usepackage{lipsum}%

\newlength\thmruledistance
% Above and below theorems \topsep-glue is added by the
% theorem-environment.
\setlength\thmruledistance{\dimexpr1cm-\topsep\relax}

\newif\ifproofs\global\proofstrue
\newcommand{\hideproofs}{%
\RenewEnviron{proof}{}%
\global\proofsfalse
}%

\newif\ifsuppressline\global\suppresslinefalse
\newcommand\suppressline{\global\suppresslinetrue}%
\newbox\MyTempBox

\newcommand\breakwithline{%
\ifproofs\else
\ifsuppressline
\par\noindent\vskip-\parskip\global\suppresslinefalse
\else
\par\noindent\vskip-\parskip\penalty-200\relax
% Without specification height of a \hrule is 0.4pt, depth is 0pt.
\setbox\MyTempBox\vtop to \dimexpr0.4pt+2\thmruledistance\relax{%
{\offinterlineskip\vfill\noindent\hrulefill\vfill}%
}%
\vskip-\topsep\vskip-\lineskip
\fi
\fi
}

\newtheorem{theorem}{Theorem:}%
\newtheorem{proof}{Proof:}

\newcommand\MySavedTheorem{}%
\let\MySavedTheorem=\theorem
\def\theorem{%
\breakwithline
\MySavedTheorem
}%

\begin{document}

\hideproofs% Comment this out to show proofs.

\lipsum[3]

\suppressline
\def\tmpcnt{1}
\loop
\begin{theorem}
This is theorem \tmpcnt!
\end{theorem}
\begin{proof}
This is proof number \fnumprint{\tmpcnt}! It should be hidden when the hideproof command is on
and instead NOT have the spacing OR the hrule,
but it should still show when hideproof is commented out.
\end{proof}
\ifnum\tmpcnt<9 %
\edef\tmpcnt{\number\numexpr\tmpcnt+1\relax}
\repeat

\lipsum[1]\lipsum[3]

\suppressline
\def\tmpcnt{10}
\loop
\begin{theorem}
This is theorem \tmpcnt!
\end{theorem}
\begin{proof}
This is proof number \fnumprint{\tmpcnt}! It should be hidden when the hideproof command is on
and instead NOT have the spacing OR the hrule,
but it should still show when hideproof is commented out.
\end{proof}
\ifnum\tmpcnt<30 %
\edef\tmpcnt{\number\numexpr\tmpcnt+1\relax}
\repeat

\lipsum[4]

\end{document}