以下 TikZ 代码按预期进行编译和渲染:
\matrix[struct]
{
\node[varname] (age) {age}; & \node[vartype] {int*}; \\
\node[varname] {height}; & \node[vartype] {float}; \\
\node[varname] {weight}; & \node[vartype] {float}; \\
};
以下情况则不然:
\documentclass[tikz,border=10pt,a4paper]{standalone}
\usetikzlibrary{arrows,intersections,shapes,backgrounds,scopes,positioning,fit,matrix}
%% Language and font encodings
\usepackage[english]{babel}
\begin{document}
\tikzset{varname/.style={rectangle,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{vartype/.style={rectangle,text=red,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{struct/.style={draw,matrix of nodes,column 1/.style={anchor=base west},column 2/.style={anchor=base west}}}
\begin{tikzpicture}
\matrix[struct] (person)
{
\node[varname] {name}; & \node[vartype] {const char*}; \\
\node[varname] {attributes}; &
\matrix[struct] (foo)
{
\node[varname] (age) {age}; & \node[vartype] {int*}; & \\
\node[varname] {height}; & \node[vartype] {float}; & \\
\node[varname] {weight}; & \node[vartype] {float}; & \\
}; \\
\node[varname] {next}; & TODO & \\
};
\end{tikzpicture}
\end{document}
Missing $ inserted.
为什么不呢?如何得到矩阵中的矩阵?
目标是分层表示数据类型和结构。如果一个数据结构Primary
包含另一个数据结构Secondary
,那么我需要能够Secondary
在绘制的代码中包含/调用绘制的代码Primary
。我需要能够唯一地命名任何给定结构中的节点,以便我可以为它们附加任意装饰。ASCII 艺术:
PRIMARY----------------------+
| basic_field: int |
| complex_field: SECONDARY--+|
| | foo: int || ______
| | bar: int<======|note|
| | baz: int || ^^^^^^
| -----------+|
| basic_field_2: int |
+----------------------------+
答案1
Segletes 解决方案的变体:
注意:(foo)
和(age)
不会在最终的 tikzpicture 中定义。
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,intersections,shapes,backgrounds,scopes,positioning,fit,matrix}
%% Language and font encodings
\usepackage[english]{babel}% Really?
\newsavebox{\tempbox}
\begin{document}
\tikzset{varname/.style={rectangle,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{vartype/.style={rectangle,text=red,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{struct/.style={draw,matrix of nodes,column 1/.style={anchor=base west},column 2/.style={anchor=base west}}}
\setbox\tempbox=\hbox{\begin{tikzpicture}[baseline=(age.text)]
\matrix[struct] (foo)
{
\node[varname] (age) {age}; & \node[vartype] {int*}; & \\
\node[varname] {height}; & \node[vartype] {float}; & \\
\node[varname] {weight}; & \node[vartype] {float}; & \\
};
\end{tikzpicture}}%
\begin{tikzpicture}
\matrix[struct] (person)
{
\node[varname] {name}; & \node[vartype] {const char*}; \\
\node[varname] {attributes}; & \node{\usebox{\tempbox}}; \\
\node[varname] {next}; & TODO \\
};
\end{tikzpicture}
\end{document}
答案2
这有点丑陋,因为我不知道如何在自己的页面中standalone
构建每个页面(感谢评论中的 John K)。因此,内部框的外部存在边框。因此,我不得不求助于消除内部框周围的垂直边框并消除水平边框。我给出了一个tikzpicture
standalone
struct
\\[-10pt]
\hspace{-10pt}
附录下面展示了当不使用时整个问题是如何消失的standalone
。
即使修好了,它仍然有点丑陋,因为我必须单独构建内盒\vbox
并保存它,以便在外盒内重新出现。
\documentclass[tikz,border=10pt,a4paper]{standalone}
\usetikzlibrary{arrows,intersections,shapes,backgrounds,scopes,positioning,fit,matrix}
%% Language and font encodings
\usepackage[english]{babel}
\usepackage{stackengine}
\newcommand\insertmatrix[1]{%
\hspace{-10pt}%
\belowbaseline[-\dimexpr\baselineskip+\ht\strutbox\relax]{#1}%
\hspace{-10pt}%
}
\begin{document}
\tikzset{varname/.style={rectangle,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{vartype/.style={rectangle,text=red,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{struct/.style={draw,matrix of nodes,column 1/.style={anchor=base west},column 2/.style={anchor=base west}}}
\setbox0=\vbox{\begin{tikzpicture}
\matrix[struct] (foo)
{
\node[varname] (age) {age}; & \node[vartype] {int*}; & \\
\node[varname] {height}; & \node[vartype] {float}; & \\
\node[varname] {weight}; & \node[vartype] {float}; & \\
};
\end{tikzpicture}}
\savestack\mycomplex{\box0}
\begin{tikzpicture}
\matrix[struct] (person)
{
\node[varname] {name}; & \node[vartype] {const char*}; \\[-10pt]
\node[varname] {attributes}; & \insertmatrix{\mycomplex}
\\[-10pt]
\node[varname] {next}; & TODO \\
\node[varname] {afternext}; & MORE TODO \\
};
\end{tikzpicture}
\end{document}
附录
感谢 John 指出问题在于standalone
,而不是tikz
。如果我在课堂上完成任务,则不需要article
所有这些更正,并且可以将 放入 中。10pt
\vbox
\hbox
\documentclass[tikz,border=10pt,a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{arrows,intersections,shapes,backgrounds,scopes,positioning,fit,matrix}
%% Language and font encodings
\usepackage[english]{babel}
\usepackage{stackengine}
\newcommand\insertmatrix[1]{%
\belowbaseline[-\ht\strutbox]{#1}%
}
\begin{document}
\tikzset{varname/.style={rectangle,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{vartype/.style={rectangle,text=red,thin,inner sep=0.3ex,font=\ttfamily,text height=1.5ex,text depth=0.35ex}}
\tikzset{struct/.style={draw,matrix of nodes,column 1/.style={anchor=base west},column 2/.style={anchor=base west}}}
\setbox0=\hbox{\begin{tikzpicture}
\matrix[struct,ampersand replacement=\&] (foo)
{
\node[varname] (age) {age}; \& \node[vartype] {int*}; \& \\
\node[varname] {height}; \& \node[vartype] {float}; \& \\
\node[varname] {weight}; \& \node[vartype] {float}; \& \\
};
\end{tikzpicture}}
\savestack\mycomplex{\box0}
\begin{tikzpicture}
\matrix[struct] (person)
{
\node[varname] {name}; & \node[vartype] {const char*}; \\
\node[varname] {attributes}; & \insertmatrix{\mycomplex}
\\
\node[varname] {next}; & TODO \\
\node[varname] {afternext}; & MORE TODO \\
};
\end{tikzpicture}
\end{document}
答案3
我建议使用普通的 LaTeX 进行网格排列,使用 tikz 进行注释。\fbox
您可以使用更花哨的方法来绘制漂亮的方框。
\documentclass{article}
\usepackage{tikz}
\newcommand\vartype[1]{\textcolor{red}{\ttfamily#1}}
\newcommand\varname[1]{{\ttfamily#1}}
\newcommand\struct[1]%
{\fbox
{\begin{tabular}[t]{@{}ll@{}}
#1
\end{tabular}%
}%
}
\newcommand\tikznode[2]%
{\tikz[remember picture,baseline=(#1.base)]\node[inner sep=0pt] (#1) {#2};}
\begin{document}
\struct
{\varname{name} & \vartype{const char*} \\
\varname{attributes}
& \struct
{\varname{age} & \vartype{int*} \\
\varname{height} & \tikznode{heighttype}{\vartype{floatp}} \\
\varname{weight} & \vartype{float}
} \\[7ex]
\varname{next} & TODO
}
\begin{tikzpicture}[remember picture,overlay]
\draw[stealth-,shorten <=2pt] (heighttype) -- +(1,1) node[right] {important!};
\end{tikzpicture}
\end{document}