\protected 如何处理参数?它与 \protect 有什么不同?

\protected 如何处理参数?它与 \protect 有什么不同?

根据这个答案 \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\writeprotected的行为就像\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或类似)来“激活”此机制。

相关内容