\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 \csname CTEX@todayold\endcsname}% \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 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