我曾与一个 LaTeX 包的作者通信,在其中我自愿提供了类似如下的代码(我已将其匿名化,因此不清楚是哪个包):
\makeatletter
\newcommand{\savemacrostatewithname}[1]{%
\expandafter\let%
\csname saved@macro@state@named@#1\endcsname%
\package@internal@macro%
}
\newcommand{\restoremacrostatewithname}[1]{%
\ifcsname saved@macro@state@named@#1\endcsname%
\else%
\errmessage{Saved macro state named "#1" doesn't exist}%
\fi%
\expandafter\let%
\expandafter\package@internal@macro%
\csname saved@macro@state@named@#1\endcsname%
}
\makeatother
他们在回复中说而不是写作 #1
在你的宏中,你应该写 \detokenize{#1}
,因为它更安全。为什么这样更安全?如果我不这样做会有什么问题?
答案1
如果你有
\catcode`\!=\active
\def!{\hspace{2in} \fbox{boo} \hspace{2in}}
然后\csname foo!\endcsname
会出现错误,因为名称不会扩展为字符标记序列,但与名称\csname\detokenize{foo!}\endcsname
相同\csname foo\string!\endcsname
并生成标记foo!