无法在 tikz 中设置 sbox

无法在 tikz 中设置 sbox

(Qrrbrbirlbel 回答后的更新版本:我想测量 tikz 节点)

我想计算将在 tikz-cd 节点中排版的内容(tikz 多行节点)的宽度,以适应父节点的形状。但是,在 tikz 内部创建的 sbox 宽度为零,并且tikzpicture在其中排版会导致无限递归……知道为什么以及如何避免该问题吗?

梅威瑟:

\documentclass{article}
\usepackage{amsmath}

\usepackage{tikz}
\usepackage{tikz-cd}
\begin{document}
\newsavebox{\tmpbox}

\NewExpandableDocumentCommand{\myNode}{m}{
  \node[inner sep=5pt,fill=green,draw,align=center]{#1};
}

\def\myContentOfInterest{\begin{tikzcd}\myNode{42\\and multiple lines};\end{tikzcd}}
\def\myContentOfInterestTikzVersion{\begin{tikzpicture}\myNode{42\\and multiple lines};\end{tikzpicture}}
Goal: measure the content of \myContentOfInterest

\sbox\tmpbox{\myContentOfInterest}%
\def\myvalue{\the\dimexpr\the\ht\tmpbox\relax}
Outside tikz: \myvalue

Inside tikz:
\tikzset{
  my style/.style={
    /utils/exec={%
      %%%%% works but too simple:
      % \pgfmathheight{"this works but too simple case"}%
      % \edef\myvalue{\pgfmathresult pt}%
      %%%%% fails (infinite computation):
      % \pgfmathheight{"\noexpand\myContentOfInterestTikzVersion"}%%
      % \edef\myvalue{\pgfmathresult pt}%
      %%%%% fails: issue with infinite recursion \pgf@selectfontorig ->\pgf@selectfontorig 
      % \sbox\tmpbox{\myContentOfInterestTikzVersion}%
      \def\myvalue{\text{What should I do to measure the final node itself?}}
    },
  }
}

\begin{tikzcd}[font={\fontsize{10}{12}\selectfont}]
  \node[my style]{\myvalue};
\end{tikzcd}


\end{document}

答案1

我原来的答案真的很肮脏,感谢 Qrrbrbirlbel 的精彩建议。解决方案是:

      \begin{lrbox}{\tmpbox}% <- this create a box (like savebox but environment)
        \begin{pgfinterruptpicture}% <- this resets the font
          \begin{pgfpicture}%
            \node{foo};%
          \end{pgfpicture}%
        \end{pgfinterruptpicture}%
        %\let\selectfont\pgf@selectfontorig%
      \end{lrbox}%

例子:

\documentclass{article}
\usepackage{amsmath}

\usepackage{tikz}
\usepackage{tikz-cd}
\begin{document}
\newsavebox{\tmpbox}

\NewExpandableDocumentCommand{\myNode}{m}{
  \node[inner sep=5pt,fill=green,draw,align=center]{#1};
}

\def\myContentOfInterestBasic{\myNode{42\\and multiple lines};}
\def\myContentOfInterest{\begin{tikzcd}\myContentOfInterestBasic\end{tikzcd}}
Goal: measure the content of \myContentOfInterest

\sbox\tmpbox{\myContentOfInterest}%
\def\myvalue{\the\dimexpr\the\ht\tmpbox\relax}
Outside tikz: \myvalue
\rule{\myvalue}{\myvalue}

\makeatletter
Inside tikz:
\tikzset{
  my style/.style={
    /utils/exec={%
      \begin{lrbox}{\tmpbox}
        \begin{pgfinterruptpicture}%
          \begin{pgfpicture}
            \myContentOfInterestBasic%
          \end{pgfpicture}
        \end{pgfinterruptpicture}%
        %\let\selectfont\pgf@selectfontorig%
      \end{lrbox}%
    },
  },
}
\makeatother

% Works:
\begin{tikzcd}
  \node[my style]{\myvalue};
\end{tikzcd}

% Works:
\begin{tikzcd}[font={\fontsize{18}{12}\selectfont}]
  \node{Test};
\end{tikzcd}

%% Works now
\begin{tikzcd}[font={\fontsize{18}{12}\selectfont}]
  \node[my style]{\myvalue};
\end{tikzcd}

\rule{\myvalue}{\myvalue}

\end{document}

相关内容