我正在尝试在 TikZ 节点内向字节字段添加可变数量的字段。之前的一个问题(使用 foreach 向 TikZ 节点内的字节字段添加可变数量的行?) 给出了有用的提示,但我仍然无法让它工作。所以,这里有一个更详细的例子。
\documentclass[tikz]{standalone}
\usepackage{bytefield}
\usetikzlibrary{positioning}
\begin{document}
% What I want to achieve, written out without loops:
% (inelegant, does not scale to the large number of nodes
% for which I need this)
\begin{tikzpicture}
\node [draw] (a) {a};
\node [draw] at (6,0) (b) {b};
\node [below=of a] {
\begin{bytefield}{8}
\wordbox{1}{Source: b}
\\ \wordbox{1}{1}
\\ \wordbox{1}{2}
\\ \wordbox{1}{3}
\end{bytefield}
};
\node [below=of b] {
\begin{bytefield}{8}
\wordbox{1}{Source: a}
\\ \wordbox{1}{4}
\\ \wordbox{1}{5}
\end{bytefield}
};
\end{tikzpicture}
% What should be a step in the right direction,
% compare https://tex.stackexchange.com/questions/679919/using-foreach-to-add-variable-number-of-rows-to-a-bytefield-inside-a-tikz-node/679923?noredirect=1#comment1687472_679923
\begin{tikzpicture}[wordbox/.code={\\\wordbox{1}{#1}}]
\node {
\begin{bytefield}{8}
\wordbox{1}{Source: A}
\tikzset{wordbox/.list={1,2,3}}
\end{bytefield}
};
\end{tikzpicture}
% How I hope to get it to work, but only get two wordboxes,
% instead of four on the left, three on the right:
\begin{tikzpicture}[wordbox/.code={\\\wordbox{1}{#1}}]
\node [draw] (a) {a};
\node [draw] at (6,0) (b) {b};
\foreach \n/\fields in {a/{1,2,3},b/{4,5}} {
\node [below=of \n] {
\begin{bytefield}{8}
\wordbox{1}{Source: \n}
\tikzset{wordbox/.list=\fields}
\end{bytefield}
};
}
\end{tikzpicture}
% An alternative with a foreach inside bytefield does not even compile:
% \begin{tikzpicture}
% \node [draw] (a) {a};
% \node [draw] at (6,0) (b) {b};
% \foreach \n/\fields in {a/{1,2,3},b/{4,5}} {
% \node [below=of \n] {
% \begin{bytefield}{8}
% \wordbox{1}{Source: \n}
% \foreach \f in \fields { \\ \wordbox{1}{\f} }
% \end{bytefield}
% };
% }
% \end{tikzpicture}
\end{document}
这三个步骤的示例图如下所示。
在最后一种情况下,列表处理程序似乎没有遍历字段?有什么办法可以解决这个问题吗?
我想要的是:
朝着正确方向迈出的中间一步?
我得到的是:
答案1
如果你只是说/.list=\fields
,那么宏\fields
将是列表中的唯一元素。在内部,这将导致一个循环,如下所示
\foreach \ELEMENT in {\fields}
在处理程序评估它之前,你需要\fields
至少扩展一次。因此,你需要.list
\tikzset{wordbox/.list/.expand once=\fields}
或者
\tikzset{wordbox/.list/.expanded=\fields}
您的第二个示例(带有显式\foreach
循环)会导致问题,因为它将对每次迭代进行分组。它类似于
\begin{bytefield}{8}
\wordbox{1}{Source: \n}
{ \\ \wordbox{1}{1} }
{ \\ \wordbox{1}{2} }
{ \\ \wordbox{1}{3} }
\end{bytefield}
这与bytefield
内部运作方式相冲突。
如果您不满意.list
(内部使用 PGFFor\foreach
并允许...
语法),您可以使用例如\int_step_inline:nnn
这样的用法:
% Preamble
\ExplSyntaxOn
\DeclareDocumentCommand{\ForeachInline}{}{\int_step_inline:nnn}
\ExplSyntaxOff
% Document
\begin{tikzpicture}
\node [draw] (a) {a};
\node [draw] at (6,0) (b) {b};
\foreach \n/\st/\en in {a/1/3, b/4/5} {
\node [below=of \n] {
\begin{bytefield}{8}
\wordbox{1}{Source: \n}
\ForeachInline{\st}{\en}{ \\ \wordbox{1}{##1} }
\end{bytefield}
};
}
\end{tikzpicture}