Establecer una longitud con una clave para un nodo TikZ

Establecer una longitud con una clave para un nodo TikZ

Me gustaría crear algunos rectángulos divididos cuyos anchos estén definidos por la longitud de una línea designada. Me gustaría hacer esto a través de una clave como en:

\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}

Pero esto no funciona. Fácilmente podría dedicar algún tiempo a solucionar este problema. Entonces este no es un problema de cómo establecer la longitud que quiero. Lo que quiero entender es por qué esta definición de clave no hace lo que quiero que haga.

Respuesta1

La explicación que está usando TikZ \nullfontya está dada en el artículo de Percusse.respuesta. Por lo tanto, \settowidthno funcionará como se esperaba.

\pgfmathsetlength{width("#1")}

En lugar de \settowidthla pgfmathfunción widthse puede utilizar en su lugar:

\pgfmathsetlength\aetmplength{width("#1")}

Ejemplo completo:

\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}

Resultado

\pgftext{...}

Otra forma es \pgftext, que escapa de regreso a TeX, donde \settowidthvolverá a funcionar. Dado que el argumento de \pgftextse procesa dentro de un grupo, \aetmplengthse asigna globalmente y \setwidthactúa en un registro de dimensión temporal local. Las asignaciones locales y globales no se deben mezclar en la misma secuencia de control por motivos de memoria.

\pgftext{%
  \settowidth{\dimen0}{#1}%%
  \global\aetmplength=\dimen0\relax
}%

node font

La última versión también se puede utilizar para respetar el valor de la opción node font. El valor se almacena en macro \tikz@node@textfont. Sin \makeatlettery \makeatotherla secuencia de control también puede especificarse mediante \csnamey \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}

Resultado con configuración de fuente de nodo

Respuesta2

El diseño de TikZ/PGF se realiza de tal manera que su sintaxis regular no tenga fugas de espacios en blanco falsos ni se impriman caracteres no deseados dentro del código, etc. Una forma de hacerlo es asignar la fuente actual a la primitiva especial \nullfont.

Esto provoca que no se pueda simplemente manejar el ancho del texto sin recrear el no \nullfontestado original. Sólo para dar algo de contexto, a continuación se toma de la definición pgf@picturedel entorno :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%

Una vez que sepamos esto, podrá volver temporalmente a la definición original dentro de un grupo, obtener el ancho y sobrevivir al grupo.

\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}

ingrese la descripción de la imagen aquí

información relacionada