LaTeX教程(009)-LaTeX文档结构(09)

LaTeX教程(009)- LaTeX \LaTeX LATEX文档结构(09)

本篇是讲解 titlesec包的最后一篇。

在第007篇中,我们讲了 dropwrap形状的区别,drop使用的是固定宽度,即在 \titlespacing中的 left-sep参数输入的长度数值会被指定为 drop形状标题的固定宽度。而对 wrap形状的标题来说,它是标题的最大宽度。wrap标题会在不超过最大宽度的前提下,优化标题的断行,最后将标题行最长的一行视作整个标题占据的宽度。这个宽度的数值会存储在 \titlewidth中。通过在调用 titlesec包时指定 calcwidth选项,这一机制可以扩展到其他形状,然后在 \titleformat的参数中根据需要使用 \titlewidth命令。

我们上一篇讲了一个 \rule命令,在 titlesec包中,也提供了一个替代命令 \titlerule,它不带任何参数时,会生成一个高度(这里指厚度)为0.4pt,横跨整个标题栏的线段(要减去 \titlespacing指定的间距,也就是说,它和标题的最大宽度等宽)。有一个可选参数可以指定线段的高度(厚度)。我们用一个例子演示一下:

\documentclass{article}
\usepackage[a5paper,margin=1in]{geometry}
\usepackage[calcwidth]{titlesec}
\usepackage{kantlipsum}
\begin{document}
\titleformat{\section}[frame]{}{\footnotesize SECTION \thesection}{0.2cm}{\bfseries\filcenter}
\titlespacing{\section}{2cm}{0.5cm}{0.2cm}[2cm]
\section{This is a section}
\titlerule % 生成一个高度为0.4pt,横跨整个标题栏的线段
\vspace*{3pt} % 生成3pt的垂直距离
\titlerule[2pt]
\vspace*{3pt} % 生成一个高度为3pt,横跨整个标题栏的线段
\kant[1]
\end{document}

编译:

在这里插入图片描述

该命令的星号形式 \titlerule*用来生成一条引导线,它是一条看不见的线段。它有一个可选参数和一个必选参数,必选参数中放置一些文本。引导线用来引导文本的排列,而可选参数可以修改文本之间的间隔。这些文本会在条线段上重复排列。默认情况下,它们以自然宽度排列,而我们可以通过指定可选参数来修改文本之间的间隔。注意,这里的间隔是指文本开头到下一个重复的文本开头的距离,这意味着,如果这个间隔不足够大,文本可能会重叠:

\documentclass{article}
\usepackage[a5paper,margin=1in]{geometry}
\usepackage[calcwidth]{titlesec}
\usepackage{kantlipsum}
\begin{document}
\titleformat{\section}[frame]{}{\footnotesize SECTION \thesection}{0.2cm}{\bfseries\filcenter}
\titlespacing{\section}{2cm}{0.5cm}{0.2cm}[2cm]
\section{This is a section}
\titlerule
\vspace*{3pt}
\titlerule*{\LaTeX}
\vspace*{3pt}
\titlerule
\vspace*{3pt}
\titlerule*[0.3cm]{\LaTeX}
\vspace*{3pt}
\titlerule
\vspace*{3pt}
\titlerule*[1.5cm]{\LaTeX}
\vspace*{3pt}
\kant[1]
\end{document}

编译:

在这里插入图片描述

\titleline生成一个行,它实际上是一个横跨整个标题栏的(减去 \titlespacing指定的间距)水平盒子。它有一个可选参数和一个必选参数。必选参数中是一些要排版的材料,如文本等。可选参数指定这此材料的对齐方式,如 l左对齐,r右对齐,c居中对齐,s分散对齐。它的星号形式的变体 \titleline*的可选参数的作用和 \titleline基本相同,不同的是 \titleline*将这些材料的排版在一个宽度为 \titlewidth的盒子中(因此可能需要在这个参数中添加弹性空间,并且调用 titlesec包时使用 calcwidth选项来确保 \titlewidth的值是正确的),这个盒子再被放置到主盒子中。

\documentclass{article}
\usepackage[a5paper,margin=1in]{geometry}
\usepackage{kantlipsum}
\usepackage[noindentafter,calcwidth]{titlesec}
\begin{document}

\titleformat{\section}[display] {\filright\normalfont\bfseries\sffamily}{\titleline[r]{Section \Huge\thesection}}{1ex}{\titleline*[l]{\titlerule[1pt]}\vspace{1pt}\titleline*[l]{\titlerule[2pt]}\vspace{2pt}}[{\titleline*[l]{\titlerule*{\tiny\LaTeX}}}]

\titlespacing{\section}{1pc}{*3}{*2}

\section{Rules and Leaders}
Note that the last \verb=\titleline*= is surrounded by braces. Without them its optional argument would prematurely end the outer optional argument of \verb=\titleformat=.

\end{document}

编译:

在这里插入图片描述

标准 LaTeX \LaTeX LATEX认为,在标题之前的空白处是一个很好的断页位置,除非该标题前面也是一个标题。 LaTeX \LaTeX LATEX为每一处都设置了一个断页的penalty值 。penalty是惩罚,损失的意思。一个地方的penalty值越大,在这个地方断页的可能性(优先级)就越低。相反,一个地方的penalty值越小,\LaTeX就越会认为这是一个好的断页位置。在很多的文档类中,标题前面的空白处断页的penalty值是-300,它被存储在内部计数器\@secpenalty中。它是一个负数,这意味着 LaTeX \LaTeX LATEX十分推荐在此处断页。所有标题前面的空白处断页的penalty值都相同,所以很少有修改它的必要。然而,使用了titlesec包,可以更精细的控制它。我们可以通过定义\<name>break来改变与标题有关的断页行为,其中<name>指划分命令的名称。例如,我们可以定义\sectionbreak:

\newcommand{\sectionbreak}{\clearpage}

这将导致section标题始终出现在页面的顶部,而所有的待处理的浮动体将首先被排版。我们做个演示:

\documentclass{article}
\usepackage[a5paper,margin=1in]{geometry}

\usepackage{titlesec}
\begin{document}

\titleformat{\section}[frame]{}{SECTION \thesection}{1ex}{\filcenter}
\titlespacing{\section}{1pc}{*3}{*2}
\newcommand{\sectionbreak}{\clearpage}

some text ......
\section{A section}
some test ......
\section{A section}
\end{document}

出于篇幅原因,编译结果我们仅用文字描述一下:

第1页仅有一行文字some text......,该页面的其余部分均是空白。第2页是一个section的标题,且位于页面的顶部(就像chapter标题那样),后面紧跟一行文字some text......,其余部分均是空白。第3页仍是一个section的标题,其余部分均是空白。

但是,如果我们将两个连续的标题放在一起,即两个标题之间的文本去掉,就会看到两个标题出现在同一个页面中的情况。这是因为section是标题类型不是top。这里我们先简单介绍一下toppage类型。top类型的标题和chapter类似,它从新的一页开始,并且默认情况下,它只在奇数页上(书的右手页)。而page类标的标题就像part标题,它不仅从新的一页开始(默认是右手页),并且会独占一页(默认情况下是一页纸的正反两面)。我们可以用\titleclass命令来改变标题的类型。例如:

\titleclass{\section}{top}

命令将section标题指定为top类。

标题的断页方式设置除了\clearpage之外还有\cleardoublepage,在讲这两个命令的区别之前,我们先介绍一下两个文档类型的选项,openrightopenany。如果我们在\documentclass命令后面指定可选参数openright,那么就意味着该文档是双页的(有左手页和右手页)。如果指定了openany,就意味着文档是单页的。book类默认是双页的。在双页文档中,top类标题和page类标题默认只从文档的右手页开始; 在单页文档中,它们会从下一个页码开始,而不管该页是不是奇数页。

那么\clearpage\cleardoublepage的区别是什么呢? \clearpage在放置标题之前,用空白将当前页面的剩余空间填满,将标题放入下一个页面。单页文档中的chapterpart标题(如果有的话)的断页方式默认就是\clearpage\cleardoublepage以一个奇数页和下一个偶数页的组合(一页纸的正反面)为基本单位,在放置标题之前,将当前的整页纸的剩余部分用空白填满,将标题放到下一个奇数页上。双页文档中的chapterpart标题的断页方式就是\cleardoublepage

我们可以改变这一行为,例如,我们可以在双页文档中将chapter标题的断页方式设置为\clearpage:

\documentclass{book}
\usepackage[a5paper,margin=1in]{geometry}
\usepackage{titlesec}
\begin{document}

\titleformat{\chapter}[frame]{}{CHAPTER \thechapter}{1ex}{\filcenter}
% 使用`\titleformat`重定义chapter类型
\titlespacing{\chapter}{1pc}{*3}{*2}

\titleclass{\chapter}{top}
% 重新指定标题类型
\newcommand{\chapterbreak}{\clearpage}

\chapter{A chapter}
\chapter{Chapter two}

\end{document}

对于在改变类型的标题,我们最好使用\titleformat重定义它们(否则使用\titleclass定义类型时会报错),并且在重定义后,再重新指定标题类型。

编译结果中我们可以看第1页中是chapter1,第2页就是chapter2。关于标题的类型的定义,我们下面会再讲。其他的标题我们也可以这样去设置,这里不重复演示。

默认情况下,标题出现在页面的顶部时,我们定义在标题上方的垂直空间会消失。如果在某些布局中,我们不想让它消失,那么可以通过如下方式实现:

\newcommand\sectionbreak{\addpenalty{-300}\vspace*{0pt}}

\addpenalty{-300}命令将标题上方的断点指定为一个penalty值为-300的断点,后面跟着一个不能消失的长度为0的垂直空间。如果在此处断页,那么标题前面的空间也将出现在页面的顶部。

对于出现在新页面上的标题,我们可能需要特殊的样式; 例如,如果我们想让\chapter标题所在的页面不出现页眉和页码,就可以使用:

\assignpagestyle{\chapter}{empty}

如果我们不进行任何设置,那么默认情况下是plain,而不是empty。该命令对所有的toppage类标题都有效,我们也可以将其他标题设置成这样,只需要在该命令的前面先将要设置的标题的类型改成top或者page

带有前提条件的布局

到目前为止,我们已经知道的如何使用\titleformat\titlespacing为标题定义固定的布局。而titlesec还可以定义带条件的布局,例如我们可以为奇数页和偶数页生成不同的布局,可以为有编号标题和无编号的标题(星号形式的标题)生成不同的布局。

这是通过在\titleformat\titlespacing的第一个参数中使用键值对(keyword-value)来实现的。我们之前使用的语法形式\titleformat{\section}...实际上是一种缩写,它的完全形式是titleformat{name=\section}...。可用的键除了name,还有page,值为odd(奇数)或even(偶数),以及numberless,是否是无编号的标题,无编号则值为true,有编号则为false。

但是要注意,判断page页码奇偶的方式只对双页文档有效,单页文档不分左手页和右手页(注意book类默认是双页文档)。我们用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper,margin=1in]{geometry}
\usepackage{kantlipsum}
\usepackage{titlesec}
\begin{document}
\tableofcontents
\titleformat{name=\section,page=odd}[block]{\normalfont\bfseries}{\thesection.}{6pt}{\itshape\filleft}
% 使section标题在左手页居左,在右手页居右。
\titleformat{name=\section,page=even}[block]{\normalfont\bfseries}{\thesection.}{6pt}{\itshape\filright}

\chapter{A chapter}
\kant[1]
\kant[1]
\section{A Head}
\kant[1]
\kant[4]
\section{Another}
\kant[2]
\end{document}

编译:

在这里插入图片描述

这里要注意调整一下你用以预览PDF的软件,使用书籍视图预览,将第一页单独放在右边。这样才能保证后面的奇数页(右手页)都在右边。

我们用一个例子演示一下numberless的使用放式:

\documentclass{article}
\usepackage[a5paper,margin=1in]{geometry}
\usepackage{titlesec}
\begin{document}
\titleformat{name=\section}[block]{\normalfont\bfseries}{\thesection.}{6pt}{\filright}
% 上述定义作用于所有section标题
\titleformat{name=\section,numberless=true}[block]{\normalfont}{---}{12pt}{\itshape\filcenter}
% 上述定义仅作用于无编号的标题,遇到无编号的标题时,它会覆盖掉第一个定义

\section{A Head}
Some text to fill the page. Some text to fill the page.
\section*{Another}
Some text to fill this line.
\end{document}

编译:

在这里插入图片描述

不管是对于页码的判断还是对于编号的判断,如果我们不加判断,则定义会对所有指定的标题生效。而加了判断的定义,则会在遇到满足判断的标题时覆盖掉已有的定义。

改变标题的层级(类型)

前面我们知道使用\titleclass命令可以改变标题的类型,实际上这个命令有三种形式:

\titleclass{cmd}{class}
\titleclass{cmd}{class}[parent-level-cmd]
\titleclass{cmd}[start-level]{class} % 加载包时指定loadonly选项

标题的类别(class)也有三种,除了我们前面讲过的page类和top类,所有其他标题我们都用straight类表示。

我们前面的例子中演示过,使用第一种形式(不带任何选项)可以直接为某个标题指定类别:

\titleclass{\section}{top}

但是要注意,对于任何标题命令,在改变它的类型之前,最好使用\titleformat重定义它,否则很可能会报错。

第二种形式可以在parent-level-cmd标题的下插入一个新的标题层级,而原本比parent-level-cmd标题级别更低的所有标题均下降一个级别。例如:

\titleclass\subchapter{straight}[\chapter]  

\chapter\section之间插入一个新的标题\subchapter。但是这个声明没有为\subchapter标题定义任何布局,也没有定义它的计数器,设计它的编号等。这些都需要另外的工作来完成:

\titleformat{\subchapter}{..}...
\titlespacing{\subchapter}{..}...
\newcounter{subchapter}
\renewcommand\thesubchapter{\thechapter.\arabic{subchapter}}
\renewcommand\thesection{\thesubchapter.\arabic{section}}

标题编号的定义结构我们在004篇详细讲过,不熟悉的话可以回顾一下。这里直接用一个例子演示一下:

\documentclass{book}
\usepackage[a5paper,margin=1in]{geometry}
% \usepackage{kantlipsum}
\usepackage{titlesec}
\begin{document}
% 定义一个新的层级的命令\subchapter
\titleclass\subchapter{straight}[\chapter]
% 定义它的计数器
\newcounter{subchapter}
% 定义被\subchapter的编号
\renewcommand\thesubchapter{\thechapter.\arabic{subchapter}}
% 重定义\section的编号,使\subchapter嵌入其中
\renewcommand\thesection{\thesubchapter.\arabic{section}}
% 定义\subchapter标题的样式
\titleformat{\subchapter}[block]{\fontsize{20.74pt}{20.74pt}\bfseries}{\thesubchapter}{12pt}{\filright}
\titlespacing{\subchapter}{0pc}{*3}{*2}

\chapter{A chapter}
\subchapter{A subchapter}
\section{A section}
some text
\section{Another section}
some text
\end{document}

编译:

在这里插入图片描述

第三种形式几乎不会用到,只有在你想要从头开始构建标题结构时——例如,你想要设计一个全新的文档类,而这个类不是基于任何标准类时——才会用到这一形式。这种情况下,包不会解释现有的标题命令并提取它们的布局。然后就可以构建标题命令了,如下例所示:

\newcounter{Ahead}
\newcounter{Bhead}
\newcounter{Chead}
\renewcommand\theBhead{\theAhead-\arabic{Bhead}}
\renewcommand\theChead{\theBhead-\arabic{Chead}}
\titleformat{name=\Ahead}{..}...
\titlespacing{name=\Ahead}{..}...
\titleformat{name=\Bhead}{..}...
...

根据不同的文档类,起始级别(start-level)通常是0-1(若不熟悉回顾一下003篇),一个文档类中,应该恰好有一个标题的声明需要用到这个参数。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值