我一直认为 TeX 的宏非常像 Lispy,偶然发现 LaTeXe 徽标的定义证实了这一点。该宏定义如下:
%\LaTeXe The LATEX2" logo as proposed by A-W designers.
\def\LaTeXe{%
\mbox{\m@th%
\if b\expandafter\@car\f@series\@nil\boldmath\fi
\LaTeX\kern.15em2$_{\textstyle\varepsilon}$}}
那么它做什么呢\@car
?
在 Lisp 编程语言中引入,car
是cdr
对由 组成的链表进行的基本操作cons cells
。
当cons
使用单元格实现单链列表(而不是树和其他更复杂的结构)时,该car
操作返回列表的第一个元素,而cdr
返回列表的其余部分。
如何@car
工作?什么是@nil
?据我所知,它是未定义的,但没有给出错误。即使我将其定义为,它也不会给出错误\def\@nil{illdefined!}
,如下面的代码所示。
\documentclass[11pt]{article}
\usepackage{graphicx}
\usepackage{verbatim}
\begin{document}
\bigskip
\makeatletter
\def\@nil{illdefined!}
\scalebox{5}{\LaTeXe}
\makeatother
\end{document}
有关 CAR 和 CDR 的更多信息,请访问维基百科
答案1
与 Lisp 的联系非常真实(在资料中提到过,但我现在还不能确定)。它的工作原理非常简单。定义如下
\def\@car#1#2\@nil{#1}
\def\@cdr#1#2\@nil{#2}
在此上下文中,\@nil
被用作分隔符,因此它扩展为什么根本不重要。这是 TeX 中典型的“分隔参数”情况。(唯一重要的是 TeX 在输入流中找到适当的标记,在本例中是在任何\par
标记之前。)TeX 将允许我们为此类分隔宏的最后一项留空。因此,和都\@cdr
需要\@car
提供至少一个标记:类似于
\expandafter\@cdr\@empty\@nil
会报错。
请注意,这些是 TeX 函数,而不是 Lisp 函数,因此我们得到第一个 <平衡文本> 与其余部分分开。
答案2
稍微扩展一下 Joseph 的回答:\@nil
只是一个宏分隔符,只有在扫描 的参数时才会看到\@car
,并且永远不会扩展。例如\@car
可以通过 调用\@car123\@nil
,结果是1
,而 则\@cdr123\@nil
产生23
。你不能使用\@car123
;然后 TeX 将继续扫描标记,因为它想要找到\@nil
调用中必需的匹配部分\@car
。正如 Joseph 已经指出的那样,使用\@car\@nil
也会出现错误。
有关更多信息,我建议阅读 TeXbook 中的第 20 章,特别是第 202 页。