下面的代码用于绘制排列图:
\documentclass[a4paper]{article}
\usepackage{tikz}
\newcommand{\normaldot}[1]{ % Make a dot of fixed absolute size.
\node at #1 {\normalsize $\bullet$};
}
\newcommand{\plotperm}[1]{% plot a permutation
\foreach \j [count=\i] in {#1} {
\normaldot{(\i,\j)}{};
};
}
\newcommand{\plotpermgrid}[1]{% plot a permutation in a grid
\foreach \i [count=\n] in {#1} {}; % Now \n stores the number of entries of the permutation.
\foreach \i in {0,1,2,...,\n}{
\draw [color=darkgray] ({\i+0.5}, 0.5)--({\i+0.5}, {\n+0.5});
\draw [color=darkgray] (0.5, {\i+0.5})--({\n+0.5}, {\i+0.5});
}
\plotperm{#1};
}
\begin{document}
\begin{tikzpicture}
\plotpermgrid{2,4,1,3}
\end{tikzpicture}
\end{document}
使用 TexLive2017,这将导致一个网格显示排列点 (2,4,1,3),如下所示
使用 TexLive2019 时,我收到错误消息,以“未定义的控制序列。\plotpermgrid{2,4,1,3}”开头
问题似乎与以下线路有关
\foreach \i [count=\n] in {#1} {};
在 TexLive2017 中,这会设置\n
为排列元素的数量,并且,至关重要的是,允许在完成\n
后使用\foreach
。在 TexLive2019、TexLine2020 和 MikTex 中,\n
在循环内设置,但之后不能使用。
我可以通过添加元素数量的第二个参数来解决这个问题,但这似乎不是一个完美的解决方案,而且容易出现错误。
我尝试过使用计数器,但是(使用名为的计数器gridsize
),当我写入时会出现错误\foreach \i in {0,1,2,...,{\thegridsize}}
。
我没有选择返回TexLive2017,并且我有大量使用\plotpermgrid
如上所述的LaTeX文档。
我如何更改定义\plotpermgrid
以使其使用 TexLive2019 或更高版本工作,同时仍然像以前一样采用单个参数?
答案1
欢迎来到 SE!
实际上,您遇到的错误是undefined control sequence \n
(或类似的话)。\n
在 中求值\foreach
,而 又位于一个组中。因此,当\foreach
完成后,\n
就会被遗忘。诀窍是在 运行\n
时使 变为全局的\foreach
,如下所示:
\documentclass[a4paper]{article}
\usepackage{tikz}
\newcommand{\normaldot}[1]{ % Make a dot of fixed absolute size.
\node at #1 {\normalsize $\bullet$};
}
\newcommand{\plotperm}[1]{% plot a permutation
\foreach \j [count=\i] in {#1} {
\normaldot{(\i,\j)}{};
};
}
\newcommand{\plotpermgrid}[1]{% plot a permutation in a grid
\foreach \i [count=\n] in {#1} {\global\let\newn=\n}; % Now \newn stores the number of entries of the permutation globally. <<<---
\foreach \i in {0,1,2,...,\newn}{
\draw [color=darkgray] ({\i+0.5}, 0.5)--({\i+0.5}, {\newn+0.5});
\draw [color=darkgray] (0.5, {\i+0.5})--({\newn+0.5}, {\i+0.5});
}
\plotperm{#1};
}
\begin{document}
\begin{tikzpicture}
\plotpermgrid{2,4,1,3}
\end{tikzpicture}
\end{document}
生成的图形正是您所发布的。
答案2
您应该计算输入数组的长度:
\documentclass[a4paper]{article}
\usepackage{tikz}
\newcommand{\normaldot}[1]{ % Make a dot of fixed absolute size.
\node at #1 {\normalsize $\bullet$};
}
\newcommand{\plotperm}[1]{% plot a permutation
\foreach \j [count=\i] in {#1} {
\normaldot{(\i,\j)}{};
};
}
\newcommand{\plotpermgrid}[1]{% plot a permutation in a grid
\pgfmathsetmacro\n{dim({#1})}% compute the length of the array
\foreach \i in {0,1,...,\n}{
\draw [color=darkgray] ({\i+0.5}, 0.5)--({\i+0.5}, {\n+0.5});
\draw [color=darkgray] (0.5, {\i+0.5})--({\n+0.5}, {\i+0.5});
}
\plotperm{#1};
}
\begin{document}
\begin{tikzpicture}
\plotpermgrid{2,4,1,3}
\end{tikzpicture}
\end{document}
使用{#1}
将参数转换为正确分隔的 PGF 数组。该方法自 TeX Live 2013 (Ti) 以来一直有效钾Z/PGF 版本 3.0.0)。
我认为,\n
在之后留下定义\foreach \i [count=\n] in {...}{...}
已被视为错误并已修复,因为\foreach
循环中使用的所有临时控制序列都应该是循环本地的,并且不会在循环之外留下任何东西(除非设为全局的)。
在被告知(老实说,以一种非常不愉快的方式)它dim
并不总是按预期运行之后,尽管在您的情况下它应该按预期运行,但前提是参数\plotpermgrid
至少有两个项目,我提供了一个更安全的解决方案。
\documentclass[a4paper]{article}
\usepackage{tikz}
\usepackage{xparse} % not needed with LaTeX release 2020-10-01 or later
\ExplSyntaxOn
\NewExpandableDocumentCommand{\clistlen}{m}
{
\clist_count:n { #1 }
}
\ExplSyntaxOff
\newcommand{\normaldot}[1]{ % Make a dot of fixed absolute size.
\node at #1 {\normalsize $\bullet$};
}
\newcommand{\plotperm}[1]{% plot a permutation
\foreach \j [count=\i] in {#1} {
\normaldot{(\i,\j)}{};
};
}
\newcommand{\plotpermgrid}[1]{% plot a permutation in a grid
\pgfmathsetmacro{\n}{\clistlen{#1}}% get the number of items in #1
\foreach \i in {0,1,...,\n}{
\draw [color=darkgray] ({\i+0.5}, 0.5)--({\i+0.5}, {\n+0.5});
\draw [color=darkgray] (0.5, {\i+0.5})--({\n+0.5}, {\i+0.5});
}
\plotperm{#1};
}
\begin{document}
\begin{tikzpicture}
\plotpermgrid{2,4,1,3}
\end{tikzpicture}
\end{document}
您甚至可以避免定义\n
和使用\clistlen{#1}
在哪里\n
使用。
答案3
有点不同的方法。仅定义了一个可以在文本中使用的新命令,网格被绘制为节点,没有网格的全局缝合维度:
\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\newcommand{\PPG}[1]% Plot a Permutation in a Grid
{
\begin{tikzpicture}[nodes={minimum size=1cm}]
\foreach \i [count=\j] in {#1} %\i: columns, \j: rows
{
\node at (\j-0.5,\i-0.5) {\textbullet};
\foreach \k in {1,...,\j}
{
\node[draw] at (\j-0.5,\k-0.5) {};
\node[draw] at (\k-0.5,\j-0.5) {};
}
}
\end{tikzpicture}
}
\begin{document}
\PPG{2,4,1,3,5}
\begin{tikzpicture}
\PPG{2,4,1,3,5}
\end{tikzpicture}
\end{document}
附录。\PPG
如果在环境中始终使用 网格终止图 ( ) tikzpicture
,例如:
\begin{tikzpicture}
\PPG{2,4,1,3,5}
\end{tikzpicture}
那么可能更好,tikzpicture
从定义中删除\PPG
:
\newcommand{\PPG}[1]% Plot a Permutation in a Grid
{
\scoped[nodes={minimum size=1cm}]{
\foreach \i [count=\j] in {#1} %\i: columns, \j: rows
{
\node at (\j-0.5,\i-0.5) {\textbullet};
\foreach \k in {1,...,\j}
{
\node[draw] at (\j-0.5,\k-0.5) {};
\node[draw] at (\k-0.5,\j-0.5) {};
}
}% end of foreach
}% end of scoped
}% end of newcommand