3

I want to save the content of a macro (which may contain text and other macros) for later use and without full expansion.

\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'

After that, when i use \save i want to get sampletext b, which is sampletext and the current meaning of \mcr.

But what i get is xy of course, because \textandmacro has changed.

When i \edef the macro \save, i will get sampletext a, because \mcris fully expanded while edef-ing. This is not what i want.

What i want is some kind of an expansion for one level, not more. I don't want to save \textandmacro but sampletext \mcr.

Any ideas?

I'm working in TeX (LuaTeX), so Latex will not help me.

Best regards, Peter

Edit: the accepted answer is cool. I solved my problem with the \toks version. The other answers with the \let seem to be also right and simpler. I did't test it yet, but they are cool answers, too!

So: thank you all!

3
  • 2
    I guess \edef\save{\unexpanded\expandafter{\textandmacro}} does what you need Mar 6 at 13:45
  • 2
    I guess \let\save\textandmacro or with LaTeX \NewCommandCopy{\save}{\textandmacro}.
    – cabohah
    Mar 6 at 13:50
  • How can you judge coolness without testing? ;-) Mar 8 at 18:15

3 Answers 3

5

This depends on whether you need working parameters or not. If not, the \unexpanded\expandafter{} approach in @PhelypeOleinik's comment is fine (needs eTeX, but since you're using LuaTeX that's fine):

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

Another approach would be just a bunch of \expandafter which would work even if you needed parameters for \save in \textandmacro (though you'd need more \expandafters then):

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

Last approach, Knuthian TeX version of the \unexpanded\expandafter{} approach:

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

(on this last one you might want to use groups to keep the assignment to \toks0 local)

3

If I understand correctly, the output should be sampletext b (because \mcr has changed to b). So IMHO \let would be fine:

\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

sampletext b

0

If you just want to save the current content of one macro, use \let.

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

You can make \save global if you need it to survive the current group.

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

For somewhat more complex cases where you want \save to contain more than a single macro, you can use \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}

In classic TeX, even more complex cases tend to call for a complex arrangement of \expandafter, \noexpand, \edef and \toks.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .