我想定义一个 TikZ 节点样式,将节点形状设置为rectangle split
并自动添加第一部分,其内容由样式定义。通常的节点文本出现在第二部分。有没有办法做到这一点,或者类似的东西?
期望的行为
代码:
\node[achtung] at (1, 2) {Falling rocks};
输出:
( Achtung | Falling rocks )
尝试
我试过了
achtung/.append style={
execute at begin node={Achtung\nodepart{two}},
rectangle split,
rectangle split horizontal,
rectangle split parts=2
}
以及更复杂的版本,例如
achtung/.append style={
execute at begin node={Achtung\protect\nodepart{two}\protect\begingroup},
execute at end node={\protect\endgroup},
rectangle split,
rectangle split horizontal,
rectangle split parts=2,
every one node part/.style={
execute at begin node={},
execute at end node={}
},
every two node part/.style={
execute at begin node={},
execute at end node={}
}
}
它们都会导致"Extra }, or forgotten \\endgroup.\n\\pgfutil@reserved@c ->\\egroup \n"
错误。
使用编译的版本\pgfnodeparttwobox
,但没有给出所需的行为。
最小不工作示例
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
achtung/.append style={
execute at begin node={Achtung\nodepart{two}}, % remove this line to compile successfully
rectangle split,
rectangle split horizontal,
rectangle split parts=2,
draw
}
}
\begin{document}
\begin{tikzpicture}
\node[achtung] {Falling rocks};
\end{tikzpicture}
\end{document}
答案1
这个钩子execute at begin node
对于 nodeparts 来说还太早了。这里确实没有合适的钩子可用。我们可以尝试滥用在开始时执行的其他宏之一 - 它们处理水平对齐和嵌套的 TikZ 图片(?) - ...
但是,我不会把它们弄乱并造成不兼容性,我只会添加我们自己的钩子,print at begin node
它的作用类似于,node contents
但它不是替换,而是简单地在{
和之间添加前缀}
。
(此钩子将不是当 TikZ 图片是节点内容的一部分时进行重置,但首先这样做很少是一个好主意。)
代码
\documentclass[tikz]{standalone}
%\documentclass{article}
%\usepackage{tikz}
\ExplSyntaxOn \makeatletter
\tl_replace_once:Nnn \tikz@do@fig
{ \ignorespaces }
{ \pgfkeysvalueof{/tikz/print~at~begin~node} \ignorespaces }
\makeatother \ExplSyntaxOff
\pgfkeyssetvalue{/tikz/print at begin node}{}
\usetikzlibrary{shapes.multipart}
\tikzset{
achtung/.append style={
print at begin node = Achtung \nodepart{two},
rectangle split, rectangle split horizontal, rectangle split parts=2, draw}}
\tikzset{
gnutcha/.append style={
print at begin node = \nodepart{two} Achtung \nodepart{one},
rectangle split, rectangle split horizontal, rectangle split parts=2, draw}}
\begin{document}
\tikz \node[achtung] {Falling rocks}
node[gnutcha] at (0, -1) {Falling rocks};
\tikz \node[achtung] {Falling rocks \nodepart{text} You're not the }
node[achtung] at (0, -1) {Falling rocks \nodepart{one} boss of me. };
\end{document}
输出
答案2
node contents
您可以使用样式node contents={Achtung\nodepart{two}#1}
,并将其用作achtung={Falling rocks}
。正如评论中所述,使用node contents
意味着您无法执行\node [..] at (x,y)...
,但\node at (x,y) [...]
确实有效。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
achtung/.append style={
rectangle split,
rectangle split horizontal,
rectangle split parts=2,
draw,
node contents={Achtung\nodepart{two}#1}
},
achtung/.default=
}
\begin{document}
\begin{tikzpicture}
\node[achtung={Falling rocks}];
\end{tikzpicture}
\end{document}
答案3
用命令?
编辑:使用 Alan Munn 的评论通过添加节点的位置作为参数和D(){}
#2 参数的规范
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\NewDocumentCommand{\mynode}{ O{achtung} d() m }{
\IfNoValueTF{#2}
{\path node[#1,right]{#1\nodepart{two}#3};}
{\path (#2) node[#1,right]{#1\nodepart{two}#3};}
}
\tikzset{
achtung/.style={
rectangle split,
rectangle split horizontal,
rectangle split parts=2,
draw,
}
}
\begin{document}
\begin{tikzpicture}
\draw[help lines](0,0)grid(3,2);
\mynode[achtung] (2,1) {Falling rocks}
\mynode (0,0) {achtung is the default style}
\end{tikzpicture}
\end{document}