Align*、& 和 \futurelet

Align*、& 和 \futurelet

有人可以解释一下 Futurelet 吗之内对齐环境?

例子:

如果下一个字符是 {,则命令 \A 应该返回“A”,如果是 &,则返回“B”,在其他情况下返回“C”。

\gdef\A{\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}

对于普通文本或内联数学,它工作得很好:

\A{a},\A&,\A a       % -> "A,B,C"
$\A{a}$,$\A&$,$\A a$ % -> "A,B,C"

当我在 align* 环境 (amsmath) 中使用它时,出现“不完整的 \ifx”错误:

\begin{align*} \A{a},\A&,\A a \end{align*}% --> error.

有人能给我解释一下吗?谢谢!

克里斯

PS:关于对齐环境中的 Futurelet,还有更多我不明白的事情:如果我们定义

\gdef\A{\futurelet\thesymbol\alpha}
\gdef\D#1{\detokenize{#1}}

然后

\begin{align*}
 \D&,\A a    % -> "&,alpha a" (okay)
 \A a,\D{&}  % -> "alpha a,&" (okay)
 \A a,\D&    % -> error: "Argument of D has an extra }." (???)
\end{align*}

答案1

\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}

当 TeX 看到时,&它会将模板的其余部分交换为\halignlatex 大小写等所指定的内容c r,因此\ifx会比较模板的前两个标记(可能\unskip然后\hfil单元格(以及组)将结束出错。

如果你想&在未来测试之前开始一个小组并在测试结束后结束它时隐藏它,你需要

{\ifnum0=`}
...
\ifnum0=`{\fi}

出现在任何表格代码中的形式。

这会产生 A、B、C,我认为这就是预期的结果。

\documentclass{article}
\usepackage{amsmath}

\gdef\A{{\ifnum0=`}\fi\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi \ifnum0=`{\fi}}

\begin{document}

\begin{align*} \A{a},\A&,\A a \end{align*}


\end{document}

对于你的第二个例子,注意&结束一个组

a,\D&就像{\D}并且都给出相同的错误:

! Argument of \D has an extra }.
<inserted text> 
                \par 
l.15 {\D}

{\D}由于不清楚您想要做什么,因此无法清楚找到解决方法。

答案2

我无法与 David 竞争对 TeX 代码的理解,所以我不会尝试修复你的宏(尽管我的观点是,你所做的从根本上来说并不明智)。但是,他关于“当 TeX 看到 ”的评论&可以扩展如下。在扫描对齐时,TeX 的行为方式与大多数用户(甚至是经验丰富且知识渊博的用户)对其执行的心理模型有些不一致。也就是说,我们想象TeX 总是在做以下三件事之一:

  1. 扫描输入,将字符标记化,为宏解析器“嘴巴”提供食物;

  2. 扩展宏;

  3. 执行不可扩展的标记:像\def或 这样的编程指令\hbox,或者像字符这样的直接排版命令。

在这个模型下,每个人都期望在对齐(TeX 基元\halign\valign)中,制表符&在第 3 点(执行)下采取行动。然而,事实并非如此;事实上,TeX 在第 1 点“注意到”了制表符!如果 TeX曾经读过一个与号(或等效类别的字符)它将立即结束当前单元格、关闭一个组、插入v模板的“部分”等等。

编辑:我只是浏览了一下errorlog.pdf(即texdoc errorlog),发现了 1978 年 3 月 18 日调试会话中的相关评论:

让获取下一个例程拦截&\cr标记。我以为我可以将&\cr放入big_switch[即 TeX 的胃中,而不是眼睛中];这是一个巨大的错误。

这是一个有趣的部分见解,可以了解是什么导致 Knuth 对这些数组标记做出上述看似奇怪的行为选择,以及确认这确实是行为。)

当然,例外情况是当 TeX 位于未完成的括号组内时(并且必须是实际的括号字符,而不是隐式字符或\begingroup来启动这个组),这导致 David 的{\ifnum0=}` 构造可扩展地等同于一个开放括号,而无需在可能放置它的宏定义内实际创建不平衡的括号。

这种奇怪的解析规则的结果是,人们必须非常小心地对待表格单元格中的宏读取的内容,或环境中包含的内容。像你这样的宏,实际上是通过赋值而不是宏参数解析来读取参数的,这就更加危险了,因为如果没有必要的括号,可以读取的制表符将不是受到保护。与表格兼容的环境包括该\ifnum功能,以便保护其中可能出现的任何制表符;更简单的环境将跨单元格拆分,因此可能会失败。

相关内容