LaTeX教程(012)-LaTeX文档结构(12)

LaTeX教程(012)- LaTeX \LaTeX LATEX文档结构(12)

2.3.2 titletoc包-设计目录列表的高级接口

titletoc包(作者Javier Bezos)最初是作为一个和titlesec包结合使用的包而开发的,但是它也可以单独使用。该包调用它自己的接口来排版目录的结构,这样就避免了原生 LaTeX \LaTeX LATEX对这一工作的限制。在开发一个新的文档类时,对这类列表的调整就是必要的了,此时titletoc包就是一个很好的选择。

为单个级别的目录条目设计布局

一个目录条目通常由一个标头(通常只有一个标题编号,也可以设置一些额外预定义文本,如第X章),一行或多行标题文本,一串引导线,以及一个页码组成。常规的排版是使所有条目的页码靠右对齐,因此,通常从标题到页码之间会有一段距离,往往使用空白、一条直线或一串圆点来填补这一段距离。

标准 LaTeX \LaTeX LATEX的目录中,标题文本所有行的左右两端都有缩进,分别用来放置标头和页码,标头设置为左对齐的无衬线字体,而页码由一串实心圆点或者一条直线(我们将这它们称为引导线,引导线负责连接标题文本与页码)将其标题文本块分离。一个典型的多行标题如下图所示:

在这里插入图片描述

标准布局

titletoc包支持上述类型的标准布局,并且相较于标准 LaTeX \LaTeX LATEX,还提供了更方便的定制方式。此外,它还支持其它布局,例如将低级标题一起放置在单个段落中,或者定制一个局部的目录列表。而对于上面展示的常规情形,该包提供了一个\dottedcontents命令,它的形式如下:

\dottedcontents{type}[left-indent]{before-code}{label-width}{leader-width}
  • 第一个参数type指我们为之设计样式的条目的类型,它可以是划分命令的名称(不带前面的反斜线),如sectionchapter等。也可以是浮动体的环境名称,如figuretable
  • left-indent: 从页面的左边距到标题文本的距离。它应当比label-width更大,因为label-width是内嵌在left-indent中的。尽管在语法上它是一个可选参数,但在实际应用中,它总是必要的,这一点要切记。
  • before-code: 我们已经见过很多命令中的before-code参数了,它们的作用基本相同。这里主要放置影响条目的前置代码,如使用\addvspace添加一段垂直距离,或者放置一些可以影响整个条目样式的代码,如字体声明代码等。这里也可以使用\filleft\filright\filcenter、或者\fillast(我们在讲titlesec包时讲过的命令)设置条目的对齐方式。
  • label-width: 标签(就是条目的标题编号,下文中的标签均指条目中的标题编号)的名义宽度,也就是标签左侧到第一行标题文本左侧之间的距离。它也应当足够大,以容纳同级别的最长标签。否则可能会有标签与标题文本重合。
  • leaders-width,引导线的两个最小单元之间的距离,在上述例子中,就是两个圆点之间的距离。

例如,我们用\dottedcontents命令排版上述条目:

\dottedcontents{section}[40pt]{\normalfont\sffamily\filright}{24pt}{6pt}

这行代码表示,它所设置的是\section条目的样式。从左边距到标题文本之间的距离是40pt,标签也在这段距离内,它从左边距向右16pt(40-24)处开始,占据水平空间不超过24pt,也就是说,从标签最左侧到标题文本的距离是24pt。整个条目靠左对齐(因为使用了\filright),而\normalfont\sffamily是字体与字号声明。最后,每个圆点占据6pt的间距。

我们用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper]{geometry}
\usepackage{titletoc} % 使用titletoc包
\begin{document}
\tableofcontents
\dottedcontents{section}[40pt]{\normalfont\sffamily\filright}{24pt}{6pt}
% 定制section条目
\chapter{This is a chapter}
\section{This is a section}
\section{This is a sample section entry which has been deliberately made very long so that it spans three lines to exhibit the handling of the first and the last line in the entry}
\end{document}

编译(只截取目录部分):

在这里插入图片描述

试着调整一下其中的几个参数,比如将left-indent改成10pt,将label-width改成8pt,将leaders-width改成24pt,再次编译:

在这里插入图片描述

可以看到左边的缩进变小了,标签的空间也变小了,以至于与标题文本重合了一部分,另外,每两个圆点之间的距离变大了。

你可能想知道,条目中标题文本的右侧缩进是多少,以及它为什么没有作为\dottedcontents的一个参数而受到控制。主要原因是在所有的设计中,所有条目都有相同的右侧缩进,因此在条目级别提供它可能会很繁琐且容易出错。在大多数文档类中,默认值都是足够大的,它足以容纳3位数字的页码(按当前文档的正文字体)。如果不够用(或者太大了),可以使用\contentsmargin命令全局地改变它,该命令的形式如下:

\contentsmargin[correction]{right-sep}

该声明的right-sep参数指定了所有条目的右侧缩进,也就是放置页码的空间。它应该足够大,否则页码可能会和条目中的标题文本重合。另外,如果我们使用了correction参数,在条目中的标题文本设置了对齐方式的时候,该参数会对标题文本除最后一行的所有行再次进行缩进。我们用一个例子演示:

\documentclass{book}
\usepackage[a5paper]{geometry}
\usepackage{titletoc}
\begin{document}
% 将标题文本设置为两端对齐
\dottedcontents{section}[40pt]{\normalfont\sffamily\fillast}{24pt}{6pt}
% 将右侧缩进设置为40pt,这行命令要放在\tableofcontents前面
\contentsmargin{40pt}
\tableofcontents
\chapter{This is a chapter}
\section{This is a section}
\section{This is a sample section entry which has been deliberately made very long so that it spans three lines to exhibit the handling of the first and the last line in the entry}
\end{document}

编译:

在这里插入图片描述

可以看到,右侧用来容纳页码的缩进距离变大了(40pt),并且引导线也和前面的标题文本保持对齐了。我们加上correction参数,将上面的代码\contentsmargin{40pt}改为\contentsmargin[20pt]{40pt},编译:

在这里插入图片描述

看到除了最后一行的所有行都又缩进了20pt

这个设置是全局的,在极少数情况下,你可能会需要为不同级别的条目设置不同的右侧缩进,那么你必须将\contentsmargin命令放置在\dottedcontents命令或者\titlecontents命令(接下来要讲的)的before-code参数中,使它仅对当前设置的条目有效。

我们用一张示意图展示一下\dottedcontents以及\contentsmargin两个命令的参数的作用位置:

在这里插入图片描述

结构更复杂的布局

大多数情况下\dottedcontents就够用了,但它有着明显的局限,例如,如果你不想要任何引导线,或者你需要的不仅仅是对字体和缩进做出调整时,使用它就不行了。应对这类情形,titletoc包提供了一个\titlecontents命令以及一些辅助命令用在它的参数中。该命令的形式如下:

\titlecontents{type}[left-indent]{before-code}{numbered-entry-format}{numberless-entry-format}{page-format}[below-code]

这个命令中,参数typeleft-indentbefore-code的作用和意义均与\dottedcontents的参数相同。不同的是\titlecontents命令不再简单地指定标签宽度,而是有两个参数允许我们设置标签和标题文本的样式,并且指定标签(也就是编号)为空的情形。这意味着你的设计有更多的可能性,但代价是你需要指定更多的代码。

  • numbered-entry-format: 用来设置编号和标题文本样式的代码。它是在水平模式下运行的。如果我们想要该条目有编号,那么必须将编号放置在该参数中。当前条目的编号储存在命令\thecontentslabel中,也有其它命令可以替代,我们下面会说到。该参数的最后可以放置一个带有一个参数的命令,它会接收标题文本作为该命令的参数。
  • numberless-entry-format: 用来设置不带编号的条目的标题文本样式的代码。它的最后也可以放置一个带有一参数的命令。也就是说,一个条目如果没有声明\numberline{text}(空的编号也不行,只有不使用这个命令,才会被认为是没有编号的),它就会执行该参数能的代码,如果有编号,则执行numbered-entry-format参数中的命令。

这里要注意,如果你使用带星号的划分命令,如\section*,那么在目录中是不会生成条目的。但是我们在上一讲(011篇)中说到了手动插入目录条目的方法,如:

\addcontentsline{toc}{section}{\protect\numberline{text}Foreword}

这样使我们可以插入带有编号的条目,如果将\numberline{text}去掉,就可以插入一个没有编号的条目了。

  • page-format: 对于引导线,不再指定leader-width了,而是用一个参数精确地定义标题文本后面在执行的代码。因此我们要手动将引导线以及页码的格式化输入包含在这些代码中。引导线可以是一些圆点,也可以是一条线,比如你可以使用\titlerule命令填充引导线(009篇讲过)。而存储当前条目的页码的命令是\thecontentspage。该参数依旧在水平模式下运行。
  • below-code: 可选参数,在垂直模式下运行,通常放置一些在条目的最后(下方)执行的代码。比如,可以放置一段垂直空间,来增大该条目与下方内容的垂直距离。

我们用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper]{geometry}
\usepackage{titletoc}
\begin{document}
\titlecontents{section}[15pt]{\addvspace{2pt}\filright}% 条目靠左对齐
{\contentspush{\thecontentslabel\enspace }}% 对与带编号的条目,输出标题
{\LaTeX{}\ \MakeUppercase}% 对于不带编号的条目,将所有字母变成大写,并且在前面加一个LaTeX标志
{~\hrulefill\hspace{0.5cm}\thecontentspage}%引导线用一条直线填充
\tableofcontents
\chapter{This is a chapter}
\section{This is a section}
\section*{Foreword}
% 插入一个不带编号的条目
\addcontentsline{toc}{section}{\protect{}Foreword}
\section{This is a sample section entry which has been deliberately made very long so that it spans three lines to exhibit the handling of the first and the last line in the entry}
\end{document}

编译:

在这里插入图片描述

有几个不认识的命令,我们下面会讲。

观察前面的文档,可以发现其他的都如我们所愿,只是设置过的页码没有和默认情形下的页码对齐。此时我们就需要介绍另外两个命令,\contentslabel\contentspage,可以将它们分别看作是\thecontentslabel\thecontentspage的升级版。它们的形式分别是:

\contentslabel[text]{size}
\contentspage[text]

\contentslabel用来代替\thecontentslabel生成条目的标签(编号),不同的是,它会首先生成一个宽度为size的盒子,该盒子在标题文本的左侧,并且紧靠着标题文本放置。text是一个可选参数,它用来放置条目的标签。标签会在盒子中靠左放置。如果我们忽略可选参数,那么标签默认就是\thecontentslabel,也就是当前条目的编号。如果我们放置了内容,那么条目的标签就是我们放置的内容。注意这里的设置的全局的,我就是说,如果我用\titlecontents命令设置的条目类型是section,并且在numbered-entry-format参数中使用了\contentslabel[abc]{25pt}命令,那么所有的section条目的标签都会变成abcabc会出现在标题文本前方25pt处。可以看出,这里的size的参数的作用,和\dottedcontents命令的label-width参数作用是一样的,因此要注意,left-indent要留出足够的空间,至少要大于size

text参数的正确的使用方法并不是将所有条目的标签变得一样,实际上,我们可以手动将\thecontentslabel放置在参数text中,并且可以根据自己的喜好为其设置样式。例如,将\bf\thecontentslabel放置其中,就可以得到加粗显示的编号。

\contentspage\contentslabel类似,首先会生成一个在标题文本的最后一行,并且靠右边距放置的盒子。text同样是一个可选参数,它用来放置条目的页码。页码会在盒子中靠右放置。如果我们忽略可选参数,页码就默认是\thecontentspage,也就是当前条目的页码。这个盒子实际上是放置在了我们为页码保留的右侧缩进中,而这个盒子也不需要我们为其设置宽度(size),它和右侧缩进的大小相同,这个距离是全局的,所有条目都相同,而我们可以使用\contentsmargin[correction]{right-sep}全局地改变它,正如上文中讲的那样。

titletoc包提供了3个包选项,用来影响\contentslabel的使用结果,如果我们使用了这个命令,并且没有使用text参数,那么使用包选项rightlabels就可以使\contentslabel指定的条目的编号在盒子中靠右放置,而leftlabels选项可以使其靠左(默认也是靠左的)。还有一个全局选项dotinlabels,指定了该包选项之后,使所有条目的编号后面加上一个圆点,注意一点对所有条目有效,包括没有用\titlecontents设置过的条目。

我们将上面的例子中的\thecontentslabel\thecontentspage分别替换成\contentslabel\contentspage,再次演示一下:

\documentclass{book}
\usepackage[a5paper]{geometry}
\usepackage{titletoc}
\begin{document}
\titlecontents{section}[36pt]{\addvspace{2pt}\filright}%
{\contentslabel{20pt}}% 注言这里不需要使用\contentspush了,接下来我们就讲该命令的作用
{\LaTeX{}\ \MakeUppercase}%
{~\hrulefill\contentspage}%
\tableofcontents
\chapter{This is a chapter}
\section{This is a section}
\section*{Foreword}
\addcontentsline{toc}{section}{\protect{}Foreword}
\section{This is a sample section entry which has been deliberately made very long so that it spans three lines to exhibit the handling of the first and the last line in the entry}
\end{document}

编译:

在这里插入图片描述

我们再用一张示意图展示一下\titlecontents\contentslabel以及\contentspage这三个命令的参数的作用位置:

在这里插入图片描述

观察上面两个例子,如果我们使用的是\thecontentslabel,就需要用\contentspush,如果使用的是\contentslabel,就不需要了。那么,\contentspush命令是作用是什么呢?

我们先在不使用\contentspush的前提下使用\thecontentslabel,看看是什么结果:

\documentclass{book}
\usepackage[a5paper]{geometry}
\usepackage{titletoc}
\begin{document}
\titlecontents{section}[36pt]{\addvspace{2pt}\filright}%
{\thecontentslabel\enspace }%
{}%
{~\hrulefill\contentspage}%
\tableofcontents
\chapter{This is a chapter}
\section{This is a section}
\section{This is a sample section entry which has been deliberately made very long so that it spans three lines to exhibit the handling of the first and the last line in the entry}
\end{document}

编译:

在这里插入图片描述

可见,默认情况下,标签会被当作标题文本的一部分一起缩进,缩进距离受left-indent控制,我们加上\contentspush,也就是将上面的例子中的\thecontentslabel\enspace 换成\contentspush{\thecontentslabel\enspace },编译如下:

在这里插入图片描述

\contentspush会使标题文本进一步缩进,这个缩进的距离根据标题编号的长度而定,因此它是一个变化的值。这里要注意,标题文本的缩进不再是left-indentleft-indent是编号的缩进,而标题文本的缩进是left-indent加上\contentspush为编号生成的宽度。因此我们建议将left-indent适当调小一些,像上面这样是不美观的。

我们也用一个示意图演示一下:

在这里插入图片描述

为什么使用一个变化的值呢?大多数时候我们都不建议这样用,除非你的章节非常多,例如有1.1,又有10.12这样的节编号,编号宽度差距会比较大。使用最大的宽度,对1.1来说太大了,小了的话10.12这样的编号又会和标题文本重合。

关注【年轻人 你渴望力量么】

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值