付费栏目万字解析

「万字解析」是体验少数派付费栏目内容的最佳方式。我们希望用一万字的篇幅,系统、深度地分享有价值的内容,让少数派读者可以享受获得新知的愉悦。

本期「万字解析」内容选自《生产力超频:LaTeX 学术写作实用手册》。《LaTeX 学术写作实用手册》面向 LaTeX 零基础的读者,栏目内容将分为六步,逐步带你掌握完整的 LaTeX 工作流程。

📍前往了解栏目

 

对于经历过(或即将经历)毕业论文撰写的大家来说,一般在学校官网提供的 Word 模板附近,我们可能有发现过一个名为 LaTeX 的东西,和 Word 模板并列供给我们下载。如果我们投稿过期刊、会议,可能也注意到有的出版商会同时提供 Word 和 LaTeX 两套模板,供我们使用。

国际著名计算机视觉会议 CVPR 在其 Author Kit 压缩包里会同时提供 LaTeX 和 Word 两个模板

优秀、专业的排版工具 LaTeX,已经成为当今世界上学术与专业技术文档印刷排版的「de facto」系统。无论是一篇文章、一章教程,还是一整部专业图书,LaTeX 都能够为我们排版出美观一致的文字作品。

诸多著名期刊、出版商的官方 LaTeX 模板(来自 Overleaf - Templates)

但不得不承认的是,LaTeX 本身上手门槛跟 Word 相比还是高了不少。以「代码」为基础的 LaTeX 让很大一部分曾经只用过 Word,从未接触过 LaTeX 的大家望而却步。如果抱着对 Word 的使用经验去使用 LaTeX,会碰到不少问题:

  • 什么是「环境」?为什么我用 LaTeX 写一篇论文还需要「编译」?
  • 一个简单的纯文本文件是怎样像 Word 一样进行排版的?
  • ......

而作为作为全平台都能使用的免费排版系统,LaTeX 虽然上手感受起来可能比较陌生,但是熟练掌握之后,能让你今后的论文写作、文本编排任务简单不少,让你轻松写出一致精美的排版作品。如果因为有一些上手难度就敬而远之,那就太可惜了。

在本篇「万字解析」中,我们将从感性和理性两个维度解析 LaTeX 的使用逻辑,来帮助大家真正理解 LaTeX 的排版思想。在之后的学习中,可以快速掌握 LaTeX 的使用方法和技巧,迅猛地用 LaTeX 排版论文著作。

感性认识:从 Markdown 的视角看 LaTeX

LaTeX 到底有何特别,为什么有那么多听上去像编程一样的概念?

我们从大家熟知的 Markdown 开始,带领各位读者熟悉 LaTeX 中所需要了解的概念与逻辑。其实,当我们将 Markdown 跟 LaTeX 对比起来看的时候,会发现二者之间确实有些异曲同工之妙。

相信大家对 Markdown 以及其工作流程早就不陌生了:

  1. 我们仅需要创建一个 .md 为后缀的「文本文件」;
  2. 用我们最喜欢的「Markdown 编辑器」打开;
  3. 依照已经写了不知多少遍的「Markdown 语法」来撰写文字、拟定格式;
  4. 「导出」一份清晰规整的文章。

如果各位对 Markdown 不太了解,可以用这两篇文章简单熟悉一下:Markdown 完全入门(上)Markdown 完全入门(下)

文本文件、语法、渲染、导出……这些步骤和描述,在 Markdown 的世界中已经是稀松平常的概念。而这些通用的概念,在 LaTeX 的使用过程中是一样能够适用的!

当我们并排着来看 Markdown 和 LaTeX 的工作流的时候

我们看看上面图中所画的工作流,不难发现:

  • Markdown 中以 .md 为后缀的「文本文件」,在 LaTeX 中就是 .tex 文件;
  • Markdown 中的「格式」语法,LaTeX 也有一套自己的定义;
  • Markdown 需要编辑器支持来将其「预览」或「导出」,而 LaTeX 同样也需要这样的步骤来将其「渲染」;
  • 当我们编写 LaTeX 文档的时候,和用 Markdown 写文章的界面是几乎一样的。
LaTeX 和 Markdown 的编写界面非常相似

因此,LaTeX 的工作流程,实际上和 Markdown 如出一辙!

理解了 Markdown 排版的逻辑,自然能将 LaTeX 用的得心应手 —— 这也是本系列教程希望大家最后能达成的效果。

文本文件 & 语法

和 Markdown 一样,LaTeX 在本质上也是一门用于排版的「语言」或「语法规则」。我们也同样是:以纯文本文件为基础,用这样的一套拟定好的标记语法来设定文字的格式。只是,LaTeX 的语法规则比 Markdown 要多得多得多,功能性也要超过 Markdown 很多:

Markdown 是通过尽量少的语法格式,来让文章的撰写者能专注于内容本身的编写,这也让 Markdown 仅拥有有限的格式支持(当然,Markdown 本身也并不是复杂排版需求而设计的)。

而 LaTeX 则更为复杂、强大:作为专业的排版系统,LaTeX 能够通过它完备的语言语法来支持「任何」格式的排版生成。

渲染 & 导出

同样的,从标记语法组成的纯文本文件,到正式导出的排版文件,LaTeX 和 Markdown 的工作流程也是一致的:它们都需要经过一个转换的过程。Markdown 相对简单,这一过程几乎是瞬间、无感的,大部分我们常用的 Markdown 编辑器也集成了预览、导出。

但 LaTeX 的语法规则和功能特性都更为复杂,因此转换所需的时间也相对较长 —— 在 LaTeX 中我们称这个用于转换的工具为「编译引擎」。

总之,当我们在用 LaTeX 撰写、导出文档时,实际上是借助编译引擎,将我们编写的 LaTeX 文本文件,转换、渲染为美观一致的文档(一般是 PDF 文件)。其中,文档的格式是由 LaTeX 模板设计决定的,我们后面会详细介绍。

而文档的一致性,则由我们这里所说的编译引擎负责,保证同一份 LaTeX 文档,在世界上任何地方、任何系统、任何平台,都能输出完全相同的 PDF 文件。

同 Markdown 一样,这份「一致性」也是 LaTeX 较 Word 等传统富文本排版工具的优势所在。

如果你有足够多使用 Word 的经历,一定会体验过「同一份 Word 文档,在不同地方打开就变得不同」这样的魔幻现实主义色彩的经历。

—— Markdown 完全入门(上)

安装 LaTeX

如此,我相信各位读者已经对 LaTeX 的工作过程有了全新的认识。如下面的流程图所示,从一份遵照 LaTeX 语法撰写的文本文件开始,LaTeX 的编译引擎会根据模板格式设定,将我们需要的 PDF 格式的文档精确导出 —— 这就是最基础的 LaTeX 工作流程。

选择编写工具

在正式开始使用 LaTeX 之前,我们需要解决工具的问题——安装 LaTeX,即选择合适的编译引擎和编辑器。

我们常说的「安装 LaTeX」,很大程度其实就是在本地安装 LaTeX 的编译引擎。根据操作系统的不同,我们安装不同的 LaTeX 系统(在 LaTeX 中称之为「发行版」)。其包括三大平台通用的 TeX Live,专为 macOS 开发的 MacTeX,以及广泛用于 Windows 平台的 MikTeX 等。

至于编辑器的选择,任何文本编辑器都可以编辑 LaTeX 文本文件,但是就像编写代码一样,合适的 LaTeX 编辑器可以大大提升你的 LaTeX 撰写体验。常用的 LaTeX 编辑器包括全平台通用的:TeXstudioTeXworks,以及为 macOS 开发的 TeXShopTexifier(付费) 等。常见的用于编写代码的编辑器,比如 VS Code 和 Vim,配合合适的 LaTeX 插件,一样可以用来编写 LaTeX 文档 —— 这也是我个人比较偏好的选择;

但在 2023 年的实践中,为了避免大家需要花时间在本地安装这么多冗杂的软件,推荐各位使用在线 LaTeX 编写平台(也可以理解为云编辑器+编译器)。

在线 LaTeX 编写平台的选择很多,我们推荐使用 Overleaf:不仅支持开箱即用的 LaTeX 编辑体验,Overleaf 同时还提供了海量的模板和素材库,以及基础的 LaTeX 教程,并还支持多人协作和部分期刊会议的直接投稿选项,可谓极为方便了。此外,国内的 TeXPage 平台也是一个非常优秀的替代。

至此,我们就已经全面的对 LaTeX 的概念有了初步认识。下面我们正式开始,用 Overleaf 作为我们编辑 LaTeX 的工具,以一个常用的 LaTeX 模板为例子,对 LaTeX 的「标记语法」规则进行简单的介绍。相信经过后面的讲解,你可以轻而易举的把一个设计好的 LaTeX 模板转变为自己的论文报告。

对中文字符支持的提示

作为中文用户,使用 Overleaf 前需要完成一个操作,使 Overleaf 可以正常渲染中文字符。

LaTeX 在默认情况下的编译引擎,仅支持编写普通英语字符。为了能够撰写中文,我们需要进行一项额外的配置,也就是 —— 将 LaTeX 的编译引擎更换为 XeLaTeX。在 Overleaf 中,我们只需要在编辑页面打开 Menu,并找到 Settings 中的 Compiler 进行更换即可。

在 Overleaf 编辑页面,点击左上 Menu,出现侧边栏找到 Settings > Compiler 并更换为 XeLaTeX,即可支持中文字符和 UTF-8 符号。

理性认识:LaTeX 文档里到底有什么?

我们了解完文本文件、语法、渲染这些宏观层面的概念,大致能明白 LaTeX 是如何工作的。但是对于一份 LaTeX 文档,依然缺乏微观层面的认识:

  • LaTeX 如何给文字加粗?
  • LaTeX 如何插入图片和表格?
  • LaTeX 如何调整图文混排的效果?

在 Word 中,这些问题都有直观而明确的答案,而在 LaTeX 中亦是如此,只不过实现的方式与 Word 这类富文本编辑器完全不同。

为了一致的叙述,我们一起使用 Overleaf 上的一份 LaTeX 模板作为样例:Style and Template for Preprints (arXiv, bio-arXiv) 。这个模板是参考 NeurIPS 国际会议模板的样式进行简化和小幅修改得到的,常用于期刊会议论文预印本的编辑(比如向 arXiv 等预印本数据库提交的预印版论文)。

以 NeurIPS 会议模板为基础的论文 LaTeX 模板

在 Overleaf 模板页面里,直接点击「Open as Template」即可在 Overleaf 中以项目开启。

我们将从这一模板的 template.tex 文件开始编辑(默认是直接在 Overleaf 编辑器中打开的)。其中,中间的箭头用来左右同步代码和 PDF 的位置,绿色 Recompile 按钮用于更新(编译)你新编辑的内容。左上角的 Menu 里面有更多设置选项,比如 LaTeX 主文件、编译器选择等,我们可以暂时不用修改。

模板在 Overleaf 中打开的样子

环境和格式

在回答上文提到的问题前,我们首先需要熟悉这样的一个概念:「环境」。

在 LaTeX 中,不同的「内容」往往以「块」为基本单位,组织合为一部完整的文档。用 Markdown 的概念来说,LaTeX 的「环境」类似于「代码块」或「数学公式块」的概念,也就是 Markdown 文档里分别以 ```$$ 为开头和结尾包裹起来的部分。

Markdown 和 LaTeX 中的数学公式「环境」

在 LaTeX 中,一个「环境」往往就是一个使用 \begin{xxx}\end{xxx} 来包裹某一部分文字块,用来定义某种特殊格式或设置某些文字性质(其中 xxx 表示环境名称)

此时,「环境」内的文字内容会以另外的方式进行处理渲染,从而呈现不同于默认情况下的格式、形态。我们称呼 \begin\end 为「宏命令」,是用于在 LaTeX 中表示实现特殊指令的「标识语言」。

格式这一概念在 LaTeX 中可能包含不同的隐藏含义。在使用 LaTeX 编写文字的时候,我们首先需要转换一下思路:我们是文档「内容」的编写者,在这一阶段不负责文档本身「格式」的编排。对于「格式」来说,我们可以根据从文档的角度,将其划分为:

  • 文档本身的格式:页眉、页脚、页码、页边距等;
  • 文档某一段落的格式:段落行距、段落缩进等;
  • 在正文中穿插的部分文字的格式:粗体、斜体、下划线等;

LaTeX 则是专门为这样的文字撰写场景设计的:编写者仅需在此专注「内容」本身的撰写,毋需担心文档「格式」的设计。而对于某段落的「段落格式」、正文内部的部分文字的「行内格式」,比如这里提到的字体加粗、下划线、段落对齐等,则是我们「内容」编写者不需要考虑的。这也是使用 LaTeX 在撰写文档时,和 Word 的编辑思路与理念大相径庭的地方。

以粗体这个「行内格式」为例,Markdown 中粗体是使用 ** 来包裹加粗的内容。与之对应,LaTeX 使用 \textbf{xxx} 的命令,在 xxx 处填入粗体内容。类似的用法还有:

  • 斜体:\textit\emph(是强调 emphasize 的缩写)
  • 下划线:\underline
加粗、斜体、下划线等「行内格式」的设定

这两个概念或者命令,是 LaTeX 中最为基础的两种用于设定格式、实现功能的特殊「标识语言」。

一部「文档」的组成

了解了「环境」的概念,就能进一步理解一部 LaTeX 文档是怎么构成的。

熟悉 LaTeX 的使用从对一部「文档」的鸟瞰开始。在撰写任何形式的文档时,我们都会为我们的编写思路形成某种形式的大纲,以理清行文思路。在剥离冗余信息之后,一个基本的 LaTeX 文档会有像下面这样的文档 Document、章节 Section、段落 Paragraph 等基本的组成部分的定义。

首先是 Document —— LaTeX 称呼一部「文档」为 document,任何文档都以 document 的关键词标签「包裹」起来,在其内部填入正文等内容。还记得「环境」吗?这里的 document 实际上就是 LaTeX 最底部的一个「环境」。我们使用 \begin{document}\end{document} 来包裹整个文档正文,用于标志 LaTeX 文档中需要渲染的全部内容。

回到我们的模板。我们从文档的开头,也就是被 document 标签包裹起来的范围之外的部分开始。模板在第一行定义了 document 的形式(即 documentclass 命令),比如这里模板定义了文档为「文章」:article。之后,我们需要稍微往下翻动,才会看到正文开始 \begin{document},并在文件末尾看到正文结束 \end{document}。而实际上,抛开其他内容,我们的模板就是这样的一个非常简单的结构:

\documentclass{article}  % --> 定义文档的形式 documentclass
...                      % --> 非正文(另有他用)
\begin{document}         % --> document 的开始
...                      % --> 这里是被 document 标签包裹的正文
\end{document}           % --> document 的结束

我们 document 环境以外的部分有另外的功能需要,这些内容稍后介绍。我们继续着眼于模板的正文环境中的内容。

之后,是 Section —— 一篇「文档」可以按照大纲结构划分为多个「章节」,这在 LaTeX 中使用 \section 进行定义。中文语境下一般称利用 \section 定义的部分为「小节」(为了和下文的「大型章节」进行区分)。我们使用\section 定义小节的「标题」。

模板中定义的 \section 与对应渲染出 PDF 的位置

LaTeX 中至多支持三级标题,与之对应的分别为 \section\subsection\subsubsection。通常情况下,LaTeX 并不建议你继续向下进行章节分级,否则会导致相对混乱的行文。

注意:在大型项目,比如书籍、论文中,LaTeX 也支持 chapter 的大型章节定义。

最后,是 Paragraph —— 位于小节内的即为正文的各个「段落」,也就是我们所书写的具体内容了。这里没有额外的命令需要我们使用,不同的段落之间使用「空行」分割。LaTeX 即可自动将段落内容进行排版,设置好相应的缩进、间距等,无需我们进一步的担心。我们按照自己的行文思路分段空行书写正文即可。(模板中使用了「宏命令」,即 \lipsum 废话生成器,生成段落文字,我们后面介绍。)

不过,对于段落的开始,LaTeX 支持名为 \paragraph 的命令,能够输出一种 LaTeX 文档中比较常见的格式。模板中有这样的一个 paragraph:

模板中定义的 \paragraph 与对应渲染出 PDF 的位置

可以看到,这里的段落以 \paragraph{xxx} 开头,就像小节标题一样位于自然段之前。在学术文档中这一格式的使用相对更为广泛,比如同一个小节下,多个不同内容主题的自然段的并列排版。

下图是使用此模板编辑一个真实论文段落的例子,可以看到其中三个「主题不同的段落」位于「同一小节」下,使用 \paragraph 并列排版。

使用 \paragraph 并列多个带有标题的小段落

如果之前没有使用过 LaTeX,这一格式还算比较新颖,希望大家能灵活使用于合适的场景下。

另外,虽然推荐大家直接使用「空行」分段,但是如果段落之间没有空行,使用 \par 命令也可以让 LaTeX 知道在哪里分段。比如下面的渲染中,圈出来的分段则是在段落内使用 \par 实现的:

使用 \par 在无空行情况下手动分段

环境:理解 LaTeX 的关键概念

正如前文所说,「环境」是 LaTeX 不同于所有富文本编辑器的关键概念。可以说,正是「环境」的强大与灵活,造就了 LaTeX 的强大与灵活。

因此,我们将用图片与表格这两个最为常见的文档元素,来带领大家深入理解「环境」的奥秘。

图片

插图是学术文章中不可缺少的部分,我们在这里介绍如何在 LaTeX 中插入、排版文章图片。

图片文件夹

在 LaTeX 中插入图片或是其他文件,和我们与 Word 直接拖拽或者粘贴进入有很大的区别。

Word 文档,也就是我们所说的 .docx 文件,实际上是一个容器,包含了我们文档中所使用的所有图片等资源;而 LaTeX 项目主文件的 .tex ,就如之前文章中所述一样,仅是一个纯文本文件。

因此我们需要手动在项目文件夹中,创建一个专门放置图片的文件夹,比如 images,用于存放图片等资源,并通过「相对路径」的格式插入正文。这一点实际上和我们在 Markdown 中的处理方式是一致的。

在项目文件夹下创建名为 images 的文件夹用于存放图片

插入图片的简单方式

我们继续用大家熟悉的 Markdown 为基础,来介绍插入图片的流程。

在 Markdown 中,对于 images/kde_ridgeplot.png 这个图片,我们可以使用如下的语句插入正文:

![kde_ridgeplot](images/kde_ridgeplot.png)

而在 LaTeX 中,首先,我们需要在 LaTeX 文档开头的\begin{document} 上方,添加一句话(我们所使用的 Overleaf 模板中已经有这句话了,不需要手动再次添加):

\usepackage{graphicx}

在 LaTeX 中,我们把\begin{document} 上方的部分,称之为你的文档的 preamble,也即是「前言」。

我们会在这里定义非正文中渲染的内容,而我们加入的这句话:\usepackage,实际上就是字面意思 —— 「使用宏包」,来引入额外的功能、特性、插件或环境。这里,为了能够插入图片,我们需要引用 graphicx 宏包。所有的「宏包」都位于 CTAN 上,安装 LaTeX 发行版的时候实际上就已经安装了宏包,一些比如 MikTeX 会根据你文档中的使用,按需下载宏包,而像比如 TeX Live,则在完整安装中已经将全部可用宏包都下载安装到你的设备上。而在 Overleaf 上无需提前安装,我们直接引用即可。

之后,我们在 LaTeX 中同样,也是利用类似的一句命令,来把图片插入正文之中:

\includegraphics[]{images/kde_ridgeplot.png}

将命令写到我们 Overleaf 模板中,会看到如此的渲染效果:

images/kde_ridgeplot.png 插入 LaTeX 正文中的效果

可以发现,LaTeX 直接按照图片的原有尺寸,将图片完整地插入了正文之中。而实际上,我们可能会想要将图片的尺寸、长宽、缩放按照合适的大小进行排版,这也就是我们命令中 [] 里面所需要设定的内容。比如,我们可以用:

\includegraphics[width=8cm, height=6cm]{images/kde_ridgeplot.png}

将图片宽度 width 设置为 8 厘米,高度 height 设置为 6cm。

或者,我们也可以用:

\includegraphics[width=0.5\linewidth]{images/kde_ridgeplot.png}

将图片的宽度设置为一行文字宽度 \linewidth 的一半(×0.5),此时图片高度会自动按比例适配。

我们可以发现这样的特点:

\includegraphics 命令的中括号中,我们可以设置一些图片的参数属性。

在中括号中我们设置的均为图片的宽度 width 和高度 height,前者直接设置了一个绝对的度量值(8 厘米、6 厘米),而后者是根据图片周围正文的宽度变量设定了一个相对的度量(文字宽度的一半)。这两种设置是我们在 LaTeX 中最为常见的度量设定形式。

除了我们这里使用到的 \linewidth 之外,我们还有文档宽度 \textwidth 和正文栏宽度 \columnwidth 等常见度量变量可以使用(比如在双栏模板中可能会使用到)。

但是,我们也会遇到一些问题:图片的位置我们不能随意的排列;我们无法直接让图片居中或靠在最上面;我们也不能给图片添加说明文字。这些都是论文排版中非常重要的功能,而单靠 \includegraphics 命令是无法完成的。

此时,我们需要使用一个独立的「环境」,也就是 figure 环境,来包裹图片,用于设定我们此处需要的排版格式。

通过图片环境完成配图

还记得上一篇文章中我们提到的「环境」吗?对,就是我们所说的「块」—— 我们将需要设定的特殊格式包裹其中,成为一个独立的格式区域,用于比如在这里设定图片的排版样式。

我们会把图片本身、图片的说明文字、图片的引用标签(也就是我们在论文中常见到的图 x、图 x.x 等样式的交叉引用)等,全部包裹在一个环境之中,像这样(Overleaf 中可以用 \figure... 自动补全这个环境):

\begin{figure}
    \centering
    \includegraphics[width=0.5\linewidth]{images/kde_ridgeplot.png}
    \caption{KDE ridge plot}
    \label{fig:kde_ridgeplot}
\end{figure}

此时我们会得到这样的效果:

使用 figure 环境将图片、说明文字、交叉引用标签插入 LaTeX 文档

环境中包含四行内容:

  • \centering:设定图片和下面的说明文字居中对齐,如果不使用的话默认情况会左对齐;
  • \includegraphics:插入图片素材路径,定义大小等,和上一段落介绍的一致;
  • \caption:图片的说明文字,居中显示于图片下方;
  • \label:图片标签,用于交叉引用,可以在正文中用同样的标签引用图片,比如:\ref{fig:kde_ridgeplot}(Overleaf 上保存编译后,此标签可以自动补全)。

通常,我们最最常用的就是此环境以及这四行命令设置,用于论文图片的 LaTeX 排版。

另外,注意到我在下面正文中交叉引用的 \ref 命令和 Figure 文字之间,会添加一个波浪线 ~,这是用于保证 Figure 文字和引用标签之间有「空格」渲染。这一习惯我们会在之后的文章中的交叉引用部分详细介绍。

设定位置的参数

虽然图片、说明、交叉引用都设定好了,但是我们此时会发现图片被 LaTeX 直接排版到页面的最上面了。我们需要对 figure 环境用一个额外的参数,来设定图片插入的位置。在 \begin{figure} 后面,我们依旧使用中括号 [] 设定额外参数,像这样:

\begin{figure}[h]
% ...

这里的 h 表示 here —— 也就是将图片放在 LaTeX 正文所应该放的位置。如果我们这样设置,那么图片会按照正文段落的顺序插入其中:

使用参数 h 来将图片按行文顺序插入正文

除了 h 之外,tbp 以及 !H 都可以作为参数,设定不同的位置:

参数位置
hhere —— 尽量按照行文顺序放在这里(如果地方足够的话)
ttop —— 尽量放在页面顶部
bbottom —— 尽量放在页面底部
ppage —— 安排单独页面放置图片
!就要在这里!不论 LaTeX 觉得图片放置位置美观与否

为什么位置参数不一定有效?

其中,大家可能注意到:我使用「尽量」这个形容词,来描述 LaTeX 对图片位置的排版。

事实上,在 LaTeX 中,图片、表格等这类环境是被称之为浮动块(也就是 float此类环境都是用这样的语法,为 LaTeX 描述其偏好位置。但正因为此环境是「浮动」环境,所以 LaTeX 往往仅会尽其努力参考,而非完全依照我们设定的位置参数而设定环境的位置。如果 LaTeX 觉得「图片、表格排版在这里位置不够或者并不美观」,那么 LaTeX 往往会忽略我们这里的参数设置,按照其认为美观的排版方式放置「浮动块」。

这一特性,导致了位置参数不一定有效。有时你希望图片放在页面底部,因此使用b这一参数,但 LaTeX 的渲染引擎还是会将它放在下一页的顶部。

这一排版思想可能大家感觉稍微陌生,其他排版引擎往往也不会这样「推荐」或「强制」我们排版模块的位置。但是,LaTeX 会!对于浮动块,LaTeX 会按照引擎认为的更美观、更适合阅读的形式,安排文中的图片、表格等模块和正文文字的排列格式关系。

正是因为这一特点,对于图片来说,我们往往只是需要保证图片大小合适、位置大致恰当,LaTeX 则会自动排列我们插入正文的图片位置,保证文章的整体阅读体验。上面表中提到的五个参数,也可以互相组合(比如 hbpt!h 等),LaTeX 会按照从前到后的顺序依次尝试我们设定的位置偏好,寻找最为合适的位置放置图片。

不过,毕竟我们自己是文档的主人,如果我们真的觉得 LaTeX 排版的不合适,也可以引入宏包:\usepackage{float},并使用参数 H 来让图片「就放在我要放的地方」。

虽说存在这种方法,但我们依旧建议大家尽量按照 LaTeX 设计的排版来,用 th(最常用的两种,其中 t 是因为习惯上论文会将一个页面的全部图片都排版于顶端)设置图片位置,由 LaTeX 决定具体位置。

表格

为了学习表格环境,我们直接来到我们一直在用的 Overleaf 模板末尾,在文档结束部分就有一个表格的例子,它使用了 table 的环境,渲染了一个简单的表格:

模板中的表格样式

事实上,LaTeX 的世界中,出现了诸多宏包,都是为了更美观的渲染一个表格,而这些都是因为,默认情况下 LaTeX 提供的表格渲染并没有那么美观。如果我们直接用默认的 LaTeX 表格功能插入一个表格(下图中上方的表格样式),对比使用第三方宏包 booktabs 的样式渲染的表格(下图里下方的表格),我们可以明显看出原始表格样式的粗糙。

使用默认样式渲染的表格(上)和使用 booktabs 宏包渲染的表格(下)

由于绘制表格的宏包选择实在太多,在这里直接为大家介绍我认为在 LaTeX 中最好、最美观的插入表格的方法:借助 booktabs 宏包渲染表格。

使用 booktabs 编写简单表格

和插入图片时一样,我们需要在文档前言中插入使用宏包的命名:

\usepackage{booktabs}

其次,表格也有自己的「环境」,即前面提到的 table 环境。我们会先创建一个 table 环境,然后在 table 环境中编辑我们的表格内容,像这样:

\begin{table}
    \caption{Table title}
    \centering
    % ...
    \label{tab:table}
\end{table}

环境中有这样的几行内容:

  • \caption 表格的说明文字:放在表格的上方;
  • \centering 居中显示:放在表格环境内部;
  • % ...:这部分会插入表格的具体内容,一般为 tabular 环境,下文介绍;
  • \label 表格的标签:用来在正文中交叉引用;

是不是看起来比较眼熟?确实是这样的,表格环境 table 和图片环境 figure 的大体构造是类似的。都包含了说明文字 caption、标签 label、用来居中显示的 centering,并在环境中加入具体的内容。

使用tabular 编写表格内容

对于表格来说,具体的内容会再使用一个环境编写,即 tabular 环境。

我们用之前模板中表格样例的简化版本为例子,也就是:

NameDescriptionSize
DendriteInput terminal~100
AxonOutput terminal~10
SomaCell bodyup to 10^6

上面这个表格的内容,在 tabular 环境中,我们需要这样编写:

\begin{tabular}{lll}
    \toprule
    Name     & Description     & Size           \\
    \midrule
    Dendrite & Input terminal  & \(\sim\)100    \\
    Axon     & Output terminal & \(\sim\)10     \\
    Soma     & Cell body       & up to \(10^6\) \\
    \bottomrule
\end{tabular}

同样,我们一行一行的来看看这个环境是如何编写的:

  1. 首先第一行的 \begin{tabular} 后面有一个 {lll},这里表示的是表格的三列,每一列用一个字母来代表,其中字母 l 表示 left,即「左对齐」。相应的rc 就分别表示 right 和 center,即「右对齐」和「居中显示」;
  2. 第 2、4 和 8 行,我们可以看到 \toprule\midrule\bottomrule 这三个宏命令,分别用来渲染表格的顶端框线、内部框线和底部框线 —— 正是这三个命令,才让 booktabs 宏包能够帮我们渲染出美观表格(区别于默认 \hline 命令);
  3. 剩下在中间的部分,就是表格的具体内容。其中 \toprule\midrule 中间一行是表头,\midrule\bottomrule 里面几行是表格内容。每一行中:单元格和单元格之间用 & 隔开,并在每行最后用 \\ 表示在此换行;

这里还有一个值得注意的地方:当我们用 {lll} 表示表格三列都左对齐的时候,我们其实也可以在每个 l 之间加上 |,即 {l|l|l},来把列和列之间加上竖框线。

但是,我以及 booktabs 的作者都不建议大家这样做!因为这会给表格带来不必要的冗余和不美观。

You will not go far wrong if you remember two simple guidelines at all times:

1. Never, ever use vertical rules.(永远,永远!也不要用竖框线。)

2. Never use double rules.(永远不要用双框线。)

—— booktabs 宏包文档原文

对比下面的两个表格,非常明显,位于下面没有竖线并使用 booktabs 渲染的表格不仅更为清爽,而且易于阅读:

默认表格带有竖线(上)v.s. 使用 booktabs 编辑无竖线表格(下)| 来自:Better LaTeX Tables with Booktabs

另外,大家可能也注意到表格左右会有一点空间,我们可以在 {lll} 左右加上 @{},也就是:{@{}lll@{}},来把文字顶格排列。

最后,将编写好的表格内容,放入 table 环境中:

\begin{table}
    \caption{Table title}
    \centering
      \begin{tabular}{lll}
        \toprule
        Name     & Description     & Size           \\
        \midrule
        Dendrite & Input terminal  & \(\sim\)100    \\
        Axon     & Output terminal & \(\sim\)10     \\
        Soma     & Cell body       & up to \(10^6\) \\
        \bottomrule
			\end{tabular}
    \label{tab:table}
\end{table}

复杂的表格功能

「合并单元格」这个功能,一直以来都是许多只有简单表格工具(比如 Markdown)所欠缺的功能。在 LaTeX 中,我们是可以借助 \multicolumn\multirow 等命令实现这种复杂功能的。

\multicolumn —— 让我们先回到上面的表格样例。我们其实有注意到原模板中将表头的 Name 和 Description 上方放置了一个大单元格:Part,这就是我们这里介绍的「合并同一行上的单元格」。

在表格中,我们在 \toprule 上框线和 Name... 内容行中间,可以用 \multicolumn{}{}{} 这个命令,来插入一个横跨两个格子的区域,放置文字 Part,像这样:

% ...
\toprule
\multicolumn{2}{c}{Part}                     \\
\cmidrule{1-2}
Name     & Description     & Size (\(\mu\)m) \\
% ...

可以发现,这里 \multicolumn 命令后面有三个 {},也就是三个参数的设定位置。其中,第一个 {2} 表示我们的区域横跨两列单元格,第二个 {c} 表示我们区域内的内容要「居中」显示(同理,左对齐就用 {l}、右对齐就用 {r}),而最后一个 {Part} 就是我们的具体内容了。非常清晰!

下面的 \cmidrule 则是为了渲染下面的框线的命令。当我们合并单元格时,往往不能直接用一整行的框线(即 \midrule),而是需要将框线断开。比如我们这里,仅第一个和第二个格子里面,也就是我们合并的区域下面,才添加框线。这就是后面 {1-2} 参数所代表的内容:中间框线从第一个格子到第二个格子。

\multirow —— 相应的,我们会使用 \multirow 来「合并同一列上的单元格」。这一命令需要我们引入宏包:\usepackage{multirow}。我们继续用上面的表格为例子,比如当我们想要给表格左侧添加这样的一列:

由于添加了新的一列,我们首先需要在 tabular 环境那里再加一列 {llll} 用来表示表格的四列。之后我们需要在每一行前加上 & ,用来表示每一行内容都往右侧移动了一格。最后我们可以在 Dendrite 一行前加上 \multirow[c]{2}{*}{Terminal} ,用来把这两个单元格合并,最终 tabular 环境的内容是这样的:

\begin{tabular}{llll}
    \toprule
                                 & Name     & Description     & Size (\(\mu\)m) \\
    \midrule
    \multirow[c]{2}{*}{Terminal} & Dendrite & Input terminal  & \(\sim\)100   \\
                                 & Axon     & Output terminal & \(\sim\)10    \\
    \midrule
    Body                         & Soma     & Cell body       & up to \(10^6\) \\
    \bottomrule
\end{tabular}

详细解释一下,在 \multirow 命令中:

  • 第一个 [c] 表示我们要居中显示内容(相应的用 [t][b] 分别表示上对齐 top 和下对齐 bottom);
  • 第二个 {2} 表示我们的区域竖向跨越两个格子;
  • 第三个 {*} 用于写入格子区域的宽度,这里我们用 * 表示按照内部文字宽度编排这一区域,我们还可以用 = 表示按照外部列的原宽度编排我们区域的宽度,或者也可以直接写入一个具体的度量(比如 3cm 等);
  • 最后 {} 中填入格子的具体内容即可。

可视化生成表格内容

尽管在功能性上 LaTeX 的表格绘制无可指责,但是用文本排版表格内容的方式实在太「反人性」了。所幸鉴于 LaTeX 的名气和传播度,有不少网站提供了可视化生成表格内容的工具。

这里我推荐 Create LaTeX tables online – TablesGenerator.com,它可以帮助我们快速在线编辑 LaTeX 表格,并选用 booktabs 生成格式,直接生成可以复制粘贴的 LaTeX 表格代码。

有了这个网站的辅助,在 LaTeX 中插入表格不再是让人头疼的事了!

其他表格环境

 booktabs是非常好用好上手的表格环境,能满足绝大多数表格的需求。但对于某些特殊表格,这里额外再介绍两个特殊的表格环境(均可以同 booktabs 一起使用),以应对不时之需。

longtable 环境 —— 这一环境是用来插入较长的「跨页表格」的,不需要放置在 table 环境中,直接插入正文即可。详细参考 longtable 的文档

tabularx 环境 —— 这一环境是 tabular 环境的扩展,能够帮我们自动匹配页面宽度,渲染占据整个页宽的表格,我们需要直接替换 tabular 环境为这个 tabularx 环境来使用,并将比如表明表格中列居中的 {c} 更改为 {>{\centering\arraybackslash}X}。详细参考 tabularx 的文档

表格的位置同样也是用上一小节中图片的「设定位置」部分介绍的语法来设置的,在 \begin{table} 后面加上比如 [h] 即可让表格在「此处」显示。表格位置同样也是 LaTeX 系统在根据我们 [] 里面设定的顺序,来决定具体将表格放在哪里的。因此,和图片一样,我们一般情况并不需要担心具体表格位置,让 LaTeX 帮我们设计即可。

写在最后

事实上,到这里可能你也已经发现了,LaTeX 就像一门编程语言一样,用来描述我们的文档规则、编写我们的文档内容。引用「包」、使用「宏指令」、编写格式「环境」等等。这些实际上都是在用严格的、精确的、计算机能够看懂的语言,来描述我们的文档,以渲染生成一致的、可复现的美观文档。

相比于 Word 等以图形化界面为核心的文字排版工具来说,LaTeX 的精确、严谨和可重复,让使用它的我们能够着眼于自己心中的内容表达,而不在格式排版的淤泥中浪费时间。这即是为什么 LaTeX 在学术、专业领域如此受欢迎的重要原因。

而通过介绍「图片」和「表格」的 LaTeX 环境概念和语法,我们不仅介绍了基础的插入图片、排版表格的语法规范,还为大家扩展延伸了具体使用时候的注意事项,以及涉及到特殊情况或者非常具体的场景下的一些约定俗成的处理方法。

LaTeX 的种种环境,正是让 LaTeX 严格但标准的语法规则大放异彩的所在。不同的 LaTeX 环境相互搭建连接,才能组成我们最终的 LaTeX 论文书籍。

这篇文章可能不能带你完全入门 LaTeX 的世界,但是希望能帮助你初步理解 LaTeX 这一专业、强大的排版工具。和我们之前听说的不一样,LaTeX 并不因历史久远而老旧,不因功能复杂而难用。

恰恰相反,LaTeX 是一款实用、强大的工具!