TeX-Core – How to \expandafter a \let#1 in Macro Definition

tex-core

Sometimes, I want to redefine some cs in a range, generally a macro definition. Like:

\def [[csname>]] {

    [[Redefine some cs]]

    [[Actual function of this macro]]

    [[Recover the redefined cs]]

}

What mainly needed to do is define macros of Redefine and Recover, let's call them \redefine and \recover.

For recovering, a hardly conflict cs should be used to store the meaning of cs to be redefined, and their names should be relative. Here I use "the csname of its csname" :

\def\redefine#1#2{
    \expandafter \let \csname\string#1\endcsname #1 \relax
    \def#1{#2}
}

Where #1 is the cs to be redefined.

Now I found that the original meaning can not be recover.

\def\recover#1{
    \let #1 \csname\string#1\endcsname
}

It seems that \csname\string#1\endcsname can not be expanded before \let, because # 1 are two different tokens but treated as argument replacement in macro definition iff they successively appear. Meanwhile \expandafter just skip 1 token.

Maybe \def but not \let can be used in most cases, I still want to know any way to make the 2nd token be expanded before the 1st when the 1st token is an argument?


i.e.

Some shorter primitive cs are defined:

\let\epaf\expandafter
\let\str\string
\let\nep\noexpand
\let\cs\csname
\let\sc\endcsname
...

for a macro named \mfont that parse a sentence until \relax, and set lots of font attribute, and make a single cs set latin font and unicode font at the same time. It use lots of primitive cs to parse sentence, definiiton is hard to read if keep the long name.

After a block from \mfont to \relax , shoter names should be recovered. \mfont should define font for global but the shorter names should be valid just in the \mfont range.

Best Answer

enter image description here

You had spurious spaces, and missing \expandafter

% no space!!!!
\def\redefine#1#2{%
    \expandafter \let \csname\string#1\endcsname #1%
    \def#1{#2}%
}




% no space!!!!
\def\recover#1{%
% missing \expandafter 
    \expandafter \let \expandafter #1\csname\string#1\endcsname
}


{\tt \string\sin=\meaning\sin}

\redefine\sin{hello}

{\tt \string\sin=\meaning\sin}

\recover\sin

{\tt \string\sin=\meaning\sin}

\bye
Related Question