我正在寻找一种方法,将文本“Chapter”作为书籍类目录中章节编号的前缀,并将章节标题换行到目录列表的最左侧。我正在将其构建为一个通用资源,目前分为两部分,一部分是仅包含包的类文件,另一部分是序言中 \input 的设置 .tex 文件。我在设置文件中尝试了两种不同的方法。下面的第一个方法没有正确捕获所需的补丁。
\documentclass{book}
\usepackage{xpatch}
\usepackage{hyperref}
\makeatletter
\xpatchcmd{\@chapter}
{\addcontentsline{toc}{chapter}{\numberline {#1}}}
{\addcontentsline{toc}{chapter}{\numberline {Chapter~\thechapter{}.~#1}}}
{\typeout{Success}}
{\typeout{Failed!}}
\makeatother
\begin{document}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second}
Perhaps soon!
\end{document}
第二种方法将章节词放在目录中,但是较长的第 2 章标题中的文本没有按照目录行中的要求换行。
\documentclass{book}
\usepackage{tocloft}
\begin{document}
\newlength{\tocchapwidth}
\settowidth{\tocchapwidth}{\chaptername\ }
\addtolength{\cftchapnumwidth}{\tocchapwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftchapaftersnumb}{~}
\renewcommand{\cftchapdotsep}{\cftdotsep}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}
Perhaps soon!
\end{document}
这是为了满足论文/学位论文文档的格式要求。我们目前有一个粗略的解决方法——我们输入包含前缀的章节标题,例如 \chapter{Chapter 2.~This is the Second ...}(并使用 titlesec 包隐藏目录中的章节编号输出)。
另外,虽然我没有在第二个示例中包含它,但该文档确实需要 hyperref 包。我从另一篇帖子中推断,我可能需要修补其 Hy@... chapter 命令,但即使我尝试这样做也失败了。
我对 LaTeX3 不太熟悉,但很乐意采纳此类修改。最后,我希望无论提供什么选项,都能在 Overleaf 上轻松运行,因为大部分使用该软件包的人都可能在 Overleaf 上完成他们的工作。
答案1
您的第一个方法存在几个问题。
首先,连的原始定义都book.cls
没有:
\addcontentsline{toc}{chapter}{\numberline {#1}}
在 的定义中\@chapter
,但是:
\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}
因此缺少一个\protect
正确的参数,\numberline
并且的第一个参数\@chapter
没有用括号。
第二个问题是加载后hyperref
定义发生\@chapter
变化。因此补丁必须前加载中hyperref
。
顺便说一句:要查看原始定义,只需\show\@chapter
在 之前添加 。这将在 -file中\xpatchcmd
输出修补之前的当前定义。\@chapter
log
第三个问题是,替换:
\addcontentsline{toc}{chapter}{\protect\numberline {Chapter~\thechapter{}.~#1}}
不仅会Chapter~<number>.
放入数字参数,还会放入标题。因此至少应该:
\addcontentsline{toc}{chapter}{\numberline {Chapter~\thechapter{}.}#1}
但是对于这个定义,你还需要改变以\l@chapter
增加为数字保留的空间。也许你不想保留数字空间,而是喜欢使用:
\addcontentsline{toc}{chapter}{Chapter~\thechapter{}.~#1}
因此:
\documentclass{book}
\usepackage{xpatch}
\makeatletter
\xpatchcmd{\@chapter}
{\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}}
{\addcontentsline{toc}{chapter}{Chapter~\thechapter{}.~#1}}
{\typeout{Success}}
{\typeout{Failed!}}
\makeatother
\usepackage{hyperref}
\begin{document}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second}
Perhaps soon!
\end{document}
你得到:
使用Chapter <number>.
作为参数的替代方法\numberline
是,例如:
\documentclass{book}
\usepackage{xpatch}
\makeatletter
\xpatchcmd{\@chapter}
{\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}}
{\addcontentsline{toc}{chapter}{\protect\numberline{Chapter~\thechapter{}.}#1}}
{\typeout{\string\@chapter\space patch success}}
{\typeout{\string\@chapter\space patch failed!}}
\xpatchcmd{\l@chapter}
{\setlength\@tempdima{1.5em}}
{\setlength\@tempdima{6em}}% increase reserved number width
{\typeout{\string\l@chapter\space patch success}}
{\typeout{\string\l@chapter\space patch failed!}}
\makeatother
\usepackage{hyperref}
\begin{document}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second}
Perhaps soon!
\end{document}
单行输入的结果与第一个建议类似。要查看差异,请尝试多行输入,例如
\chapter{This is Second Chapter with very long Titel Needing more than one
Line in the Table of Contents}
所以恕我直言,我的第二种方法就是您想要的。
第二种方法的问题在于,在增加时,你没有考虑数字后面的点.
和空格。下面是对您的设置的一种可能的更正:~
\cftchapnumwidth
\documentclass{book}
\usepackage{tocloft}
\begin{document}
\newlength{\tocchapwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\settowidth{\tocchapwidth}{\cftchappresnum}
\renewcommand{\cftchapaftersnum}{.~}
\newlength{\tocchapafternumwidth}
\settowidth{\tocchapafternumwidth}{\cftchapaftersnum}
\addtolength{\cftchapnumwidth}{\tocchapwidth}
\addtolength{\cftchapnumwidth}{\tocchapafternumwidth}
\renewcommand{\cftchapdotsep}{\cftdotsep}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}
Perhaps soon!
\end{document}
但是如果你仔细研究这个建议,你会发现它仍然不正确,因为你测量的是当前文档字体中的文本,而不是章节条目使用的字体。所以前面的代码似乎是正确的,但事实并非如此。为了获得正确的代码,你必须在测量文本宽度时考虑到这一点。(现在,如果没有前缀和后缀的\cftchapfont
数字宽度已经足够,你不需要再通过空格来增加宽度)。所以更好的代码应该是这样的:Chapter
.
\documentclass{book}
\usepackage{tocloft}
\newlength{\tocchapwidth}
\newlength{\tocchapafternumwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftchapdotsep}{\cftdotsep}
\AtBeginDocument{% final font setup is done in \begin{document} so we delay all text measuring
\settowidth{\tocchapwidth}{\cftchapfont\cftchappresnum}%
\settowidth{\tocchapafternumwidth}{\cftchapfont\cftchapaftersnum}%
\addtolength{\cftchapnumwidth}{\tocchapwidth}%
\addtolength{\cftchapnumwidth}{\tocchapafternumwidth}%
}
\begin{document}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}
Perhaps soon!
\end{document}
阑尾问题
注意:这两个例子都不适用于带有附录的文档,因为在这种情况下Chapter
附录中不会有正确的术语。
提出不适用于带附录的文档的推荐建议很容易。你只需要替换tocloft
硬编码并增加宽度:Chapter
\@chapapp
\documentclass{book}
\usepackage{xpatch}
\makeatletter
\xpatchcmd{\@chapter}
{\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}}
{\addcontentsline{toc}{chapter}{\protect\numberline{\@chapapp~\thechapter{}.}#1}}
{\typeout{\string\@chapter\space patch success}}
{\typeout{\string\@chapter\space patch failed!}}
\xpatchcmd{\l@chapter}
{\setlength\@tempdima{1.5em}}
{\setlength\@tempdima{7em}}% increase reserved number width
{\typeout{\string\l@chapter\space patch success}}
{\typeout{\string\l@chapter\space patch failed!}}
\makeatother
\usepackage{hyperref}
\begin{document}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second}
Perhaps soon!
\appendix
\chapter{This is a Rather Long and Windy Road Leading to a Door Going
to Nowhere Fast}
\end{document}
对于tocloft
解决方案,您可以使用类似以下方法:
\documentclass{book}
\usepackage{tocloft}
\newlength{\tocchapwidth}
\newlength{\tocappwidth}
\newlength{\tocchapafternumwidth}
\renewcommand{\cftchappresnum}{\chaptername\ }
\renewcommand{\cftchapaftersnum}{.}
\renewcommand{\cftchapdotsep}{\cftdotsep}
\AtBeginDocument{%
\settowidth{\tocchapwidth}{\cftchapfont\chaptername}%
\settowidth{\tocappwidth}{\cftchapfont\appendixname}%
\ifdim\tocappwidth>\tocchapwidth
\addtolength{\cftchapnumwidth}{\tocappwidth}%
\else
\addtolength{\cftchapnumwidth}{\tocchapwidth}%
\fi
\settowidth{\tocchapafternumwidth}{\cftchapfont\cftchapaftersnum}%
\addtolength{\cftchapnumwidth}{\tocchapafternumwidth}%
}
\AddToHook{cmd/appendix/after}{%
\addtocontents{toc}{%
\protect\renewcommand{\protect\cftchappresnum}{\protect\appendixname{} }%
}%
}
\begin{document}
\tableofcontents
\chapter{This is First}
Some day this will work.
\chapter{This is Second, a Rather Long and Windy Road Leading to a Door Going to Nowhere Fast}
Perhaps soon!
\appendix
\chapter{A Rather Long Appendix Heading and Windy Road Leading to a Door Going to Nowhere Fast}
\end{document}