
Ich möchte einige geteilte Rechtecke erstellen, deren Breite durch die Länge einer bestimmten Linie definiert ist. Dies möchte ich über einen Schlüssel wie in tun:
\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}
Aber das funktioniert nicht. Ich könnte leicht einige Zeit damit verbringen, das zu umgehen. Es geht also nicht darum, wie ich die gewünschte Länge einstelle. Was ich verstehen möchte, ist, warum diese Definition für den Schlüssel nicht das tut, was ich möchte.
Antwort1
Die Erklärung, die TikZ verwendet, \nullfont
ist bereits in PercussesAntwort\settowidth
. Funktioniert daher nicht wie erwartet.
\pgfmathsetlength{width("#1")}
Anstelle \settowidth
der pgfmath
Funktion width
kann stattdessen verwendet werden:
\pgfmathsetlength\aetmplength{width("#1")}
Vollständiges Beispiel:
\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{...}
Ein anderer Weg ist \pgftext
, der zurück zu TeX führt, wo \settowidth
es wieder funktioniert. Da das Argument von \pgftext
innerhalb einer Gruppe verarbeitet wird, \aetmplength
wird es global zugewiesen und \setwidth
wirkt auf ein lokales temporäres Dimensionsregister. Aus Speichergründen sollten lokale und globale Zuweisungen nicht in derselben Steuersequenz gemischt werden.
\pgftext{%
\settowidth{\dimen0}{#1}%%
\global\aetmplength=\dimen0\relax
}%
node font
Die neueste Version kann auch verwendet werden, um den Wert der Option zu berücksichtigen node font
. Der Wert wird im Makro gespeichert \tikz@node@textfont
. Ohne \makeatletter
und \makeatother
kann die Steuersequenz auch durch \csname
und angegeben werden \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}
Antwort2
Das Design von TikZ/PGF ist so gestaltet, dass die reguläre Syntax keine unerwünschten Leerzeichenlecks aufweist oder unbeabsichtigte Zeichen im Code usw. ausgedruckt werden. Eine Möglichkeit besteht darin, die aktuelle Schriftart dem speziellen Primitiv zuzuordnen \nullfont
.
Dies führt dazu, dass Sie die Textbreite nicht einfach handhaben können, ohne den ursprünglichen Nicht- \nullfont
Zustand wiederherzustellen. Um etwas Kontext zu geben, ist das Folgende der pgf@picture
Umgebungsdefinition entnommen 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%
Sobald wir dies wissen, können Sie innerhalb einer Gruppe vorübergehend zur ursprünglichen Definition zurückkehren, die Breite ermitteln und die Gruppe überleben.
\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}