5

In the recent post How to define a proof environment which can be displayed/hidden? [combining two TeX solutions], Werner helped me to redefine a proof environment which can be hidden by an optional boolean argument (showProof). Without an argument, somehow the line/paragraph breaking is not correct. How can one fix this?

\documentclass{scrartcl}

\usepackage{ifthen}
\usepackage{environ}
\usepackage{amsthm}

\newboolean{showProof}% for showing proofs
\setboolean{showProof}{true}% setting the switch
\newif\ifstarttheorem

% proof environment (with hide feature)
\makeatletter
\providecommand{\env@proof@save@env}{}
\providecommand{\env@proof@process}{}
\RenewEnviron{proof}[2][showProof]{
  \gdef\@tmp{#1}%
  \ifthenelse{\boolean{#1}}{\par\pushQED{\qed}%
    \normalfont\topsep2\p@\@plus2\p@\relax
    \trivlist\item[\hskip\labelsep\sffamily\bfseries Proof~#2]\gdef\mycurrenvir{proof}\global\starttheoremtrue\mbox{}\hfill\\*\ignorespaces
    \BODY}{\ignorespaces}
}[\ifthenelse{\boolean{\@tmp}}{%
  \gdef\mycurrenvir{\relax}
  \popQED\endtrivlist\@endpefalse
}{\ignorespacesafterend}]
\makeatother

\begin{document}
Just some text
\begin{proof}
  Just some text in a standard proof. As we can see, there is a problem.
\end{proof}
\begin{proof}[false]
  Proof with optional argument set to \texttt{false}. This proof correctly does
  not appear.
\end{proof}
\begin{proof}[showProof]{(Heading)}
  Proof with optional argument (\texttt{true}) and second argument ``(Heading)''
\end{proof}
\end{document}
  • It seems like you're more interested in having two optional arguments for your proof environment. Is there any reason why you use environ specifically? – Werner Apr 23 '14 at 19:14
  • Hi Werner, thanks for helping. Yes, it's indeed like two optional arguments. There is no specific reason why I use environ, it was just suggested in the post here http://tex.stackexchange.com/questions/172404/solution-environment-via-true-false-switch?noredirect=1#172408 for a solution environment with show/hide feature, that's why I thought I can adapt it for proofs as well. If there's a simpler/easier approach, that would even be better. – Marius Hofert Apr 23 '14 at 19:18
  • you can adapt my answer to your earlier question: Solution environment via true/false switch the xparse package allows great flexibility with optional/mandatory arguments – cmhughes Apr 23 '14 at 19:22
  • I think what Werner alludes to is the fact that your environment, as written, has one optional argument, and one mandatory argument. Your first use case fails to provide the mandatory argument (the label). Thus, the environment grabs the next thing, which is the first letter of your proof, and calls it the label. If your first use case is made as \begin{proof}{}, it gives the expected result. – Steven B. Segletes Apr 23 '14 at 19:26
  • @Steven: thanks for the explanation. @cmhughes: Okay, I haven't thought about this. I read from http://tex.stackexchange.com/questions/98387/defining-a-list-environment-with-multiple-optional-arguments that (of course) if one wants to specify the second optional arg, then the first as to be given as well. Can one then specify the first as 'empty'? (say, the first is the heading, the second the boolean). Hmmm... not very 'natural' but at least xparse seems to be able to address these problems. – Marius Hofert Apr 23 '14 at 19:39
  • @MariusHofert: Yes, it can be empty. But you can also supply different delimiters for the optional argument, say [..](..) for the boolean (show/not) and heading. – Werner Apr 23 '14 at 19:41

2 Answers2

6

I have a different proposal; instead of complicating your life, just redefine proof in such a way that \begin{proof}* doesn't print the proof. Instead of * you can choose whatever (single) character you prefer. After all, it's just a switch, so be it.

\documentclass{scrartcl}

\usepackage{xparse}
\usepackage{environ}
\usepackage{amsthm}

%% save the original macros
\let\amsthmproof\proof
\let\amsthmendproof\endproof

%% redefine proof
\RenewDocumentEnvironment{proof}{s}
 {\IfBooleanTF{#1}
   {\ignoreproof}
   {\amsthmproof}}
 {\IfBooleanTF{#1}
   {\endignoreproof}
   {\amsthmendproof}}

%% In case you want all proofs to appear, comment the above and
%% uncomment the following; a * following \begin{proof} will be ignored
%\RenewDocumentEnvironment{proof}{s}
% {\amsthmproof}
% {\amsthmendproof}

\NewEnviron{ignoreproof}{}

\begin{document}

Just some text

\begin{proof}
  Just some text in a standard proof.
\end{proof}

\begin{proof}*
  Proof with the asterisk appended. This proof correctly does not appear.
\end{proof}

\begin{proof}*[Secondary proof]
  Proof with the asterisk appended. This proof correctly does not appear.
\end{proof}

\begin{proof}[Proof of the main theorem]
  This is the proof of the main theorem.
\end{proof}

\end{document}

enter image description here

If you want a different character, say -, the first line should be

\RenewDocumentEnvironment{proof}{t-}

and the rest would be exactly the same.


A variant code for ignoring all proofs, starred or not; just uncomment the marked line if you want no proof at all.

\documentclass{scrartcl}

\usepackage{xparse}
\usepackage{environ}
\usepackage{amsthm}

%% save the original macros
\let\amsthmproof\proof
\let\amsthmendproof\endproof

%% a conditional for ignoring all proofs
\newif\ifignoreallproof
%\ignoreallprooftrue % <----- uncomment for ignoring all proofs

%% redefine proof
\ifignoreallproof
  \RenewDocumentEnvironment{proof}{s}
   {\ignoreproof}
   {\endignoreproof}
\else
  \RenewDocumentEnvironment{proof}{s}
   {\IfBooleanTF{#1}
     {\ignoreproof}
     {\amsthmproof}}
   {\IfBooleanTF{#1}
     {\endignoreproof}
     {\amsthmendproof}}
\fi

\NewEnviron{ignoreproof}{}

\begin{document}

Just some text

\begin{proof}
  Just some text in a standard proof.
\end{proof}

\begin{proof}*
  Proof with the asterisk appended. This proof correctly does not appear.
\end{proof}

\begin{proof}*[Secondary proof]
  Proof with the asterisk appended. This proof correctly does not appear.
\end{proof}

\begin{proof}[Proof of the main theorem]
  This is the proof of the main theorem.
\end{proof}

\end{document}
egreg
  • 1,121,712
  • Nice idea, indeed. But I'm not sure if it has this 'vertical space is suppressed'-feature (see http://tex.stackexchange.com/questions/66739/how-to-suppress-vertical-space-between-proof-environment-heads-and-itemize-envir/makeatletter) – Marius Hofert Apr 23 '14 at 21:16
  • @MariusHofert Use the redefined proof environment. Where's the problem? That is, redefine the proof environment like in that answer and then apply the code I show here. In any case I remain with my opinion that the word “Proof” should never be on a line by itself. – egreg Apr 23 '14 at 21:24
  • Do you know how to incorporate the following feature? Suppose we have a boolean variable showProof. If this is true then all proofs without star shall appear and if it is false then all proofs without star shall disappear (those with star should always disappear). I tried \ifthenelse{\boolean{showProof}}{\IfBooleanTF{#1}{...}{...}}{} but that didn't work (proofs were still shown on false) – Marius Hofert Apr 23 '14 at 22:35
  • @MariusHofert Yes, I do; it's already on line. – egreg Apr 23 '14 at 22:44
  • With xparse released 2019-03-05 (or later), environ is no longer necessary and the definition of ignoreproof can be \NewDocumentEnvironment{ignoreproof}{+b}{}{} – egreg Mar 09 '19 at 11:33
4

To reiterate from my comment, the problem with your MWE is the fact that your environment, as written, has one optional argument, and one mandatory argument. Your first use case fails to provide the mandatory argument (the label). Thus, the environment grabs the next thing, which is the first letter of your proof, and calls it the label. If your first use case is made as \begin{proof}{}, it gives the expected result.

Since you reply to Werner that "Yes, it's indeed like two optional arguments," I have taken that under advisement. I believe I have made it so that yourproof environment now takes two optional and zero mandatory arguments. Optional arguments are enclosed in square [] brackets, not {} braces.

However, note that, with two optional arguments, you can't specify a second optional argument without also specifying the first optional argument. Thus,

\begin{proof}[(Heading)]

is not a valid invocation. This, in the long run, could be more of a pain than what you started with.

\documentclass{scrartcl}

\usepackage{ifthen}
\usepackage{environ}
\usepackage{amsthm}

\newboolean{showProof}% for showing proofs
\setboolean{showProof}{true}% setting the switch
\newif\ifstarttheorem

% proof environment (with hide feature)
\makeatletter
\providecommand{\env@proof@save@env}{}
\providecommand{\env@proof@process}{}
\renewenvironment{proof}[1][showProof]{%
  \def\proofarg{#1}\proofhelper}{\endproofhelper}
\NewEnviron{proofhelper}[1][]{
  \gdef\@tmp{\proofarg}%
  \ifthenelse{\boolean{\proofarg}}{\par\pushQED{\qed}%
    \normalfont\topsep2\p@\@plus2\p@\relax
    \trivlist\item[\hskip\labelsep\sffamily\bfseries Proof~#1]\gdef\mycurrenvir{proof}\global\starttheoremtrue\mbox{}\hfill\\*\ignorespaces
    \BODY}{\ignorespaces}
}[\ifthenelse{\boolean{\@tmp}}{%
  \gdef\mycurrenvir{\relax}
  \popQED\endtrivlist\@endpefalse
}{\ignorespacesafterend}]
\makeatother

\begin{document}
Just some text
\begin{proof}
  Just some text in a standard proof. As we can see, there is a problem.
\end{proof}
\begin{proof}[false]
  Proof with optional argument set to \texttt{false}. This proof correctly does
  not appear.
\end{proof}
\begin{proof}[showProof][(Heading)]
  Proof with optional argument (\texttt{true}) and second argument ``(Heading)''
\end{proof}
\end{document}

enter image description here