我正在使用 TeXShop 5.0.4 并遇到一个神秘的错误
! Incomplete \iffalse; all text was ignored after line 15.
<inserted text>
\fi
我的代码不包含明确的“if”。
如何创建一个定义各种命令的循环,每个命令都包含自己的循环?
非常感谢您的解释和解决方案。
小复制品:
\documentclass[11pt]{article}
\usepackage{tikz}
% given input x, define \allx as a function that consumes input list qlist and operates on the elements of qlist (here, prints "x: q", but eventually some tikz command)
% This errors out with the comprehensive error
% ! Incomplete \iffalse; all text was ignored after line 15.
% <inserted text>
% \fi
\newcommand{\allcolor}[1]{\expandafter\xdef\csname all#1\endcsname##1{\foreach \q in {##1} {#1: \q}}}
% Interestingly, the \foreach seems to cause the error. If using the command below instead, which just prints "x: qlist", LaTeX is happy.
%\newcommand{\allcolor}[1]{\expandafter\xdef\csname all#1\endcsname##1{#1: ##1}}
% Reasons for pieces of the above code:
% use \xdef instead of edef to make the new function global, since \allcolor will be called in a loop, from with edef would only define the function within the loop body
% use \xdef instead of \newcommand because of other cryptic errors with \newcommand
% use \expandafter on \xdef since we first need to form the name of the new function, "\all#1", via \csname
% given input list {x,y,z}, call \allcolor on each one, to define \allx \ally and \allz
\newcommand{\allcolors}[1]{\foreach \color in {#1} {\allcolor{\color}}}
\allcolors{orange}
\begin{document}
\allorange{ha,haa}
\end{document}
编辑:最终目标是定义 \allorange、\allbrown(能够轻松添加其他颜色命令),每个命令处理一个坐标对列表,并在 tikz 中绘制该颜色的点。
使用egreg
的答案,我能够这样做,使用以下代码:
\documentclass[11pt]{article}
\usepackage{tikz}
\edef\getxnow(#1,#2){#1}
\edef\getynow(#1,#2){#2}
\newcommand*{\getx}[1]{\expandafter\getxnow#1}
\newcommand*{\gety}[1]{\expandafter\getynow#1}
\newcommand{\allcolor}[1]{%
\expandafter\gdef\csname all#1\endcsname##1{%
\foreach \pt in {##1} {\node at (\getx{\pt}, \gety{\pt})[circle, fill, inner sep=5pt, #1]{};}%
}%
}
\newcommand{\allcolors}[1]{\foreach \r in {#1} {\expandafter\allcolor\expandafter{\r}}}
% Define \allorange and \allbrown which create points of those colors
\allcolors{orange, brown}
\begin{document}
\begin{tikzpicture} {
\allorange{(0,1),(1,2),(2,3)}
\allbrown{(1,1),(2,2),(3,3)}
} \end{tikzpicture}
\end{document}
评论者须知:
- 在原始代码中,我没有考虑我的本地循环变量名称
\color
- 它是一个任意名称,任何其他名称都可以 - 看起来这
\xdef
往往会破坏一些东西,但\gdef
最终还是会起作用。我可以看到\def、\edef、\gdef 和 \xdef 之间有什么区别?\xdef = \global\edef
在定义时会扩展替换文本,而 则不会gdef = \global\def
。我不熟悉 TeX 替换的内部工作原理,因此解释一下为什么一个成功而另一个失败将有助于普通用户的理解。
参考资源:
- \def 和 \newcommand 之间有什么区别?
- \def、\edef、\gdef 和 \xdef 之间有什么区别?
- 使用 \edef 和 \foreach 时未定义控制序列
- https://tikz.dev/pgffor
- 使用 `edef` 替代 `foreach` 循环
- 这是最接近答案的,但那里发布的解决方案是针对该特定问题的,并且没有足够的解释让我理解如何用于
expl3
任何其他用例
- 这是最接近答案的,但那里发布的解决方案是针对该特定问题的,并且没有足够的解释让我理解如何用于
- 在 for 循环内定义新命令
- \foreach 与 \newcommand 如何一起使用?
答案1
目前尚不清楚您的宏应该实现什么,但主要问题是\foreach
不能在 中使用\xdef
。
使用以下代码
\documentclass[11pt]{article}
\usepackage{tikz}
\newcommand{\allcolor}[1]{%
\expandafter\gdef\csname all#1\endcsname##1{%
\foreach \q in {##1} {#1: \q\par}%
}%
}
% given input list {x,y,z}, call \allcolor on each one, to define \allx \ally and \allz
\newcommand{\allcolors}[1]{\foreach \r in {#1} {\expandafter\allcolor\expandafter{\r}}}
\allcolors{orange}
\begin{document}
\allorange{ha,haa}
\end{document}
(\par
为了输出清晰而添加)我得到
该命令\allorange
有替换文本
\foreach \q in {#1} {orange: \q \par }