
Gostaria de criar alguns retângulos divididos cujas larguras sejam definidas pelo comprimento de uma linha designada. Eu gostaria de fazer isso através de uma chave como em:
\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}
Mas isso não funciona. Eu poderia facilmente passar algum tempo trabalhando nisso. Portanto, este não é um problema de como definir o comprimento que desejo. O que quero entender é por que essa definição de chave não está fazendo o que eu quero.
Responder1
A explicação que o TikZ está usando \nullfont
já é dada no percusse'sresponder. Portanto, \settowidth
não funcionará conforme o esperado.
\pgfmathsetlength{width("#1")}
Em vez \settowidth
da pgfmath
função width
pode ser usado:
\pgfmathsetlength\aetmplength{width("#1")}
Exemplo 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{...}
Outra forma é \pgftext
, que escapa de volta para o TeX, onde \settowidth
funcionará novamente. Como o argumento de \pgftext
é processado dentro de um grupo, \aetmplength
é atribuído globalmente e \setwidth
atua em um registro de dimensão temporária local. As atribuições locais e globais não devem ser misturadas na mesma sequência de controle por motivos de memória.
\pgftext{%
\settowidth{\dimen0}{#1}%%
\global\aetmplength=\dimen0\relax
}%
node font
A versão mais recente também pode ser usada para respeitar o valor de option node font
. O valor é armazenado na macro \tikz@node@textfont
. Sem \makeatletter
e \makeatother
a sequência de controle também pode ser especificada por \csname
e \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}
Responder2
O design do TikZ/PGF é feito de forma que sua sintaxe regular não tenha nenhum vazamento falso de espaço em branco ou caracteres não intencionais sejam impressos dentro do código, \nullfont
etc.
Isso faz com que você não possa simplesmente manipular a largura do texto sem recriar o não- \nullfont
estado original. Apenas para dar algum contexto, abaixo é retirado da definição do pgf@picture
ambiente :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%
Assim que soubermos disso, você poderá voltar temporariamente à definição original dentro de um grupo, obter a largura e sobreviver ao 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}