4
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsthm,amsfonts}
\usepackage{xifthen}


\newcounter{example}[subsection]

\newcommand{\challenge}[3]{\refstepcounter{example}\par\medskip\noindent \textbf{Challenge~\theexample.}
    #1
    \vskip0.2cm
    \noindent\textbf{Solution}: #2
    \vskip0.2cm
    \ifthenelse{\equal{#3}{}}{}{\noindent\textbf{Notes}: #3}}


\begin{document}
\challenge{
    Write a note.
}{
    We simply write a note.
}{
    A note.
}

\challenge{
    Do not write any notes.
}{
    We simply leave the last argument empty.
}{}

\challenge{
    Demonstrate that notes can cause problems
}{
    We simply put a matrix to the notes.
}{
    Let $\varepsilon > 0$
%       and 
%       $$
%       A = \begin{matrix}
%       1
%       \end{matrix}
%       $$
%       be a matrix
        .
}
\end{document}

Which results in

output

When I uncomment the matrix part, I get the error:

line 46: Undefined control sequence. } : Incomplete \iffalse; all text was ignored after line 46.

The line 46 is where the closing } for the third argument of the third challenge is.

I haven't faced any problems when I put the matrices etc. in any or both of the first two arguments.

Antoine
  • 291
  • I think this is a problem with the nested \if from \ifthenelse and the math mode introduced with \[...\] –  Feb 27 '17 at 16:30
  • @ChristianHupfer I am not sure that this is completely true: If I replace the matrix part with $$A = 2$$, it compiles as expected. – Antoine Feb 27 '17 at 16:36
  • I actually meant the \if command internally used in matrix –  Feb 27 '17 at 16:36
  • @ChristianHupfer it's more just that ifthenelse is a protected edef, so environments don't work unless you sprinkle with \protect. – David Carlisle Feb 27 '17 at 16:43
  • @DavidCarlisle: What should be be protected then? \protect\begin{matrix}? –  Feb 27 '17 at 16:46
  • @ChristianHupfer \protect\begin and \protect\end would work but really the answer is not to do that but to use a better test for empty, either xparse or simply \if\relax\detokenize{#3}\relax\else\noindent\textbf{Notes}: #3\fi} Or if using ifthenelse just to protect the whole thing eg via a toks register as you did below – David Carlisle Feb 27 '17 at 16:51
  • @DavidCarlisle: Well, please add your answer with \if\relax\detokenize then. The token register was my first idea. I am not really much into \ifthenelse, yet, so don't really know how it is defined –  Feb 27 '17 at 16:52
  • See Why is \[ … \] preferable to $$? for reasons why avoiding $$ in LaTeX. – egreg Feb 27 '17 at 17:17

2 Answers2

4

Ifthenelse fully expands its first argument, so fragile commands have to be \protected

You could use

{
    Let $\varepsilon > 0$
       and 
       $$
       A = \protect\begin{matrix}
       1
       \protect\end{matrix}
       $$
       be a matrix
        .
}

But better really would be to use a better test for empty argument

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsthm,amsfonts}
\usepackage{xifthen}


\newcounter{example}[subsection]

\newcommand{\challenge}[3]{\refstepcounter{example}\par\medskip\noindent \textbf{Challenge~\theexample.}
    #1
    \vskip0.2cm
    \noindent\textbf{Solution}: #2
    \vskip0.2cm
    \if\relax\detokenize{#3}\relax\else\noindent\textbf{Notes}: #3\fi}


\begin{document}
\challenge{
    Write a note.
}{
    We simply write a note.
}{
    A note.
}

\challenge{
    Do not write any notes.
}{
    We simply leave the last argument empty.
}{}

\challenge{
    Demonstrate that notes can cause problems
}{
    We simply put a matrix to the notes.
}{
    Let $\varepsilon > 0$
       and 
       $$
       A = \begin{matrix}
       1
       \end{matrix}
       $$
       be a matrix
        .
}
\end{document}
David Carlisle
  • 757,742
3

I used a token register to preexpand the content of #3 in order to silence the nested \if... there.

However, I suggest to use something like xparse rather with optional arguments (see the other answer at the end of this post)

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsthm,amsfonts}
\usepackage{xifthen}


\newcounter{example}[subsection]
\newtoks\daviddoesnotliketoksasname
\newcommand{\challenge}[3]{%
  \refstepcounter{example}\par\medskip% \par?
  \noindent%
  \textbf{Challenge~\theexample.}
  #1%
  \vskip0.2cm
  \noindent\textbf{Solution}: #2%
  \vskip0.2cm
  \daviddoesnotliketoksasname={#3}%
  \ifthenelse{\equal{\the\daviddoesnotliketoksasname}{}}{}{\noindent\textbf{Notes}: \the\toks}%
}


\begin{document}
\challenge{
    Write a note.
}{
    We simply write a note.
}{
    A note.
}

\challenge{
    Do not write any notes.
}{
    We simply leave the last argument empty.
}{}

\challenge{
    Demonstrate that notes can cause problems
}{
    We simply put a matrix to the notes.
}{%
  Let $\varepsilon > 0$
  and 
  \[
  A = \begin{matrix}
    1
  \end{matrix}
  \]
  be a matrix.
}
\end{document}

Update with a xparse version

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amsthm,amsfonts}
\usepackage{xparse}
%\usepackage{xifthen}


\newcounter{example}[subsection]

\NewDocumentCommand{\challenge}{+m+m+o}{%
  \refstepcounter{example}\par\medskip% \par?
  \noindent%
  \textbf{Challenge~\theexample.}
  #1%
  \vskip0.2cm
  \noindent\textbf{Solution}: #2%
  \vskip0.2cm
  \IfValueT{#3}{%
    \noindent\textbf{Notes}: #3%
  }%
}


\begin{document}
\challenge{%
    Write a note.
}{%
    We simply write a note.
}[
    A note.
]

\challenge{%
    Do not write any notes.
}{%
    We simply leave the last argument empty.
}

\challenge{%
    Demonstrate that notes can cause problems
}{
    We simply put a matrix to the notes.
}[%
  Let $\varepsilon > 0$
  and 
  \[
  A = \begin{matrix}
    1 & 5  \\
    3 & 4 
  \end{matrix}
  \]
  be a matrix.
]
\end{document}

enter image description here