Festlegen einer Länge mit einem Schlüssel für einen TikZ-Knoten

Festlegen einer Länge mit einem Schlüssel für einen TikZ-Knoten

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, \nullfontist bereits in PercussesAntwort\settowidth. Funktioniert daher nicht wie erwartet.

\pgfmathsetlength{width("#1")}

Anstelle \settowidthder pgfmathFunktion widthkann 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}

Ergebnis

\pgftext{...}

Ein anderer Weg ist \pgftext, der zurück zu TeX führt, wo \settowidthes wieder funktioniert. Da das Argument von \pgftextinnerhalb einer Gruppe verarbeitet wird, \aetmplengthwird es global zugewiesen und \setwidthwirkt 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 \makeatletterund \makeatotherkann die Steuersequenz auch durch \csnameund 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}

Ergebnis mit Knotenschriftarteinstellung

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- \nullfontZustand wiederherzustellen. Um etwas Kontext zu geben, ist das Folgende der pgf@pictureUmgebungsdefinition 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}

Bildbeschreibung hier eingeben

verwandte Informationen