我正在尝试弄清楚 verbatim 环境是如何工作的。在基本 LaTeX 文件中,latex.ltx
我发现以下定义(第 4037 行):
\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-}
\def\do@noligs#1{%
\catcode`#1\active
\begingroup
\lccode`\~`#1\relax
\lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}}
\def\@noligs{\let\do\do@noligs \verbatim@nolig@list}
宏的目的是什么\do@noligs
?此外,它是如何工作的?
在上面的代码中,我有理解问题:
\lccode`\~`#1
- 为什么要使用
\lowercase
控制字? - 为什么
\endgroup
在左括号后面{
? - 为什么
\leavevmode
? - 为什么
\kern\z@
?
答案1
此处的“大局”目标是确保不应用任何连字符:例如,--
在“正常”情况下会转换为短破折号,因为它是连字符。实现此目的的方式是在字符之间插入一个字距,使潜在的连字符在逐字环境中“安全”。
您询问的细节如下。宏\do@noligs
一次接收一个转义字符,例如\-
。这将具有类别代码“其他”,但为了使其“安全”,代码需要使其处于活动状态。这就是小写业务的目的:其中大部分是“标准技巧”。发生的事情是,\lowercase
可用于更改标记的字符代码,但保持类别代码不变。所以我们需要一些“现成的”活动字符来“转换”:这就是~
进来的地方。以示例为例\-
,代码执行以下操作:
- 使
-
角色活跃起来 (\catcode`#1\active
) - 设置一个组,使小写行为的改变是本地的
- 使其
-
小写相当于~
(\lccode`\~`#1\relax
) - 插入一个
\lowercase
,它读取并标记其参数并用 替换~
,-
但在此阶段不执行它 - 结束该组,以便大小写变化恢复正常,并且
-
不需要全局进行活动的定义。 - 设置 的定义
-
。
在 的定义中-
,\kern\z@
是关键部分,因为它可以防止例如--
连字,因为两个字符之间有一个不可见的“障碍”。\leavevmode
是一种安全预防措施,确保我们不会“在段落之间”。 如果您只是在垂直模式下直接插入字距,就会发生后者(我们最终会得到一个概念上的垂直字距)。
最终结果是,在环境创建的组内verbatim
,标准 TeX 连字不起作用,输出符合预期。