避免 \chapter 命令分页

LaTeX 的 book 类中,\chapter 命令用来标记章节。在生成的 PDF 文稿中,\chapter 总是另起一页;在打开(默认)openright 选项的时候,可能还会空白一页。在实际使用过程中,很多人希望 \chapter 不要换页,紧接着当前页的内容排版。

传统工具没有提供此功能,因此用户需要自行修改 \chapter 的定义。

找到 \chapter 的定义

LaTeX 标准文档类的定义写在 classes.pdf 这个文档中,你可以在命令行下使用 texdoc classes 来打开这份文档。

你可以在文档的 7.2.6 节中找到 \chapter 的定义。和我们的问题相关的,就是 \chapter 定义的第一行。

`\chapter` 的定义

得益于 文学编程,我们看到文档中明确地写着「章节总是应该从新的一页开始,因此我们需要调用 \clearpage」。

显然,为了达到目的,我么只需要令 \chapter 定义的第一行失效就好了。

打补丁

xpatch 宏包可以用来打补丁。它的 \xpatchcmd 命令接受五个参数:\xpatchcmd{命令}{搜索}{替换}{成功}{失败}

  • 命令:待处理的命令
  • 搜索:需要被替换的部分
  • 替换:将被替换的内容
  • 成功:替换成功执行的内容
  • 失败:替换失败执行的内容

这里我们需要将 \if@openright\cleardoublepage\else\clearpage\fi 替换掉。用于替换的内容则是:\par\relax。因此我们有代码:

1
2
3
4
5
6
\usepackage{xpatch}
\makeatletter
\xpatchcmd{\chapter}
{\if@openright\cleardoublepage\else\clearpage\fi}{\par\relax}
{}{}
\makeatother

注意,符号 @ 是一个保留符号。它在用户编写 .tex 文档的时候和开发者编写宏包/文档类的时候具有不同含义。我们用 \makeatletter@ 的含义切换到开发者模式;在进行修改之后,用 \makeatother@ 的含义切换到用户模式。

这样,\chapter 定义中的换行部分,就被替换成了分段。

完整的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
\documentclass{book}
\usepackage{xpatch}
\makeatletter
\xpatchcmd{\chapter}
{\if@openright\cleardoublepage\else\clearpage\fi}{\par\relax}
{}{}
\makeatother
\usepackage{blindtext}
\begin{document}
\blindtext
\chapter{test}
\end{document}

您的鼓励是我写作最大的动力

俗话说,投资效率是最好的投资。 如果您感觉我的文章质量不错,读后收获很大,预计能为您提高 10% 的工作效率,不妨小额捐助我一下,让我有动力继续写出更多好文章。


撰写评论

写了这么多年博客,收到的优秀评论少之又少。在这个属于 SNS 的时代也并不缺少向作者反馈的渠道。因此,如果你希望撰写评论,请发邮件至我的邮箱并注明文章标题,我会挑选对读者有价值的评论附加到文章末尾。