为什么我可以说 \input something 但不能说 \centerline something?

为什么我可以说 \input something 但不能说 \centerline something?

我目前正在阅读 TeXbook(第 6 次印刷,1986 年 3 月)。

在第 6 章中,Knuth 解释了\input story可以用来加载/处理story.tex

然而,在前面的章节中,读者可以通过以下例子了解分组的重要性:

\centerline{This information should be {centered}.}

\centerline So should this.

这表明,只有后续符号正在\centerline使用,因此对于第二个,\centerlineS居中,但o should this.会在新行上,而不是居中。

所以我想知道为什么\input story它有效(是的,我测试过)以及为什么它无效不得不 \input{story}这正是我在 LaTeX 中习惯的。

这似乎是违反直觉的,因为第一次读到这篇文章时,我当时得到的信息是控制字 \input应该采取下一步行动象征仅有的。

也许我遗漏了什么?

答案1

\centerline是一个宏,在 中定义plain.tex\def\centerline#1{\line{\hss#1\hss}}因此它接受一个参数。通常,参数将是一个单个标记(S例如,是一个单个标记),除非这个标记是一个{,在这种情况下,将接受一个{...}平衡的标记列表作为参数。

在 Plain TeX 中\input是一个原语,因此其规则不同。原语将查找字符标记,并在第一个空格标记[1]处停止。在 LaTeX 中\input是一个宏,但如果下一个标记不是{,则它充当原语输入。如果下一个标记是{,则\input充当宏并获取文件名作为参数。

\centerline您可以通过让它抓取输入行的其余部分来模拟这种情况:

\def\centerline{%
  \begingroup
  \catcode`\^^M=13
  \centerlineaux}
\begingroup
\catcode`\^^M=13
\gdef\centerlineaux#1^^M{\endgroup\line{\hss#1\hss}}
\endgroup

\centerline This entire line is centered.
  But this is not.

\bye

1有不同的实现\input:Knuth\input会扫描字符标记,直到找到非字符标记或空格。如果该标记是空格,则将其丢弃。找到的字符将作为文件名。
Web2C 实现(TeXLive 和 MiKTeX 使用它)允许\input文件名中有空格,只要空格出现在两个 之间即可"
最后,在 TeXLive 2020 及以后的所有 TeX 引擎中(在此之前仅在 LuaTeX 中),如果基元后的下一个标记\input{,则文件名将在括号之间被抓取(\input{story}将输入)。由于这就是 Knuth 所说的“依赖于文件系统的更改”,因此这也story.tex适用于。tex

答案2

\input实际上是原始的,它们被定义为 TeX 核心的一部分,而不是基于其他宏构建的单独宏。如果您查看\input和朋友的定义(在latex.ltx):

\ifx\@@input\@undefined\let\@@input\input\fi
% <some other definitions>
\def\input{\@ifnextchar\bgroup\@iinput\@@input}
% <some other definitions>
\def\@iinput#1{%
  \InputIfFileExists{#1}{}%
  {\filename@parse\@curr@file
   \edef\reserved@a{\noexpand\@missingfileerror
     {\filename@area\filename@base}%
     {\ifx\filename@ext\relax tex\else\filename@ext\fi}}%
   \reserved@a}}

请注意,命令序列在加载 LaTeX 内核时\input将 TeX 原始定义存储在内部。然后它(重新)定义为通过 有条件的。此条件检查您是否提供了左花括号(或)。如果是,它会调用 。当您使用时,情况就是这样\@@input\input\@ifnextchar{\bgroup\@iinput

\input{story}

的定义\@iinput意味着它接受一个强制参数,就像您使用的任何其他宏一样。从您最初的用例来看,这是有道理的。但是,为什么 的\input story工作方式相同?为此,我们遵循\@ifnextchar条件中的错误分支。也就是说,\@@input

由于是原语\@@input的精确副本\input,它将文件名读取为后面的非空字符串\input。此过程的参考资料scan_file_nametex.web

相关内容