I write lecture notes and beamer slides using lots of macros containing math expressions. I'd like to be able to format conditional on whether or not I'm running beamer. So I've written conditional code using a \newif statement, which works except when I want to include formatting characters like \\ and &, in which case beamer throws an error. Here's sample code: There are three \ifThenBeamer lines of code: the first two throw the same error, i.e.,

! Missing } inserted.
<inserted text> 
                }
l.40 \end{frame}

The third line is fine.

\documentclass{beamer}
\newif\ifConditionOnBeamer
\makeatletter
\def\isConditionOnBeamer#1{
        \ifnum\pdf@strcmp{\useBeamer}{#1}=0
                \ConditionOnBeamertrue
        \else
                \ConditionOnBeamerfalse
        \fi
}
\makeatother
\def\useBeamer{on}
\def\BeamerOn{\isConditionOnBeamer{on}}
\def\BeamerOff{\isConditionOnBeamer{off}}
\def\ifThenBeamer#1#2{
    \ifConditionOnBeamer
        {#1}
    \else
        {#2}
    \fi
}
\BeamerOn
\begin{document}
\begin{frame}
\begin{align}
\ifThenBeamer{a \\ b}{c   d} %This throws a Missing } inserted error
\ifThenBeamer{a & b}{c   d}%This throws a Missing } inserted error
\ifThenBeamer{a b}{c   d}
\end{align}
\end{frame}
\end{document}

Could somebody please explain why the error is being thrown, and how to fix it? Or else a workaround if it's unfixable?

Thanks!

  • i'm not sure i understand what you expect the output to look like, but if you split the code into two separate align blocks (the first appropriate for the "on" and the second for the "off" condition), and put these into the two branches of \ifThenBeamer, that should work. – barbara beeton Mar 25 '16 at 20:05
up vote 6 down vote accepted

Environment align internally uses a table (\halign) and macro \ifThenBeamer puts group braces around it arguments. The groups messes with the groups of the table cells and lines. Without the braces the example works:

\def\ifThenBeamer#1#2{
    \ifConditionOnBeamer
        #1%
    \else
        #2%
    \fi
}

A more defensive version moves the expansion of the conditionals at the beginning:

\makeatletter
\newcommand*{\ifThenBeamer}{%
  \ifConditionOnBeamer
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

First \ifConditionOnBeamer is called. Then the \expandafter in the branch executes the closing \else or \fi. It remains\@firstoftwoor\@secondoftwo. The macro reads the two arguments and selects one of them. Then#1or#2` are called without a following token from the conditional.

  • Sorry @DavidCarlisle, don't understand? can't find any mail anywhere??? – Leo Simon Mar 26 '16 at 4:07
  • Thanks @heiko-oberdiek, your first suggestion works, but the second throws the error, You can't use \spacefactor in math mode – Leo Simon Mar 26 '16 at 4:09
  • @LeoSimon See: What do \makeatletter and \makeatother do? – Heiko Oberdiek Mar 26 '16 at 7:22
  • @LeoSimon that was for Heiko, sorry. – David Carlisle Mar 26 '16 at 10:33
  • Thanks very much @heiko-oberdiek, works now. Seems odd to me that we had to switch to \newcommand* from \def, which doesn't work, even when enclosed in \makeatletter and \makeatother. But "if it ain't broke..." – Leo Simon Mar 26 '16 at 16:18

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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