我想创建一些分割矩形,其宽度由指定线的长度定义。我想通过如下键来实现:
\documentclass[border=4pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\newlength\aetmplength
\begin{document}
\begin{tikzpicture}[
set text to width of/.code={%%
\settowidth\aetmplength{#1}%%
\typeout{--->`#1`::\the\aetmplength}%%
\pgfkeysalso{text width=\the\aetmplength}%%
},
]
\node[draw,
shape=rectangle split,
rectangle split parts=2,
set text to width of=This is the top of the node,
%text width=0.95in
] ()
{
This is the top of the node
\nodepart{two}
first item\\
second item\\
\ldots};
\end{tikzpicture}
\end{document}
但这不管用。我可以轻松地花一些时间来解决这个问题。所以这不是如何设置我想要的长度的问题。我想了解的是为什么这个键的定义没有达到我想要的效果。
答案1
TikZ 使用的解释\nullfont
已在 percusse 的回答。因此\settowidth
不会按预期工作。
\pgfmathsetlength{width("#1")}
\settowidth
可以用以下pgfmath
函数来width
代替:
\pgfmathsetlength\aetmplength{width("#1")}
完整示例:
\documentclass[border=4pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\newlength\aetmplength
\begin{document}
\begin{tikzpicture}[
set text to width of/.code={%%
% \settowidth\aetmplength{#1}%%
\pgfmathsetlength\aetmplength{width("#1")}%
\typeout{--->`#1`::\the\aetmplength}%%
\pgfkeysalso{text width=\the\aetmplength}%%
},
]
\node[draw,
shape=rectangle split,
rectangle split parts=2,
set text to width of=This is the top of the node,
%text width=0.95in
] ()
{
This is the top of the node
\nodepart{two}
first item\\
second item\\
\ldots};
\end{tikzpicture}
\end{document}
\pgftext{...}
另一种方法是\pgftext
,它会转回 TeX,然后\settowidth
再次起作用。由于 的参数\pgftext
是在组内处理的,因此\aetmplength
被全局分配并\setwidth
作用于本地临时 dimen 寄存器。出于内存原因,不应在同一控制序列上混合使用本地和全局分配。
\pgftext{%
\settowidth{\dimen0}{#1}%%
\global\aetmplength=\dimen0\relax
}%
node font
最新版本也可以使用 option 的值来表示node font
,该值存储在宏中\tikz@node@textfont
,不用 和\makeatletter
,\makeatother
控制序列也可以通过 和\csname
来指定\endcsname
:
\documentclass[border=4pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\newlength\aetmplength
\begin{document}
\begin{tikzpicture}[node font=\tiny,
set text to width of/.code={%%
\pgftext{%
\csname tikz@node@textfont\endcsname
\settowidth{\dimen0}{#1}%%
\global\aetmplength=\dimen0\relax
}%
\typeout{--->`#1`::\the\aetmplength}%%
\pgfkeysalso{text width=\the\aetmplength}%%
},
]
\node[draw,
shape=rectangle split,
rectangle split parts=2,
set text to width of=This is the top of the node,
%text width=0.95in
] ()
{
This is the top of the node
\nodepart{two}
first item\\
second item\\
\ldots};
\end{tikzpicture}
\end{document}
答案2
TikZ/PGF 的设计方式是,其常规语法不会出现任何虚假的空白泄漏或在代码中打印出意外的字符等。一种方法是将当前字体映射到特殊原语\nullfont
。
这导致您无法简单地处理文本宽度而不重新创建原始的非状态\nullfont
。为了提供一些背景信息,下面取自pgf@picture
环境begin
定义:
\begingroup%
\let\pgf@setlengthorig=\setlength%
\let\pgf@addtolengthorig=\addtolength%
\let\pgf@selectfontorig=\selectfont% <== Records the original
\let\setlength=\pgf@setlength%
\let\addtolength=\pgf@addtolength%
\let\selectfont=\pgf@selectfont% <== Overwrites
\nullfont\spaceskip0pt\xspaceskip0pt% <== Resets font
\setbox\pgf@layerbox@main\hbox to0pt\bgroup%
\begingroup%
一旦我们知道了这一点,您就可以暂时回到组内的原始定义,获取宽度并在组中生存。
\documentclass[border=4pt,tikz]{standalone}
\usetikzlibrary{shapes.multipart}
\makeatletter
\tikzset{set text to width of/.code={%%
\begingroup%
\pgfutil@selectfont%
\settowidth\pgf@xc{#1}% <== PGF internal scratch registers xa,ya,xb,yb,xc,yc
\edef\temp{\noexpand\pgfkeysalso{text width=\the\pgf@xc}}%<- Nonzero
\expandafter\endgroup\temp%%
\typeout{--->`#1`::\the\pgf@xc}%<-Still zero!
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[draw,
align=center,%<- for line breaks
shape=rectangle split,
rectangle split parts=2,
set text to width of=This is looooooooonnnnnnnnger than the top,
] ()
{
This is the top of the node
\nodepart{two}
first item\\
second item\\
\ldots};
\end{tikzpicture}
\end{document}