受保护的限制

受保护的限制

看到

\cs_new_protected:Nn \feuds_newteorema_define:nn

\feuds_newteorema_define这只是一个名为(据我所知,它接受两个参数)的函数的定义,还是别的什么?

这到底是什么意思Protected Restriction

答案1

简短理论

\cs_new_protected:Nn记录在interface3.pdf并指出用它定义的函数不会在xe类型扩展中进一步扩展。

这在较低层次上意味着它使用 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

相关内容