Definir um comprimento com uma chave para um nó TikZ

Definir um comprimento com uma chave para um nó TikZ

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 \nullfontjá é dada no percusse'sresponder. Portanto, \settowidthnão funcionará conforme o esperado.

\pgfmathsetlength{width("#1")}

Em vez \settowidthda pgfmathfunção widthpode 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}

Resultado

\pgftext{...}

Outra forma é \pgftext, que escapa de volta para o TeX, onde \settowidthfuncionará novamente. Como o argumento de \pgftexté processado dentro de um grupo, \aetmplengthé atribuído globalmente e \setwidthatua 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 \makeatlettere \makeatothera sequência de controle também pode ser especificada por \csnamee \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 com configuração de fonte do nó

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, \nullfontetc.

Isso faz com que você não possa simplesmente manipular a largura do texto sem recriar o não- \nullfontestado original. Apenas para dar algum contexto, abaixo é retirado da definição do pgf@pictureambiente :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}

insira a descrição da imagem aqui

informação relacionada