\def 和 \edef:只扩展一层,不扩展更多

\def 和 \edef:只扩展一层,不扩展更多

我想保存宏的内容(可能包含文本和其他宏)以供以后使用,而无需完全展开。

\def\mcr{a}
\def\textandmacro{sampletext \mcr} % this content i want to recall later with unexpanded \mcr
\def\save{\textandmacro}           % so i save it
\def\mcr{b}                        % the macro may change
\def\textandmacro{xy}              % this macro may change, too
%
\save                              % use '\save' here as if to type 'sampletext \mcr'

之后,当我使用时,\save我想要获得sampletext b,也就是sampletext的当前含义\mcr

但是我得到的xy当然是,因为\textandmacro已经改变了。

当我使用\edef宏时\save,我将得到sampletext a,因为\mcr在 edef 时已完全展开。这不是我想要的。

我想要的是某种程度的扩展,而不是更多。我不想保存,\textandmacro但是sampletext \mcr

有任何想法吗?

我正在使用 TeX(LuaTeX)工作,所以 Latex 对我没有帮助。

谨致问候,彼得

编辑:接受的答案很酷。我用 \toks 版本解决了我的问题。其他使用 \let 的答案似乎也正确且更简单。我还没有测试过,但它们也是很酷的答案!

所以,谢谢大家!

答案1

这取决于你是否需要工作参数。如果不需要,\unexpanded\expandafter{}@PhelypeOleinik 的评论很好(需要 eTeX,但是因为你使用 LuaTeX 所以也可以):

\edef\save{\unexpanded\expandafter{\textandmacro}}

另一种方法是只使用一堆\expandafter可以工作的参数,即使你需要\savein的参数\textandmacro(尽管你需要更多的\expandafter参数):

\expandafter\def\expandafter\save\expandafter{\textandmacro}

最后一种方法,Knuthian TeX 版本的\unexpanded\expandafter{}方法:

\toks0\expandafter{\textandmacro}
\edef\save{\the\toks0}

(对于最后一个,你可能需要使用组来将任务保留在\toks0本地)

答案2

如果我理解正确,输出应该是sampletext b(因为\mcr已更改为b)。所以恕我直言,这样\let就没问题了:

\def\mcr{a}
\def\textandmacro{sampletext \mcr} % this content i want to recall later with unexpanded \mcr
\let\save\textandmacro           % so i save it
\def\mcr{b}                        % the macro may change
\def\textandmacro{xy}              % this macro may change, too
%
\save                              % use '\save' here as if to type 'sampletext \mcr'

\tt\meaning\save
\bye

示例文本 b

答案3

如果您只想保存一个宏的当前内容,请使用\let

\def\textandmacro{sampletext \mcr}
\let\save\textandmacro
\def\mcr{b}
\def\textandmacro{xy}
%
\save % expands to "sampletext \mcr" then further to "sampletext b"

\save如果您需要它来在当前组中生存,您可以将其设为全局。

{
  \def\textandmacro{sampletext \mcr}
  \global\let\save\textandmacro
}
% here \save still expands to "sampletext \mcr"

对于更复杂的情况,如果您想要\save包含多个宏,则可以使用\expandafter

\def\one{old1}
\def\two{old2}
\expandafter\def\expandafter\save\expandafter{\one\two} % = \def\save{old1\two}
\expandafter\def\expandafter\save\expandafter{\expandafter\one\two} % = \def\save{\one old2}
\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\save\expandafter\expandafter\expandafter{\expandafter\one\two} % = \def\save{old1old2}

在经典 TeX 中,更复杂的情况往往需要\expandafter\noexpand\edef的复杂排列\toks

相关内容