如何使以下 MWE 工作:
\documentclass{article}
\usepackage{xifthen}
\usepackage{lipsum}
\newboolean{bar}
\setboolean{bar}{true}
\def\foo{\parshape = 2
\ifthenelse{\boolean{positionLeft}}{%
0pt 0.5\textwidth%
}{%
0.5\textwidth 0.5\textwidth%
}%
0pt \textwidth
}
\begin{document}
\foo
\lipsum[1]
\end{document}
我相信这与未扩展有关\ifthenelse
,但我似乎从未掌握这一点(我真的需要尽快获得 TeXbook)......
答案1
\ifthenelse
进行不允许设置的作业\parshape
。
使用提供的条件命令etoolbox
:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{lipsum}
\newtoggle{bar}
\toggletrue{bar}
\def\foo{\parshape = 2
\iftoggle{bar}{%
0pt 0.5\textwidth
}{%
0.5\textwidth 0.5\textwidth
}%
0pt \textwidth
}
\begin{document}
\foo
\lipsum[1]
\end{document}
如果你坚持\ifthenelse
,你必须提供完整的规范:
\def\foo{%
\ifthenelse{\boolean{bar}}{%
\parshape = 2
0pt 0.5\textwidth%
0pt \textwidth
}{%
\parshape = 2
0.5\textwidth 0.5\textwidth%
0pt \textwidth
}%
}
当 TeX 看到一个\parshape
命令时,它期望看到一个数字n而如果n> 0,2n长度。关于这些“期望”的规则是,TeX 会扩展宏,直到找到它要找的东西。例如,如果说
\def\baz{2} \def\bazz{0pt} \def\bazzz{\textwidth}
\parshape \baz \bazz .5\bazzz 0pt \bazzz
然后 TeX 会扩展所有内容,并执行与所呈现的内容完全相同的操作
\parshape 2 0pt .5\textwidth 0pr \textwidth
(请注意,这\textwidth
是不可扩展的)。任何不可扩展的标记当然会停止搜索,并且可能出现两种情况:
不可扩展标记在此上下文中有意义(数字或长度参数),或
不可扩展的标记已错位。
的定义\ifthenelse
可以在以下位置找到ifthen.sty
:
% ifthen.sty, line 70:
\long\def\ifthenelse#1{%
\toks@{#1}%
\TE@repl\or\TE@or
[...]
}
第一行是赋值:将名为 的记号寄存器的\toks@
参数赋值给\ifthenelse
。由于\toks@
不可扩展,我们最终陷入上述第二种情况,从而导致 TeX 发出错误消息。
etoolbox
's不会发生这种情况\iftoggle
,因为已经采取了措施确保它在没有任何分配的情况下“完全可扩展”,除非出现与切换相关的某些错误(例如切换的名称输入错误),这时这并不重要,因为无论如何都会有错误。
答案2
您可以使用一个简单的\newif
不带包的:
\documentclass{article}
\usepackage[latin]{babel}
\usepackage{lipsum}
\newif\ifbar
\bartrue
\def\foo{\parshape = 2
\ifbar%
0pt 0.5\textwidth%
\else
0.5\textwidth 0.5\textwidth%
\fi
0pt \textwidth
}
\begin{document}
\foo
\lipsum[1]
\barfalse
\foo
\lipsum[1]
\end{document}