我正在尝试构建一些宏来解析我在其中偷运隐藏参数的其他宏的参数。
下面的代码可以完美运行:
\documentclass{article}
\makeatletter
\def\ae@w@@{1}
\def\ae@m@@{1}
\def\ae@set@m@@#1/#2\ae@sep@@{\def\ae@m@@{#1}}
\def\ae@sep@wm@@#1/#2\ae@sep@@{%%
\def\ae@w@@{#1}%%
\ifx#2\relax\else
\ae@set@m@@#2\ae@sep@@
\fi
}
\def\aegetWM#1{%%
\bgroup
\ae@sep@wm@@#1/\relax\ae@sep@@
W=\ae@w@@\newline
M=\ae@m@@
\egroup
}
\makeatother
%% to visually emphasize groupings
\setlength{\parskip}{5ex}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\begin{document}
\aegetWM{400}
\aegetWM{234/100}
\aegetWM{300}
\end{document}
但如果我定义\ae@set@m@@
如下:
\def\ae@set@m@@#1/\ae@sep@@{\def\ae@m@@{#1}}
我收到以下错误:
Runaway argument?
100/\relax \ae@sep@@ \fi W=\ae@w@@ \newline M=\ae@m@@ \egroup
! Paragraph ended before \ae@set@m@@ was complete.
<to be read again>
\par
l.35
?
这是怎么回事?为什么其中一个定义有效,而另一个却无效?
答案1
当你说
\def\cs#1/\@nil{...}
每个的调用\cs
必须/\@nil
在段落结束之前的某个地方找到,因为宏不在\long
,或者,如果你声明它\long
,则在当前正在读取的文件结束之前。
使用第二个定义,您调用\ae@set@m@@#1/\relax\ae@sep@@
并且 TeX 找不到所需的标记。
实际上,你的做法太复杂了:
\documentclass{article}
\makeatletter
\def\aegetWM#1{\ae@sep@wm@@#1//\ae@sep@@}
\def\ae@sep@wm@@#1/#2/#3\ae@sep@@{%
W=#1\newline
M=\if\relax\detokenize{#2}\relax1\else#2\fi
}
\makeatother
%% to visually emphasize groupings
\setlength{\parskip}{5ex}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\begin{document}
\aegetWM{400}
\aegetWM{234/100}
\aegetWM{300}
\end{document}
让我们看看当你调用时会发生什么\aegetWM{400}
:
\ae@sep@@wm@@ 400//\@ae@sep@@
所以#1<-400
,,#2<-<empty>
。#3<-<empty>
当您致电时,\aegetWM{234/100}
我们会
\ae@sep@@wm@@ 234/100//\@ae@sep@@
所以#1<-234
,#2<-100
,#3<-/
。