3

My boolean variable managing works with article class or within a single frame, but it doesn't work from a frame to another, why?

\documentclass{beamer}
\usepackage{tikzducks}
\usepackage{ifthen}
\newboolean{toleft}
\setboolean{toleft}{false}     
\newcommand{\duckfamily}[1][1]{%
    \begin{center}
        \begin{tikzpicture}[xscale=#1]
        \begin{scope}[scale=.15]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+10pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+20pt, scale=.1]
        \duck
        \end{scope}
        \end{tikzpicture}
    \end{center}
}

\newcommand{\duckdecor}{%
    \ifthenelse{\boolean{toleft}}{%
        \duckfamily
        \setboolean{toleft}{false}
        }{%
        \duckfamily[-1]
        \setboolean{toleft}{true}
        } 
}

\begin{document}
\begin{frame}
    I would like to type this decor:
    \duckdecor
    alternatively from right to left
    \duckdecor
    and from left to right
    \duckdecor
\end{frame}
\begin{frame}
    But if it is in different frames\dots  
    \duckdecor
\end{frame}
\begin{frame}
    \dots it doesn't work.
    \duckdecor
\end{frame}
\begin{frame}
    Why?
    \duckdecor
\end{frame}
\end{document}

enter image description here enter image description here enter image description here enter image description here

3

etoolbox has boolean commands that you can prefix with \global:

\documentclass{beamer}
\usepackage{tikzducks}
\usepackage{etoolbox} %already loaded by beamer
\newbool{toleft}
\global\booltrue{toleft}
\newcommand{\duckfamily}[1][1]{%
    \begin{center}
        \begin{tikzpicture}[xscale=#1]
        \begin{scope}[scale=.15]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+10pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+20pt, scale=.1]
        \duck
        \end{scope}
        \end{tikzpicture}
    \end{center}
}

\newcommand{\duckdecor}{%
    \ifbool{toleft}{%
        \duckfamily
        \global\boolfalse{toleft}
        }{%
        \duckfamily[-1]
        \global\booltrue{toleft}
        }
}

\begin{document}
\begin{frame}
    I would like to type this decor:
    \duckdecor
    alternatively from right to left
    \duckdecor
    and from left to right
    \duckdecor
\end{frame}
\begin{frame}
    But if it is in different frames\dots
    \duckdecor
\end{frame}
\begin{frame}
    \dots it doesn't work.
    \duckdecor
\end{frame}
\begin{frame}
    Why?
    \duckdecor
\end{frame}
\end{document}
  • \usepackage{etoolbox} is no no longer necessary for beamer – user36296 Aug 22 '17 at 12:35
  • @samcarter yes, but I wanted to show it explicitly. – Ulrike Fischer Aug 22 '17 at 12:36
3

I used Jagath's answer at Variable persist outside environment, adding 4 lines at the beginning of the preamble and commenting out \usepackage{ifthen}.

\documentclass{beamer}
\usepackage{tikzducks}
%\usepackage{ifthen}
%
\def\boolean#1{#1}
\def\newboolean#1{\expandafter\newif\csname if#1\expandafter\endcsname\csname  #1false\endcsname}
\def\setboolean#1#2{\expandafter\global\csname #1#2\endcsname}
\def\ifthenelse#1#2#3{\csname if#1\endcsname#2\else#3\fi}
%
\newboolean{toleft}
\setboolean{toleft}{false}     
\newcommand{\duckfamily}[1][1]{%
    \begin{center}
        \begin{tikzpicture}[xscale=#1]
        \begin{scope}[scale=.15]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+10pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+20pt, scale=.1]
        \duck
        \end{scope}
        \end{tikzpicture}
    \end{center}
}

\newcommand{\duckdecor}{%
    \ifthenelse{\boolean{toleft}}{%
        \duckfamily
        \setboolean{toleft}{false}
        }{%
        \duckfamily[-1]
        \setboolean{toleft}{true}
        } 
}

\begin{document}
\begin{frame}
    I would like to type this decor:
    \duckdecor
    alternatively from right to left
    \duckdecor
    and from left to right
    \duckdecor
\end{frame}
\begin{frame}
    But if it is in different frames\dots  
    \duckdecor
\end{frame}
\begin{frame}
    \dots it doesn't work.
    \duckdecor
\end{frame}
\begin{frame}
    Why?
    \duckdecor
\end{frame}
\end{document}

enter image description here

It is probably not good practice to redefine \ifthenelse, but rather to name it as, for example, \def\gifthenelse#1#2#3{\csname if#1\endcsname#2\else#3\fi} and then use \gifthenelse inside of the \duckdecor macro, in lieu of \ifthenelse.

  • @CarLaTeX I think Sam should get it, as she wrote tikzducks. – Steven B. Segletes Aug 22 '17 at 12:43
  • @StevenB.Segletes Please not, mine does not solve the problem it's just a workaround. @ CarLaTeX please accept Ulrike or Stevens answer! – user36296 Aug 22 '17 at 12:45
2

The problem is, that beamer wraps the content of the frame inside a group, you'd have the same problem with { \duckdecor } \duckdecor.

As a workaround: use a counter instead of the boolean and test if the counter is odd or even.

\documentclass{beamer}
\usepackage{tikzducks}

\newcommand{\duckfamily}[1][1]{%
    \begin{center}
        \begin{tikzpicture}[xscale=#1]
        \begin{scope}[scale=.15]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+10pt, scale=.1]
        \duck
        \end{scope}
        \begin{scope}[xshift=14pt+20pt, scale=.1]
        \duck
        \end{scope}
        \end{tikzpicture}
    \end{center}
}

\newcounter{test}
\setcounter{test}{1}

\newcommand{\duckdecor}{%
    \addtocounter{test}{1}%
    \ifodd\value{test}%
        \duckfamily%
    \else%
        \duckfamily[-1]%
    \fi%
}

\begin{document}

\begin{frame}
    \duckdecor
\end{frame}

\begin{frame}
    \duckdecor
\end{frame}

\end{document}
  • @CarLaTeX I would have been faster, if a colleague of mine would not have chosen the exact second I wanted to submit the answer to come and asked me a question :) – user36296 Aug 22 '17 at 12:37
  • @CarLaTeX A good question with a clear MWE makes answering easy :) – user36296 Aug 22 '17 at 12:41
  • @CarLaTeX In TUGBoat? I am looking forward to it! – user36296 Aug 22 '17 at 12:47

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.