如果在 verbatim 环境或类似环境中将 catcodes 更改为 11(字母)而不是 12(其他),会发生什么情况?会出现什么问题吗?或者,使用 catcode12 而不是 catcode11 有什么优势吗?
答案1
嗯,从A
到Z
和从a
到 的 字符z
确实\catcode
在环境中保留了它们的 (11) verbatim
。我认为将\catcode
其他符号的 s 也设置为 11 并没有什么特别的禁忌,除了以下情况(其中第一个很明显):
为什么我们要将符号视为字母?
要逐字排版的文本被 TeX 吸收为由字符串 分隔的参数
\end{verbatim}
。为了识别此分隔字符串,其字符的字符代码和类别代码必须匹配(参见TeXbook,第 203 页,第 -3 至 -2 行)。设置verbatim
环境的代码将此字符串存储为,,和\catcode
的 s等于 12,以及,,,... 的 s 等于 11。如果将 ,,和的s设置为11 ,则分隔字符串将不再被识别。\
{
}
\catcode
v
e
r
m
\catcode
\
{
}
下面的小程序可以用来验证上述说法;尝试将\MyCatcode
宏的定义从
\newcommand*\MyCatcode{12}
到
\newcommand*\MyCatcode{11}
并检查一切是否按预期运行。
% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.
\usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.
\usepackage{etoolbox}
\makeatletter
\newcommand*\MyCatcode{12}
\newcommand*\@makemychar[1]{\catcode`#1=\MyCatcode\relax}
\patchcmd{\@verbatim}
{\let\do\@makeother \dospecials}
{\let\do\@makemychar \dospecials \@makeother\\\@makeother\{\@makeother\}}
{}
{}
\newcommand*{\testverbatim}{%
\begin{verbatim}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
\typeout{A few examples:}%
\typeout{}%
\typeoutcatcode{\\}%
\typeoutcatcode{\{}%
\typeoutcatcode{\}}%
\typeoutcatcode{\$}%
\typeoutcatcode{\&}%
\typeoutcatcode{\#}%
\typeoutcatcode{\^}%
\typeoutcatcode{\_}%
\typeoutcatcode{\%}%
\typeoutcatcode{\ }%
\typeoutcatcode{0}%
\typeoutcatcode{9}%
\typeoutcatcode{@}%
\typeoutcatcode{A}%
\typeoutcatcode{Z}%
\typeoutcatcode{a}%
\typeoutcatcode{z}%
\typeoutcatcode{.}%
\typeoutcatcode{,}%
\typeoutcatcode{?}%
\typeoutcatcode{!}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
}
\newcommand*{\typeoutcatcode}[1]{%
\typeout{\string\catcode `\string #1 = \number \catcode `#1}%
}
\makeatother
\begin{document}
Non-verbatim text.
\testverbatim
Verbatim text: \{}$&#^_%
% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.
\usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.
\usepackage{etoolbox}
\makeatletter
\newcommand*\MyCatcode{12}
\newcommand*\@makemychar[1]{\catcode`#1=\MyCatcode\relax}
\patchcmd{\@verbatim}
{\let\do\@makeother \dospecials}
{\let\do\@makemychar \dospecials \@makeother\\\@makeother\{\@makeother\}}
{}
{}
\newcommand*{\testverbatim}{%
\begin{verbatim}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
\typeout{A few examples:}%
\typeout{}%
\typeoutcatcode{\\}%
\typeoutcatcode{\{}%
\typeoutcatcode{\}}%
\typeoutcatcode{\$}%
\typeoutcatcode{\&}%
\typeoutcatcode{\#}%
\typeoutcatcode{\^}%
\typeoutcatcode{\_}%
\typeoutcatcode{\%}%
\typeoutcatcode{\ }%
\typeoutcatcode{0}%
\typeoutcatcode{9}%
\typeoutcatcode{@}%
\typeoutcatcode{A}%
\typeoutcatcode{Z}%
\typeoutcatcode{a}%
\typeoutcatcode{z}%
\typeoutcatcode{.}%
\typeoutcatcode{,}%
\typeoutcatcode{?}%
\typeoutcatcode{!}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
}
\newcommand*{\typeoutcatcode}[1]{%
\typeout{\string\catcode `\string #1 = \number \catcode `#1}%
}
\makeatother
\begin{document}
...
\end{document}
\end{verbatim}
Non-verbatim text again.
\end{document}
和
\newcommand*\MyCatcode{12}
读取诊断消息
--------------------------------
A few examples:
\catcode`\\ = 12
\catcode`\{ = 12
\catcode`\} = 12
\catcode`\$ = 12
\catcode`\& = 12
\catcode`\# = 12
\catcode`\^ = 12
\catcode`\_ = 12
\catcode`\% = 12
\catcode`\ = 13
\catcode`0 = 12
\catcode`9 = 12
\catcode`@ = 12
\catcode`A = 11
\catcode`Z = 11
\catcode`a = 11
\catcode`z = 11
\catcode`. = 12
\catcode`, = 13
\catcode`? = 12
\catcode`! = 12
--------------------------------
表示剩余的字母为\catcode
11 个;另一方面,
\newcommand*\MyCatcode{11}
表明只要、和 verbatim
三个关键\catcode
因素没有被篡改,环境就不会被破坏。\
{
}
添加
如需进一步的证据,请尝试以下操作:
% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.
\usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.
\usepackage{etoolbox}
\makeatletter
\begingroup \catcode `|=0 \catcode `[= 1
\catcode`]=2
% Beware:
\catcode `\{=11 \catcode `\}=11 \catcode`\\=11
% ------
|gdef|@xverbatim#1\end{verbatim}[#1|end[verbatim]]
|gdef|@sxverbatim#1\end{verbatim*}[#1|end[verbatim*]]
|endgroup
\newcommand*\MyCatcode{11}
\newcommand*\@makemychar[1]{\catcode`#1=\MyCatcode\relax}
\patchcmd{\@verbatim}
{\let\do\@makeother}
{\let\do\@makemychar}
{}
{}
\newcommand*{\testverbatim}{%
\begin{verbatim}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
\typeout{A few examples:}%
\typeout{}%
\typeoutcatcode{\\}%
\typeoutcatcode{\{}%
\typeoutcatcode{\}}%
\typeoutcatcode{\$}%
\typeoutcatcode{\&}%
\typeoutcatcode{\#}%
\typeoutcatcode{\^}%
\typeoutcatcode{\_}%
\typeoutcatcode{\%}%
\typeoutcatcode{\ }%
\typeoutcatcode{0}%
\typeoutcatcode{9}%
\typeoutcatcode{@}%
\typeoutcatcode{A}%
\typeoutcatcode{Z}%
\typeoutcatcode{a}%
\typeoutcatcode{z}%
\typeoutcatcode{.}%
\typeoutcatcode{,}%
\typeoutcatcode{?}%
\typeoutcatcode{!}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
}
\newcommand*{\typeoutcatcode}[1]{%
\typeout{\string\catcode `\string #1 = \number \catcode `#1}%
}
\makeatother
\begin{document}
Non-verbatim text.
\testverbatim
Verbatim text: \{}$&#^_%
% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.
\usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.
\usepackage{etoolbox}
\makeatletter
\newcommand*\MyCatcode{12}
\newcommand*\@makemychar[1]{\catcode`#1=\MyCatcode\relax}
\patchcmd{\@verbatim}
{\let\do\@makeother \dospecials}
{\let\do\@makemychar \dospecials \@makeother\\\@makeother\{\@makeother\}}
{}
{}
\newcommand*{\testverbatim}{%
\begin{verbatim}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
\typeout{A few examples:}%
\typeout{}%
\typeoutcatcode{\\}%
\typeoutcatcode{\{}%
\typeoutcatcode{\}}%
\typeoutcatcode{\$}%
\typeoutcatcode{\&}%
\typeoutcatcode{\#}%
\typeoutcatcode{\^}%
\typeoutcatcode{\_}%
\typeoutcatcode{\%}%
\typeoutcatcode{\ }%
\typeoutcatcode{0}%
\typeoutcatcode{9}%
\typeoutcatcode{@}%
\typeoutcatcode{A}%
\typeoutcatcode{Z}%
\typeoutcatcode{a}%
\typeoutcatcode{z}%
\typeoutcatcode{.}%
\typeoutcatcode{,}%
\typeoutcatcode{?}%
\typeoutcatcode{!}%
\typeout{}%
\typeout{--------------------------------}%
\typeout{}%
}
\newcommand*{\typeoutcatcode}[1]{%
\typeout{\string\catcode `\string #1 = \number \catcode `#1}%
}
\makeatother
\begin{document}
...
\end{document}
\end{verbatim}
Non-verbatim text again.
\end{document}
答案2
请查看 LaTeX 2ε 注释源代码中逐字环境的实现方式,该源代码可在 source2e.pdf 中找到(https://ctan.org/pkg/source2e).verbatim 环境位于文件 y:ltmiscen.dtx,第 53.3 节 Verbatim 中。
\verbatim
您可以在那里看到被调用的宏\begin{verbatim}
,
- 首先调用命令
\@verbatim
,然后进行大量准备工作,例如执行所需的 catcode 更改(通过\let\do=\@makeother
和\dospecials
)、添加垂直空间等, - 然后要求
\frenchspacing
所有空间的宽度相等, - 然后确实要求
\@vobeyspaces
将空格变成没有换行符的东西, - 然后调用
\@xverbatim
。
\@xverbatim
反过来会根据带分隔符的参数“捕获”要逐字排版的文本,其中分隔符由一系列字符标记组成,,,,,,,,,,,,,,,,其中在定义文本中对分隔\
符进行标记时的 catcode- régime设置如下:e
n
d
{
v
e
r
b
a
t
i
m
}
\@xverbatim
\begingroup \catcode ‘|=0 \catcode ‘[= 1
\catcode‘]=2 \catcode ‘\{=12 \catcode ‘\}=12
\catcode‘\\=12 |gdef|@xverbatim#1\end{verbatim}[#1|end[verbatim]]
|endgroup
这意味着“期望”分隔短语中的字符\@xverbatim
标记\
和具有 catcode 12(其他)。{
}
\end{verbatim}
\@xverbatim
将吐出它的参数,后面跟着序列|end[verbatim]
,其中|end
是控制字\end
,并且[
和]
分别是类别代码 1 和 2,从而充当开括号/闭括号,以便整个东西就是\end
环境的命令。
为了好玩你可以说
\def\@makeother#1{\catcode`#1=11\relax}
和
\begingroup
\catcode`|=0 \catcode`[=1 \catcode`]=2
\catcode`{=11 \catcode`\}=11 \catcode`\\=11
|@firstofone[%
|endgroup
|def|@xverbatim#1\end{verbatim}[#1|end[verbatim]]%
]%
并且现在看到 verbatim-environment 也适用于 catcode-11-characters:
\documentclass{article}
\begin{document}
\begingroup
\makeatletter
\def\@makeother#1{\catcode`#1=11\relax}%
\begingroup
\catcode`|=0 \catcode`[=1 \catcode`]=2
\catcode`{=11 \catcode`\}=11 \catcode`\\=11
|@firstofone[%
|endgroup
|def|@xverbatim#1\end{verbatim}[#1|end[verbatim]]%
]%
\makeatother
\begin{verbatim}
\{}[]~^_-+#'blabla
\{}[]~^_-+#'blabla
\{}[]~^_-+#'blabla
\end{verbatim}
\endgroup
\end{document}