\aftergroup 递归奇怪扩展

\aftergroup 递归奇怪扩展

我正在尝试编写一个递归,使用\aftergroup它在每个组末尾执行某些操作。mwe:

\protected\def\printB{B \aftergroup\printB}
$$\halign \bgroup ${#}$\cr a \printB \crcr\egroup$$
\bye

eTex 因错误而中断! Missing $ inserted.某些情况是如何发生的,它不仅\aftergroup需要宏。 是否可以保护这样的扩展?$\printB

答案1

\aftergroup只需要一个标记\printB,但递归永远不会结束,如果你添加一个\message

\protected\def\printB{\message{.}B \aftergroup\printB}
$$\halign \bgroup ${#}$\cr a \printB \crcr\egroup$$
\bye

你看

 . . . . . .

! Missing $ inserted.
<inserted text> 
                $
<to be read again> 
                   \par 
\bye ->\par 

在失败之前它被调用了 6 次。

$最终导致错误的额外原因是因为 aftergroup-inserted 标记是在之后插入的\crcr,因此会启动一个新的 halign 行,因此{#}模板已被插入,但您永远不会结束该行,直到最终遇到\bye错误。

您会看到基本上相同的错误,但有\aftergroup一个明确的B\crcr

\halign {
${#}$\cr a \crcr B}$$
\bye

生产

! Missing $ inserted.
<inserted text> 
                $
<to be read again> 
                   \par 
\bye ->\par 
            \vfill \supereject \end 
l.4 \bye

? x

答案2

请考虑以下示例:

\tabskip=30pt
\halign{{$#$x}&u#v\cr
  a\aftergroup b&c\cr
  a\aftergroup \aftergroup \aftergroup b&c\cr
  a\aftergroup \aftergroup \aftergroup \aftergroup
   \aftergroup \aftergroup \aftergroup b&c\cr
}

\bye

在此处输入图片描述

在第一种情况下,b打印在数学模式之外。在第二种情况下,它打印在 周围的组之后$#$x。在第三种情况下,它打印在\halign单元格周围的隐式组之后,因此最终成为下一个单元格中的第一个项目。

你定义\printb要做的事情b\aftergroup\printb是希望当 TeX 到达顶层时\aftergroup不会产生任何影响,但是……

就像第三个案例b中打印的那样第二对齐的单元格,在你的情况下,b当 TeX 尚未看到}结尾时,将出现\halign。由于b不是\omit,因此会开始一个新单元格,形成一个组……

一个更简单的例子是

\def\printb{b\printb}
\halign{#\cr a\printb\cr}

\bye

问题完全一样。

如果你认为这\crcr结束了,\halign那你可真错了。它的功能是执行\cr(原始的\cr),前提是它不遵循一个(原始的)\cr命令。在那个位置上,它与 相同\cr

相关内容