是否可以使用循环为 foreach 循环生成列表?更具体地说,我想要以下内容:
考虑一下我之前提出的一个问题的以下答案:https://tex.stackexchange.com/a/38793/4011
它工作得很好,除非我定义\alist
如下:
\def\alist{
\foreach \i in {1,2,3}{
\i/1,
}4/1
}
我收到以下错误:
ERROR: Undefined control sequence.
--- TeX said ---
\foreach ...reach \let \pgffor@assign@before@code
=\pgfutil@empty \let \pgff...
l.38 \rectDiv{7}{5}{(1,1)}{(4,3)}{\alist}
有没有什么办法解决这一问题?
编辑:
完整示例:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\rectDiv#1#2#3#4#5{%#columns, #rows, rectangle start, rectangle end, list of elements to fill
\begin{tikzpicture}
\draw #3 rectangle #4;
\path #3;
\pgfgetlastxy{\firstx}{\firsty}
\path #4;
\pgfgetlastxy{\secondx}{\secondy}
\pgfmathsetlengthmacro{\xdiff}{\secondx-\firstx}
\pgfmathsetlengthmacro{\ydiff}{\secondy-\firsty}
\pgfmathsetlengthmacro{\myxstep}{\xdiff/#1}
\pgfmathsetlengthmacro{\myystep}{\ydiff/#2}
\foreach \x in {1,...,#1}{
\draw ($#3 +\x*(\myxstep,0)$) -- ($#3 +(0,\ydiff) +\x*(\myxstep,0)$);
}
\foreach \y in {1,...,#2}{
\draw ($#3 +\y*(0,\myystep)$) -- ($#3 +(\xdiff,0) +\y*(0,\myystep)$);
}
\edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}
\temp{
\path[fill=blue!20,draw] ($#3 + (\i*\myxstep,\j*\myystep)$) rectangle ($#3 + (\i*\myxstep,\j*\myystep) + (\myxstep,\myystep)$);
}
\end{tikzpicture}
}
\begin{document}
\rectDiv{7}{5}{(1,1)}{(4,3)}{0/0,1/1,2/0,5/3}
\def\list{1/0}
\rectDiv{7}{5}{(1,1)}{(4,3)}{\list}
\rectDiv{7}{5}{(1,1)}{(4,3)}{\list,2/0,5/3}
\def\alist{
\foreach \i in {1,2,3}{
\i/1,
}4/1
}
\alist
\rectDiv{7}{5}{(1,1)}{(4,3)}{\alist} %this doesn't work
\end{document}
答案1
你的问题是你写的
\edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}
% Here is what #5 is in \temp:
\def\alist{
\foreach \i in {1,2,3}{
\i/1,
}4/1
}
这要求括号中的内容“完全可扩展”。可惜的是,\foreach
是不可扩展的,它是 的一部分\alist
。因此,当\temp
被定义时,它会“尽可能地”扩展,并触及 代码中某些不可扩展的部分\foreach
,在本例中是\let \pgffor@assign@before@code = ...
;\let
是一个任务,并且不可扩展,因此不会被 改变\edef
。因此,实际上并没有执行赋值,而是\edef
继续尝试\pgffor@assign@before@code
直接解释以下控制序列。毫不奇怪,它没有定义,因为应该是\let
来定义它,所以你会得到一个错误。
为此,您必须创建一个包含输出的\alist
。例如,
\gdef\alist{}
\foreach \i in {1,2,3} {
\xdef\alist{\alist \i/1,}
}
\xdef\alist{\alist 4/1}
然后您可以\alist
直接使用而不是\temp.
(我已经使用全局分配,因为\alist
在\foreach
组中执行其内容。)