让我们从一个可以说明我的问题的最小工作示例开始。
\documentclass{article}
\usepackage{collect}
\usepackage{makeidx}
\makeindex
\definecollection{test}
\makeatletter
\newenvironment{testenv}[1]
{\@nameuse{collect}{#1}{%
\par%
{\noindent Test}\par\noindent
}{
\par
}
}%
{\@nameuse{endcollect}}
\makeatother
\begin{document}
Text
\begin{testenv}{test}
test \index{testindex}
\end{testenv}
\newpage
\includecollection{test}
\newpage
\printindex
\end{document}
生成的文档现在应由第一页包含“Text”、第二页包含“Test”和“test”组成,最后一页包含索引,其中只有“testindex”引用第 2 页。但是,第二页也包含单词“testindex”,索引页仅包含引用第 2 页的空字符串。
收集页面构建一个文件\jobname.test
(由于\definecollection{test}
),其中收集的内容位于其中。此文件的内容为
\par {\noindent Test}\par \noindent
test \index {testindex}
\par
\index
这里我们可以看到我的问题:和之间的空白{testindex}
。因此,索引包似乎\index{}
因此想到了一个调用。
有人知道如何解决这个问题吗?
答案1
当后面跟着空格时确实会出现问题\index
,因为这个命令没有寻找参数,而是进行一些调整,然后调用\@wrindex
。当\@wrindex
调用时,空格不再是真正的空格,而是类别代码为 12 的字符,因此在宏名后面时不会被忽略。
发生这种情况是因为 TeX “看到”了空格,所以它知道控制序列名称已经结束,但仍然没有标记或忽略它。宏被展开,混乱随之而来。:-(
以下是解决这个问题的方法:
\documentclass{article}
\usepackage{collect}
\usepackage{makeidx}
\makeindex
\makeatletter
\let\ori@wrindex\@wrindex
\def\@wrindex{%
\@ifnextchar\bgroup\ori@wrindex{\expandafter\ori@wrindex\@gobble}%
}
\makeatother
\definecollection{test}
\newenvironment{testenv}[1]
{\collect{#1}{%
\par%
{\noindent Test}\par\noindent
}{
\par
}
}%
{\endcollect}
\begin{document}
Text
\begin{testenv}{test}
test \index{testindex}
\end{testenv}
\newpage
\includecollection{test}
\newpage
\printindex
\end{document}
如果\index
后面跟着一个括号,则立即执行原始命令,否则会消耗一个令牌(即命令\index
在收集的文件中时的空间)。