我的布尔变量管理在article
类中或在单个框架内有效,但在从一个框架到另一个框架时却不起作用,为什么?
\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}
答案1
etoolbox 具有布尔命令,您可以将其加上前缀 \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}
答案2
我使用了 Jagath 的答案变量在环境之外持续存在,在序言开头添加4行并注释掉\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}
重新定义 可能不是一个好的做法\ifthenelse
,而是将其命名为,例如,\def\gifthenelse#1#2#3{\csname if#1\endcsname#2\else#3\fi}
然后在宏\gifthenelse
内部使用\duckdecor
来代替\ifthenelse
。
答案3
问题是,beamer 将框架的内容包装在一个组内,您会遇到同样的问题{ \duckdecor } \duckdecor
。
解决方法:使用计数器而不是布尔值并测试计数器是奇数还是偶数。
\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}