![\def 和 \edef:只扩展一层,不扩展更多](https://linux22.com/image/480688/%5Cdef%20%E5%92%8C%20%5Cedef%EF%BC%9A%E5%8F%AA%E6%89%A9%E5%B1%95%E4%B8%80%E5%B1%82%EF%BC%8C%E4%B8%8D%E6%89%A9%E5%B1%95%E6%9B%B4%E5%A4%9A.png)
我想保存宏的内容(可能包含文本和其他宏)以供以后使用,而无需完全展开。
\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
可以工作的参数,即使你需要\save
in的参数\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
答案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
。