我的书中有一个目录memoir
。我希望每章都有一行,此外还有每组类似章节的标题。
由于某种原因,第一章的行出现在第一phantom
行之前。
\documentclass{memoir}
\begin{document}
\frontmatter
\tableofcontents*
\mainmatter
\phantomsection
\addcontentsline{toc}{part}{Topic 1}
\include{intro}
\chapter{Chapter 2}
This is the second chapter.
\phantomsection
\addcontentsline{toc}{part}{Topic 2}
\chapter{Chapter 3}
This is the third chapter.
\chapter{Chapter 4}
This is the fourth chapter.
\end{document}
intro.tex
同一目录中的文件包含以下内容:
\chapter{Introduction} \label{chap:intro}
\noindent This is the introductory chapter.
我注意到,如果我将 的内容粘贴intro.tex
到主文件中(而不是使用\include
),问题就解决了——目录中的“简介”行出现在“主题 1”之前!然而,这不是一个好的解决方案,因为我有大型章节文件,我想单独包含它们……
什么原因可能导致此问题?有办法解决吗?
答案1
\addcontentsline
这是(或\addtocontents
)和 的一个众所周知的问题\include
;只需移动这些线
\phantomsection
\addcontentsline{toc}{part}{Topic 1}
到文件intro.tex
。
让我们看一下问题的原因;为简单起见,我们考虑以下示例文件main.tex
\documentclass{memoir}
\begin{document}
\tableofcontents*
\mainmatter
\addcontentsline{toc}{part}{Topic 1}
\include{intro}
\chapter{Chapter 2}
\end{document}
文件 intro.tex 类似于
\chapter{Introduction}
Text
当然,在真实的文档中“第 2 章”也应该写在它自己的.tex
文件中并\includ
编辑main.tex
,但这与下面的解释无关。
这里有两件事很重要:
- 每个
\includ
ed 文件都会生成其自己的.aux
文件。 - 有关目录的信息不会直接写入
.toc
文件;\@write
程序首先进入.aux
文件,并且仅在执行时才\enddocument
从文件读取该信息.aux
并将其写入文件.toc
。
现在,让我们来看一下 的处理步骤main.tex
。在\end{document}
到达 之前,文件main.aux
和main.toc
仍为空,但至关重要的是, 该文件intro.aux
已被写入,并且包含(除其他内容外) 行。
\@writefile{toc}{\contentsline {chapter}{\chapternumberline {1}Introduction}{1}}
\enddocument
执行时,文件main.aux
将被处理并包含以下行
\@writefile{toc}{\contentsline {part}{Topic 1}{1}}
\@writefile{lof}{\addvspace {10pt}}
\@writefile{lot}{\addvspace {10pt}}
\@writefile{toc}{\contentsline {chapter}{\chapternumberline {2}Chapter 2}{3}}
此外,写入.toc
文件的操作已完成,但完成时,顺序并非预期(请记住,是intro.aux
先写入的):与“简介”相关的写入将首先完成,然后是“主题 1”的写入,最后是“章节 2”的写入。事实上,文件main.toc
将
\contentsline {chapter}{\chapternumberline {1}Introduction}{1}
\contentsline {part}{Topic 1}{1}
\contentsline {chapter}{\chapternumberline {2}Chapter 2}{3}
文档的下一步处理将会按该顺序查找行,并且这些行将以错误的顺序排版在文档中。
可能的解决方案
将该
\addtocontents
行移至 的开头intro.tex
。这样做后,intro.aux
写入时将包含以下行\@writefile{toc}{\contentsline {part}{Topic 1}{1}} \@writefile{lof}{\addvspace {10pt}} \@writefile{lot}{\addvspace {10pt}} \@writefile{toc}{\contentsline {chapter}{\chapternumberline {1}Introduction}{1}}
所以现在文件
\@write
中的 s.toc
将按正确的顺序排列:\contentsline {part}{Topic 1}{1} \contentsline {chapter}{\chapternumberline {1}Introduction}{1} \contentsline {chapter}{\chapternumberline {2}Chapter 2}{3}
我知道这可能听起来很“黑客”,但其他替代解决方案(见下文)也或多或少具有相同的性质。
如果您不需要
\includeonly
的功能\include
,您可以改用\input
(但请注意,\input
不会在内部发出\cleardoublepage
或\clearpage
)。\input
不会.aux
为附属文件生成文件,这将避免出现问题。如果您需要使用
\include
,并且所有包含的文件将在必要时负责发出\cleardoublepage
或\clearpage
(例如,如果所有包含的文件都包含\chapter
),那么您可以按原样处理文档;这将在目录中产生错误的顺序),但会让您从功能中获利\includeonly
,然后,对于最终版本,将所有\include
命令替换为\input
命令并执行最终的完整处理(根据文档的要求执行尽可能多的运行)。为该行使用子文件,
\addtocontents
并将\include
其放在主文档中。在示例中,main.tex
现在看起来如下所示:\mainmatter \include{topic1} \include{intro} \chapter{Chapter 2}
包含
topic1.tex
行\addcontentsline{toc}{part}{Topic 1}