3

I'm currently writing a .sty-file that defines the look of assignment-sheets for students. I now want do define some custom environments for the questions and answers.

The answer blocks are printed inside of a tcolorbox and only shown, if a boolean is set to true. So in the definition of my custom environment I first check the boolean and then paste the tcolorbox opening tag. Unfortunately this returns the following error:

LaTeX Error: \begin{tcb@savebox} on input line 62 ended by \end{enumerate}.

Here is the code:

\newenvironment{solution}
    {
        \ifthenelse{\boolean{solution}}{
            \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]
    }
    {
            \end{tcolorbox}
        }{} 
    }

I used the code like this:

\begin{solution}
    \begin{align*}
        x^2 + y^2 &= z^2\\
        \Rightarrow x &= \sqrt{z^2 - y^2}\\
        &= ...
    \end{align*}
\end{solution}

What have I done wrong? Thank you very much in advance!


Clarification

It seems that my question is a bit unclear, so I'm trying to explain it a little better by the use of the following picture. example

Note that the page on the left only displays the assignments and the page on the right also includes the solutions to the problems. What I want to do, is to be able to compile both of these documents out of one single .tex file. I don't want to have a file for the assignments and one for the solutions. In my preamble i want to set a boolean to either true or false. If the boolean solution is set to false, the solution should NOT be compiled, so the resulting document is the one on the left. If the boolean is set to true, the solutions should be compiled, so the resulting document is the one on the right.

The solution-environment I asked for should check if the boolean is set to true and if so, compile it's content.

Until now it worked if I coded like this:

\begin{enumerate}[a)]
    %
    %
    %%%%%%%%%%%%%%%
    %% Question
    \item Compute the Fourier transform of $e^{-|x|}$ for $x\in \mathbb{R}$.
        %
        %
        %%%%%%%%%%%%%%%
        %% Solution
        \ifthenelse{\boolean{solution}}{
            \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]
                \begin{eqnarray*}
                    \hat{f}(\xi)&=&\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-|x|}e^{-ix\xi}dx\\
                    &=&\frac{1}{\sqrt{2\pi}}\int_{0}^{\infty}e^{-x-ix\xi}dx+\int_{-\infty}^0e^{x-ix\xi}dx\\
                    &=&\frac{1}{\sqrt{2\pi}}\int_{0}^{\infty}(e^{-x-ix\xi}-e^{-x+ix\xi})dx\\
                    &=&\frac{1}{\sqrt{2\pi}}[\frac{1}{-(1+i\xi)}(-1)-\frac{1}{-1+i\xi}(-1)]\\
                    &=&\frac{1}{\sqrt{2\pi}}[\frac{1-i\xi}{1+\xi^2}+\frac{-(1+i\xi)}{1+\xi^2}]\\
                    &=&\frac{1}{\sqrt{2\pi}}\frac{-2i\xi}{1+\xi^2}\\
                    &=&-\sqrt{\frac{2}{\pi}}\frac{i\xi}{1+\xi^2}
                \end{eqnarray*}
            \end{tcolorbox}
        }{}
    %
    %
    \item Compute the Fourier transform of $e^{-a|x|^2},~a>0$, directly, where $x\in \mathbb{R}$.\\
        \ifthenelse{\boolean{solution}}{
            \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]
                \begin{eqnarray*}
                    \hat{f}(\xi)&=&\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-a|x|^2}e^{-ix\xi}dx\\
                    &=&\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-a(x+\frac{i\xi}{2a})^2+\frac{-\xi^2}{4a}}dx~~~~~~~~x'\doteq x+\frac{i\xi}{2a}\\
                    &=&\frac{1}{\sqrt{2\pi}}e^{-\frac{\xi^2}{4a}}\int_{-\infty}^{\infty}e^{-ax^2}dx\\
                    &=&\frac{e^{-\frac{\xi^2}{4a}}}{2a}
                \end{eqnarray*}
            \end{tcolorbox}
        }{}
\end{enumerate}

The custom solution-environment should combine these two lines (and their closing tags) to make programming quicker and cleaner:

\ifthenelse{\boolean{solution}}{
    \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]

Hopefully this clears up the misunderstandings. If you have any further question, feel free to ask. :)

  • Off-Topic: The eqnarray* environment is outdated – user31729 Jul 27 '17 at 18:30
  • See the update please – user31729 Jul 27 '17 at 18:43
  • To the off-topic: I'm actually using align*, I just copied this math code from the internet because I didn't want to write something out myself. Back to the main question: @ChristianHupfer, you're awesome!! This now really works as expected. Great! – Sam Jul 27 '17 at 22:33
7

The \ifthenelse condition ends prematurely and leaves an open environment hanging around in the middle of nowhere.

In conjunction with tcolorbox environment, the end - delimiter is \endtcolorbox and I suggest to use two \ifthenelse statements, one for the start code of the environment and another one for the end code.

A better approach would use \DeclareTColorbox, in my opinion or a weird \scantokens construct.

Also possible: Use \tcolorboxenvironment to wrap around an existing solution environment.

\documentclass{article}

\usepackage{ifthen}

\usepackage[most]{tcolorbox}

\newboolean{solution}

\newenvironment{solution}{%
  \ifthenelse{\boolean{solution}}{%
    \tcolorbox[breakable, width=\textwidth, colframe=red, colback=white]
    }{%
  }%
}{\ifthenelse{\boolean{solution}}{\endtcolorbox}{}}


\begin{document}

\setboolean{solution}{true}
\begin{solution}
  \begin{align*}
    x^2 + y^2 &= z^2\\
    \Rightarrow x &= \sqrt{z^2 - y^2}\\
    &= ...
  \end{align*}
\end{solution}

\setboolean{solution}{false}
\begin{solution}
  \begin{align*}
    x^2 + y^2 &= z^2\\
    \Rightarrow x &= \sqrt{z^2 - y^2}\\
    &= ...
  \end{align*}
\end{solution}


\end{document}

enter image description here

Cleaner solution with two different environments

\documentclass{article}

\usepackage[most]{tcolorbox}


\tcbset{
  commonboxes/.style={nobeforeafter},
  nobox/.style={commonboxes,blank,breakable},
  solutionbox/.style={commonboxes,breakable, colframe=red, colback=white}
}


\newtcolorbox{solutionbox}[1][]{
  solutionbox,#1
}

\newtcolorbox{solutionbox*}[1][]{%
  nobox,#1
}






\begin{document}

\begin{solutionbox*}
  \begin{align*}
    x^2 + y^2 &= z^2\\
    \Rightarrow x &= \sqrt{z^2 - y^2}\\
    &= ...
  \end{align*}
\end{solutionbox*}

\begin{solutionbox}
  \begin{align*}
    x^2 + y^2 &= z^2\\
    \Rightarrow x &= \sqrt{z^2 - y^2}\\
    &= ...
  \end{align*}
\end{solutionbox}



\end{document}

Third installment of a solution with \NewEnviron and the \BODY command.

\documentclass{article}


\usepackage{environ}
\usepackage{ifthen}
\usepackage[shortlabels]{enumitem}
\usepackage{amssymb}
\usepackage{mathtools}
\usepackage[most]{tcolorbox}

\newboolean{solution}

\tcbset{
 commonboxes/.style={nobeforeafter,breakable},
  nobox/.style={commonboxes,blank,breakable},
  solutionbox/.style={commonboxes,breakable, colframe=red, colback=white}
}


\NewEnviron{solution}[1][]{%
  \ifthenelse{\boolean{solution}}{%
    \tcolorbox[solutionbox, width=\textwidth,#1]
    \BODY
    }{%
  }%
}[\ifthenelse{\boolean{solution}}{\endtcolorbox}{}]





\begin{document}

\begin{enumerate}[label={\alph*)}]
\item Compute the Fourier transform of $e^{-|x|}$ for $x\in \mathbb{R}$.
  \begin{solution}[colframe=blue]
    \begin{align*}
      \hat{f}(\xi)&=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-|x|}e^{-ix\xi}dx\\
      &=\frac{1}{\sqrt{2\pi}}\int_{0}^{\infty}e^{-x-ix\xi}dx+\int_{-\infty}^0e^{x-ix\xi}dx\\
      &=\frac{1}{\sqrt{2\pi}}\int_{0}^{\infty}(e^{-x-ix\xi}-e^{-x+ix\xi})dx\\
      &=\frac{1}{\sqrt{2\pi}}[\frac{1}{-(1+i\xi)}(-1)-\frac{1}{-1+i\xi}(-1)]\\
      &=\frac{1}{\sqrt{2\pi}}[\frac{1-i\xi}{1+\xi^2}+\frac{-(1+i\xi)}{1+\xi^2}]\\
      &=\frac{1}{\sqrt{2\pi}}\frac{-2i\xi}{1+\xi^2}\\
      &=-\sqrt{\frac{2}{\pi}}\frac{i\xi}{1+\xi^2}
    \end{align*}
  \end{solution}             
\item Compute the Fourier transform of $e^{-a|x|^2},~a>0$, directly, where $x\in \mathbb{R}$.\\
  \begin{solution}
    \begin{align*}
      \hat{f}(\xi)&=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-a|x|^2}e^{-ix\xi}dx\\
      &=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-a(x+\frac{i\xi}{2a})^2+\frac{-\xi^2}{4a}}dx~~~~~~~~x'\doteq x+\frac{i\xi}{2a}\\
      &=\frac{1}{\sqrt{2\pi}}e^{-\frac{\xi^2}{4a}}\int_{-\infty}^{\infty}e^{-ax^2}dx\\
      &=\frac{e^{-\frac{\xi^2}{4a}}}{2a}
    \end{align*}
  \end{solution}

\end{enumerate}

\setboolean{solution}{true}

\begin{enumerate}[label={\alph*)}]
\item Compute the Fourier transform of $e^{-|x|}$ for $x\in \mathbb{R}$.
  \begin{solution}[colframe=blue]
    \begin{align*}
      \hat{f}(\xi)&=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-|x|}e^{-ix\xi}dx\\
      &=\frac{1}{\sqrt{2\pi}}\int_{0}^{\infty}e^{-x-ix\xi}dx+\int_{-\infty}^0e^{x-ix\xi}dx\\
      &=\frac{1}{\sqrt{2\pi}}\int_{0}^{\infty}(e^{-x-ix\xi}-e^{-x+ix\xi})dx\\
      &=\frac{1}{\sqrt{2\pi}}[\frac{1}{-(1+i\xi)}(-1)-\frac{1}{-1+i\xi}(-1)]\\
      &=\frac{1}{\sqrt{2\pi}}[\frac{1-i\xi}{1+\xi^2}+\frac{-(1+i\xi)}{1+\xi^2}]\\
      &=\frac{1}{\sqrt{2\pi}}\frac{-2i\xi}{1+\xi^2}\\
      &=-\sqrt{\frac{2}{\pi}}\frac{i\xi}{1+\xi^2}
    \end{align*}
  \end{solution}             
\item Compute the Fourier transform of $e^{-a|x|^2},~a>0$, directly, where $x\in \mathbb{R}$.\\
  \begin{solution}
    \begin{align*}
      \hat{f}(\xi)&=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-a|x|^2}e^{-ix\xi}dx\\
      &=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{\infty}e^{-a(x+\frac{i\xi}{2a})^2+\frac{-\xi^2}{4a}}dx~~~~~~~~x'\doteq x+\frac{i\xi}{2a}\\
      &=\frac{1}{\sqrt{2\pi}}e^{-\frac{\xi^2}{4a}}\int_{-\infty}^{\infty}e^{-ax^2}dx\\
      &=\frac{e^{-\frac{\xi^2}{4a}}}{2a}
    \end{align*}
  \end{solution}

\end{enumerate}

\end{document}

The \BODY command contains the environment 'text' and is printed only in the case solution is true.

  • Works fine, but the tcolorbox doesn't do page-breaks anymore. As you see, I had the argument breakable in my previous code. I also used \tcbuselibrary{breakable} to allow page breaks which worked. Now with the new \begin{solution}-environment, it doesn't perform the breaks anymore. How could I fix this? PS: I used your first method. – Sam Jul 23 '17 at 20:51
  • @Sam: I forgot the breakable option in the nobox style, I've added it to the second solution, it can be used in commonboxes style as well, since it should apply to all boxes of this kind. – user31729 Jul 23 '17 at 20:55
  • No, I'm using your very first solution, not the cleaner one. – Sam Jul 23 '17 at 20:58
  • @Sam: well, I tried the first solution and the breaking works for me. – user31729 Jul 23 '17 at 21:00
  • 1
    Maybe, using code={\ifthenelse{\boolean{solution}}{\tcbset{solutionbox}}{\tcbset{nobox}}} is another alternative, if the boolean switch is important for the OP? – Thomas F. Sturm Jul 24 '17 at 5:30
1

Here is the code you wrote:

\newenvironment{solution}
    {% open 1
        \ifthenelse{\boolean{solution}}{% open 2
            \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]
    }% close 1
    {% open 3
            \end{tcolorbox}
        }{}% close 2, open & close 4
    }% close 3

But this is mixing open and closed (and TeX doesn’t look at indentation). Here is the code TeX sees:

\newenvironment{solution}
    {% open 1
        \ifthenelse{\boolean{solution}}{% open 2
            \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]
        }% close 2
        {% open 3
            \end{tcolorbox}
        }{}% close 3, open & close 4
    }% close 1

And of course, this doesn’t make sense. The environment is missing its second argument; if solution, then the tcolorbox opens (but never closes); if not solution, then the tcolorbox closes (but never opened). And {} #4 does nothing. Something more along the lines of your original would be:

\newenvironment{solution}
    {% open 1
        \ifthenelse{\boolean{solution}}{% open 2
            \begin{tcolorbox}[breakable, width=\textwidth, colframe=red, colback=white]
        }{% close 2, open 3
            \begin{comment}
        }% close 3
    }% close 1
    {% open 4
        \ifthenelse{\boolean{solution}}{% open 5
            \end{tcolorbox}
        }{% close 5, open 6
            \end{comment}
        }% close 6
    }% close 4

where we use the comment package to discard the answer. (You may want to use different variable names, so that solution isn't an environment and a boolean.)

  • How is this different to my first solution? – user31729 Jul 27 '17 at 9:16
  • @ChristianHupfer Unfortunately it's not different to your's at all. – Sam Jul 27 '17 at 9:25
  • @Teepeemm I see wat my mistake was, that caused the error, but it still does not answer the main issue. – Sam Jul 27 '17 at 9:26
  • Took me awhile to spot the "main issue". I've added the comment environment to discard the solution when necessary. – Teepeemm Jul 29 '17 at 0:23

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.