在 \xdef 中使用另一个 \foreach 时,在 \foreach 中使用 \xdef 会出现错误

在 \xdef 中使用另一个 \foreach 时,在 \foreach 中使用 \xdef 会出现错误

我正在使用 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 替换的内部工作原理,因此解释一下为什么一个成功而另一个失败将有助于普通用户的理解。

参考资源:

答案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 }

相关内容