首先,请注意,这个问题应被视为学习问题,因为我不是在寻找包(我非常了解该xparse
包)。
我正在尝试编写一个具有以下用途的宏:
\dsee*{text}[optarg]
因此我的代码如下:
\def\md@err{*}
\def\@hmno[#1]{%
\textsubscript{#1}}
\newcommand{\dsee}{\@ifstar\@@dsee\@dsee}
\def\@@dsee#1{%
\md@err#1\@ifnextchar[\@hmno\relax}
\def\@dsee#1{%
#1\@ifnextchar[\@hmno\relax}
到目前为止,它的工作符合预期:\dsee{test1}, \dsee{test2}[opt]
变成
然后我给宏添加一些格式。
\def\md@styl@foreign{%
\color[HTML]{0000AA}%
\rmfamily\mdseries\itshape}
% The new defs for \@@dsee and \@dsee
\def\@@dsee#1{%
\begingroup%
\md@styl@foreign\md@err#1\@ifnextchar[\@hmno\relax%]
\endgroup}
\def\@dsee#1{%
\begingroup%
\md@styl@foreign#1\@ifnextchar[\@hmno\relax%]
\endgroup}
然后我的输出结束为:。据我所知,\@ifnextchar
宏检查以下标记是否等同于其第一个参数,在我的情况下是[
。但是,由于更改了宏的定义,\@ifnextchar
与不匹配[
,显然,它不再是下一个标记。我怀疑我需要一些\expandafter
在我的之前\endgroup
。
我的问题是:
有没有办法确定流中的下一个标记是哪个,或者有没有办法确定哪里的扩展必须延迟?
也许使用\tracing...
选项?
任何指点都将不胜感激。
答案1
请随时发帖完全的显示所有必需包裹的文件。
您不需要跟踪来查看下一个标记,它在源中是明确的\endgroup
,因此您只需将其移动到两个分支中。
\documentclass{article}
\usepackage{fixltx2e,color}
\begin{document}
\makeatletter
\def\md@err{*}
\def\@hmno[#1]{%
\endgroup
\textsubscript{#1}}
\newcommand{\dsee}{\@ifstar\@@dsee\@dsee}
\def\md@styl@foreign{%
\color{red}%
\rmfamily\mdseries\itshape}
% The new defs for \@@dsee and \@dsee
\def\@@dsee#1{%
\begingroup%
\md@styl@foreign\md@err#1\@ifnextchar[\@hmno\endgroup%]
}
\def\@dsee#1{%
\begingroup%
\md@styl@foreign#1\@ifnextchar[\@hmno\endgroup%]
}
So far it works as intended: \dsee{test1}, \dsee{test2}[opt] becomes First test
I then add some formatting to the macros.
\end{document}
请注意,这并不是关于扩张 \@ifnextchar
不能通过扩展工作,并且在其定义中包含了赋值等不可扩展的操作。它接受两个指定真假情况的参数,然后跳过空格并测试以下标记,因此它几乎总是只用作最后的宏定义中的东西,否则不需要测试,因为下面的标记是明确的,所以它将始终采用相同的分支,例如在原始代码中,两个参数后的第一个非空白标记是,\endgroup
所以它总是会采取错误的分支。