Undefined control sequence when using \edef with \foreach
I had to speculate what you want to do, so my guess it is something like this:
\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}
Comments:
- You were loading but not using the
matrix
library. I think using it makes things much simpler here. \tikzstyle
is deprecated.- I basically used the commented out solution in Martin Scharrer's answer.
- A TikZ matrix has counts
\pgfmatrixcurrentrow
and\pgfmatrixcurrentcolumn
which, when used, may allow you to make this whole enterprise much simpler. Yet I am not sure I am on the right track.
There are several problems in your code.
\foreach
executes each cycle in a group, so any definition made inside it is forgotten as soon as the group ends, unless it is done globally; thus not\edef
, but\xdef
(global expanded definition)The code
\unexpanded\expandafter{\MatrixContent}
is meant to access the previous value of\MatrixContents
(but with no further expansion). You don't want to expand\node...
, so that should be the argument of a simple\unexpanded
; however it is the only token that should be protected from expansion, together with\\
, so a couple of\noexpand
suffice;\num
is by itself protected from expanding in\edef
or\xdef
.Further problem:
\num
wants to see a number, not the set of instruction to produce it, so\pgfmathbin{\n}
should be done before updating\MatrixContent
; and\pgfmathresult
should not be hidden in\unexpanded
.\tikzstyle
has been deprecated for a few years.
Here's the amended code:
\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}