LaTeX3:在(未知的未知数量)参数后插入宏?

LaTeX3:在(未知的未知数量)参数后插入宏?

我刚刚玩了几个小时的 expl3。很多功能都比 2e 方便得多。有些功能可以实现我认为 LaTeX 无法实现的功能。但是,我缺少一个功能。

我很想有一个函数,也许execute_after:NN <macroA> <macroB>先执行宏 A,让它从输入流中获取尽可能多的标记,然后执行宏 B。因此,假设\macroA\macroB都接受 2 个参数,\execute_after:NN \macroA \macroB abcdefg则相当于\macroA{a}{b}\macroB{c}{d}efg

答案1

“简单”情况:参数定义为宏的参数\macroA

正式的宏参数在宏的定义(参数文本)中指定,例如

\def\foo[#1]#2{...}

它定义了一个宏,foo其参数文本[#1]#2包含两个参数,#1,以 分隔,]以及一个未分隔的参数#2。有两种方法可以了解宏的参数文本\foo

  • 应用于\meaning宏会扩展为包含其定义的字符串。\meaning\foo扩展为macro:[#1]#2->...。但是这是一个纯文本字符串,字符是字符标记,catcode 为 12(其他),但空格字符除外,其 catcode 为 10(空格)。因此,有关原始标记和 catcode 的信息丢失了。

    \catcode \[=\$ \catcode \]=\& \def\funny[#1]#2{...}

    定义一个宏\funny,其中[]具有不寻常的 catcode。但是\meaning\funny扩展为与完全相同的字符串\meaning\foo

  • 可以定义一个宏,并将其与未知宏进行比较。如果测试为\ifx真,则参数文本已知。

由于 的结果\meaning是有限的,因此可以遍历所有字节/标记/catcode 组合来定义所有宏,其\meaning扩展为完全相同的字符串。然后可以通过 进行比较来找到正确的宏\ifx

然后\execute_after:NN可以根据宏的参数文本解析输入流以获取参数,使用该参数调用宏并\macroB随后插入。

然而它的用途非常有限:

  • 枚举所有可能的宏定义并非易事。
  • 效率:太糟糕了。
  • 通常,“参数”在稍后的扩展或执行步骤中被读取,例如: \section正式定义为无参数宏。它扩展为\@startsection执行某些操作并最终检查星号标记,查找可选参数和...

  • “参数”定义不明确。例如,\begin有一个参数。它调用可以有更多参数的启动环境宏。此外,还有一个带有结束标记的环境主体\end{...}\macroB\begin{tabular}或之后插入\begin{verbatim}可能不是最佳选择。

执行\macroA

\execute_after:NN可以将宏存储\macroB在某处并执行\macroA。但那\execute_after:NN已成历史,没有代码可以执行存储的\macroB。请参阅 egreg 的注释。

分析执行情况\macroA

无需执行,\execute_after:NN就可以检查宏定义\macroA并进一步分析宏,以及执行时可能读取的参数。由于 TeX 语言的图灵完备性,因此很可能存在这样的分析算法(Rice 定理/停机问题)。

什么是可能的?

在两种情况下,TeX 允许在将来插入代码:

  • \aftergroup记住当前组结束后立即调用的标记。它可以被调用多次,并且标记将按照执行顺序附加\aftergroup

  • \afterassignment记住一个标记,该标记在下一次赋值后立即执行。后续执行将\afterassignment覆盖记住的标记。

这两种情况都不能在这里应用,因为它会限制\macroA为结束当前组的宏或在最后一步执行一个分配。

相关内容