7

I would like to create a solution environment that prints a solution in the case where an optional argument is set to true (the default) and hides the solution in the case that the argument is false. I tried to use egreg's idea from Is there an "identity" (or "no-op") environment that simply uses its contents unaltered? but my construction already fails due to the optional argument (Illegal parameter number in definition of \endsolution). The idea would be to not show anything (ideally no vertical space would be created either) if we are in the ``false'' case.

Note: I'm aware of other solutions to this problem (see Comparing packages which facilitate typesetting exercises and solutions: exercise vs. answers vs. probsoln) but I am interested to see what I am doing wrong in my construction.

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage{ifthen}

% solution environment
\newenvironment{solution}[1][true]{
  \ifthenelse{\boolean{#1}}{\par{\sffamily\bfseries Solution}\par}{\ignorespaces}
}{\ifthenelse{\boolean{#1}}{}{\ignorespacesafterend}}

\begin{document}
This is Exercise 1 with solution.
\begin{solution}
  Solution to Exercise 1
\end{solution}

\bigskip
This is Exercise 2 (without solution).
\begin{solution}[false]
  This should not appear.
\end{solution}

\end{document}
7

The arguments passed to an environment are not available in the code that is executed at the end. You can get around this by saving them using global declarations in the initialisation code. Also, there is nothing in your example to prevent the body of the environment (i.e. between \begin{solution} and \end{solution}) from being processed in the false case. You can do this using the environ package. In this code, the body of the environment is only processed when the \BODY macro is executed.

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{ifthen}
\usepackage{environ}

% solution environment
\makeatletter
\NewEnviron{solution}[1][true]{
  \gdef\@tmp{#1}
  \ifthenelse{\boolean{#1}}{\par{\sffamily\bfseries Solution}\par\BODY}{\ignorespaces}
}[\ifthenelse{\boolean{\@tmp}}{}{\ignorespacesafterend}]
\makeatother    

\begin{document}
This is Exercise 1 with solution.
\begin{solution}
  Solution to Exercise 1
\end{solution}

\bigskip
This is Exercise 2 (without solution).
\begin{solution}[false]
  This should not appear.
\end{solution}

\end{document}
6

Here's a solution using the xparse package, and its NewDocumentEnvironment which allows the use of arguments in the \end{environment} code.

The important part is

% solution environment
\NewDocumentEnvironment{solution}{O{true}}{%
    \ifthenelse{\boolean{#1}}{\par{\sffamily\bfseries Solution}\par}{\setbox0=\hbox\bgroup}
    }{%
    \ifthenelse{\boolean{#1}}{}{\egroup}
}

Here's a complete MWE to play with; see Why can't the end code of an environment contain an argument? and Passing \newenvironment parameters to the end block? for further reference.

% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass{article}

\usepackage{xparse}
\usepackage{ifthen}

% solution environment
\NewDocumentEnvironment{solution}{O{true}}{%
    \ifthenelse{\boolean{#1}}{\par{\sffamily\bfseries Solution}\par}{\setbox0=\hbox\bgroup}
    }{%
    \ifthenelse{\boolean{#1}}{}{\egroup}
}

\begin{document}
This is Exercise 1 with solution.
\begin{solution}
    Solution to Exercise 1
\end{solution}

\bigskip
This is Exercise 2 (without solution).
\begin{solution}[false]
    This should not appear.
\end{solution}

\begin{solution}[true]
    This *should*  appear.
\end{solution}

\end{document}
  • 1
    I'd use \vbox which allows paragraphs, not \hbox. – egreg Apr 19 '14 at 21:25
  • @cmhughes: I would like to use \usepackage{ifthen} and define a global variable \newboolean{sol}. I set it to false \setboolean{sol}{false} and sol should be the default for the solution environment, how would one incorporate this? If I use ...{solution}{O{sol}}{... it gives me an error. – Marius Hofert Apr 23 '14 at 19:51
  • @egreg: I realized a problem with (both \hbox and) \vbox. See here: tex.stackexchange.com/questions/173128/… – Marius Hofert Apr 23 '14 at 20:54
  • @MariusHofert Yes, of course, if you're devious enough to use the figure environment in a proof. ;-) My proposal for the last question of yours can be easily adapted, I believe. My objection was that \hbox can't work if there is more than simple text and will fail with lists and other things. – egreg Apr 23 '14 at 20:56
  • @egreg :-) Thanks. Do you know a solution to the problem? Most solution manual contain figures (for better understanding). I like the approach based on xparse, but if I can't use a figure inside a solution environment, this would be quite a drawback – Marius Hofert Apr 23 '14 at 20:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.