根据这个答案 \protect\foo
扩展为类似于\noexpand\protect\noexpand\foo
当它被保存到宏时的内容(例如在 beamer 框架之类的上下文中)。我认为\protected\def
基本上只是将 \protect 放在宏的每个实例前面。如果不是,它会做什么?如果是,为什么\expandafter
在应用于参数的受保护宏中可以正常工作?
其余内容仅供说明。我试图理解这\protected
是什么意思,并认为示例可能有助于解释我所问的问题。
例如,下面定义的命令即使在 beamer 框架中也能正常工作,但如果我考虑一下如果我用 替换会发生什么,\Tdeg{\zeron{5}}
结果会不会是在被in捕获之前\noexpand\protect\noexpand\Tdeg{\zeron{5}}
扩展参数?如果是这样,为什么当我在 beamer 框架中运行它时它仍然有效(即输出 A 而不是 B)?\zeron{5}
\expandafter
\Tdeg
\def\zeron#1{0^{#1}}
\def\first@pmg@rdmxs(#1#2){#1}
\protected\def\Tdeg#1{\ifthenelse{
\equal{\string \zeron }{\expandafter\string \first@pmg@rdmxs(#1)}
{A}
{B}}
答案1
\protected
与 LaTeX 宏无关,\protect
它在类似的宏上设置一个标志,\long
但在定义点没有效果。
所以
\def\foo{zzz \textbf{x}}
\show\foo
\long\def\foo{zzz \textbf{x}}
\show\foo
\protected\def\foo{zzz \textbf{x}}
\show\foo
生产
> \foo=macro:
->zzz \textbf {x}.
l.3 \show\foo
?
> \foo=\long macro:
->zzz \textbf {x}.
l.6 \show\foo
?
> \foo=\protected macro:
->zzz \textbf {x}.
l.9 \show\foo
然而,当在仅扩展上下文中使用时,例如\edef
或\write
宏protected
的行为就像\relax
并且不会扩展。
所以...
\documentclass{article}
\begin{document}
\def\foo{zzz \textbf{x}}
\immediate\write20{1: \foo}
\long\def\foo{zzz \textbf{x}}
\immediate\write20{2: \foo}
\protected\def\foo{zzz \textbf{x}}
\immediate\write20{3: \foo}
\end{document}
生产
1: zzz \protect \unhbox \voidb@x \bgroup \def l3backend-pdftex.def{x}\let \futu
relet \@let@token \let \protect \relax \edef cmr{cmr}\edef cmss{cmss}\edef cmtt
{cmtt}\def ##1,b,{}\series@check@toks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,me
c,mc,msc,msx,mx,mex,mux,{}{},b,}\edef {}\edef b{b}\def ##1,m,{}\series@check@to
ks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,mec,mc,msc,msx,mx,mex,mux,{}{},m,}\ed
ef {}\edef m{m}\protect \let
2: zzz \protect \unhbox \voidb@x \bgroup \def l3backend-pdftex.def{x}\let \futu
relet \@let@token \let \protect \relax \edef cmr{cmr}\edef cmss{cmss}\edef cmtt
{cmtt}\def ##1,b,{}\series@check@toks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,me
c,mc,msc,msx,mx,mex,mux,{}{},b,}\edef {}\edef b{b}\def ##1,m,{}\series@check@to
ks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,mec,mc,msc,msx,mx,mex,mux,{}{},m,}\ed
ef {}\edef m{m}\protect \let
3: \foo
您会发现\foo
在中表现不佳\write
(并且\protect
不会像通常那样有帮助,\relax
并且仅在内具有特殊定义\typeout
,\protected@write
以及类似的乳胶结构),但\protected
的版本\foo
保持\foo
不变\write
。
答案2
LaTeX\protect
机制和 e-TeX\protected
机制的工作方式不同。使用 定义的宏\protected\def
不会在\edef
或类似上下文中扩展,但其他方面与使用 定义的宏完全相同\def
。相反,\protect
使用变量定义的标记来避免在某些地方扩展:这需要“选择加入”处理(\protected@edef
或类似)来“激活”此机制。