这是一个最小的非工作示例:
\documentclass{article}
\begin{document}
\let\@var\@empty
\newcommand{\append}[1]{ \xdef\@var{\@var #1} }
\append{1}
\append{2}
\append{3}
\@var
\end{document}
我原本期望\@var
包含字符串1 2 3
,但是却收到以下错误:
! TeX capacity exceeded, sorry [input stack size=5000].
\@var->\@var
我怎样才能达到我期望达到的目标?
答案1
您缺少\makeatletter...\makeatother
一些对 —— 由于\@
宏(启动器)名称,这些对是必需的。
如果“字符串”宏不应指示为内部(\@....
内部“隐藏”),请选择其他名称,例如\mystringvar
,这将消除以下问题\makeatletter...\makeatother
\documentclass{article}
\begin{document}
\makeatletter
\let\@var\@empty
\newcommand{\append}[1]{\xdef\@var{\@var #1} }
% Another variant with kernel \g@addto@macro
\newcommand{\appendother}[1]{\g@addto@macro{\@var}{#1}}
\makeatother
\newcommand{\foo}{789}
\append{1}
\append{2}
\append{3}
\appendother{456\foo}
\makeatletter
\@var
\makeatother
\end{document}
答案2
Christian 已经展示了你可以做什么,但要解释错误
@
不是主文档中的字母,因此
\let\@var\@empty
做
\let\@=v
然后排版ar\@empty
产生段落文本arvempty
(您看不到,因为后来的错误阻止了 pdf 的制作。
然后
\newcommand{\append}[1]{ \xdef\@var{\@var #1} }
定义\append
为排版一个空格(为什么?)然后重新定义\@
并排版另一个空格。
\append{1}
因此是一个空格(由于我们处于垂直模式,因此被忽略),然后
\xdef\@var{\@var 1}
这是定义宏,后面\@
跟着要var
扩展的标记\@var 1
,此时\@
是不可扩展的,所以\let
现在v
必须\@
跟随着var
并扩展为\@var 1
然后输出另一个被忽略的空格,
\append{2}
然后输出另一个空格
\xdef\@var{\@var 2}
这再次重新定义\@
为必须遵循的宏var
,但定义是通过扩展获得的\@var 1
,但如上所述,扩展\@var
是在这一点上\@var 1
,因此第一次扩展产生
\@var 1 2
然后\@
再次扩大生产
\@var 1 1 2
依此类推,直到用完输入堆栈。(因为所有 1 都被推到了你前面)