我正在尝试使用嵌套循环创建矩阵\foreach
。我尝试按照我在上一个问题,但我一直收到错误。
这是我尝试运行的代码:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
\foreach \i in {0,...,5} {
\xappto\mymatrixcontent{\expandonce{
\node {\i}; &
}}
}
\xappto\mymatrixcontent{\\}
}
\row{1}
\begin{tikzpicture}
\matrix[matrix of nodes]{
\mymatrixcontent
};
\end{tikzpicture}
\end{document}
我收到一个错误:
! Undefined control sequence.
\\ ->\let \reserved@e
\relax \let \reserved@f \relax \@ifstar {\let \reserv...
l.16 \row{1}
我注意到只有在循环后添加新行后才会出现此错误\foreach
。 有办法避免吗?
编辑:我完成了这个例子。
答案1
如果你
\let\mymatrixcontent\empty
\newcommand{\row}{%
\foreach \i in {0,...,5} {%
\gappto\mymatrixcontent{\node{\i}; \&}%
}%
\gappto\mymatrixcontent{\\}%
}
\row
(\&
由于“裸”&
标记的问题,使用更好; percusse 的答案告诉了在构建矩阵时如何应对这个问题)然后\mymatrixcontent
将扩展为
\node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \& \node{\i}; \&\
并且将使用 的当前定义\i
,即“打印无点 i”,因为\i
仅在 操作期间才会扩展为连续值。因此,需要的是在 操作期间\foreach
扩展:\i
\foreach
\let\mymatrixcontent\empty
\newcommand{\row}{%
\foreach \i in {0,...,5} {%
\begingroup\edef\x{\endgroup
\noexpand\gappto\noexpand\mymatrixcontent{\noexpand\node{\i}; \&}}\x
}%
\gappto\mymatrixcontent{\\}%
}
\row
然而,使用时必须特别注意\edef
:并非所有标记都允许放在替换文本中,而我们想要作为其本身获取的标记需要以 为前缀\noexpand
。在这种特殊情况下,其中\i
是唯一需要扩展的标记,可以使用不同的方法
\let\mymatrixcontent\empty
\newcommand{\row}{%
\foreach \i in {0,...,5} {%
\expandafter\gappto\expandafter\mymatrixcontent\expandafter{%
\expandafter\node\expandafter{\i} \&}}%
}%
\gappto\mymatrixcontent{\\}%
}
\row
因为该链在执行之前\expandafter
会引起扩展。\i
\gappto
另一种方法可能是expl3
:
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{matrix}
\ExplSyntaxOn
\NewDocumentCommand{\row}{mmm}
{%#1 is the macro to define, #2 is the final number, #3 is the code
\tl_clear_new:N #1
\int_step_inline:nnnn { 0 } { 1 } { #2 }
{
\tl_put_right:Nn #1 { #3 }
}
\tl_put_right:Nn #1 { \\ }
}
\ExplSyntaxOff
\begin{document}
\row{\mymatrixcontent}{5}{\node { #1 }; \& }
\begin{tikzpicture}
\matrix[matrix of nodes,ampersand replacement=\&]{
\mymatrixcontent
};
\end{tikzpicture}
\end{document}
在 的第三个参数中\row
,#1
依次求值为 0,...,5(因为 5 是第二个参数)。
答案2
正如 Martin 在链接的答案中所写,它与\gappto
命令一起工作。这是一个对我有用的例子。我还更改了 & 符号,因为将一个孤独的符号放入&
扩展宏的内部总是有问题的 :)
\documentclass{article}
\usepackage{etoolbox}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\let\mymatrixcontent\empty
\newcommand{\row}[1]{
\foreach \i in {0,...,5} {
\gappto\mymatrixcontent{\expandonce{
A \&
}}
}
\gappto\mymatrixcontent{\\}
}
\row{1}
\begin{tikzpicture}
\matrix (a) [matrix of nodes,ampersand replacement=\&]{
\mymatrixcontent
};
\draw (a-1-1) -- (a-1-5);
\end{tikzpicture}
\end{document}
答案3
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usepackage{etoolbox}
\begin{document}
\begin{tikzpicture}
\let\mymatrixcontent\empty
\foreach \row in {1,...,8}{%%
\foreach \col in {1,...,5}{%
\xappto\mymatrixcontent{r\row c\col \expandonce{\&}}
}%
\gappto\mymatrixcontent{\\}
}%%
\matrix[matrix of nodes, ampersand replacement=\&,
column sep=2ex, label={Matrix}
] (m){
\mymatrixcontent
};
\end{tikzpicture}
\end{document}
答案4
没有扩展,没有全局分配,没有额外的包,没有额外的列,没有&符号快捷方式,只有两个\foreach
循环。
但是,库|…|
的语法matrix
不再包含。但是,当您生成单元格时,您可以直接使用\node[…]{…};
(或使用各种row …
//样式来更改行、列或单元格的样式)column …
。row … column …
对于您来说,只需使用create matrix={1}{1, ..., 5}
和set matrix macro=#2
。这将创建1
包含 5 列1
、2
、... 的行,5
但只将列号放在节点中。
代码
\documentclass[tikz]{standalone}
\tikzset{
% \protected because \pgfmatrixnextcell and \pgfmatrixendrow expand
% → can't use |…| shortcut, though
matrix node/.style 2 args={
name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn,
alias={\tikzmatrixname'-#1-#2}},
set matrix macro/.code=
\protected\def\tikzmatrixcell##1##2{\node[matrix node={##1}{##2}]{#1};},
set matrix macro'/.code=\protected\def\tikzmatrixcell##1##2{#1},
set matrix macro=r#1\,c#2,
create matrix/.style 2 args={
/tikz/matrix/content/.initial=,
/tikz/matrix/create rows/.style={
/tikz/matrix/reset create cell,
/tikz/matrix/create columns/.style={
/tikz/matrix/create cell={##1}{####1}},
/tikz/matrix/create columns/.list={#2},
/tikz/matrix/content/.append=\pgfmatrixendrow},
/tikz/matrix/create rows/.list={#1},
/tikz/node contents=\pgfkeysvalueof{/tikz/matrix/content}},
matrix/reset create cell/.style={
/tikz/matrix/create cell/.style 2 args={
/tikz/matrix/content/.append=\tikzmatrixcell{##1}{##2},
/tikz/matrix/create cell/.style 2 args={
/tikz/matrix/content/.append=
\pgfmatrixnextcell\tikzmatrixcell{####1}{####2}}}}}
\begin{document}
\tikz
\matrix[
draw, column sep=2ex,
set matrix macro=#2, create matrix={1}{1, ..., 5}];
\tikz
\matrix (m) [
draw, column sep=2ex, row sep=1em,
row 1 column 1/.style={set matrix macro=},
column 1/.append style={set matrix macro=row ##1},
row 1/.append style={set matrix macro=column ##2},
set matrix macro=#2#1, % like a spreadsheet
create matrix={0, ..., 8}{0, A, B, ..., E}]
(m'-1-A) edge[out=0, in=180] (m'-4-B);
\end{document}