\chapter{文档元素}\label{chap:elements}
\addtocontents{los}{\protect\addvspace{10pt}}

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

\section{章节和目录}\label{sec:secs}

\subsection{章节标题}\label{subsec:secs}

\cmdindex{part,chapter,section,subsection,subsubsection,paragraph,subparagraph}
\clsindex{article,report,book}

一篇结构化的、条理清晰文档一定是层次分明的，通过不同的命令分割为章、节、小节。三个标准文档类 \cls{article}、\cls{report} 和 \cls{book}%
\footnote{千万注意是\textbf{标准文档类}，其它文档类，如果不是从标准文档类衍生而来，
很可能没有定义或只定义了一部分命令，如 \cls{beamer} 或 \cls{moderncv} 等。}%
提供了划分章节的命令：
\begin{command}
\cmd{chapter}\marg{title} \quad
\cmd{section}\marg{title} \quad
\cmd{subsection}\marg{title} \\
\cmd{subsubsection}\marg{title} \quad
\cmd{paragraph}\marg{title} \quad
\cmd{subparagraph}\marg{title}
\end{command}
其中 \cmd{chapter} \textbf{只在 \cls{report} 和 \cls{book} 文档类有定义}。这些命令生成章节标题，并能够自动编号。
除此之外 \LaTeX{} 还提供了 \cmd{part} 命令，用来将整个文档分割为大的分块，但不影响 \cmd{chapter} 或 \cmd{section} 等的编号。

上述命令除了生成带编号的标题之外，还向目录中添加条目，并影响页眉页脚的内容（详见 \ref{sec:pagestyle} 节）。每个命令有两种变体：
\begin{itemize}
  \item 带可选参数的变体：\cmd{section}\oarg{short title}\marg{title}\par
  标题使用 \Arg{title} 参数，在目录和页眉页脚中使用 \Arg{short title} 参数；
  \item 带星号的变体：\cmd{section*}\marg{title}\par
  标题不带编号，也不生成目录项和页眉页脚。
\end{itemize}

较低层次如 \cmd{paragraph} 和 \cmd{subparagraph} 即使不用带星号的变体，生成的标题默认也不带编号，事实上，除 \cmd{part} 外：
\begin{itemize}
  \item \cls{article} 文档类带编号的层级为 \cmd{section}、\cmd{subsection}、\cmd{sub\-sub\-section} 三级；
  \item \cls{report} 和 \cls{book} 文档类带编号的层级为 \cmd{chapter}、\cmd{section}、\cmd{sub\-section} 三级。
\end{itemize}
对此的详细解释和调整方法见 \ref{subsec:latex-counts} 小节。

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

\subsection{目录}\label{sec:toc}

\cmdindex{tableofcontents}
\pkgindex{tocbibind,tocloft,titletoc}
在 \LaTeX{} 中生成目录非常容易，只需在合适的地方使用命令：
\begin{command}
\cmd{tableofcontents}
\end{command}

这个命令会生成单独的一章（\cls{report}/\cls{book}）或一节（\cls{article}），标题默认为“Contents”，可通过 \ref{sec:latex-settings} 节给出的方法定制标题。
\cmd{tableof\-contents} 生成的章节默认不写入目录（\cmd{section*} 或 \cmd{chapter*}），可使用 \pkg{tocbibind} 等宏包修改设置。

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

\cmdindex{addcontentsline}
有时我们使用了 \cmd{chapter*} 或 \cmd{section*} 这样不生成目录项的章节标题命令，
而又想手动生成该章节的目录项，可以在标题命令后面使用：
\begin{command}
\cmd{addcontentsline}\marg*{toc}\marg{level}\marg{title}
\end{command}

其中 \Arg{level} 为章节层次 \texttt{chapter} 或 \texttt{section} 等，\Arg{title} 为出现于目录项的章节标题。

\pkg{titletoc}、\pkg{tocloft} 等宏包提供了具体定制目录项格式的功能，详情请参考宏包的帮助文档。

\subsection{文档结构的划分}\label{sec:matters}

\cmdindex{appendix}
所有标准文档类都提供了一个 \cmd{appendix} 命令将正文和附录分开%
\footnote{有的参考文档可能使用 \cmd{begin}\marg*{appendix} \ldots{} \cmd{end}\marg*{appendix} 这样的写法，
虽然有效，但并不规范，只要使用 \cmd{appendix} 命令就够了。}，
使用 \cmd{appendix} 后，最高一级章节改为使用拉丁字母编号，从 A 开始。

\clsindex{book}
\cmdindex{frontmatter,mainmatter,backmatter}
\cls{book} 文档类还提供了前言、正文、后记结构的划分命令：
\begin{description}
  \item[\cmd{frontmatter}] 前言部分，页码使用小写罗马数字；其后的 \cmd{chapter} 不编号。
  \item[\cmd{mainmatter}] 正文部分，页码使用阿拉伯数字，从 1 开始计数；其后的章节编号正常。
  \item[\cmd{backmatter}] 后记部分，页码格式不变，继续正常计数；其后的 \cmd{chapter} 不编号。
\end{description}

\cmdindex{include}
以上三个命令还可和 \cmd{appendix} 命令结合，生成有前言、正文、附录、后记四部分的文档。
源代码 \ref{code:book-struct} 结合 \ref{sec:latex-multi-files} 节的 \cmd{include} 命令
和其它一些命令示意了一份完整的文档结构。

\begin{sourcecode}[htp]
\begin{Verbatim}
\documentclass{book}

% 导言区，加载宏包和各项设置，包括参考文献、索引等
\usepackage{makeidx}        % 调用 makeidx 宏包，用来处理索引
\makeindex                  % 开启索引的收集
\bibliographystyle{plain}   % 指定参考文献样式为 plain

\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{epilogue}   % 后记 epilogue.tex
\bibliography{books} % 利用 BibTeX 工具从数据库文件 books.bib 生成参考文献
\printindex          % 利用 makeindex 工具生成索引

\end{document}
\end{Verbatim}
\caption{\cls{book} 文档类的文档结构示例。}\label{code:book-struct}
\end{sourcecode}

\section{标题页}\label{sec:titlepage}

\cmdindex{title,author,date,today}
\cmdindex{thanks,and}
\LaTeX{} 支持生成简单的标题页。首先需要给定标题和作者等信息：
\begin{command}
\cmd{title}\marg{title} \quad
\cmd{author}\marg{author} \quad
\cmd{date}\marg{date}
\end{command}
其中前两个命令是必须的（不用 \cmd{title} 会报错；不用 \cmd{author} 会警告），\cmd{date} 命令可选。
\LaTeX{} 还提供了一个 \cmd{today} 命令自动生成当前日期，\cmd{date} 默认使用 \cmd{today}。
在 \cmd{title}、\cmd{author} 等命令内可以使用 \cmd{thanks} 命令生成标题页的脚注，用 \cmd{and} 隔开多个人名。

\cmdindex{maketitle}
\pinyinindex{biaotiye}{标题页}
在信息给定后，就可以使用 \cmd{maketitle} 命令生成一个简单的标题页了。
源代码 \ref{code:titlepage} 给出了一个标题页的示例和大致效果。
\cls{article} 文档类的标题默认不单独成页，而 \cls{report} 和 \cls{book} 默认单独成页。
可在 \cmd{document\-class} 命令调用文档类时指定 \texttt{titlepage} 或 \texttt{notitlepage} 选项以修改默认的行为。

\begin{sourcecode}[htp]
\begin{Verbatim}
\title{Test title}
\author{ Mary\thanks{E-mail:*****@***.com}
  \and Ted\thanks{Corresponding author}
  \and Louis}
\date{\today}
\end{Verbatim}
\bigskip
\makeatletter
\begin{minipage}{\textwidth}
    \centering
    \renewcommand\thempfootnote{\@fnsymbol\c@mpfootnote}%
    {\LARGE Test title \par}%
    \vskip 1.5em%
    {\large
        \lineskip .5em%
        \begin{tabular}[t]{c}%
            Mary\footnote{E-mail:*****@***.com}
        \end{tabular}
        \hskip 1em \@plus.17fil%
        \begin{tabular}[t]{c}%
            Ted\footnote{Corresponding author}
        \end{tabular}
        \hskip 1em \@plus.17fil%
        \begin{tabular}[t]{c}%
            Louis
        \end{tabular}\par}%
    \vskip 1em%
    {\large \CTEX@todayold}%
\end{minipage}
\makeatother
\caption{\LaTeX{} 默认的标题页示例和效果。}\label{code:titlepage}
\end{sourcecode}

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

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

以上是 \LaTeX{} 标准文档类的标题页相关命令用法。在各种文档模板中经常有自定义的标题页，
有可能需要除了 \cmd{title} 和 \cmd{author} 以外的命令给定信息，用法也可能与标准文档类的不一致
（甚至有些模板可能没有定义 \env{titlepage} 等环境）。使用文档模板前\textbf{一定要仔细阅读文档模板的帮助文档}。

\section{交叉引用}\label{sec:crossref}

\cmdindex{label}
交叉引用是 \LaTeX{} 强大的自动排版功能的体现之一。在能够被交叉引用的地方，如章节、公式、图表、定理等位置使用 \cmd{label} 命令：
\begin{command}
\cmd{label}\marg{label-name}
\end{command}

\cmdindex{ref,pageref}
之后可以在别处使用 \cmd{ref} 或 \cmd{pageref} 命令，分别生成交叉引用的编号和页码：
\begin{command}
\cmd{ref}\marg{label-name} \quad
\cmd{pageref}\marg{label-name}
\end{command}
\begin{example}
A reference to this subsection
\label{sec:this} looks like:
``see section~\ref{sec:this} on
page~\pageref{sec:this}.''
\end{example}

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

\cmd{label} 命令可用于记录各种类型的交叉引用，使用位置分别为：
\begin{description}
  \item[章节标题] 在章节标题命令 \cmd{section} 等之后紧接着使用。
  \item[行间公式] 单行公式在公式内任意位置使用；多行公式在每一行公式的任意位置使用。
  \item[有序列表] 在 \env{enumerate} 环境的每个 \cmd{item} 命令之后、下一个 \cmd{item} 命令之前任意位置使用。
  \item[图表标题] 在图表标题命令 \cmd{caption} 之后紧接着使用。
  \item[定理环境] 在定理环境内部任意位置使用。
\end{description}

在使用不记编号的命令形式（\cmd{section*}、\cmd{caption*}\footnote{需加载相关宏包，如 \pkg{caption}}、带可选参数的 \cmd{item} 命令等）时不要使用 \cmd{label} 命令，
否则生成的引用编号不正确。

\section{脚注和边注}\label{sec:footnote-marginpar}

\cmdindex{footnote}
使用 \cmd{footnote} 命令可以在页面底部生成一个脚注：
\begin{command}
\cmd{footnote}\marg{footnote}
\end{command}

假如我们输入以下文字和命令：
\begin{verbatim}
“天地玄黄，宇宙洪荒。日月盈昃，辰宿列张。”\footnote{出自《千字文》。}
\end{verbatim}

在正文中则为：%
“天地玄黄，宇宙洪荒。日月盈昃，辰宿列张。”\footnote{出自《千字文》。}

\cmdindex{footnotemark,footnotetext}
有些情况下（比如在表格环境、各种盒子内）使用 \cmd{footnote} 并不能正确生成脚注。我们可以分两步进行，
先使用 \cmd{foot\-note\-mark} 为脚注计数，再在合适的位置用 \cmd{foot\-note\-text} 生成脚注。比如：

\begin{verbatim}
\begin{tabular}{l}
\hline
“天地玄黄，宇宙洪荒。日月盈昃，辰宿列张。”\footnotemark \\
\hline
\end{tabular}
\footnotetext{表格里的名句出自《千字文》。}
\end{verbatim}

效果为：

\leavevmode\begin{tabular}{l}
\hline
“天地玄黄，宇宙洪荒。日月盈昃，辰宿列张。”\footnotemark \\
\hline
\end{tabular}
\footnotetext{表格里的名句出自《千字文》。}

\cmdindex{marginpar}
使用 \cmd{marginpar} 命令可在边栏位置生成边注：
\begin{command}
\cmd{marginpar}\oarg{left-margin}\marg{right-margin}
\end{command}
如果只给定了 \Arg{right-margin}，那么边注在奇偶数页文字相同；如果同时给定了 \Arg{left-margin}，
则偶数页使用 \Arg{left-margin} 的文字。

例如以下代码：
\begin{verbatim}
\marginpar{\footnotesize 边注较窄，不要写过多文字，最好设置较小的字号。}
\end{verbatim}
其效果见边栏。\marginpar{\footnotesize 边注较窄，不要写过多文字。最好设置较小的字号。}

\section{特殊环境}\label{sec:envs}

\subsection{列表}\label{subsec:lists}

\envindex{enumerate,itemize}
\cmdindex{item}
\LaTeX{} 提供了基本的有序和无序列表环境 \env{enumerate} 和 \env{itemize}，两者的用法很类似，都用 \cmd{item} 标明每个列表项。
\env{enumerate} 环境会自动对列表项编号。
\begin{command}
\cmd{begin}\marg*{enumerate} \\
\cmd{item} \ldots \\
\cmd{end}\marg*{enumerate}
\end{command}

其中 \cmd{item} 可带一个可选参数，将有序列表的计数或者无序列表的符号替换成自定义的符号。
列表可以嵌套使用，最多嵌套四层。
\begin{example}
\begin{enumerate}
  \item An item.
  \begin{enumerate}
    \item A nested item.\label{itref}
    \item[*] A starred item.
  \end{enumerate}
  \item Reference(\ref{itref}).
\end{enumerate}
\end{example}

\begin{example}
\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{itemize}
\end{example}

\envindex{description}
关键字环境 \env{description} 的用法与以上两者类似，不同的是 \cmd{item} 后的可选参数用来写关键字，以粗体显示，一般是必填的：
\begin{command}
\cmd{begin}\marg*{description} \\
  \cmd{item}\oarg{item title} \ldots \\
\cmd{end}\marg*{description}
\end{command}

\begin{example}
\begin{description}
  \item[Enumerate] Numbered list.
  \item[Itemize] Non-numbered list.
\end{description}
\end{example}

各级无序列表的符号由命令 \cmd{labelitemi} 到 \cmd{labelitemiv} 定义，可以简单地重新定义它们：
\begin{example}
\renewcommand{\labelitemi}{\ddag}
\renewcommand{\labelitemii}{\dag}
\begin{itemize}
  \item First item
  \begin{itemize}
    \item Subitem
    \item Subitem
  \end{itemize}
  \item Second item
\end{itemize}
\end{example}

有序列表的符号由命令 \cmd{labelenumi} 到 \cmd{labelenumiv} 定义，
重新定义这些命令需要用到 \ref{sec:counters} 节的计数器相关命令：
\begin{example}
\renewcommand{\labelenumi}%
  {\Alph{enumi}>}
\begin{enumerate}
  \item First item
  \item Second item
\end{enumerate}
\end{example}

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

\subsection{对齐环境}\label{subsec:flush}

\envindex{center,flushleft,flushright}
\env{center}、\env{flush\-left} 和 \env{flush\-right} 环境分别用于生成居中、左对齐和右对齐的文本环境。
\begin{command}
\cmd{begin}\marg*{center} \ldots\ \cmd{end}\marg*{center} \\
\cmd{begin}\marg*{flushleft} \ldots\ \cmd{end}\marg*{flushleft} \\
\cmd{begin}\marg*{flushright} \ldots\ \cmd{end}\marg*{flushright}
\end{command}

\begin{example}
\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}
\end{example}

\cmdindex{centering,raggedleft,raggedright}
除此之外，还可以用以下命令直接改变文字的对齐方式：
\begin{command}
\cmd{centering} \quad
\cmd{raggedright} \quad
\cmd{raggedleft}
\end{command}

\begin{example}
\centering
Centered text paragraph.

\raggedright
Left-aligned text paragraph.

\raggedleft
Right-aligned text paragraph.
\end{example}

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

\subsection{引用环境}\label{subsec:quote}

\envindex{quote,quotation}
\LaTeX{} 提供了两种引用的环境：\env{quote} 用于引用较短的文字，首行不缩进；\env{quotation} 用于引用若干段文字，首行缩进。
引用环境较一般文字有额外的左右缩进。
\begin{example}
Francis Bacon says:
\begin{quote}
Knowledge is power.
\end{quote}
\end{example}

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

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

\envindex{verse}
\env{verse} 用于排版诗歌，与 \env{quotation} 恰好相反，\env{verse} 是首行悬挂缩进的。
\begin{example}
Rabindranath Tagore's short poem:
\begin{verse}
Beauty is truth's smile
when she beholds her own face in
a perfect mirror.
\end{verse}
\end{example}

\subsection{摘要环境}\label{subsec:abstract}

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

\subsection{代码环境}\label{subsec:verbatim}

\envindex{verbatim}
有时我们需要将一段代码原样转义输出，这就要用到代码环境 \env{verbatim}，它以等宽字体排版代码，回车和空格也分别起到换行和空位的作用；
带星号的版本更进一步将空格显示成“\textvisiblespace”。
\begin{example}
\begin{verbatim}
#include <iostream>
int main()
{
  std::cout << "Hello, world!"
            << std::endl;
  return 0;
}
\end{verbatim}
\end{example}

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

\cmdindex{verb}
要排版简短的代码或关键字，可使用 \cmd{verb} 命令：
\begin{command}
\cmd{verb}\Arg{delim}\Arg{code}\Arg{delim}
\end{command}

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

同 \env{verbatim} 环境，\cmd{verb} 后也可以带一个星号，以显示空格：
\begin{example}
\verb|\LaTeX| \\
\verb+(a || b)+ \verb*+(a || b)+
\end{example}

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

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

\section{表格}\label{sec:tabular}

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

\envindex{tabular}
\cmdindex{hline}
\index{&@\texttt\& (\textit{单元格/对齐})}
\index{\@\crcmd{} (\textit{换行})}
排版表格最基本的 \env{tabular} 环境用法为：
\begin{command}
\cmd{begin}\marg*{tabular}\oarg{align}\marg{column-spec}\\
 \Arg{item1} \texttt\& \Arg{item2} \texttt\& \ldots\ \crcmd \\
 \cmd{hline} \\
 \Arg{item1} \texttt\& \Arg{item2} \texttt\& \ldots\ \crcmd \\
\cmd{end}\marg*{tabular}
\end{command}
其中 \Arg{column-spec} 是列格式标记，在接下来的内容将仔细介绍；\texttt\& 用来分隔单元格；
\crcmd{} 用来换行；\cmd{hline} 用来在行与行之间绘制横线。

直接使用 \env{tabular} 环境的话，会\textbf{和周围的文字混排}。此时可用一个可选参数 \Arg{align} 控制垂直对齐：
\verb|t| 和 \verb|b| 分别表示按表格顶部、底部对齐，其他参数或省略不写（默认）表示居中对齐。
\begin{example}
\begin{tabular}{|c|}
  center-\\ aligned \\
\end{tabular},
\begin{tabular}[t]{|c|}
  top-\\ aligned \\
\end{tabular},
\begin{tabular}[b]{|c|}
  bottom-\\ aligned\\
\end{tabular} tabulars.
\end{example}

但是通常情况下 \env{tabular} 环境很少与文字直接混排，而是会放在 \env{table} 浮动体环境中，并用 \cmd{caption} 命令加标题。

\subsection{列格式}\label{subsec:tabular-cols}

\env{tabular} 环境使用 \Arg{column-spec} 参数指定表格的列数以及每列的格式。基本的列格式见表 \ref{tbl:table-column-spec}。
\begin{table}[htp]
\centering
\caption{\LaTeX{} 表格列格式}\label{tbl:table-column-spec}
\begin{tabular}{*{2}{l}}
 \hline
 \textbf{列格式} & \textbf{说明} \\
 \hline
 \ttfamily l/c/r          & 单元格内容左对齐/居中/右对齐，不折行 \\
 \ttfamily p\marg{width}  & 单元格宽度固定为 \Arg{width}，可自动折行 \\
 \ttfamily |              & 绘制竖线 \\
 \ttfamily @\marg{string} & 自定义内容 \Arg{string} \\
 \hline
\end{tabular}
\end{table}

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

表格中每行的单元格数目不能多于列格式里 \texttt{l/c/r/p} 的总数（可以少于这个总数），否则出错。

\texttt{@} 格式可在单元格前后插入任意的文本，但同时它也消除了单元格前后额外添加的间距。
\texttt{@} 格式可以适当使用以充当“竖线”。特别地，\texttt{@}\marg*{} 可直接用来消除单元格前后的间距：
\begin{example}
\begin{tabular}{@{} r@{:}lr @{}}
  \hline
  1  & 1 & one \\
  11 & 3 & eleven \\
  \hline
\end{tabular}
\end{example}

另外 \LaTeX{} 还提供了简便的将格式参数重复的写法 \texttt*\marg{n}\marg{column-spec}，比如以下两种写法是等效的：
\begin{verbatim}
\begin{tabular}{|c|c|c|c|c|p{4em}|p{4em}|}
\begin{tabular}{|*{5}{c|}*{2}{p{4em}|}}
\end{verbatim}

\pkgindex{array}
有时需要为整列修饰格式，比如整列改变为粗体，如果每个单元格都加上 \cmd{bfseries} 命令会比较麻烦。
\pkg{array} 宏包提供了辅助格式 \texttt> 和 \texttt<，用于给列格式前后加上修饰命令：
\begin{example}
% \usepackage{array}
\begin{tabular}{>{\itshape}r<{*}l}
  \hline
  italic & normal \\
  column & column \\
  \hline
\end{tabular}
\end{example}

辅助格式甚至支持插入 \cmd{centering} 等命令改变 \texttt{p} 列格式的对齐方式，
一般还要加额外的命令 \cmd{array\-back\-slash} 以免出错%
\footnote{\cmd{centering} 等对齐命令会破坏表格环境里 \crcmd{} 换行命令的定义，
\cmd{array\-back\-slash} 用来恢复之。如果不加 \cmd{array\-back\-slash} 命令，
也可以用 \cmd{tabular\-newline} 命令代替原来的 \crcmd{} 实现表格换行。}：
\begin{example}
% \usepackage{array}
\begin{tabular}%
{>{\centering\arraybackslash}p{9em}}
  \hline
  Some center-aligned long text. \\
  \hline
\end{tabular}
\end{example}

\pkg{array} 宏包还提供了类似 \texttt{p} 格式的 \texttt{m} 格式和 \texttt{b} 格式，
三者分别在垂直方向上靠顶端对齐、居中以及底端对齐。
\begin{example}
% \usepackage{array}
\newcommand\txt{a b c d e f g h i}
\begin{tabular}{cp{2em}m{2em}b{2em}}
  \hline
  pos & \txt & \txt & \txt \\
  \hline
\end{tabular}
\end{example}

\subsection{列宽}\label{subsec:colwidth}

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

\envindex{tabular*}
\LaTeX{} 本身提供了 \env{tabular*} 环境用来排版定宽表格，但是不太方便使用，
比如要用到 \texttt{@} 格式插入额外命令，令单元格之间的间距为 \cmd{fill}，但即使这样仍然有瑕疵：
\begin{example}
\begin{tabular*}{14em}%
{@{\extracolsep{\fill}}|c|c|c|c|}
  \hline
  A & B & C & D \\ \hline
  a & b & c & d \\ \hline
\end{tabular*}
\end{example}

\pkgindex{tabularx}
\envindex[tabularx]{tabularx}
\pkg{tabularx} 宏包为我们提供了方便的解决方案。它引入了一个 \texttt{X} 列格式，类似 \texttt{p} 列格式，
不过会根据表格宽度自动计算列宽，多个 \texttt{X} 列格式平均分配列宽。
\texttt{X} 列格式也可以用 \pkg{array} 里的辅助格式修饰对齐方式：
\begin{example}
% \usepackage{array,tabularx}
\begin{tabularx}{14em}%
{|*{4}{>{\centering\arraybackslash}X|}}
  \hline
  A & B & C & D \\ \hline
  a & b & c & d \\ \hline
\end{tabularx}
\end{example}

\subsection{横线}\label{subsec:hline}

\cmdindex{hline,cline}
我们已经在之前的例子见过许多次绘制表格线的 \cmd{hline} 命令。另外 \cmd{cline}\marg*{\Arg{i}-\Arg{j}} 用来绘制跨越部分单元格的横线：
\begin{example}
\begin{tabular}{|c|c|c|}
  \hline
  4 & 9 & 2 \\ \cline{2-3}
  3 & 5 & 7 \\ \cline{1-1}
  8 & 1 & 6 \\ \hline
\end{tabular}
\end{example}

\pkgindex{booktabs}
\cmdindex[booktabs]{toprule,midrule,bottomrule,cmidrule}
在科技论文排版中广泛应用的表格形式是三线表，形式干净简明。
三线表由 \pkg{booktabs} 宏包支持，它提供了 \cmd{toprule}、\cmd{midrule} 和 \cmd{bottomrule} 命令用以排版三线表的三条线，
以及和 \cmd{cline} 对应的 \cmd{cmidrule}。除此之外，最好不要用其它横线以及竖线：
\begin{example}
% \usepackage{booktabs}
\begin{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}
\end{example}

\subsection{合并单元格}\label{subsec:tabular-multicol}

\LaTeX{} 是一行一行排版表格的，横向合并单元格较为容易，由 \cmd{multi\-column} 命令实现：
\begin{command}
\cmd{multicolumn}\marg{n}\marg{column-spec}\marg{item}
\end{command}
其中 \Arg{n} 为要合并的列数，\Arg{column-spec} 为合并单元格后的列格式，只允许出现一个 \texttt{l/c/r} 或 \texttt{p} 格式。
如果合并前的单元格前后带表格线 \texttt|，合并后的列格式也要带 \texttt| 以使得表格的竖线一致。
\begin{example}
\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}
\end{example}

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

\pkgindex{multirow}
\cmdindex[multirow]{multirow}
纵向合并单元格需要用到 \pkg{multirow} 宏包提供的 \cmd{multirow} 命令：
\begin{command}
\cmd{multirow}\marg{n}\marg{width}\marg{item}
\end{command}
\Arg{width} 为合并后单元格的宽度，可以填 \texttt{*} 以使用自然宽度。

我们看一个结合 \cmd{cline}、\cmd{multi\-column} 和 \cmd{multi\-row} 命令的例子：
\begin{example}
% \usepackage{multirow}
\begin{tabular}{ccc}
  \hline
  \multirow{2}{*}{Item} &
    \multicolumn{2}{c}{Value} \\
  \cline{2-3}
    & First & Second \\ \hline
  A & 1     & 2 \\ \hline
\end{tabular}
\end{example}

\subsection{嵌套表格}\label{subsec:tabular-embed}

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

\begin{example}
\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}
\end{example}

\pkgindex{makecell}
如果不需要为“拆分的单元格”画线，并且只在垂直方向“拆分”的话，\pkg{makecell} 宏包提供的 \cmd{make\-cell} 命令是一个简单的解决方案：

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

\subsection{行距控制}\label{subsec:tabular-colht}

\cmdindex{arraystretch}
\LaTeX{} 生成的表格看起来通常比较紧凑。修改参数 \cmd{array\-stretch} 可以得到行距更加宽松的表格
（相关命令参考 \ref{subsec:newcmd} 小节）：
\begin{example}
\renewcommand\arraystretch{1.8}
\begin{tabular}{|c|}
  \hline
  Really loose \\ \hline
  tabular rows.\\ \hline
\end{tabular}
\end{example}

\index{\@\crcmd{} (\textit{换行})}
另一种增加间距的办法是给换行命令 \crcmd{} 添加可选参数，在这一行下面加额外的间距，适合用于在行间不加横线的表格：
\begin{example}
\begin{tabular}{c}
  \hline
  Head lines \\[6pt]
  tabular lines \\
  tabular lines \\ \hline
\end{tabular}
\end{example}

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

\pinyinindex{biaoge}{表格|)}

\section{图片}\label{sec:figures}

\pkgindex{graphicx}

\LaTeX{} 本身不支持插图功能，需要由 \pkg{graphicx} 宏包辅助支持。

使用 \texttt{latex + dvipdfmx} 编译命令时，调用 \pkg{graphicx} 宏包时要指定 \texttt{dvipdfmx} 选项%
\footnote{早期常使用 \texttt{latex + dvips} 组合命令，后者将 \texttt{.dvi} 文件转为 \texttt{.ps} 文件（PostScript），
可进一步通过 \texttt{ps2pdf} 工具生成 PDF。\texttt{dvips} 和 \texttt{dvipdfmx} 在图形、颜色、超链接等功能的实现上有差别，而 \LaTeX{} 无法识别
用户是用 \texttt{dvips} 还是 \texttt{dvipdfmx}，所以要指定选项（缺省为 \texttt{dvips}）。
\ref{sec:hyperlinks} 节中的 \pkg{hyperref} 宏包同理。}；而使用 \texttt{pdflatex} 或 \texttt{xelatex} 命令编译时不需要。

读者可能听说过“\LaTeX{} 只能插入 \texttt{.eps} 格式的图片，需要把 \texttt{.jpg} 转成 \texttt{.eps} 格式”的观点。
\LaTeX{} 发展到今天，这个观点早已过时。事实上不同编译命令支持的图片格式种类各异，见表~\ref{tbl:figure-format}。
这个表格也能解答诸如“为什么 \texttt{.eps} 格式图片在 \texttt{pdflatex} 编译命令下出错”之类的问题。本表格也再一次说明，使用
\texttt{xelatex} 命令是我们最推荐的方式。

\begin{table}[htp]
\centering
\caption{各种编译方式支持的主流图片格式}\label{tbl:figure-format}
\begin{tabular}{*{3}{l}}
 \hline
 \textbf{格式}  & \textbf{矢量图} & \textbf{位图} \\
 \hline
 \texttt{latex + dvipdfmx}           & \texttt{.eps}      & N/A \\
 \quad $\llcorner$（调用 \pkg{bmpsize} 宏包 ）   & \texttt{.eps .pdf}     & \texttt{.jpg .png .bmp} \\[.3\baselineskip]
 \texttt{pdflatex}                   & \texttt{.pdf}      & \texttt{.jpg .png} \\
 \quad $\llcorner$（调用 \pkg{epstopdf} 宏包）   & \texttt{.pdf .eps} & \texttt{.jpg .png} \\[.3\baselineskip]
 \texttt{xelatex}                    & \texttt{.pdf .eps} & \texttt{.jpg .png .bmp} \\
 \hline
\end{tabular}
\begin{quote}\footnotesize
注：在较新的 \TeX{} 发行版中，\texttt{latex + dvipdfmx} 和 \texttt{pdf\-latex} 命令可不依赖宏包，支持原来需要宏包扩展的图片格式
（但 \texttt{pdf\-latex} 命令仍不支持 \texttt{.bmp} 格式的位图）。
\end{quote}
\end{table}

\cmdindex[graphicx]{includegraphics}
在调用了 \pkg{graphicx} 宏包以后，就可以使用 \cmd{include\-graphics} 命令加载图片了：
\begin{command}
\cmd{includegraphics}\oarg{options}\marg{filename}
\end{command}

\cmdindex[graphicx]{graphicspath}
其中 \Arg{filename} 为图片文件名，与 \cmd{include} 命令的用法类似，文件名可能需要用相对路径或绝对路径表示（见 \ref{sec:latex-multi-files} 节）。
图片文件的扩展名一般可不写。另外一定要注意，\textbf{文件名里既不要有空格（类似 \cmd{include}），也不要有多余的英文点号}，否则宏包在解析文件名的过程中会出错。

另外 \pkg{graphicx} 宏包还提供了 \cmd{graphics\-path} 命令，用于声明一个或多个图片文件存放的目录，
使用这些目录里的图片时可不用写路径：
\begin{verbatim}
% 假设主要的图片放在 figures 子目录下，标志放在 logo 子目录下
\graphicspath{{figures/}{logo/}}
\end{verbatim}

在 \cmd{includegraphics} 命令的可选参数 \Arg{options} 中可以使用 \Arg{key}=\Arg{value} 的形式，
常用的参数如下：
\begin{table}[htp]
\centering
\caption{\cmd{includegraphics} 命令的可选参数}\label{tbl:graphics-options}
\begin{tabular}{lp{18em}}
 \hline
 \textbf{参数} & \textbf{含义} \\
 \hline
 \texttt{width=}\Arg{width}    &  将图片缩放到宽度为 \Arg{width} \\
 \texttt{height=}\Arg{height}  &  将图片缩放到高度为 \Arg{height} \\
 \texttt{scale=}\Arg{scale}    &  将图片相对于原尺寸缩放 \Arg{scale} 倍 \\
 \texttt{angle=}\Arg{angle}    &  将图片逆时针旋转 \Arg{angle} 度 \\
 \hline
\end{tabular}
\end{table}

\pkg{graphicx} 宏包也支持 \texttt{draft}/\texttt{final} 选项。当 \pkg{graphicx} 宏包或文档类指定
\texttt{draft} 选项时，图片将不会被实际插入，取而代之的是一个包含文件名的与原图片等大的方框。

\section{盒子}\label{sec:box}

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

不管如何，\LaTeX{} 提供了一些命令让我们手动生成一些有特定用途的盒子。

\subsection{水平盒子}\label{subsec:mbox}

\cmdindex{mbox,makebox}
生成水平盒子的命令如下：
\begin{command}
\cmd{mbox}\marg*{\ldots} \\
\cmd{makebox}\oarg{width}\oarg{align}\marg*{\ldots}
\end{command}

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

\cmd{makebox} 更进一步，可以加上可选参数用于控制盒子的宽度 \Arg{width}，以及内容的对齐方式 \Arg{align}，
可选居中 \texttt{c}（默认值）、左对齐 \texttt{l}、右对齐 \texttt{r} 和分散对齐 \texttt{s}%
\footnote{分散对齐方式强行拉开单词的间距，往往会报 \texttt{Underfull} \cmd{hbox} 的警告。}。

% 此处会有 Underfull \hbox 警告
\begin{example}
|\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.}|
\end{example}

\subsection{带框的水平盒子}\label{subsec:fbox}

\cmdindex{fbox,framebox}
\cmd{fbox} 和 \cmd{framebox} 让我们可以为水平盒子添加边框。使用的语法与 \cmd{mbox} 和 \cmd{makebox} 一模一样：
\begin{command}
\cmd{fbox}\marg*{\ldots} \\
\cmd{framebox}\oarg{width}\oarg{align}\marg*{\ldots}
\end{command}
\begin{example}
\fbox{Test some words.}\\
\framebox[10em][r]{Test some words.}
\end{example}

\cmdindex{setlength}
\cmdindex{fboxrule,fboxsep}
可以通过 \cmd{setlength} 命令（见 \ref{subsec:lengths} 小节）调节边框的宽度 \cmd{fbox\-rule} 和内边距 \cmd{fbox\-sep}：
\begin{example}
\framebox[10em][r]{Test box}\\[1ex]
\setlength{\fboxrule}{1.6pt}
\setlength{\fboxsep}{1em}
\framebox[10em][r]{Test box}
\end{example}

\subsection{垂直盒子}\label{subsec:parbox}

\cmdindex{parbox}
\envindex{minipage}
如果需要排版一个文字可以换行的盒子，\LaTeX{} 提供了两种方式：
\begin{command}
\cmd{parbox}\oarg{align}\oarg{height}\oarg{inner-align}\marg{width}\marg*{\ldots} \\[0.5ex]
\cmd{begin}\marg*{minipage}\oarg{align}\oarg{height}\oarg{inner-align}\marg{width} \\
\ldots \\
\cmd{end}\marg*{minipage}
\end{command}

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

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

\cmdindex{footnote,footnotetext,footnotemark}
如果在 \env{minipage} 里使用 \cmd{footnote} 命令，生成的脚注会出现在盒子底部，编号是独立的，并且使用小写字母编号。
这也是 \env{minipage} 环境之被称为“迷你页”（Mini-page）的原因。
而在 \cmd{parbox} 里无法正常使用 \cmd{footnote} 命令，只能在盒子里使用 \cmd{foot\-note\-mark}，在盒子外使用 \cmd{foot\-note\-text}。
\begin{example}
\fbox{\begin{minipage}{15em}%
  这是一个垂直盒子的测试。
  \footnote{脚注来自 minipage。}
\end{minipage}}
\end{example}

\subsection{标尺盒子}\label{subsec:rules}

\cmdindex{rule}
\cmd{rule} 命令用来画一个实心的矩形盒子，也可适当调整以用来画线（标尺）：
\begin{command}
\cmd{rule}\oarg{raise}\marg{width}\marg{height}
\end{command}
\begin{example}
Black \rule{12pt}{4pt} box.

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

A \rule[-.4pt]{3em}{.4pt} line.
\end{example}

\section{浮动体}\label{sec:float}

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

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

以 \env{table} 环境的用法举例，\env{figure} 同理：
\begin{command}
\cmd{begin}\marg*{table}\oarg{placement} \\
\ldots \\
\cmd{end}\marg*{table}
\end{command}

\Arg{placement} 参数提供了一些符号用来表示浮动体允许排版的位置，如 \texttt{hbp} 允许浮动体排版在当前位置、底部或者单独成页。
\env{table} 和 \env{figure} 浮动体的默认设置为 \texttt{tbp}。
\begin{table}[htp]
\centering
\caption{浮动体的位置参数}\label{tbl:float-placement}
\begin{tabular}{*{2}{l}}
 \hline
 \textbf{参数} & \textbf{含义} \\
 \hline
 \texttt{h} & 当前位置（代码所处的上下文） \\
 \texttt{t} & 顶部 \\
 \texttt{b} & 底部 \\
 \texttt{p} & 单独成页 \\
 \texttt{!} & 在决定位置时忽视限制 \\
 \hline
\end{tabular}
\begin{quote}\footnotesize
注 1：排版位置的选取与参数里符号的顺序无关，\LaTeX{} 总是以 \texttt{h-t-b-p} 的优先级顺序决定浮动体位置。
也就是说 \texttt{[!htp]} 和 \texttt{[ph!t]} 没有区别。\par
注 2：限制包括浮动体个数（除单独成页外，默认每页不超过 3 个浮动体，其中顶部不超过 2 个，底部不超过 1 个）
以及浮动体空间占页面的百分比（默认顶部不超过 70\%，底部不超过 30\%）。
\end{quote}
\end{table}

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

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

\pkgindex{float}

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

\subsection{浮动体的标题}\label{subsec:caption}

\cmdindex{caption,label}
图表等浮动体提供了 \cmd{caption} 命令加标题，并且自动给浮动体编号：
\begin{command}
\cmd{caption}\marg*{\ldots}
\end{command}
\cmd{caption} 的用法非常类似于 \cmd{section} 等命令，可以用带星号的命令 \cmd{caption*}\footnote{需加载相关宏包，如 \pkg{caption}} 生成不带编号的标题，
也可以使用带可选参数的形式 \cmd{caption}\oarg*{\ldots}\marg*{\ldots}，使得在目录里使用短标题。
\cmd{caption} 命令之后还可以紧跟 \cmd{label} 命令标记交叉引用。

\pkgindex{caption}
\cmd{caption} 生成的标题形如“Figure 1: \ldots”（\env{figure} 环境）或“Table 1: \ldots”（\env{table} 环境）。
可通过修改 \cmd{figurename} 和 \cmd{tablename} 的内容来修改标题的前缀（详见第 \ref{sec:latex-settings} 节）。
标题样式的定制功能由 \pkg{caption} 宏包提供，详见该宏包的帮助文档，在此不作赘述。

\cmdindex{listoftables,listoffigures}
\env{table} 和 \env{figure} 两种浮动体分别有各自的生成目录的命令：
\begin{command}
\cmd{listoftables} \\
\cmd{listoffigures}
\end{command}

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

\subsection{并排和子图表}\label{subsec:subfig}

我们时常有在一个浮动体里面放置多张图的用法。最简单的用法就是直接并排放置，
也可以通过分段或者换行命令 \crcmd{} 排版多行多列的图片。以下为示意代码，效果大致如图 \ref{fig:parallel-fig} 所示。
\begin{verbatim}
\begin{figure}[htbp]
  \centering
  \includegraphics[width=...]{...}
  \qquad
  \includegraphics[width=...]{...} \\[...pt]
  \includegraphics[width=...]{...}
  \caption{...}
\end{figure}
\end{verbatim}

\begin{figure}[htp]
  \centering
  \fcolorbox[gray]{0}{0.96}{\parbox{10em}{\vrule width 0pt height 10ex\hfil}}
  \qquad
  \fcolorbox[gray]{0}{0.96}{\parbox{10em}{\vrule width 0pt height 12ex\hfil}}
  \par\bigskip
  \fcolorbox[gray]{0}{0.96}{\parbox{20em}{\vrule width 0pt height 12ex\hfil}}
  \caption{并排放置图片的示意。}\label{fig:parallel-fig}
\end{figure}

由于标题是横跨一行的，用 \cmd{caption} 命令为每个图片单独生成标题就需要借助前文提到的 \cmd{parbox}
或者 \env{minipage} 环境，将标题限制在盒子内。效果见图 \ref{fig:parallel-cap1} 和图 \ref{fig:parallel-cap2}。
\begin{verbatim}
\begin{figure}[htbp]
  \centering
  \begin{minipage}{...}
    \centering
    \includegraphics[width=...]{...}
    \caption{...}
  \end{minipage}
  \qquad
  \begin{minipage}{...}
    \centering
    \includegraphics[width=...]{...}
    \caption{...}
  \end{minipage}
\end{figure}
\end{verbatim}

\begin{figure}[htp]
  \centering
  \begin{minipage}{12em}
    \centering
    \fcolorbox[gray]{0}{0.96}{\parbox{10em}{\vrule width 0pt height 12ex\hfil}}
    \caption{并排图1。}\label{fig:parallel-cap1}
  \end{minipage}
  \qquad
  \begin{minipage}{12em}
    \centering
    \fcolorbox[gray]{0}{0.96}{\parbox{10em}{\vrule width 0pt height 12ex\hfil}}
    \caption{并排图2。}\label{fig:parallel-cap2}
  \end{minipage}
\end{figure}

\pkgindex{subcaption}
\envindex[subcaption]{subfigure}
当我们需要更进一步，给每个图片定义小标题时，就要用到 \pkg{subcaption} 宏包的功能了。这里仅举一例，
效果见图 \ref{fig:subfigure-cap1} 和 \ref{fig:subfigure-cap2}。更详细的用法请参考 \pkg{subcaption}
宏包的帮助文档。
\begin{verbatim}
\begin{figure}[htbp]
  \centering
  \begin{subfigure}{...}
    \centering
    \includegraphics[width=...]{...}
    \caption{...}
  \end{subfigure}
  \qquad
  \begin{subfigure}{...}
    \centering
    \includegraphics[width=...]{...}
    \caption{...}
  \end{subfigure}
\end{figure}
\end{verbatim}

\begin{figure}[htp]
  \centering
  \begin{subfigure}{12em}
    \centering
    \fcolorbox[gray]{0}{0.96}{\parbox{10em}{\vrule width 0pt height 12ex\hfil}}
    \caption{并排子图 1}
    \label{fig:subfigure-cap1}
  \end{subfigure}
  \qquad
  \begin{subfigure}{12em}
    \centering
    \fcolorbox[gray]{0}{0.96}{\parbox{10em}{\vrule width 0pt height 12ex\hfil}}
    \caption{并排子图 2}
    \label{fig:subfigure-cap2}
  \end{subfigure}
  \caption{使用 \pkg{subcaption} 宏包的 \env{subfigure} 环境排版子图。}
  \label{fig:subcaption}
\end{figure}

\pkgindex{caption,subfig}
\cmdindex[subfig]{subfloat}
\pkg{subcaption} 依赖上文提到过的 \pkg{caption} 宏包，因此也支持子图表标题样式的定制。并排子图表的
功能也可通过 \pkg{subfig} 宏包的 \cmd{subfloat} 命令实现，具体请参考宏包文档。

\endinput
