44

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?

5 Answers 5

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
4
  • 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, 2020 at 23:42
  • \excludecomment{}, what a lifesaver. Thanks for pointing this out.
    – vanPelt2
    Sep 27, 2021 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, 2022 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. Jan 16 at 17:48
15

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}
8
  • I think \NewEnviron{myenv}{}{ should be \NewEnviron{myenv}{%. Apr 11, 2011 at 9: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. Apr 11, 2011 at 9: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. Apr 11, 2011 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>]. Apr 11, 2011 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, 2022 at 0:43
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"
1
  • 2
    1. 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? Jun 5, 2013 at 8:22
1

This is an implementation of the non-catcode-changing method (bullet point 2 in David's answer below).

\documentclass{article}
\usepackage{environ}

\ExplSyntaxOn

\NewEnviron{disposecontentinside}{}

\newif\ifshow

\newenvironment{testenv}{
    \ifshow
        \let\execute_this_when_environment_end\relax  % = do nothing when environment end
        % then do nothing
    \else
        % in this case, we want to execute \disposecontentinside here, and \enddisposecontentinside when the environment ends:
        \let\execute_this_when_environment_end\enddisposecontentinside
        \expandafter\disposecontentinside   % see https://tex.stackexchange.com/questions/21262/what-do-firstoftwo-and-secondoftwo-do/ for explanation for the expandafters
    \fi
}{
    \execute_this_when_environment_end
}

\ExplSyntaxOff

\begin{document}

\showtrue
\begin{testenv}
    show this
\end{testenv}

\showfalse
\begin{testenv}
    hide this
\end{testenv}
\end{document}

Advantages...

  • keep synctex (unlike this other answer)
  • can use \verb inside (except when it's something like \verb+}+ then you get problems with brace balancing if \showfalse)
  • can use inside the argument of another commands etc.
  • don't need to copy paste the code of environ package to grab the body
  • unlike this other answer, it can be used even when the conditional is only known when the environment begins

Other solutions include

The 2 methods above has the property that the inner content are still executed instead of being "skipped over".

1
1

When doing that for exercises/exams/etc, I want also to have a separate numbering for equations and floats (figures and tables). So my solution is to have this:

% requires ifthenelse package
\newboolean{Solucion} % True/False to show the solution
\setboolean{Solucion}{true} %

% define the color we use to typeset the solution, requires xcolor
\colorlet{darkgreen}{green!40!black}
\colorlet{darkblue}{blue!40!black}
\colorlet{solcolor}{darkblue}

\usepackage{environ}
\newcounter{soleq}
\makeatletter
\NewEnviron{solution}{\ifSolucion\color{solcolor}%
    \let\c@equation\c@soleq\def\theequation{S\thesoleq}%
\expandafter\BODY\fi}
\makeatother

\usepackage{newfloat}
\DeclareFloatingEnvironment[name={\textcolor{solcolor}{Figura}}]{solfigure}
\renewcommand{\thesolfigure}{\textcolor{solcolor}{S\arabic{solfigure}}}
% This is for use with babel[Spanish,English], adapt to your case
\addto\captionsenglish{\floatname{solcolor}{Figure}}
\addto\captionsspanish{\floatname{solcolor}{Figura}}

This outputs the solution in a different color, and the equations are numbered independently from the main part --- so that the equation and float numbers do not change between the document with and without the solution.

enter image description here

You probably need to tweak that a bit (I use Spanish and English with babel, for example), and it could be made better (notice the color of the figure caption), but I think it's a good starting point.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .