8

I am relatively new to writing LaTeX packages. I would like to create an environment so that anything contained in that environment can be ignored when producing output. The desired behavior would be the following:

\documentclass{article}
\usepackage[hide]{MyPackage}
\begin{document}
This should always show up.
\begin{Hidden}
This should show up unless the [hide] option is used.
\end{Hidden}
\end{document}

One possible use case: if I write a problem set for a class, I can write the solutions into the same document wrapped in the Hidden environment. That way, I can compile with the [hide] option to produce the problem set for my students, and I can recompile without the [hide] option to produce the solution set.

Here's the code I currently use to accomplish this. It was at some point borrowed from a package offering similar functionality, but unfortunately I can't remember the original package.

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyPackage}
\RequirePackage{ifthen}
\newboolean{MyPackage@hidden}
\setboolean{MyPackage@hidden}{false}
\DeclareOption{hide}{\setboolean{MyPackage@hidden}{true}}
\ProcessOptions\relax
\newenvironment{Hidden}
    {\ifthenelse{\boolean{MyPackage@hidden}}
    {\setbox\z@\vbox\bgroup}{}}
    {\ifthenelse{\boolean{MyPackage@hidden}}{\egroup}{}}

This code has been working somewhat, but there are three main issues. The first is that there are errors when I put figures inside the Hidden environment. (This is a pretty common need when writing solutions to homework problems.) The following code does not compile:

\documentclass{amsart}

\usepackage{amsmath}
\usepackage{tikz}
\usepackage[hidden]{hideexample}

\begin{document}

This always shows up.

\begin{Hidden}
\begin{figure}[h]
\begin{tikzpicture}

\draw (0,0) circle (2cm);

\end{tikzpicture}
\caption{This shows up when not hidden, but causes an error when the [hide] option is used.}
\end{figure}
\end{Hidden}

\end{document}

The second issue is that I would like to implement multiple hide-able environments. (Expanding on the homework use case, I might also want to create notes to the grader about how to assign partial credit. So I would want to be able to independently hide/show the solutions and the grader comments.) I have no idea how to adapt the code above to do this. I never really understood what the code does, just that it (partially) worked.

The third "issue" isn't really a problem with the functionality, but another feature. It would be really convenient if, instead of [hide]/[show] options, there was a [solutions] option (or something similar) so that compiling the document would produce both the homework set and the solution set at the same time. (So, I would be working on HW.tex, and compiling would produce HW.pdf and HW_solutions.pdf at the same time.) Is something like this possible?

Thanks in advance.


Follow-up: After modifying Werner's answer below, I'm using the code

\if@hidden
  \long\gdef\hide[#1]#2\ehide{\vspace{#1}}%
\else
  \long\gdef\hide[#1]#2\ehide{#2}%
\fi

This allows the following use:

\hide[4in]
%stuff
\ehide

This shows %stuff when I'm not using the global [hide] option. When I am using the [hide] option, %stuff is hidden, and 4 inches of blank vertical space are shown instead (as a placeholder for %stuff). The only issue is that this usage makes it look like [4in] is an optional argument. Since \def requires an exact calling match, the argument is actually required. How can I make this argument optional (i.e., with 0in as the default value)?

3

1 Answer 1

5

It seems like you are trying to hide fairly common document elements. For that I would suggest capturing the environment contents using environ.

enter image description here

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents*}{MyPackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyPackage}
\RequirePackage{environ}
\newif\if@hidden% \@hiddenfalse
\DeclareOption{hide}{\global\@hiddentrue}
\ProcessOptions\relax
\NewEnviron{Hidden}
  {\if@hidden\else\BODY\fi}
\end{filecontents*}

\usepackage[hide]{MyPackage}

\begin{document}

This should always show up.
\begin{Hidden}
This should show up unless the [hide] option is used.
\end{Hidden}

\end{document}

I've used basic TeX conditionals rather than xifthen, but that's up to you. See Why is the ifthen package obsolete?.


If you wish to hide content using an abbreviated form, you'll have to specify it as such in a verbatim way. That is, if you want \hide and \ehide to define your start- and end-clause for capturing content to hide/not, then you have to use them as-is. Here's an example that includes an optional argument to \hide so you can specify a vertical gap to be left under the [hide] option:

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents*}{MyPackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyPackage}
\newif\if@hidden% \@hiddenfalse
\DeclareOption{hide}{\global\@hiddentrue}
\ProcessOptions\relax
\gdef\hide{\@ifnextchar[\hide@{\hide@[]}}
\if@hidden
  \long\gdef\hide@[#1]#2\ehide{\ifx\relax#1\relax\else\par\rule{0pt}{#1}\fi}% Gobble content between \hide...\ehide
\else
  \long\gdef\hide@[#1]#2\ehide{#2}% Release content between \hide...\ehide (ignore [.]
\fi
\end{filecontents*}

\usepackage[hide]{MyPackage}

\begin{document}

This should always show up.
\hide[2in]
This should show up unless the [hide] option is used.
\ehide

This should also show up.
\hide
This should show up unless the [hide] option is used.
\ehide

This will show up.
\end{document}

Note that nesting in these cases won't work.

11
  • Or the comment package?
    – daleif
    Commented Sep 12, 2015 at 6:07
  • Thanks for this, and for pointing me towards the etoolbox package. I was using ifthen because whatever guide to writing a package I was using suggested it. I'm happy to learn other methods. I don't suppose you know how to produce both the HW set and solution set with one compile? I think it's a separate enough question that I accepted your answer already and I'll write a separate question.
    – user18452
    Commented Sep 12, 2015 at 20:52
  • I'm having a new strange problem using this method. With many of the other environments I use frequently, I define shortcuts like \newcommand{\thm}{\begin{Theorem}} and \newcommand{\ethm}{\end{Theorem}}. This saves a lot of typing, and it has always worked perfectly fined. But when I did the same thing for the Hidden environment, I get an error 'LaTeX Error: \begin{Hidden} on input line 27 ended by \end{document}.' Why does the \ehide shortcut not seem to work?
    – user18452
    Commented Sep 13, 2015 at 1:25
  • @user18452: It is a requirement for you to use the complete \end{Hidden} clause, as this is used by TeX as the end-marker for defining \BODY. If you want to use an alternative way of handling it, like \bthm and \ethm, then I can show you how to do that.
    – Werner
    Commented Sep 13, 2015 at 2:10
  • Oh, I see. Is there a simple way to redefine the end-marker so that I can use \hide and \ehide? It's not such a big deal to have to type out \begin{Hidden} and \end{Hidden} every time, except that all of the other environments defined in this package have shortcuts, so I'd rather the Hidden environment have the same behavior. Thanks!
    – user18452
    Commented Sep 13, 2015 at 3:44

You must log in to answer this question.

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