《LaTeX Notes》

1. TeX家族

第一章参考:网站

1.1 TeX - LaTeX

TeX 是高德纳(Donald Ervin Knuth,1938 年 1 月 10 日 -)教授愤世嫉俗(大雾;追求完美)做出来的排版引擎,同时也是该引擎使用的标记语言(Markup Lang)的名称。

所谓的引擎,是指能够实现断行、分页等操作的程序(请注意这并不是定义);

所谓的标记语言,是指一种将控制命令和文本结合起来的格式,它的主体是其中的文本而控制命令则实现一些特殊效果(同样请注意这并不是定义)。

而 LaTeX 则是 L. Lamport (1941 年 2 月 7 日 — ) 教授开发的基于 TeX 的排版系统。

实际上 LaTeX 利用 TeX 的控制命令,定义了许多新的控制命令并封装成一个可执行文件。

这个可执行文件会去解释 LaTeX 新定义的命令成为 TeX 的控制命令,并最终交由 TeX 引擎进行排版。

因此在 TeX - LaTeX 组合中:

  • 最终进行断行、分页等操作的,是 TeX 引擎;

  • LaTeX 实际上是一个工具,它将用户按照它的格式编写的文档解释成 TeX 引擎能理解的形式并交付给 TeX 引擎处理,再将最终结果返回给用户。

1.2 pdfTeX - pdfLaTeX

TeX 系统生成的文件是 dvi 格式,虽然可以用其他程序将其转换为例如 pdf 等更为常见的格式,但是毕竟不方便。

为了解决这个问题,Hàn Thế Thành 博士在他的博士论文中提出了 pdfTeX 这个对 TeX 引擎的扩展。

二者最主要的差别就是 pdfTeX 直接输出 pdf 格式文档,而 TeX 引擎则输出 dvi 格式的文档。

pdfLaTeX 这个程序的主要工作依旧是将 LaTeX 格式的文档进行解释,不过此次是将解释之后的结果交付给 pdfTeX 引擎处理。

1.3 XeTeX - XeLaTeX

高德纳教授在实现 TeX 的当初并没有考虑到中日韩等字符的处理,而只支持 ASCII 字符

ASCII 字符简单理解,就是在半角模式下你的键盘能直接输出的字符。

但是,这并不是说中日韩字符就无法使用 TeX 引擎排版。

事实上, TeX 将每个字符用一个框包括起来(这被称为盒子),然后将一个个的盒子按照一定规则排列起来,因而 TeX 的算法理论上适用于任何字符。

在 XeTeX 出现之前,为了能让 TeX 系统排版中文,国人曾使用了 天元、CCT、CJK 等手段处理中文。

其中 天元和 CCT 现在已经基本不用,CJK 因为使用时间长且效果相对较好,现在还有人使用。

不同于 CJK 等方式使用 TeX 和 pdfTeX 这两个不直接支持 Unicode 字符的引擎,XeTeX 引擎直接支持 Unicode 字符。

也就是说现在不使用 CJK 也能排版中日韩文的文档了,并且这种方式要比之前的方式更加优秀。

XeLaTeX 和 XeTeX 的关系与 pdfLaTeX 和 pdfTeX 的关系类似,这里不再赘述。

使用 XeTeX 引擎需要使用 UTF-8 编码。

1.4 CTeX - MiKTeX - TeX Live

之前介绍了 TeX, LaTeX, pdfTeX, pdfLaTeX, XeTeX, XeLaTeX, LuaTeX 等,他们都是 TeX 家族的一部分。

但是作为一个能够使用的 TeX 系统,仅仅有他们还是不够的。

CTeX, MiKTeX, TeX Live 都是被称为“发行”的软件合集。

他们包括了上述各种引擎的可执行程序,以及一些文档类、模板、字体文件、辅助程序等等。

其中 CTeX 是建立在 MiKTeX 的基础之上的。

2. 入门

2.1 Hello, World!

% hello_world.tex
\documentclass{article}
\begin{document}
Hello, World!
\end{document}

在TeXstudio编译后,文件夹里会自动生成pdf。

也可以手动在终端编译:xelatex hello_world生成pdf。.tex后缀可忽略。

2.2 语法和结构

语法

LaTeX源文件的语句分为3种:

  1. 命令command,又分为普通命令和环境environment

  2. 数据,即普通内容

  3. 注释comment,以%起始

普通命令以\起始,大多只有一行;环境包含配对的起始和结尾声明,一般是多行。二者可以互相嵌套。

回到原程序:

% hello_world.tex 注释
\documentclass{article} %普通命令
\begin{document} % 环境的起始声明
Hello, World! % 数据
\end{document} % 环境的结尾声明

物理结构

LaTeX文档的结构可以分为:

  1. 物理结构:源文件的组织形式,包括序言preamble和正文;

  2. 逻辑结构:最终输出文档的结构,包括标题、目录、章节等。

序言:用以完成一些设置,如指定文档类型,引入宏包,定义命令、环境等。

正文:文档的实际内容。

基本结构:

\documentclass[options]{class} % 文档类声明
\usepackage[options]{package} % 引入宏包
...
\begin{document} % 正文
...
\end{document}

常用的文档类documentclass有3种:

  1. article

  2. report

  3. book

基本选项有:

Note | LaTeX-LMLPHP

宏包的意义类似于include和import,引入除LaTeX核心基本功能外的其他丰富功能。

逻辑结构

基本结构如下:

\title{LaTeX Notes} % 标题
\author{Alpha Huang} % 作者
\data{\today} % 日期
\maketitle % 必须放最后

在3种常用文档类中,article和report可以有摘要,book没有。

摘要用法:

\begin{abstract}
...
\end{abstract}

LaTeX提供了7种层次结构,高级结构可以包含若干低级结构。

report和book支持所有层次,article不含chapter结构。

层次结构如下:

\part{...} % level -1
\chapter{...} % level 0
\section{...} % level 1
\subsection{...} % level 2
\subsubsection{..} % level 3
\paragraph{...} % level 4
\subparagraph{...} % level 5

我们也可以生成目录,还可以指定目录深度。

举例:

\seccounter{tocdepth}{2} % 设定深度2,即最多细化到subsection 注意该命令在前
\tableofcontents % 产生目录

初次使用目录,或层次结构发生变化时,需要执行两次编译,才能获得正确结果。

之所以这样设计,是因为当时内存不够,需要分布执行。

如果不想让特定的层次出现,我们可以加上星号再命令:

\chapter*{...} % level 0
\section*{...} % level 1
\subsection*{...} % level 2
\subsubsection*{..} % level 3

类似地,插图和表格的目录也可以生成:

\listoffigures
\listoftables

也需要编译两次。

2.3 文字

文档内容可以分为:

  1. 文本模式:缺省工作方式

  2. 数学模式:需要特殊命令或环境

字符输入

特殊字符输入,需要在前面加一个\

\# \$ \^ \& \_ \{ \} \~ \%

\本身要用以下方式:

\textbackslash

因为\\是换行符。

下面2表给出了特殊符号和预定义字符串,以及注音符号的输入方法:

Note | LaTeX-LMLPHP

其中\XeTeX, \XeLaTeX命令需要metalogo宏包,\MF, \MP命令需要mflogo宏包,\AmS命令需要texnames宏包。

更多符号参见:网站

LaTeX中由3种划线:

  1. 短划线hypen:用来连接单词
  2. 中划线en-dash:用来连接数字 重复2次短划线得到
  3. 长划线em-dash:中文破折号 重复3次短划线得到

重复1次短划线是数学减号,形似中划线。

字体样式和大小

拉丁文字体主要有3大类:

  1. 衬线字体roman, serif 类似于中文宋体等,边缘有修饰

  2. 无衬线字体sansserif 类似于中文黑体

  3. 等宽字体monospace, typewriter

字体:

  1. 粗体bold

  2. 半粗体medium weight

  3. 斜体italic

  4. 伪斜体oblique, slanted 仅倾斜不修饰,用于无衬线字体

  5. 小型大写字母small caps

Note | LaTeX-LMLPHP

字体强调命令:\emph

如果周围文字是正体,那么强调结果就是斜体;反之就是正体。

下划线命令:\underline

但它不能正确断字。

ulem宏包改进了断字,还增加了删除线、波浪号等功能。

Note | LaTeX-LMLPHP

但ulem宏包把\emph重定义为下划线。为此,我们可以改回去:

\usepackage[normalem]{ulem}

LaTeX会根据正文字体大小来调整:标题、章节、上下标、脚注等字号。

我们可以用下表命令来调整字体的相对尺寸:

Note | LaTeX-LMLPHP

比如,当使用\tiny命令时,若正文大小是10pt,则tiny字号就是5pt。

换行、换页和断字

LaTeX会自动换行。

我们可以用\\\newline命令强制换行,用\newpage命令来强制换页。

LaTeX也会自动断字hyphenate,使字间距分布均匀。

在英文文章的排版中,hyphenation是很重要的,特别是当行尾的单词很长的时候,如果不作断字,把单词都放在当前行就显得挤,新起一行就显得松。

有时我们需要指明断字位置。比如我们指明'BASIC'不能断开,而blarblar可以只可以断成blar-blar:

\hyphenation{BASIC, blar-blar}

2.4 长度

Note | LaTeX-LMLPHP

最后一列都是相对单位,

LaTeX定义了一系列宏变量,方便排版对象的尺寸和位置,特别是重复使用时非常方便:

\newlength{name} % 定义新变量
\setlength{name} % 设置变量值 \addtolength{name} % 增加变量的值

2.5 对齐和间距

段落对齐

段落缺省为两端对齐fully justified,以下3个环境可以让段落分别完成3种对齐:

Note | LaTeX-LMLPHP

此外还有3个命令:\raggedright, \centering, \raggedleft

缩进和段间距

正文中第一个段落,缺省不缩进首行。

我们可以用identfirst宏包,使第一段也缩进首行。

缩进距离和段落间距分别由\parindent\parskip变量控制:

\usepackage{identfirst}
...
\setlength{\parindent}{2em}
\addtolength{\parskip}{3pt}

行间距

行间距:段落中相邻两行基线之间的距离。

缺省使用单倍行距。

我们可以用\linespread命令来控制行距:

\linespread{1.3} % 一倍半行距
\linespread{1.6} % 两倍行距

注意,该命令不仅改正文行距,同时也会把目录、脚注、图表标题等行距统统改了。

如果只想改正文行距,可以用setspace宏包的行距命令:

\usepackage{setspace}
...
\singlespacing % 单倍行距
\onehalfspacing % 1.5倍行距
\doublespacing % 双倍行距
\setstretch{1.25} % 任意行距

如果想修改局部文字的行距,可以使用由该宏包提供的环境:

Note | LaTeX-LMLPHP

2.6 特殊段落

摘录

LaTeX中由3种摘录环境:

  1. quote:两端都缩进

  2. quotation:两端都缩进且首行缩进

  3. verse:两端都缩进且第二行起缩进

原文打印

文档中命令和源代码通常使用等宽字体,即原文打印。

正文中插入少量等宽文字,可采用 \verb命令;

大段原文打印,采用verbatim环境较好。其带星号版本可标出空格:

Note | LaTeX-LMLPHP

脚注

脚注可以使用\footnote命令。

如果要改变编号形式,可采取如图命令:

Note | LaTeX-LMLPHP

footnote是一种counter。

我们还会遇到其他计数器,它们都有同样的方法修改显示格式:

Note | LaTeX-LMLPHP

边注

P26.

注释

小段文字用百分号,大段文字用verbatim宏包的comment环境:

\begin{comment}
...
\end{comment}

2.7 列表

基本列表

LaTeX有3种基本列表:

Note | LaTeX-LMLPHP

其他列表

上述列表的缺省行间距较大,如果要节省空间,可以考虑paralist宏包:

Note | LaTeX-LMLPHP

定制列表

P29.

2.8 盒子

P29-P30.

2.9 交叉引用

我们可以设置一个标签,引用其编号或页码。例:

Note | LaTeX-LMLPHP

第一次编译会失败,第二次才成功。

3. 字体

字体有3个层次:

  1. 编码层,涉及字符集和字符编码。

  2. 格式层,如字形的定义描述方法和字体文件存储格式。

  3. 显示层。

之所以这么复杂,是因为TeX设计之初,编码、字符集和字体格式都很少。

本章内容参见P33-41。

4. 数学

为了使用AMS-LaTeX提供的数学功能,我们需要在文档的序言部分加载amsmath宏包:

\usepackage{amsmath}

4.1 数学模式

LaTeX的数学模式有2种:

  1. 行间inline:在正文中插入

  2. 独立display:独立排列,有或无编号

简单输入方法:

Note | LaTeX-LMLPHP

无编号独立公式建议用\[...\],因为$$...$$与AMS-LaTeX有冲突。

4.2 基本元素

希腊字母

Note | LaTeX-LMLPHP

注意,如果希腊字母是大写的,其命令首字母也是大写的。

上下标和根号

Note | LaTeX-LMLPHP

分数

命令是\frac

它会根据环境自动调整字号。比如在行间较小,在独立公式中较大。

可以使用\dfrac\tfrac命令,强制其字号同独立公式或行间公式:

Note | LaTeX-LMLPHP

运算符

\(+ - * / =\)等可以直接输入,其他的需要特殊命令:

Note | LaTeX-LMLPHP

Note | LaTeX-LMLPHP

其中\quad是空格。

这些符号的上下标在行间公式中会被压缩,以适应行高。

\limits\nolimits可以显式地压缩上下标,看例子。

更多的参见:网站

如果要追求完美,自己定义格式,那么可以这么操作:

Note | LaTeX-LMLPHP

对于多重积分,多个\int显然太宽了。

正确的方法是:\iint, \iiint, \idotsint等。

箭头

Note | LaTeX-LMLPHP

数学注音和标注

Note | LaTeX-LMLPHP

Note | LaTeX-LMLPHP

分隔符

Note | LaTeX-LMLPHP

其中,调整分隔符的方法是\big, \Big, \bigg等命令。

省略号

dots:位置较低的省略号,一般用于有下标的序列。

cdots:位置正常居中的省略号。

空白间距

Note | LaTeX-LMLPHP

4.3 矩阵

可以用array环境来生成矩阵。

它提供了外部对齐和列对齐控制参数。

外部对齐:整个矩阵和周围对象的纵向关系,有3种:

  1. 居中:缺省,c

  2. 居顶:t

  3. 居底:b

列对齐也是3种,分别是:

  1. 居中:c

  2. 居左:l

  3. 居右:r

&\\分别用来分隔行和列。

Note | LaTeX-LMLPHP

amsmath宏包的pmatrix, bmatrix, Bmatrix等环境,可以在矩阵两边加上各种分隔符,注意没有对齐方式参数:

Note | LaTeX-LMLPHP

最后的smallmatrix是行间矩阵。

4.4 多行公式

长公式

长公式就是一行写不下的公式,既可以不考虑对齐(multline环境):

Note | LaTeX-LMLPHP

也可以考虑对齐(split环境):

Note | LaTeX-LMLPHP

公式组

同理,既可以考虑对齐(gather环境),也可以考虑对齐(align环境):

Note | LaTeX-LMLPHP

带星号版本不生成编号。

分支公式

cases环境:

Note | LaTeX-LMLPHP

4.5 定理和证明

我们首先定义定理、定义等环境:

Note | LaTeX-LMLPHP

然后再使用这些环境:

Note | LaTeX-LMLPHP

4.6 数学字体

以下是常用数学字体:

Note | LaTeX-LMLPHP

\mathbb\mathfrak需要amsfonts宏包,\mathscr需要mathrsfs宏包。

5. 插图

5.1 图形概述

LaTeX支持点阵图像格式JPEG和PNG,也支持矢量格式EPS和PDF。

矢量图可以无限缩放而输出质量不变,并且所占空间较小。

对于示意图,我们应首选矢量格式;

对于包含大量自然色彩的图片(如照片),我们应首选JPEG;

人工点阵图像首选PNG。

有下面4种驱动:

  1. dvips:只支持EPS。

  2. pdflatex:支持JPEG,PNG和PDF,不支持EPS。

    LaTeX宏包:epstopdf和pst-pdf可以实时地将EPS转成PDF,但有bug,建议事先转成PDF。

  3. dvipdfm(x):dvipdfm也不支持EPS,但可以实时调用Ghostscipt将EPS转为PDF。dvipdfmx对图形格式的支持增强,并且支持BMP。

  4. xdvipdfmx:XeLaTeX的缺省驱动,基本都支持。

最常用的分辨率单位:像素/英寸pixels per inch, PPI。

比如,有一副\(100 \times 150\)像素的点阵图片,分辨率为100PPI。

在输出时,其缺省尺寸就是\(100/100 \quad in \times 150/100 \quad in\)。

如果强制输出为\(2in \times 3in\),那么实际分辨率就会降至50PPI。

当图形分辨率和输出分辨率不一致时,就涉及降采样和上采样。

插值算法中,Lanczos算法效果最好,但速度慢。

图形分辨率适可而止,太大体积也大。

对于屏幕阅读,72PPI即可;

考虑到放大,150PPI足够;

高质量打印,需要300PPI。

如果要在LaTeX文档中嵌入一幅图形,通栏情况下宽度为4.8-5.4in。

如果只是屏幕阅读,400px足够。

若要放大阅读或打印,分别需要800px和1600px。

5.2 插入图形

范围框

由于历史原因,LaTeX编译程序不能提取JPEG,PNG等点阵图形的尺寸信息。

因此,在处理它们时,引擎需要范围框bounding box

对于矢量图形,尺寸就没有太大意义了。

但对于EPS,有个缺省尺寸还是比较方便的,这就是它的范围框。

范围框格式:左上角坐标+右下角坐标,见下例。

有了范围框,LaTeX在编译源文件时,就只需要为插图预留空间:输出的.dvi只记录图形尺寸和文件名,而不记录具体图片:由驱动负责。

因此,没有范围框,LaTeX就会报错。

dvipdfm附带的ebb程序可以检查JPEG和PNG,生成范围框文件:同名.bb。

但用ebb生成范围框有个缺点:它懒得理会真正的分辨率,直接用100PPI计算。

基本命令

插图命令基本用法如下:

\usepackage[dvipdfm]{graphicx} % 宏包是graphicx,驱动是dvipdfm
\includegraphics[bb=0 0 300 200]{fig.png}

使用latex,pdflatex和xelatex时,缺省驱动分别是dvips,pdftex和xetex,因此可以不加该选项。

使用pdflatex和xelatex不要加范围框参数。

图形操作

\includegraphics命令有一些参数选项,用于缩放等操作:

Note | LaTeX-LMLPHP

说明:

  1. 若不设置任何尺寸参数,latex将按范围框处理,pdflatex按缺省输出尺寸处理。

  2. scale尽量不要用。

  3. XeTeX目前不支持裁剪。

Note | LaTeX-LMLPHP

Note | LaTeX-LMLPHP

文件名和路径

Note | LaTeX-LMLPHP

第一行指定后缀,让编译程序自行查找;

第二行指出后缀都是EPS;

后三行设置缺省搜索路径,分别是绝对、相对和多个路径。

路径不能有空格。

figure环境

figure环境可以调整插图的位置。

这种自动调整位置的环境,我们称之为浮动环境float

Note | LaTeX-LMLPHP

htbp就是插图的位置选项,分别代表:here, top, bottom, float page。

\centering是让插图居中,\caption用来设置标题。

一定要注意,\label应放在标题之后,否则引用的将是一个结构对象。

插入多幅图形

如果需要共享标题,那么我们要用到figure环境中的\includegraphics命令,并且用两次:

Note | LaTeX-LMLPHP

如果标题各异,那么就要在figure环境中使用两个minipage环境:

Note | LaTeX-LMLPHP

其中,\hspace调整两个minipage之间的距离。3个\centering中,第一个是让整体居中。

Note | LaTeX-LMLPHP

如果还需要共享一个大标题,那么就需要subfig宏包的\subfloat命令:

Note | LaTeX-LMLPHP

上面的问题是,子标题变成了多行。

原因在于\subfloat命令缺少宽度参数。

我们的办法是:在\subfloat中嵌套\minipage,后者可以设置宽度。

Note | LaTeX-LMLPHP

5.3 矢量绘图

参见P71-74。

6. 表格

6.1 简单表格

tabular环境提供了最简单的表格功能。

\hline命令表示横线,|表示竖线,l c r表示对齐方式:

Note | LaTeX-LMLPHP

与图形中的figure环境类似,表格也有常用的浮动环境:table。

其标题设置、交叉引用等也是类似的。

使用table,我们可以把表格变成三线表。

如果嫌三条横线一样粗不好看,我们可以用booktabs宏包中的\toprule\midrule\bottomrule来表示三条横线:

Note | LaTeX-LMLPHP

纵向缺省为居中对齐。

6.2 宽度控制

如果我们想控制列的宽度,只需要在对齐方式后加上列宽:

Note | LaTeX-LMLPHP

此时纵向对齐方式必须是居顶,内容缺省居左对齐。

我们可以用列前置命令:>{}配合\centering\raggedleft等,来实习居中或居右:

Note | LaTeX-LMLPHP

如要控制整个表格的宽度,则需要用tabularx宏包的同名环境。

6.3 跨行跨列

跨列直接用\multicolumn命令,跨特定列的横线用booktabs宏包的\cmidrule命令,如图:

Note | LaTeX-LMLPHP

跨行要使用multirow宏包的\multirow命令。语法相同。

6.4 数字表格

当表格中包含数字时,对齐小数点和数位是一件麻烦的事。

为此,我们可以使用warpcol宏包为tabular环境提供的对齐参数P:

Note | LaTeX-LMLPHP

2和5分别是小数点前、后的位数。负号可选。

\multicolumn是横跨单元命令。之所以用横跨,是为了保护表头,避免其被P误伤。

需要跨页的长表格、需要翻转的宽表格、彩色表格等,参见P113~。

7. 结构

7.1 长文档

如果一篇文档很长,我们可以分解其为多个文件,逐个编写。

下例示范了如何在主控文档中引用子文档:

Note | LaTeX-LMLPHP

注意,每一个文件都会新起一页。

如果不想新起,应该将\include改为\input

7.2 标题

Note | LaTeX-LMLPHP

注意第二章介绍的文档类控制选项:notitlepagetitlepage,可以控制标题是否独占一页。

缺省情况下,article文档类的标题和正文混居一页,其余二者都是独占。

7.3 目录

参见P122。

7.4 参考文献

Thebibliography

LaTeX中最原始的方法是:用thebibliography环境和\bibtem命令来定义参考文献。

Note | LaTeX-LMLPHP

例中9是编号的宽度。如果有几十个条目,可以改为99。

该环境一般用于末尾。在正文中,我们用\cite命令引用:

Note | LaTeX-LMLPHP

其他的引用效果,需要借助Natbib宏包。见参考教程10.4.3节。

BibTeX

上述方法的问题是:用户要自己调整显示格式,这样做容易出错还很麻烦。

为此,我们可以用数据库文件:.bib记录参考文献条目,用样式文件.bst设置显示格式。普通用户一般不需要改动样式文件。

这样做继承了LaTeX内容与格式分离的思想。

每种类型的参考文献有不同的选项,参见P125。

如图就是上例的.bib数据:

Note | LaTeX-LMLPHP

编辑.bib文件可以用普通的文本编辑器,但最好用文献管理网站(如Google Scholar)直接输出。

下图是4种基本样式:

Note | LaTeX-LMLPHP

在使用时,我们先选定样式,再输出:

Note | LaTeX-LMLPHP

含参考文献的文档需要执行4次编译操作,流程见P127。

其余内容不再赘述。

8. 布局

在LaTeX中,每一个排版对象都是一个盒子。

页面是最大的盒子。

排版,就是要把小盒子,用空白间距粘在一起,然后放到大盒子里。

依次嵌套。

怎么优化这些大小盒子呢?

8.1 页面尺寸

关于A B C的来历很有趣,参见P133。

Note | LaTeX-LMLPHP

Note | LaTeX-LMLPHP

8.2 分栏

支持双栏的选项:

\documentclass[twocolumn]{article}
05-11 16:26