首页 产品价格 LaTeX 模板
3. 文档元素

3. 文档元素 #

在知道了如何输入文字后,我们将在本章了解一个结构化的文档所依赖的各种元素——章节、目录、列表、图表、交叉引用、脚注等等。

3.1 章节和目录 #

3.1.1 章节标题 #

一篇结构化的、条理清晰文档一定是层次分明的,通过不同的命令分割为章、节、小节。三个标准文档类 article、report 和 book 提供了划分章节的命令:

\chapter{title}

\section{title}

\subsection{title} 

\subsection{title}

\paragraph{title}

\subparagraph{title}

其中 \chapter 只在 book 和 report 文档类有定义。这些命令生成章节标题,并能够自动编号。除此之外 LaTeX 还提供了 \part 命令,用来将整个文档分割为大的分块,但不影响 \chapter\section 等的编号。

上述命令除了生成带编号的标题之外,还向目录中添加条目,并影响页眉页脚的内容(详见 5.4 节)。每个命令有两种变体:

  • 带可选参数的变体: \section[short title]{title} 标题使用 {title} 参数,在目录和页眉页脚中使用 {short title} 参数;
  • 带星号的变体: \section\*{title} 标题不带编号,也不生成目录项和页眉页脚。

较低层次如 \paragraph\subparagraph 即使不用带星号的变体,生成的标题默认也不带编号,事实上,除 \part 外:

  • article 文档类带编号的层级为 \section \subsection \subsubsection 三级;
  • report/book 文档类带编号的层级为 \chapter \section \subsection 三级。

对此的详细解释和调整方法见 8.3.3 小节。

LaTeX 及标准文档类并未提供为 \section 等章节命令定制格式的功能,这一功能由 titlesec 宏包提供。详情请参考宏包的帮助文档。

3.1.2 目录 #

在LaTeX中生成目录非常容易,只需要在合适的地方使用命令:

\tableofcontents

这个命令会生成单独的一章 (book / report) 或一节 (article),标题默认为 “Contents”,可通过 8.4 节给出的方法定制标题。\tableofcontents 生成的章节默认不写入目录 \section*\chapter*,可使用 tocbibind 等宏包修改设置。

正确生成目录项,一般需要编译两次源代码。

有时我们使用了 \chapter*\section* 这样不生成目录项的章节标题命令,而又想手动生成该章节的目录项,可以在标题命令后面使用:

\addcontentsline{toc}{level}{title}

其中 {level} 为章节层次 chapter 或 section 等,{title} 为出现于目录项的章节标题。 titletoc、tocloft 等宏包提供了具体定制目录项格式的功能,详情请参照宏包的帮助文档。

3.1.3 文档结构的划分 #

所有标准文档类都提供了一个 \appendix 命令将正文和附录分开,使用 \appendix 后,最高一级章节改为使用拉丁字母编号,从 A 开始。

book 文档类还提供了前言、正文、后记结构的划分命令:

\frontmatter 前言部分,页码为小写罗马字母格式;其后的 \chapter 不编号。

\mainmatter 正文部分,页码为阿拉伯数字格式,从 1 开始计数;其后的章节编号正常。

\backmatter 后记部分,页码格式不变,继续正常计数;其后的 \chapter 不编号。

以上三个命令还可和 \appendix 命令结合,生成前言、正文、附录、后记四部分文档。源代码 3.1 结合 1.6 节的 \include 命令和其它一些命令示意了一份完整的文档结构。

3.2 标题页 #

LaTeX 支持生成简单的标题页。首先需要给定标题和作者等信息:

\title{title}

\author{author}

\date{date}

其中前两个命令是必须的(不用 \title 会报错;不用 \author 会警告),\date 命令可选。LaTeX 还提供了一个 \today 命令自动生成当前日期,\date 默认使用 \today。在 \title\author 等命令内可以使用 \thanks 命令生成标题页的脚注,用 \and 隔开多个人名。

在信息给定后,就可以使用 \maketitle 命令生成一个简单的标题页了。源代码 3.2 给出了一个标题页的示例和大致效果。article 文档类的标题默认不单独成页,而 report 和 book 默认单独成页。可在 \documentclass 命令调用文档类时指定 titlepage / notitlepage 选项以修改默认的行为。

LaTeX 标准类还提供了一个简单的 titlepage 环境,生成不带页眉页脚的一页。用户可以在这个环境中使用各种排版元素自由发挥,生成自定义的标题页以替代 \maketitle 命令。甚至可以利用 titlepage 环境重新定义 \maketitle

\documentclase[…]{book}

% 导言区,加载宏包和各项设置,包括参考文献、索引等

\usepackage{…}

\usepackage{makeidx}

\makeindex

\bibliographystyle{…}



\begin{document}

\frontmatter

\maketitle % 标题页

\include{preface} % 前言章节 preface.tex

\tableofcontents

\mainmatter

\include{chapter1} % 第一章 chapter1.tex

\include{chapter2} % 第二章 chapter2.tex


\appendix

\include{appendixA} % 附录 A appendixA.tex


\backmatter

\include{prologue} % 后记 prologue.tex

\bibliography{…}   % 利用 BibTeX 工具生成参考文献

\printindex        % 利用 makeindex 工具生成索引

\end{document}

源代码3.1:book 文档类的文档结构示例。

\title{Test title}

\author{ Mary\thanks{E-mail:*****@***.com}

    \and Ted \thanks{Corresponding author}

    \and Louis}

\date{\today}

源代码 3.2:LaTeX 默认的标题页示例和效果。

\renewcommand{\maketitle}{
  \begin{titlepage}
% 用户自定义命令
  \end{titlepage}
}

事实上,为标准文档类指定了 titlepage 选项以后,使用 \maketitle 命令生成的标题页就是一个 titlepage 环境。

以上是 LaTeX 标准文档类的标题页相关命令用法。在各种文档模版中经常有自定义的标题页,有可能需要除了 \title\author 以外的命令给定信息,用法也可能与标准类文档的不一致(甚至有些模板可能没有定义titlepage等环境)。

使用文档模板前一定要仔细阅读文档模板的帮助文档

3.3 交叉引用 #

交叉引用是 LaTeX 强大的自动排版功能的体现之一。在能够被交叉引用的地方,如章节、公示、图表、定理等位置使用 \label 命令:

\label{label-name}

之后可以在别处使用 \ref\pageref 命令,分别生成交叉引用的编号和页码:

\ref{label-name}

\pageref{label-name}

为了生成正确的交叉引用,一般也需要多次编译源代码。

\label 命令可用于记录各种类型的交叉引用,使用位置分别为:

章节标题 在章节标题命令 \section 等之后紧接着使用。

行间公式 单行公式在公式内任意位置使用;多行公式在每一行公式的任意位置使用。

有序列表 在 enumerate 环境的每个 \item 命令之后、下一个 \item 命令之前任意位置使用。

图表标题 在图表标题命令 \caption 之后紧接着使用。

定理环境 在定理环境内部任意位置使用。

在使用不记编号的命令形式 (\section*\caption*、带可选参数的 \item 命令等)时不要使用 \label 命令,否则生成的引用编号不正确。

3.4 脚注和边注 #

使用 \fotnote 命令可以在页面底部生成一个脚注:

\footnote{footnote}

假如我们输入以下文字和命令:

“天地玄黄,宇宙洪荒。日月盈昃,辰宿列张。” \footnote {出自《千字文》。}

在正文中则为:“天地玄黄,宇宙洪荒。日月盈昃,辰宿列张。1

有些情况下(比如在表格环境、各种盒子内)使用 \footnote 并不能正确生成脚注。我们可以分两步进行,先使用 \footnotemark 为脚注计数,再在合适的位置用 \footnotetext 生成脚注。比如:

\begin{tabular}{1}

\hline 

“天地玄黄,宇宙洪荒。日月盈昃,辰宿列张" \footnotemark\\

\hline

\end{tabular}

\footnotetext{表格里的名句出自《千字文》。}

效果为:

使用 \marginpar 命令可在边栏位置生成边注:

marginpar[left-margin]{right-margin}

如果只给定了 {right-margin} ,那么边注在奇偶数页文字相同;如果同时给定了 {left-margin} ,则偶数页使用 {left-margin} 的文字。

例如以下代码:

\marginpar{\footnotesize 边注较窄,不要写过多文字,最好设置较小的字号。}

其效果见边栏。

3.5 特殊环境 #

3.5.1 列表 #

Latex 提供了基本的有序和无序环境列表 enumerate 和 itemize, 两者的用法很类似,都用 \item 标明每个列表项。 enumerate 环境会自动对列表项编号。

\begin{enumerate}

\item
\end{enumerate}

其中 \item 可带一个可选参数,将有序列表的计数或者无序列表的符号替换成自定义的符号。列表可以嵌套使用,最多嵌套四层。

\begin{enumerate}
    \item An item.
    \begin{enumerate}
        \item A nested item. \lable{itref}
        \item[*] A starred item.
    \end{enumerate}
    \item Reference(\ref{itref}).
\end{enumerate}

\begin{itemize}
    \item An item.
    \begin{itemize}
        \item A nested item.
        \item[+] A ‘plus’ item.
        \item Another item.
    \end{itemize}
    \item Go back to upper level.
\end{itenize}

关键词环境 description 的用法与以上两者类似,不同的是 \item 后的可选参数用来写关键词,以粗体显示,一般是必填的:

\begin{description}

\item[<*item title*>]
\end{description}
\begin{description}
    \item{Enumerate} Numbered list.
    \item{Itemize} Non-numbered list.
\end{description}

各级无序列表的符号由命令 \labelitemi\labelitemiv 定义,可以简单地重新定义它们:

\renewcommand{\labelitemi}{\ddag}
\renewcommand{\labelitemii}{\dag}
\begin{itemize}
    \item First item
    \begin{itemize}
        \item Subitem
        \item Subitem
    \end{itemize}
    \item Second item
\end{itemize}

有序列表的符号由命令 \labelenumi\labelenumiv 定义,重新定义这些命令需要用到 8.3 节的计数器相关命令:

\renewcommand{\labelenumi}
    {\Alph{enumi}>}
\begin{enumerate}
    \item First item
    \item Second item
\end{enumerate}

默认的列表间距比较宽,LaTeX 本身也未提供方便的定制功能,可用 enumitem 宏包定制各种列表间距。 enumitem 宏包还提供了对列表标签、引用等的定制。有兴趣的读者可参考其帮助文档。

3.5.2 对齐环境 #

center、flushleft 和 flushright 环境分别用于生成居中、左对齐和右对齐的文本环境。

\begin{center}… \end{center}

\begin{flushleft}… \end{flushleft}

\begin{flushright}… \end{flushright}
\begin{center}
  Centered text using a
  \verb|center| environment.
\end{center}

\begin{flushleft}
  Left-aligned text using a
  \verb|flushleft| environment.
\end{flushleft}

\begin{flushright}
  Right-aligned text using a
  \verb|flushright| environment.
\end{flushright}

除此之外,还可以用以下命令直接改变字体的对齐方式:

\centering \raggedright \raggedleft
\centering
Centered text paragraph.

\raggedright
Left-aligned text paragraph.

\raggedleft
Right-aligned text paragraph.

三个命令和对应的环境经常被误用,有直接用所谓 \flushleft 命令或者 raggedright 环境的,都是不甚严格的用法(即使它们可能有效)。有一点可以将两者区分开来:center 等环境会在上下文产生一个额外间距,而 \centering 等命令不产生,只是改变对齐方式。比如在浮动体环境 table 或 figure 内实现居中对齐,用 \centering 命令即可,没必要再用 center 环境。

3.5.3 引用环境 #

LaTeX 提供了两种引用环境: quoto 用于引用较短的文字,首行不缩进; quotation 用于引用若干段文字,首行缩进。引用环境较一般文字有额外的左右缩进。

Francis Bacon says:
\begin{quote}
  Knowledge is power.
\end{quote}

《木兰诗》:
\begin{quotation}
万里赴戎机,关山度若飞。
朔气传金柝,寒光照铁衣。
将军百战死,壮士十年归。

归来见天子,天子坐明堂。
策勋十二转,赏赐千百强。……
\end{quotation}

verse 用于排版诗歌,与 quotation 恰好相反, verse 是首行悬挂缩进的。

Rabindranath Tagore's short poem:
\begin{verse}
Beauty is turth's smile
when she beholds her own face in
a perfect mirror.
\end{verse}

3.5.4 摘要环境 #

摘要环境 abstract 默认只在标准文档类中的 article 和 report 文档类可用,一般用于紧跟 \maketitle 命令之后介绍文档的摘要。如果文档类指定了 titlepage 选项,则单独成页;反之,单栏排版时相当于一个居中的小标题加一个 quotation 环境,双栏排版时相当于 \section* 定义的一节。

3.5.5 代码环境 #

有时我们需要将一段代码原样转义输出,这就要用到代码环境 verbatim, 它以等宽字体排版代码,回车和空格也分别起到换行和空位的作用;带星号的版本更进一步将空格现实成。

\begin{verbatim}
#include <iostream>
int main()
{
    std::cout << "Hello, world!"
              << std::end1;
    return 0;
}
\end{verbatim}

\begin{verbatim*}
for (int i=0; i<4; ++i)
    printf("Number %d\n",i);
\end{verbatim*}

要排版简短的代码或关键词,可使用 \verb 命令

\verb{delim}{code}{delim}

{delim} 标明代码的分界位置,前后必须一致,除字母、空格或星号外,可任意选择使得不与代码本身冲突,习惯上使用|符号。

同 verbatim 环境,\verb 后也可以带一个星号,以显示空格:

\verb|\LaTeX|\\
\verb+(a || b)+ \verb*+(a || b)+

\verb 命令对符号的处理比较复杂,一般不能用在其他命令的参数里,否则多半会出错。

verbatim 宏包优化了 verbatim 环境的内部命令,并提供了 \verbatimiput 命令用来直接读入文件生成代码环境。 fancyvrb 宏包提供了可定制格式的 Verbatim 环境;listings 宏包更进一步,可生成关键字高亮的代码环境,支持各种程序设计语言的语法和关键字。详情请参考各自的帮助文档。

3.6 表格 #

LaTeX 里排版表格不如 Word 等所见即所得的工具简便和自由,不过对于不太复杂的表格来讲,完全能够胜任。

排版表格最基本的 tabular 环境用法为:

\begin{tabular}{column-spec}
{item1} & {item2} & … \\
\hline
{item1} & {item2} & … \\
\end{tabular}

其中 {column-spec} 是列格式标记,在接下来的内容将仔细介绍;& 用来分隔单元格;\ 用来换行; \hline 用来在行与行之间绘制横线。

直接使用 tabular 环境的话,会和周围的文字混搭。 tabular 环境可带一个可选参数控制垂直对齐(默认是垂直居中);

\begin{tabular}{|c|}
    center-\\ aligned \\
\end{tabular},
\begin{tabular}{t}{|c|}
    top-\\ aligned \\
\end{tabular},
\begin{tabular}{b}{|c|}
    bottom-\\ aligned \\
\end{tabular} tabulars.

但是通常情况下我们不这么用,tabular 环境一般会放置在 table 浮动体环境中,并用 \caption 命令加标题。

3.6.1 列格式 #

tabular 环境使用 {column-spec} 参数指定表格的列数以及每列的格式。基本的列格式见表 3.1

\begin{tabular}{1cr|p{6em}}
    \hline
    left & center & right
         & par box with fixed width\\
    L    & C      & R     & P \\
    \hline
\end{tabular}

表格中每行的单元格数目不能多于列格式里 1/c/r/p 的总数(可以少于这个数),否则出错。

@格式可在单元格前后插入任意的文本,但同时它也消除了单元格前后额外添加的间距。@格式可以适当使用以充当“竖线”。特别地,@{} 可直接用来消除单元格前后的间距:

\begin{tabular}{@{} r@{:}lr @{}}
    \hline
    1  & 1 & one \\
    11 & 3 & eleven \\
    \hline
\end{tabular}

另外 LaTeX 还提供了简便的将格式参数重复的写法 *{n}{column-spec},比如以下两种写法是等效的:

\begin{tabular}{|c|c|c|c|c|p{4em}|p{4em}|}
\begin{tabular}{|*{5}{c|}*{2}{p{4em}|}}

有时需要为整列修饰格式,比如整列改变为粗体,如果每个单元都加上 \bfseries 命令会比较麻烦。 array 宏包提供了辅助格式 > 和 <,用于给格式前后加上修饰命令:

\begin{tabular}{>{\itshape}r<{*}1}
    \hline
    italic & normal \\
    column & column \\
    \hline
\end{tabular}

辅助格式甚至支持插入 \centering 等命令改变 p 列格式的对齐方式,一般还要加额外的命令 \arraybackslash 以免出错:

\begin{tabular}
{>{\centering\arraybackslash}p{9em}}
    \hline
    Some center-aligned long text. \\
    \hline
\end{tabular}

array 宏包还提供了类似 p 格式的 m 格式和 b 格式,三者分别在垂直方向上靠顶端对齐、居中以及底端对齐。

\newcommand\tet
    {a b c d e f g h i }
\begin{tabular}{cp{2em}m{2em}b{2em}}
    \hline
    pos & \tet & \tet & \tet \\
    \hline
\end{tabular}

3.6.2 列宽 #

在控制列宽方面, LaTeX 表格有着明显的不足:1/c/r 格式的列宽是由文字内容的自然宽度决定的,而 p 格式给定了列宽却不好控制对齐(可用 array 宏包的辅助格式),更何况列与列之间通常还有间距,所以直接生成给定总宽度的表格并不容易。

LaTeX 本身提供了 tabular* 环境用来排版定宽表格,但是不太方便使用,比如要用到 @ 格式插入额外命令,令单元格之间的间距为 \fill,但即使这样仍然有瑕疵:

\begin{tabular*}{14em}%
{@{\extracolsep{\fill}}|c|c|c|c}
    \hline
    A & B & C & D \\ \hline
    a & b & c & d \\ \hline
\end{tabular*}

tabularx 宏包为我们提供了方便的解决方案。它引入了一个 x 列格式,类似 p 列格式,不过会根据表格宽度自动计算列宽,多个 x 列格式平均分配列宽。X 列格式也可以用 array 里的辅助格式修饰对齐方式:

\begin{tabular}{14em}%
{|*{4}{>{\centering\arraybackslash}X|}}
    \hline
    A & B & C & D \\ \hline
    a & b & c & d \\ \hline
\end{tabularx}

3.6.3 横线 #

我们已经在之前的例子见过许多次绘制表格线的 \hline 命令。另外 \cline-{i-j} 用来绘制跨越部分单元格的横线:

\begin{tabular}{|c|c|c}
    \hline
    4 & 9 & 2 \\ \cline{2-3}
    3 & 5 & 7 \\ \cline{1-1}
    8 & 1 & 6 \\ \hline
\end{tabular}

在科技论文排版中广泛应用的表格形式是三线表,形式干净简明。三线表由 booktabs 宏包支持,它提供了 \toprule\midrule\bottomrule 命令用以排版三线表的三条线,以及和 \cline 对应的 \cmidrule。除此之外,最好不要用其他横线以及竖线:

\being{tabular}{cccc}
    \toprule
    & \multicolumn{3}{c}{Numbers} \\
    \cmidrule{2-4}
             & 1 & 2 & 3 \\
    \midrule
    Alphabet & A & B & C \\
    Roman    & I & II& III \\
    \bottomrule
\end{tabular}

3.6.4 合并单元格 #

LaTeX 是一行一行排版表格的,横向合并单元格较为容易,由 \multicolumn 命令实现;

\multicolumn{n}{column-spec}{item}

其中 {n} 为要合并的列数,{column-spec} 为合并单元格后的列格式,只允许出现一个 1/c/r 或 p 格式。如果合并前的单元格前后带表格线 |,合并后的列格式也要带|以使得表格的竖线一致。

\begin{tabular}{|c|c|c|}
    \hline
    1 & 2 & Center \\ \hline
    \multicolumn{2}{|c|}{3} &
    \multicolumn{1}{r|}{Right} \\ \hline
    4 & \multicolumn{2}{c|}{C} \\ \hline
\end{tabular}

上面的例子还体现了,形如 \multicolumn{1}{column-spec}{item} 的命令可以用来修改某一个单元格的列格式

纵向合并单元格需要用到 multirow 宏包提供的 \multirow 命令:

\multirow{n}{width}{item}

{width} 为合并单元格的宽度,可以填 * 以使用自然宽度。

我们看一个结合 \cline\muticolumn\multirow 命令的例子:

\begin{tabular}{ccc}
    \hline
    \multirow{2}{*}{Item} &
        \multicolumn{2}{c}{Value} \\
    \cline{2-3}
        & First & Second \\ \hline
    A & 1     & 2 \\ \hline
\end{tabular}

3.6.5 嵌套表格 #

相对于合并单元格,拆分单元格对于 LaTeX 来说并非易事。在单元格中嵌套一个小表格可以起到“拆分单元格”的效果。在以下的例子中,注意要用 \multicolumn 命令配合 @{} 格式把单元格的额外边距去掉,使得嵌套的表格线能和外层的表格线正确相连:

\begin{tabular}{|c|c|c|}
    \hline
    a & b & c \\ \hline
    a & \multicolumn{1}{@{}c@{}|}
    {\begin{tabular}{c|c}
        e & f \\ \hline
        e & f \\
        \end{tabular}}
            & c \\ \hline
    a & b & c \\ \hline
    \end{tabular}

如果不需要为“拆分的单元格”画线,并且只在垂直方向“拆分”的话,makecell 宏包提供的 \makecell 命令是一个简单的解决方案:

\begin{tabular}{|c|c|}
    \hline
    a & \makecell{d1 \\ d2} \\
    \hline
    b & c \\
    \hline
\end{tabular}

3.6.6 行距控制 #

LaTeX 生成的表格看起来通常比较紧凑。修改参数 \arraystretch 可以得到行距更加宽松的表格(相关命令参考 8.1.1 小节):

\renewcommand\arraystretch{1.8}
\begin{tabular}{|c|}
    \hline
    Really loose \\ \hline
    tabular rows.\\ \hline
\end{tabular}

另一种增加间距的办法是给换行命令 \ 添加可选参数,在这一行下面加额外的间距,适合用于在行距下不加横线的表格:

\begin{tabular}{c}
    \hline
    Head lines \\[6pt]
    tabular lines \\
    tabular lines \\ \hline
\end{tabular} 

但是这种换行方式的存在导致了一个缺陷——表格的首个单元格不能直接使用中括号 [],否则 \ 往往会将下一行的中括号当作自己的可选参数,因而出错。如果要使用中括号,应当放在花括号 {} 里面。或者也可以选择将换行命令写成 \ [0pt]。

3.7 图片 #

LaTeX 本身不支持插图功能,需要由 graphicx 宏包辅助支持。

使用 latex + dvipdfmx 编译命令时,调用 graphicx 宏包时要指定 dxipdfmx 选项;而使用 pdflatex 或 xelatex 命令编译时不需要。

读者可能听说过 “ LaTeX 只能插入 .eps 格式的图片,需要把 .jpg 转换成 .eps 格式” 的观点。 LaTeX 发展到今天,这个观点早已过时。事实上不同的编译命令支持的图片格式范围各异,见表 3.2 。这个表格也能解决诸如 “为什么 .eps 格式图片在 pdflatex 编译命令下出错” 之类的问题。本表格也再一次说明,使用 xelatex 命令是笔者最推荐的方式。

注:在较新的 TEX 发行版中,latex + dvipdfmx 和 pdflatex 命令可不依赖宏包,支持原来需要宏包扩展的图片格式(但 pdflatex 命令仍不支持除 .jpg 和 .png 以外的位图)。

在调用了 graphicx 宏包以后,就可以使用 \includegraphics 命令加载图片了:

\includegraphics{option}{filename}

其中 {filename} 为图片文件名,与使用 \include 命令类似,文件名有时需要使用相对或绝对路径(见1.6 节)。图片文件的扩展名可写可不写。

另外 graphicx 宏包还提供了 \graphicspath 命令,用于声明一个或多个图片文件存放的目录,使用这些目录里的图片时可不用写路径:

% 假设主要的图片放在 figures 子目录下,标志放在 logo 子目录下

\graphicspath {{figures/}{logo/}}

\inclusegraphics 命令的可选参数 {option} 支持 {key}={value} 形式赋值,常用的参数如下:

3.8 盒子 #

盒子是 LaTeX 排版的基础单元,虽然解释上去有些抽象:每一行是一个盒子,里面的文字从左到右依次排列:每一页也是一个盒子,各行文字从上到下依次排布……颇有一些活字印刷术的味道。

不管如何,LaTeX 提供了一些命令让我们生成一些有特定用途的盒子。

3.8.1 水平盒子 #

生成水平盒子的命令如下:

\mbox{…}
\makebox{width}{align}{…}

\mbox 生成一个基本的水平盒子,内容只有一行,不允许分段(除非嵌套其他盒子,比如后文的垂直盒子)。外表看上去,\mbox 的内容与正常的文本无二,不过断行时文字不会从盒子里断开。

\makebox 更进一步,可以加上可选参数用于控制盒子的宽度{width},以及内容的对齐方式{align},可选居中 c (默认值)、左对齐1、右对齐 r 和分散对齐 s 。

|\mbox{Test some words.}|\\
|\makebox{10em}{Test some words.}|\\
|\makebox{10em}{l}{Test some words.}|\\
|\makebox{10em}{r}{Test some words.}|\\
|\makebox{10em}{s}{Test some words.}|

3.8.2 带框的水平盒子 #

\fbox 和 \framebox 让我们可以为水平盒子添加边框。使用的语法与 \mbox 和 \makebox 一模一样:

\fbox{…}
\framebox{width}{align}{…}
\fbox{Test some words.}\\
\framebox{10em}{r}{Test some words.}

可以通过 \setlength 命令(见5.2.1 小节)调节边框的宽度 \fboxrule 和内边距 \fboxsep:

\framebox{10em}{r}{Test box}\\{1ex}
\setlength{\fboxrule}{1.6pt}
\setlength{\fboxsep}{1em}
\framebox{10em}{r}{Test box}

3.8.3 垂直盒子 #

如果需要排版一个文字可以换行的盒子,LaTeX 提供了两种方式:

\parbox{align}{height}{inner-align}{width}{…}
\begin{minipage}{align}{height}{inner-align}{width}
\end{minipage}

其中 {align} 为盒子和周围文字的对齐情况(类似 tabular 环境);{height} 和 {inner-align} 设置盒子的高度和内容的对齐方式,类似水平盒子 \makebox 的设置,不过 {inner-align} 接受的参数是顶部 t、底部 b、居中 c 和分散对齐 s。

三字经:\parbox{t}{3em}%
{人之初 性本善 性相近 习相远}
\quad
千字文:
\begin{minipage}{b}{8ex}{t}{4em}
天地玄黄 宇宙洪荒
\end{minipage}

如果在 minipage 里使用 \footnote 命令,生成的脚注会出现在盒子底部,编号是独立的,并且使用小写字母编号。这也是 minipage 环境之所以被称为“迷你页”(Mini-page)的原因。而在 \parbox 里无法正常使用 \footnote 命令,只能在盒子里使用 \footnotemark,在盒子外使用 \footnotetext。

\fbox{\begin{minipage}{15em}%
    这是一个垂直盒子的测试。
    \footnote{脚注来自 minipage。}
\end{minipage}}

3.8.4 标尺盒子 #

\rule 命令用来画一个实心的矩形盒子,也可适当调整以用来画线(标尺):

\rule{raise}{width}{height}

Black \rule{12pt}{4pt} box.

Upper \rule{4pt}{6pt}{8pt} and
lower \rule{-4pt}{6pt}{8pt} box.

A \rule{-.4pt}{3em}{.4pt} line.

3.9 浮动体 #

内容丰富的文章或者书籍往往包含许多图片和表格等内容。这些内容的尺寸往往太大,导致分页困难。LaTeX 为此引入了浮动体的机制,令大块的内容可以脱离上下文,放置在合适的位置。

LaTeX 预定义了两类浮动体环境 figure 和 table。习惯上 figure 里放图片,table 里放表格,但没有严格限制,可以在任何一个浮动体里放置文字、公式、表格、图片等等任意内容。

以 table 环境的用法举例,figure 同理:

\begin{table}{placement}
\end{table}

{placement} 参数提供了一些符号用来表示浮动体允许排序的位置,如 hbp 允许浮动体排版在当前位置、底部或者单独成页。table 和 figure 浮动体的默认设置为 tbp。

注1:排版位置的选取与参数里符号的顺序无关,LaTeX 总是以 h-t-b-p 的优先级顺序决定浮动体位置。也就是说[!htp] 和 [ph!t] 没有区别。

注2:限制包括浮动体个数(除单独成页外,默认每页不超过 3 个浮动体,其中顶部不超过 2 个,底部不超过 1 个)以及浮动体空间占页面的百分比(默认顶部不超过 70%,底部不超过 30%)。

双栏排版环境下,LaTeX 提供了 table* 和 figure* 环境用来排版跨栏的浮动体。它们的用法与 table 和 figure 一样,不同之处为双栏的{placement} 参数只能用 tp 两个位置。

浮动体的位置选取受到先后顺序的限制。如果某个浮动体由于参数限制、空间限制等原因在当前页无法放置,就要推迟到之后处理,并使得之后的同类浮动体一并推迟。\clearpage 命令会在另起一页之前,先将所有推迟处理的浮动体排列成页,此时 htbp 等位置限制被完全忽略。

float 宏包为浮动体提供了 H 位置参数,不与 htbp 及 !混用。使用 H 位置参数时,会取消浮动机制,将浮动体现为一般的盒子插入当前位置。这在一些特殊情况下很有用(如使用 multicol 宏包排版分栏内容的时候),但尺寸过大的浮动体可能使得分页比较困难。

3.9.1 浮动体的标题 #

图表等浮动体提供了 \caption 命令加标题,并且自动给浮动体编号:

\caption{…}

\caption 的用法非常类似于 \section 等命令,可以用带星号的命令 \caption* 生成不带编号的标题,也可以使用带可选参数的形式 \caption{…}{…},使得在目录里使用短标题。\caption 命令之后还可以紧跟 \lable 命令标记交叉引用。

\caption 生成的标题形如“Figure1:…”(figure 环境)或“Table 1:…”(table 环境)。可通过修改 \figurename 和 \tablename 的内容来修改标题的前缀(详见第 8.4 节)。标题样式的定制功能由 caption 宏包提供,详见改宏包的帮助文档,在此不作赘述。

table 和 figure 两种浮动体分别有各自的生成目录的命令:

\listoftables
\listoffigures

它们类似 \tableofcontents 生成单独的章节。

3.9.2 并排和子图表 #

我们时常有一个浮动体里面放置多张图的用法。最简单的用法就是直接并排放置,也可以通过分段或者换行命令 \ 排版多行多列的图片。以下为示意代码,效果大致如图 3.1 所示。

\begin{figure}{htbp}
    \centering
    \includegraphics[width=…]{…}
    \qquad
    \includegraphics[width=…]{…} \\ {…pt}
    \includegraphics[width=…]{…}
    \caption{…}
\end{figure}

由于标题是横跨一行的,用 \caption 命令为每个图片单独生成标题就需要借助前文提到的 \parbox 或者 minipage 环境,将标题限制在盒子内。效果见图 3.2 和图 3.3

\begin{figure}{htbp}
    \centering
    \begin{minipage}{…}
        \centering
        \includegraphics[width=…]{…}
        \caption{…}
    \end{minipage}
    \qquad
    \begin{minipage}{…}
        \centering
        \includegraphics[width=…]{…}
        \caption{…}
    \end{minipage}
\end{figure}

当我们需要更进一步,给每个图片定义小标题时,就要用到 subfig 宏包的功能了。这里仅举一例,效果见图 3.4 。更详细的用法请参照 subfig 宏包的帮助文档。

\begin{figure}{htbp}
    \centering
    \subfloat[…]{\lable{sub-fig-1}% 为子图加交叉引用
        \begin{minipage}{…}
            \centering
            \includegraphics[width]{…}
        \end{minipage}
    }
    \qquad
    \subfloat[…]{%
    \begin{minipage}{…}
        \centering
        \includegraphics[width=…]{…}
    \end{minapage}
    }
    \caption{…}
\end{figure}


  1. 出自《千字文》。 ↩︎