
指定された線の長さによって幅が定義される分割された長方形をいくつか作成したいと思います。次のようなキーを使用してこれを実行したいと思います。
\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}
しかし、これはうまくいきません。この問題を回避するには、いくらかの時間を費やす必要があります。したがって、これは必要な長さを設定する方法の問題ではありません。私が理解したいのは、このキーの定義が、なぜ私が望む動作をしないのかということです。
答え1
TikZが使用している説明は、\nullfont
すでにpercusseの答えしたがって、\settowidth
期待どおりに動作しません。
\pgfmathsetlength{width("#1")}
\settowidth
関数の代わりに次の関数pgfmath
をwidth
使うこともできます:
\pgfmathsetlength\aetmplength{width("#1")}
完全な例:
\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{...}
もう 1 つの方法は で\pgftext
、これは TeX に戻り、ここで が\settowidth
再び機能します。 の引数は\pgftext
グループ内で処理されるため、\aetmplength
はグローバルに割り当てられ、\setwidth
ローカルの一時次元レジスタに作用します。メモリ上の理由から、ローカル割り当てとグローバル割り当てを同じ制御シーケンスで混在させないでください。
\pgftext{%
\settowidth{\dimen0}{#1}%%
\global\aetmplength=\dimen0\relax
}%
node font
最新バージョンは、オプション の値を尊重するためにも使用できますnode font
。値はマクロ に格納されます\tikz@node@textfont
。 と がない場合\makeatletter
、\makeatother
制御シーケンスは と によっても指定でき\csname
ます\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}
答え2
TikZ/PGF の設計は、通常の構文に不要な空白の漏れが生じたり、コード内に意図しない文字が出力されたりしないように行われます。その方法の 1 つは、現在のフォントを特殊なプリミティブにマップすることです\nullfont
。
このため、元の非\nullfont
状態を再作成せずにテキストの幅を単純に処理することはできません。コンテキストを説明するために、以下はpgf@picture
環境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%
これを知れば、グループ内の元の定義に一時的に戻って幅を取得し、グループを存続させることができます。
\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}