我想创建一个pspicture
具有各种相互依赖的参数的。我正在使用expl3
接口。但是当我尝试使用时出现错误\getr
Error: /undefined in \getr
Operand stack:
--nostringval-- 56.9055 0.0
最初,我不知道错误是从哪里产生的。现在我尝试了多种方法来复制错误。大多数方法都有效不是失败。我唯一一次失败是当我使用它xparse
来定义我想要的接口时。
这是我的 MWE:
\documentclass{article}
\usepackage{xparse}
\usepackage{pst-eucl}
\usepackage[margin=1in]{geometry}
\psset{unit=1cm}
\pagestyle{empty}
%%
\ExplSyntaxOn
\cs_generate_variant:Nn \int_eval:n {c}
\NewDocumentCommand{\setr}{ m m }
{
\int_if_exist:cF { g__ace_angle_ #1 _int }
{ \int_new:c { g__ace_angle_ #1 _int }}
\int_gset:cn { g__ace_angle_ #1 _int }
{\int_eval:n {#2}}
}
\NewDocumentCommand{\getr}{ m }
{
\int_eval:c { g__ace_angle_ #1 _int }
}
%%
\setr{r1}{-30}
\setr{u1}{\getr{r1}+90}
%%
\newcounter{dummy}\setcounter{dummy}{-30}
\newcommand{\asimplecommand}{-30}
\newcommand{\expliiimacro}{\int_eval:n {\asimplecommand + 60}}
\newcommand{\argdependentmacro}[1]{\ifcase#1\relax-30\or0\or30\or60\fi}
\NewDocumentCommand{\xparsemacroA}{ }{120}
\NewDocumentCommand{\xparsemacroB}{ m }{#1}
\cs_new:Npn \latexiiimacro #1 { #1 }
\ExplSyntaxOff
\setlength{\parindent}{0ex}
\setlength{\parskip}{5ex}
\begin{document}
Works:\hspace*{1in}\texttt{getr(r1)=}$\getr{r1}$\newline
Works:\hspace*{1in}\texttt{getr(u1)=}$\getr{u1}$
\vspace{1cm}
\textbf{It's not a problem with passing a counter-like thingy:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\thedummy]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\textbf{It's not a problem with a command:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\asimplecommand]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\textbf{It's not with a command name whose internals are defined with \texttt{expl3}:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\expliiimacro]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\textbf{It's not a problem with first having to evaluate an argument:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\argdependentmacro{2}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\textbf{It's not a problem with command name defined in \texttt{latex3}:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\latexiiimacro{-120}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\textbf{What about \texttt{xparse}:}\newline
Fails:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\xparsemacroA]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\textbf{What about \texttt{xparse}:}\newline
Fails:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\xparsemacroB{120}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
Fails:
\begin{pspicture}(-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}(0,1){u}
\pstRotation[RotAngle=\getr{r1}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}
\end{document}
制作:
在我使用的所有方法中,xparse
似乎只会导致错误:
Error: /undefined in \xparsemacro
事实上,我最没想到会出现问题的地方就是这里。有什么想法吗?
答案1
问题在于可扩展性。当你有
\pstRotation[RotAngle=\SomeMacro{argument}]{o}{r}[r1]
PStricks 需要能够将角度写入.dvi
文件,然后 PostScript 会进一步使用该角度。如果\SomeMacro
是可扩展的,那么这种方法就很好,因为它会变成数字。但是,如果是受保护的(不可扩展)命令,那么这种方法就行不通了:相反,命令的名称会写入文件.dvi
,这对 PStricks 来说毫无意义。
LaTeX3 文档命令是受保护的,因为这在几乎所有情况下都是最有意义的。但是,有一种方法可以创建可扩展的文档命令
\DeclareExpandableDocumentCommand{\getr}{ m }
{
\int_use:c { g__ace_angle_ #1 _int }
}
如果将其用于所有“get”函数,您会发现示例确实可以编译。