了解代币扩展

了解代币扩展

首先,请注意,这个问题应被视为学习问题,因为我不是在寻找包(我非常了解该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所以它总是会采取错误的分支。

相关内容