\saveddimen
我对命令内部的用法有疑问\pgfdeclareshape
。我的代码如下:
\documentclass{article}
\usepackage{tikz}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\makeatletter
\pgfdeclareshape{myshape}{
\savedanchor{\centerpoint}{\pgf@x=0pt\pgf@y=0pt}
\saveddimen{\mydima}{%
\pgf@x=20pt
}
\saveddimen{\mydimb}{%
\pgf@x=20pt %% =\mydima
\pgf@x=-\pgf@x
}
%
\anchor{center}{\centerpoint}
\backgroundpath{%
\pgf@xa=\mydima \pgf@ya=\mydima
\pgf@xb=\mydimb \pgf@yb=\mydimb
\pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}
\pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[help lines] (0,0) grid (4,4);
\node[myshape,draw] at (2,2) {test};
\end{tikzpicture}
\end{document}
这将生成一个节点,顶部和底部有水平线。在我的实际示例中,我希望有一个维度,\dimenb
它是 的函数。如果我在 命令设置中\dimena
取消注释 , 我会收到一条错误消息。%%
\saveddimen{\dimenb}
\pgf@x=\dimmena
问题:在另一个已保存的维度的定义中使用一个已保存的维度是否合法?如果合法,该如何做?
答案1
在评论中,percusse建议写作:
\saveddimen{\mydima}{\pgf@x=20pt}
\saveddimen{\mydimb}{\pgf@x=-\pgf@x}
要了解其工作原理,我们需要追溯定义。其中\pgfdeclareshape
实际上\saveddimen
是\pgf@sh@saveddimen
其定义:
\def\pgf@sh@saveddimen#1#2{%
\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}}
因此,当声明形状时,我们会看到\pgf@sh@s@<shapename>
获得命令。据推测,当使用形状设置所有尺寸等时,会运行\pgf@sh@resaveddimen{#1}{#2}
该宏。因此,要找出运行时会发生什么,我们需要查看。这是:\pgf@sh@s@<shapename>
\pgf@sh@resaveddimen
\def\pgf@sh@resaveddimen#1#2{%
{#2\global\pgf@x=\pgf@x}%
\edef\pgf@sh@marshal{%
\noexpand\pgfutil@g@addto@macro\noexpand\pgf@sh@savedpoints{%
\noexpand\def\noexpand#1{\the\pgf@x}%
}}%
\pgf@sh@marshal%
}
因此#2
(这是执行代码)运行,然后\pgf@x
设置为全球的版本本身(这很重要)。现在这个没有保存为给定的名称,但代码\def\<given name>{<the actual value of \pgf@x>}
保存为\pgf@sh@savedpoints
。请注意,这是实际的值,而不是宏\pgf@x
。
因此,我们分为三个阶段:宣言当模板设置完成后,定义定义形状的位置,使用各个部件的使用情况(其中部分部件位于定义阶段,因此这可能会令人困惑)。
让我们通过上面的代码及其变体来追踪这一点。
宣言。因此,我们在这里运行
\saveddimen
执行代码附加的命令。最后,它\pgf@sh@s@myshape
具有(除了它具有的其他内容之外):\pgf@sh@resaveddimen{\mydima}{\pgf@x=20pt} \pgf@sh@resaveddimen{\mydimb}{\pgf@x=-\pgf@x}
定义。现在
\pgf@sh@s@myshape
运行。这将执行上述两个命令(以及其他命令)。运行第一个命令后,运行状态如下\pgf@x
:全球设置为20pt
并且其中\pgf@sh@savedpoints
有。其中第一个是我们可以在 的定义中\def\mydima{20pt}
使用 的原因。第二个是我们为什么不能使用 的原因。\pgf@x
\mydimb
mydima
然后最后
\pgf@sh@savedpoints
包含\def\mydima{20pt}\def\mydimb{-20pt}
。使用。这是
\pgf@sh@savedpoints
执行的位置,所有宏最终都已定义。所以一切都已设置好前任务已完成。
总之,\mydima
在设置的代码时不可用\mydimb
,但只要它们一个接一个地声明,那么在\mydimb
执行的定义代码时,的值就是设置的\pgf@x
值。\mydima