ToC 文件中的 `\settocdepth` 后跟 `\include` 顺序错误

ToC 文件中的 `\settocdepth` 后跟 `\include` 顺序错误

我可以使用\settocdepth来更改 ToC 最小文档的深度。当我注释掉该\include语句时,这在下面的 MWE 中按预期工作。但是,当\settocdepth命令后跟一个包含包含不同\chapter\section语句的文件的 include 语句时,toc 文件的顺序最终会错误。

我的 MWE 如下:

\documentclass{memoir}    
\begin{document}       

\frontmatter    
\settocdepth{chapter}    
\tableofcontents*    
\chapter{Preface}    
\chapter{Introduction}    
\section{Section 1}    
\section{Section 2}    
\section{Section 3}    

\mainmatter    
\settocdepth{section}    
\include{first-chapter}
%\chapter{First chapter}    
%\section{A section}    
%\section{Another section}    
\chapter{Second chapter}    
\section{A section}    
\section{Another section}    

\end{document}

目录文件:

\changetocdepth {0}    
\contentsline {chapter}{Preface}{iii}{}%
\contentsline {chapter}{Introduction}{v}{}%
\contentsline {section}{Section 1}{v}{}%
\contentsline {section}{Section 2}{v}{}%
\contentsline {section}{Section 3}{v}{}%
\contentsline {chapter}{\chapternumberline {1}First chapter}{1}{}%
\contentsline {section}{\numberline {1.1}A section}{1}{}%
\contentsline {section}{\numberline {1.2}Another section}{1}{}%
\changetocdepth {1}
\contentsline {chapter}{\chapternumberline {2}Second chapter}{3}{}%
\contentsline {section}{\numberline {2.1}A section}{3}{}%
\contentsline {section}{\numberline {2.2}Another section}{3}{}%

您可以看到,它仅在包含的文件中以 s\changetocdepth结尾处添加。contentsline

我该如何修复这个问题?我做错了什么?

答案1

您需要在\mainmatter执行 a之前切换值\clearpage并刷新待处理的写入。

$ cat aa105.toc
\changetocdepth {0}
\contentsline {chapter}{Preface}{iii}{}%
\contentsline {chapter}{Introduction}{v}{}%
\contentsline {section}{Section 1}{v}{}%
\contentsline {section}{Section 2}{v}{}%
\contentsline {section}{Section 3}{v}{}%
\changetocdepth {1}
\contentsline {chapter}{\chapternumberline {1}First chapter}{1}{}%
\contentsline {section}{\numberline {1.1}A section}{1}{}%
\contentsline {section}{\numberline {1.2}Another section}{1}{}%
\contentsline {chapter}{\chapternumberline {2}Second chapter}{3}{}%
\contentsline {section}{\numberline {2.1}A section}{3}{}%
\contentsline {section}{\numberline {2.2}Another section}{3}{}%

产自

\documentclass{memoir}    
\begin{document}       

\frontmatter    
\settocdepth{chapter}    
\tableofcontents*    
\chapter{Preface}    
\chapter{Introduction}    
\section{Section 1}    
\section{Section 2}    
\section{Section 3}    



\settocdepth{section}
\mainmatter    
\include{first-chapter}
%\chapter{First chapter}    
%\section{A section}    
%\section{Another section}    
\chapter{Second chapter}    
\section{A section}    
\section{Another section}    

\end{document}

答案2

使用它的主要原因\include是它允许您使用\includeonly只编译某些章节但仍可引用其他章节的编号和标签。

为了使其工作,每个人都\include写入自己的.aux文件(并在主文件中记录其名称)并记录计数器的状态等。

这仅当每个包含的文件基本上都是独立的并且对您的文档施加了一些限制时才有效:一是您需要在文件内部进行一些设置,主要是通过写入辅助文件和其他文件(如您的命令)来进行的设置。

让这些命令\include立即生效有效,但通常会导致其他问题,因为它们现在通常发布得太早,所以我不推荐这样做。

选项

  • 如果你不需要\includeonly使用\input\include

  • 如果您需要\includeonly并且希望在主文件中进行这样的设置,请考虑在每个文件的开头添加一个钩子,然后使用钩子命令向其中添加命令(这自然可以隐藏在一些较短的命令中):

  • 如果您的包含文件总是以 \chapter 开头,那么您也可以使用钩子cmd/chapter/before

\documentclass[a4paper]{book}
\NewHook{myhook/settings}

\begin{filecontents}[overwrite]{foobar1.tex}
\UseHook{myhook/settings}
\chapter{Foobar 1 chapter}

test

\section{Foobar section}
\end{filecontents}

\begin{filecontents}[overwrite]{foobar2.tex}
\UseHook{myhook/settings}
\chapter{Foobar 2 chapter}

test

\section{Foobar section}
\end{filecontents}

\begin{document}

\frontmatter

\tableofcontents

\AddToHookNext{myhook/settings}
 {\addtocontents{toc}{\protect\setcounter{tocdepth}{0}}}
\include{foobar1}


\mainmatter

\AddToHookNext{myhook/settings}
 {\addtocontents{toc}{\protect\setcounter{tocdepth}{1}}}
\include{foobar2}

\end{document}

在此处输入图片描述

答案3

下一个memoir版本将解决这个问题。将添加一个带星号的版本,该版本会自动\clearpage在 David 的回答中添加点赞,或者在安全的情况下使用立即写入。


这实际上本身并不是一个memoir问题。您的代码相当于article最后的示例,它显示了相同的问题(\settocdepth是包装器\addtocontents)。由于将内容写入 toc 文件主要涉及将页码写入文件,因此其写入是在输出例程中处理的,因此事情可能会乱序。

但无论如何,还是可以做些事情的。

我们定义 的直接版本\settocdepth

但使用时要格外小心,如果你在同一级别使用 \section,你可能会遇到相反的问题

\makeatletter

% we need an immediate version of \addtocontents.
% Note this can be dangerous and give wrong results, so we remove \thepage
\long\def\immediateaddtocontents#1#2{%
\immediate@protected@write\@auxout% <-- \immediate@protected@write is defined in memoir
{\let\label\@gobble \let\index\@gobble \let\glossary\@gobble \let\thepage\relax}%
{\string\@writefile{#1}{#2}}}

% it is a lot easier to define \settocdepth using expl3, here is a helper
\ExplSyntaxOn
\newcommand*{\settocdepth@}[2]{%
  \str_case_e:nnTF{#2}{
    {none}{          #1{toc}{\changetocdepth{-10} }}
    {book}{          #1{toc}{\changetocdepth{-2} }}
    {part}{          #1{toc}{\changetocdepth{-1} }}
    {chapter}{       #1{toc}{\changetocdepth{0} }}
    {section}{       #1{toc}{\changetocdepth{1} }}
    {subsection}{    #1{toc}{\changetocdepth{2} }}
    {subsubsection}{ #1{toc}{\changetocdepth{3} }}
    {paragraph}{     #1{toc}{\changetocdepth{4} }}
    {subparagraph}{  #1{toc}{\changetocdepth{5} }}
    {all}{           #1{toc}{\changetocdepth{50} }}
  }{
    \@ifundefined{toclevel@#2}{%
      \@memwarn{Unknown~toclevel~for~#2}%
    }{%
      \setcounter{tocdepth}{\@nameuse{toclevel@#2}}%
    }
  }{
    \@memerror{%
      Unknown~document~division~name~(#2)
    }{%
     I'll~ignore~ it.~
     Type~<return>~and~I'll~continue.}%
  }
}

\newcommand*\immediatesettocdepth[1]{%
  \settocdepth@{\immediateaddtocontents}{#1}%
}
\ExplSyntaxOff
\makeatother

然后在您的代码中使用\immediatesettocdepth而不是\settocdepth

memoir我将来可能会添加这个。


这里的例子表明这不是一个memoir问题。

\documentclass[a4paper]{book}
\begin{filecontents}[overwrite]{foobar.tex}
\chapter{Foobar chapter}

test

\section{Foobar section}
\end{filecontents}
\begin{document}

\frontmatter
\tableofcontents

\addtocontents{toc}{\protect\setcounter{tocdepth}{0}}
\include{foobar}


\mainmatter

\addtocontents{toc}{\protect\setcounter{tocdepth}{1}}
\include{foobar}

\end{document}

相关内容