46

I have a custom environment which adds some text around its content, but I also want it to be able to show or hide its contents depending on a boolean.

I have tried doing the following:

\newif\ifshow
\showfalse
\newenvironment{myenv}
{\ifshow\textbf{Content of myenv:}}
{\fi}

But the first \begin{myenv} raises an Incomplete \iffalse; all text was ignored after line X. It would seem that the \iffalse is causing the \end{myenv} to be ignored, so the \fi is never written.

Any idea on how could I accomplish this?

lockstep
  • 250,273

5 Answers5

45

I usually do it the other way around, i.e. define "different environments" based on the if. I use the comment package for excluding the contents of the environment.

\usepackage{comment}
\ifshow
  \newenvironment{myenv}{\textbf{Content of myenv:}}{}
\else
  \excludecomment{myenv}
\fi
  • 1
    FYI This doesn't work with Beamer documents. I did not understand the source of the error but this conversation indicates that the version package can be used in place of comment. So: \usepackage{version} and \excludeversion{myenv}. – Dominique Mar 24 '20 at 23:42
  • \excludecomment{}, what a lifesaver. Thanks for pointing this out. – vanPelt2 Sep 27 '21 at 15:31
  • @Dominique You saved my day! The \excludeversion is the only solution that works for my section with minted content. Thank you, mate! – Ma3x Sep 19 '22 at 15:11
  • Is it possible to combine this with 2 differently named short environments (following the \maybe example in the comment package description)? I have \maybe and \alternative, and I would like to always only have either or. – canIchangethis Jan 16 '23 at 17:48
16

Another way to do this is to use the environ package and conditionally keep or toss the \BODY.

\usepackage{environ}
\NewEnviron{myenv}{
  \ifshow
    \textbf{Content of myenv: \BODY}
  \fi}
Matthew Leingang
  • 44,937
  • 14
  • 131
  • 195
  • I think \NewEnviron{myenv}{}{ should be \NewEnviron{myenv}{%. – Martin Scharrer Apr 11 '11 at 09:39
  • I wonder what's the difference in efficiency is between \NewEnviron environments and the comment package. The first one might be significant slower if there are a lot of sub-environments. AFAIK it scans for \end until the \end{myenv} is reached. The comment package skips everything verbatim instead, which has the initial catcode-change overhead. – Martin Scharrer Apr 11 '11 at 09:41
  • @Martin: you're right about the syntax. For some reason I thought you could have opening code. As for the efficiency, I hadn't thought about it—I bet it wouldn't make a big difference until you get up to 100 pages or so. I use the first method but it was before I found out about environ so I thought I would throw it out there. – Matthew Leingang Apr 11 '11 at 11:58
  • The first argument is the opening code. You can set some end-code with the trailing optional argument \NewEnviron{myenv}{code \BODY code}[<end-of-env code>]. – Martin Scharrer Apr 11 '11 at 12:15
  • This has another disadvantage, namely you can't use verbatim content inside the environment. (as well as losing synctex support) – user202729 May 30 '22 at 00:43
  • @user202729: Quite true. – Matthew Leingang May 31 '22 at 17:32
  • That's too bad about the verbatim, and listings don't work for me either. Otherwise this would be great, since it can be turned on and off. – Guido Sep 23 '22 at 04:32
  • @Guido listings uses the same kind of catcode hackery as verbatim, so no surprise that they both don't work – Matthew Leingang Sep 23 '22 at 17:22
5

I use

\newcommand\suppress[1]{} 

in combination with

\newcommand\myOptElse[3]{\ifthenelse{\boolean{#1}}%
{#2\suppress{#3}}%
{\suppress{#2}#3}}% if #1 then #2 else #3

and a boolean variable. This enables me to change between #2 and #3 with an ON/OFF switch #1.

Example:

%Declare the boolean variable    
\newboolean{showmyenv} %Testblöcke anzeigen
%
%Set to OFF
\setboolean{showmyenv}{false}
\myOptElse{showmyenv}{MyEnv content}{Alternative content} 
%the above will show "Alternative content", if you do not want any, leave it empty
%
%Set to ON
\setboolean{showmyenv}{true}
\myOptElse{showmyenv}{MyEnv content}{Alternative content} 
%the above will show "MyEnv content"
Werner
  • 603,163
  • 2
  • You need to include the ifthenelse package for your code. However, generally the commands from etoolbox should be preferred. 2. The questioner asks how to apply this to environments. Can you give a complete working document?
  • – Andrew Swann Jun 05 '13 at 08:22