使用 \edef 和 \foreach 时未定义控制序列

使用 \edef 和 \foreach 时未定义控制序列

我正在尝试定义一个命令来构建几个类似的 tikz 节点。这些节点只有一个参数不同(#2如下)。以下是我迄今为止提到的主要问题:

我感觉我已经很接近了,但除了下面详述的内容之外,我不知道还能去哪里。该图的左侧部分几乎是预期的结果:

预期结果

这是当前命令的定义:

\documentclass[11pt,a4paper]{article}

\usepackage{siunitx}
\usepackage{tikz}
\usepackage{xparse}

\begin{document}

\tikzstyle{ht_num} = [draw, semithick]
\tikzstyle{ht_hash} = [draw, semithick, minimum width=2em]

\NewDocumentCommand \HashTable { m m } {%
    \def\MatrixContent{\empty}
    \pgfmathtruncatemacro\nn{2^#2-1}
    \foreach \n in {0,...,\nn}{%
        \edef\MatrixContent{\unexpanded\expandafter{\MatrixContent}\unexpanded\expandafter{%
            \node[ht_hash] (#1-\n) {\num[minimum-integer-digits=#2]{\pgfmathbin{\n}\pgfmathresult}}; \\
        }}
    }

    \matrix [outer sep=0pt,every node/.style={anchor=west}] (#1) {
        \node[ht_num] (#1-a) {#2}; \\
        \MatrixContent
    };
}

\begin{tikzpicture}
    \HashTable{table1}{2}
    % Other tikz nodes...
\end{tikzpicture}

\end{document}

最后,错误信息:

./Diagrams.tex:398: Missing } inserted.
<inserted text> 
                }
l.398 ^^I^^I\end{tikzpicture}
                             \end{center}

这没什么帮助。


我尝试从命令中删除代码并将其直接放入带有硬编码值的文档中:

\def\MatrixContent{\empty}
\pgfmathtruncatemacro\nn{2^2-1}
\foreach \n in {0,...,\nn}{%
    \edef\MatrixContent{\unexpanded\expandafter{\MatrixContent}\unexpanded\expandafter{%
        \node[ht_hash] (table-\n) {\n};
    }}
}

\begin{tikzpicture}
    \matrix [outer sep=0pt,every node/.style={anchor=west}] (table) {
        \MatrixContent
    };
\end{tikzpicture}

这产生了一个新错误:

./Diagrams.tex:403: Undefined control sequence.
\pgffor@body ... }\unexpanded \expandafter {\node 
                                                  [ht_hash] (table-\n ) {...
l.403 ^^I^^I}

最后,我尝试使用不同的方法进行构建\MatrixContent

\let\MatrixContent\empty
\pgfmathtruncatemacro\nn{2^2-1}
\foreach \n in {0,...,\nn}{%
    \expandafter\gappto\expandafter\MatrixContent\expandafter{%
        \node[ht_hash] (table-\n) {\n};
    }
}

\begin{tikzpicture} ...

产生另一个错误:

./Diagrams.tex:413: Undefined control sequence.
\pgffor@body ...MatrixContent \expandafter {\node 
                                                  [ht_hash] (table-\n ) {...
l.413 ^^I^^I}

答案1

我不得不猜测你想要做什么,所以我的猜测是这样的:

\documentclass[11pt,a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{siunitx}
\tikzset{ht_num/.style={draw, semithick},
ht_hash/.style={draw, semithick, minimum width=2em}}
\begin{document}

\NewDocumentCommand \HashTable { m m } {%
    \def\MatrixContent{\empty}
    \pgfmathtruncatemacro\nn{2^#2-1}
    \foreach \n in {0,...,\nn}{%
        \pgfmathbin{\n}%
        \edef\myresult{|[ht_hash]| 
        \num[minimum-integer-digits=#2]{\pgfmathresult}}%
        \xappto\MatrixContent{\expandonce{\myresult\\}}%
    }
    \matrix [outer sep=0pt,matrix of nodes] (#1) {
        |[ht_num,name=#1-a]|  #2 \\
        \MatrixContent %\\
    };
}

\begin{tikzpicture}
    \HashTable{table1}{2}
\end{tikzpicture}
\end{document}

在此处输入图片描述

评论:

  1. 您正在加载但未使用该matrix库。我认为使用它会让事情变得简单得多。
  2. \tikzstyle已被弃用。
  3. 我基本上使用了注释掉的解决方案Martin Scharrer 的回答
  4. Z 矩阵有计数\pgfmatrixcurrentrow\pgfmatrixcurrentcolumn使用时,可以让您使整个企业变得更加简单。但我不确定我是否走在正确的道路上。

答案2

您的代码中存在几个问题。

  1. \foreach执行组中的每个循环,因此,组结束后,其中的任何定义都会被遗忘,除非它完成全球;因此不是\edef,但是\xdef(全局扩展定义)

  2. 该代码\unexpanded\expandafter{\MatrixContent}用于访问以前的的值\MatrixContents(但不再扩展)。您不想扩展\node...,因此这应该是简单的的参数\unexpanded;但是它是唯一应该避免扩展的标记,与一起\\,因此几个\noexpand就足够了;\num本身就受到保护,不会在\edef或中扩​​展\xdef

  3. 进一步的问题:\num想要看到一个数字,而不是产生它的指令集,因此\pgfmathbin{\n}应该在更新之前完成\MatrixContent;并且\pgfmathresult不应该隐藏在中\unexpanded

  4. \tikzstyle已被弃用几年了。

修改后的代码如下:

\documentclass{article}

\usepackage{siunitx}
\usepackage{tikz}

\begin{document}

\tikzset{
  ht_num/.style={draw, semithick},
  ht_hash/.style={draw, semithick, minimum width=2em},
}

\newcommand\HashTable[2]{%
  \def\MatrixContent{}% not \empty
  \pgfmathtruncatemacro\nn{2^(#2)-1}
  \foreach \n in {0,...,\nn}{%
    \pgfmathbin{\n}% the current value in binary format
    \xdef\MatrixContent{%
      \unexpanded\expandafter{\MatrixContent}% the previous value
      \noexpand\node[ht_hash] (#1-\n) {\num[minimum-integer-digits=#2]{\pgfmathresult}};
      \noexpand\\%
    }%
  }%
  \matrix [outer sep=0pt,every node/.style={anchor=west}] (#1) {
        \node[ht_num] (#1-a) {#2}; \\
        \MatrixContent
  };
}

\begin{tikzpicture}
    \HashTable{table1}{2}
    % Other tikz nodes...
\end{tikzpicture}
\qquad
\begin{tikzpicture}
    \HashTable{table1}{3}
    % Other tikz nodes...
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容