逐字逐句是如何实现的?

逐字逐句是如何实现的?

我很好奇 TeX 内部是如何实现逐字逐句的。我最熟悉 TeX 内部机制的基础知识(catcode 等等),但我对这个命令很好奇。

答案1

例如

\beginverbatim
 verbatim text & $ #
 in more    lines... 
\endverbatim

可以实现为

\def\beginverbatim{\par
   \begingroup
      ... set all special catcodes to other
      ... set space as active and define it as \space
      ... set ^^M as active and define it as \par
      \beginverbatimA
}
\def\beginverbatimA #1<tricky of \endverbatim separator>{%
    #1%
    \endgroup % restores normal catcodes
}

当然,这只是伪代码。我们需要定义\beginverbatimA参数,#1分隔符为,\endverbatim其中此分隔符用作\catcode“other”的正常字符。它需要一些“棘手”的代码。例如,像这样:

\let\ea=\expandafter
\ea\def\ea\beginverbatimA\ea#\ea1\string\endverbatim{%
    #1\endgroup
}

这里介绍的是主要思想,而不是整个实现。

编辑:LaTeX 注意事项:这里的第二个答案专门针对 LaTeX,但遗漏了一件事:它的\@xverbatim工作原理和实现方式。这与\endverbatimA我的答案中提到的类似,但参数的分隔符#1必须是\end{verbatim},不仅如此\,而且在它上面,{并且}必须有 catcode“other”。例如,可以通过以下方式完成此操作:

\let\ea=\expandafter
\edef\tmp{\string\end\string{verbatim\string}}
\ea\def\ea\@xverbatim\ea#\ea1\tmp{#1\end{verbatim}}

但您可以看到latex.ltx这里采用了另一种方法。

答案2

让我们从一段摘录latex.ltx(LaTeX“内核”)开始:

\def\verbatim{\@verbatim \frenchspacing\@vobeyspaces \@xverbatim}
\def\endverbatim{\if@newlist \leavevmode\fi\endtrivlist}
\def\verbatim@font{\normalfont\ttfamily}

指令\@verbatim完成了大部分繁重的工作。其定义如下(也在 中latex.ltx,就在 之前\def\verbatim...):

\def\@verbatim{\trivlist \item\relax
  \if@minipage\else\vskip\parskip\fi
  \leftskip\@totalleftmargin\rightskip\z@skip
  \parindent\z@\parfillskip\@flushglue\parskip\z@skip
  \@@par
  \language\l@nohyphenation
  \@tempswafalse
  \def\par{%
    \if@tempswa
      \leavevmode \null \@@par\penalty\interlinepenalty
    \else
      \@tempswatrue
      \ifhmode\@@par\penalty\interlinepenalty\fi
    \fi}%
  \let\do\@makeother \dospecials
  \obeylines \verbatim@font \@noligs
  \everypar \expandafter{\the\everypar \unpenalty}%
}

有很多事情要做,不是吗?最重要的指令如下。首先,LaTeX 进入一个trivlist环境(将\endtrivlist在 的末尾以结束\endverbatim)。除非我们在环境中,否则将执行 的minipage垂直跳过量。在执行段落分隔符(通过)并抑制所有连字符后,将在本地重新定义。最重要的一组指令是。它们将(space)、(backslash)、、、、、、、、和的catcode 设置为“其他”(12)。本质上,所有 TeX 特殊字符在环境中都不是特殊的。接下来,指示 TeX 遵守换行符,将字体切换为等宽字体(也称为“电传打字机”或),并激活一些字符以打破连字,例如。换行符的标准段落生成器惩罚是未设置的。哇 - 我们已经到了代码块的末尾。\parskip\@@par\parlet\do\@makeother \dospecials\\{}$&#^_%~verbatimtt<<«\@verbatim

接下来,\frenchspacing(在 LaTeX 内核中复制的纯 TeX 命令)确保标点符号后不会插入多余的空格。相比之下, 处理的任务\endverbatim几乎微不足道:最重要的指令是\endtrivlist,它关闭trivlist开始时打开的环境\@verbatim

环境trivlist是 LaTeX 中非常重要的工具。它在 中出现过多次latex.ltx。例如,centerflushleftflushright环境都设置为 trivlist,并且list环境在内部使用trivlistenumerateitemizedescription环境list在内部使用环境,因此最终trivlist也使用环境。

相关内容