赋值宏

赋值宏

出于好奇,我想找到 TeX 在宏定义方面的限制。假设应该有一个赋值命令,将已定义的宏的值赋给尚​​未定义的宏,因此类似

\def\newVariable{\variable}

只需使用其他语言中常见的语法,即使用等号作为赋值运算符。

我想不可能写

\newVariable = \variable

因为这样在读取时会导致“未定义的控制序列” \newVariable。是否可以挂接到检测到未定义控制序列的程序的执行中,并向前查看@ifnextchars用于等号和宏?

如果我们写

newVariable = \variable

现在这至少应该可以无错误地运行。当 \variable 扩展时,是否有机会newVariable =再次从输出字符串中删除文本(进行某种倒带)并将其用作\variable类似于的选项\variable{newVariable}?所以我想我会在这里寻找类似的东西\@iflastchars。我完全接受所有 TeX 风格的奇怪解决方案,例如在输出例程中或在辅助文件中或甚至在上次运行生成的 PDF 文件中(或任何其他输出文件)找到字符串。

我猜答案会是“这是不可能的”,但由于周围有很多聪明人喜欢挑战,所以我想尝试一下。请注意,我完全了解使用正常 TeX 语法的解决方案,因此这更像是一个理论练习。

答案1

如果 TeX 不知道控制序列的含义,它将会发出抱怨Undefined control sequence,除非您为控制序列本身赋予含义。

所以,不,没有办法说这样的话

\varB=\varA

where\varB没有先前的含义。无论如何,允许这样的语法仅有的对于寄存器(之前已声明或为原始寄存器)。例如,

\tolerance=\mycount

是对原始寄存器的合法分配\tolerance,但只有当\mycount是同一类型的寄存器(在本例中为整数)时才有效,无论是原始的还是由定义的\countdef,例如

\countdef\mycount=123

(这种分配相当于\mycount原始寄存器的分配\count123,通常由宏在后台执行\newcount。)

如果有人说

\varB=\varA

如果\varA有意义而\varB没有,则会出现错误,如前所述。如果\varB有意义并且与赋值不兼容,则再次出现错误。例如,

\newcount\varA \varA=42
\newdimen\varB
\varB=\varA

将抛出错误Illegal unit of measure (pt inserted),除非碰巧以下标记可以被解释为合法的计量单位。

反过来,

\newdimen\varA \varA=42pt
\newcount\varB
\varB=\varA

是合法的,\varB并将保存整数 2752512(相当于 42pt 的缩放点数:2752512 = 42 * 65536)。这是因为维度在内部存储为整数,但这是一个相当深奥的话题。

请注意

\newcount\varA \varA=42
\newcount\varB
\varB=\varA

非常不同于

\newcount\varA \varA=42
\let\varB=\varA

在第一种情况下,改变 中存储的值\varA不会改变 中存储的值\varB,而在第二种情况下则会改变,因为\varB已成为 的别名\varA

在用户层面上不可能接入发现未定义控制序列的机制,需要重写“TeX 程序”。

当然,理论上可以通过在创建一组合适的宏后声明所有字符为活动字符来修改 TeX 的语法规则;因此,例如,每个字母可能将自己存储在某个地方,等待某个操作符出现来告诉如何处理保存的标记。比如说

newvariable = myvar ;

分号充当“指令结束”。主动操作=将被定义为“查看分号之前的内容,确定其类型并执行对变量的赋值,该变量的名称来自存储箱中的标记”。Jonathan Fine 在 TUGboat 上发表了一些论文,描述了此类操作,例如“Active TeX 和 DOT 输入语法”(TUGboat,第 20 卷,第 3 期,第 248-254 页)。没有什么是真正不可能的,问题是:值得付出努力吗?当然必须定义一个“编程环境”和一个“排版环境”,因为毕竟 TeX 的工作主要是排版文档。

答案2

不,除了调用错误之外,无法让 TeX 在找到未定义序列时执行某些操作。TeX 核心以线性方式读取输入序列,因此没有命令可以真正影响之前读取的内容。此外,该字符=也需要在其他上下文中使用,因此无法轻易激活。

正如我在评论中指出的那样,存在=意味着分配的情况:

  • \let定义:\let\newmacro=\oldmacro
  • 长度分配:\topskip = 10pt
  • 计数器分配:\c@section = 5

相关内容