看到
\cs_new_protected:Nn \feuds_newteorema_define:nn
\feuds_newteorema_define
这只是一个名为(据我所知,它接受两个参数)的函数的定义,还是别的什么?
这到底是什么意思Protected Restriction
?
答案1
简短理论
\cs_new_protected:Nn
记录在interface3.pdf
并指出用它定义的函数不会在x
或e
类型扩展中进一步扩展。
这在较低层次上意味着它使用 e-TeX 原语\protected
。您可以在 e-TeX 手册 ( texdoc etex
) 中看到这意味着什么。但总结一下:
宏定义\protected
\edef
在或\expanded
上下文中不扩展\write
在或\message
上下文中不扩展- 停止 TeX 扫描对齐上下文
\omit
或\noalign
对齐上下文内部(就像\relax
会一样)
简单示例
展示不同行为的一个例子(以纯 TeX 格式):
\protected\def\foo{protected }
\def\bar{unprotected}
\edef\baz{\foo\bar}
\show\baz
\bye
导致以下输出到标准输出:
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdflatex 2023.8.16) 29 SEP 2023 12:21
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**document
(./document.tex
LaTeX2e <2023-06-01> patch level 1
L3 programming layer <2023-08-11>
> \baz=macro:
->\foo unprotected.
l.4 \show\baz
?
如您所见,\bar
它被扩展了(扩展为单词“unprotected”),但\foo
并未扩展,而是保留在替换文本\foo
中。\baz
另一个使用 L3 语法并打印到 PDF 的示例:
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\cs_new_protected:Nn \test_foo: { foo }
\cs_new:Nn \test_bar: { bar }
\cs_new:Nx \test_baz: { \test_foo: \test_bar: }
\test_baz: \par
\cs_set_protected:Nn \test_foo: { FOO }
\cs_set:Nn \test_bar: { BAR }
\test_baz:
\end{document}
如您所见,第一次使用时\test_baz:
会打印“foobar”,因为和\test_foo:
都是\test_bar:
小写。如果我们随后将其改为大写,则只会产生“FOO”,而“bar”仍为小写。之所以如此,是因为在定义时我们将\test_baz:
其扩展\test_bar:
为“bar”,但\test_foo:
由于它是,因此没有扩展protected
,因此重新定义也会改变的结果\test_baz:
。
这种行为为何或何时如此重要?
在 TeX 中,我们有可扩展的事物和不可扩展的事物的概念。有些原语是可扩展的,但大多数都不是。另一方面,宏是可扩展的(除非已定义\protected
,在这种情况下它们只能通过某些操作(如)进行扩展\expandafter
,但不能通过\edef
或进行扩展\expanded
)。
如果一个宏现在使用了一个不可扩展的原语,但不知何故最终进入了\edef
或\expanded
上下文并自行扩展,那么您将得到未定义/不可预测的行为(因为不可扩展原语之后的任何内容仍会被扩展)。因此,有必要定义这样的宏\protected
,以便行为(几乎——让我们忽略仍然扩展宏的方式\protected
)始终保持良好定义。
这是一个小例子,希望容易理解(再次使用简单的 TeX 语法):
\def\mymacroA{\def\mythingA{foobar}}
\protected\def\mymacroB{\def\mythingB{foobar}}
\edef\test{\mymacroB}% this is still fine
\edef\test{\mymacroA}% this throws an error
\bye
这将打印到标准输出:
! Undefined control sequence.
\mymacroA ->\def \mythingA
{foobar}
l.5 \edef\test{\mymacroA
}% this throws an error
?
尽管如果在 之外使用\mythingA
和都\mythingB
可以\edef
。原因很简单:不可扩展,因此保持不变,但 TeX 会继续扩展 中命中\def
的其余替换文本。该宏不可扩展,因此我们收到上述错误消息。\mymacroA
\mythingA