
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 \nullfont
ya está dada en el artículo de Percusse.respuesta. Por lo tanto, \settowidth
no funcionará como se esperaba.
\pgfmathsetlength{width("#1")}
En lugar de \settowidth
la pgfmath
función width
se 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}
\pgftext{...}
Otra forma es \pgftext
, que escapa de regreso a TeX, donde \settowidth
volverá a funcionar. Dado que el argumento de \pgftext
se procesa dentro de un grupo, \aetmplength
se asigna globalmente y \setwidth
actú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 \makeatletter
y \makeatother
la secuencia de control también puede especificarse mediante \csname
y \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}
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 \nullfont
estado original. Sólo para dar algo de contexto, a continuación se toma de la definición pgf@picture
del 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}