
Я хотел бы создать несколько разделенных прямоугольников, ширина которых определяется длиной обозначенной линии. Я хотел бы сделать это через ключ, например:
\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
действует на локальный временный регистр размерности. Локальные и глобальные назначения не следует смешивать в одной и той же управляющей последовательности по соображениям памяти.
\pgftext{%
\settowidth{\dimen0}{#1}%%
\global\aetmplength=\dimen0\relax
}%
node font
Последняя версия также может использоваться для учета значения option node font
. Значение хранится в макросе \tikz@node@textfont
. Без \makeatletter
and \makeatother
последовательность управления также может быть указана с помощью \csname
and \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}