\chapter{入门} \section{Hello, World!} \label{sec:hello_world} 把下面例子用编辑器保存为~\verb|hello_world.tex|,这就是一个最简单的~\LaTeX~源文件。 \begin{code} %hello_world.tex \documentclass{article} \begin{document} Hello, World! \end{document} \end{code} 有了源文件,我们可以在命令行把它编译成~DVI~文件(DVI~格式见\ref{sec:dvi}小节)。此命令知道输入的是~\LaTeX~源文件,所以这里的~\verb|.tex|~后缀可以省略。以后的示例中可以省略的后缀都用~\verb|()|~标出,不再特别声明。 \begin{code} latex hello_world(.tex) \end{code} 如果系统显示类似下面的错误信息,请检查源文件是否有拼写错误。\verb|.log|~文件里有更详细的编译信息。 \begin{code} ! LaTeX Error: ... ! Emergency stop. ... No pages of output. Transcript written on hello_world.log. \end{code} 如果编译成功,系统会报出类似下面的信息: \begin{code} Output written on hello_world.dvi (1 page, 232 bytes). Transcript written on hello_world.log. \end{code} 每种~\LaTeX~发行包附带不同的~DVI~浏览器,比如~MiKTeX~的是~yap。 \begin{code} yap hello_world(.dvi) \end{code} \section{格式及其转换} \subsection{页面描述语言} \label{sec:pdl} 页面描述语言(Page Description Language,PDL)是一种在较高层次上描述实际输出结果的语言。本文只讨论其中三种与~\LaTeX~紧密相关的格式:DVI、PostScript、PDF。 \subsubsection{PostScript} 最早的打印机只用于打印字符,它使用的硬字符与打字机类似。后来出现的点阵(dot matrix)打字机用一系列的点来“画”出字符,当然它也可以画出图形。当时矢量图的打印只能由绘图仪(plotter)来完成。 1976~年,施乐(Xerox)推出了首台激光打印机,它结合了点阵打印机和绘图仪的优点,可以同时打印高质量的图形和文字。 同一时期,John Warnock~也在酝酿一种类似于~Forth~的图形设计语言,也就是后来的~PostScript(PS),当时他正在旧金山一家电脑图形公司~Evans \& Sutherland~工作。1978~年老板想让~Warnock~搬到位于犹他州的总部,他不想搬家就跳槽到了施乐。 Warnock~和~Martin Newell~开发了新的图形系统~JaM(John and Martin),它后来被合并到施乐的打印机驱动程序~InterPress~中去。这两位还开发过另一个系统~MaJ。 1982~年,Warnock~和施乐研究中心图形实验室主任~Chuck Geschke~一起离开施乐,成立了~Adobe~公司。Newell~后来也加入了~Adobe。 1984~年~Adobe~发布~PS~后不久,Steve Jobs~跑来参观,并建议用它来驱动激光打印机。次年,武装着~PS~驱动的~Apple LaserWriter~横空出世,打响了~80~年代中期桌面出版革命的第一枪。 90~年代中后期,廉价喷墨打印机的流行使得~PS~逐渐式微,因为~PS~驱动对它们毕竟是一个成本负担。 \subsubsection{PDF} 1993~年,Adobe~推出了一种开放的格式:Portable Document Format(PDF),它于~2007~年成为~ISO 32000~标准。除了开放,PDF~比起~PS~还有一些其它优势: \begin{itemize} \item PDF~基本上是~PS~的一个子集,因此更轻便。 \item PDF~可以嵌入更先进的字体,具体见\ref{sec:font}节。 \item PDF~支持嵌入乱七八糟的东东,比如动画。 \item PDF~支持透明图形。 \end{itemize} PDF~虽然拥有上述优势,起初它的推广却并不顺利,因为其读写工具~Acrobat~太贵。Adobe~很快推出了免费的~Acrobat Reader(后更名为~Adobe Reader),并不断改进~PDF,终于使它超越了曾经的事实标准~PS,成为网络时代电子文档的新标准。 \subsubsection{DVI} \label{sec:dvi} Knuth~最初设计的~\TeX~只能用于~XGP~打印机,这台打印机本身还需要一台~PDP-6~主机为它服务。1979~年,David Fuchs\footnote{Fuchs~本科毕业于普林斯顿,1978~年进入斯坦福攻读博士学位。他不是~Knuth~的学生,但是完成过一些~\TeX~的开发任务。他在~Adobe~工作过一段时间,现在混入了娱乐圈,担任过电影《Red Diaper Baby》和《Haiku Tunnel》的制片人。}提出把~\TeX~的输出改为设备无关的格式,也就是~Device Independent format(DVI)。 DVI~只是一种中间格式,用户还需要另外的处理程序(driver)把它转换为其它格式,比如~PS~或~PDF~,甚至~PNG、SVG~等。DVI~不能嵌入字体和图形,PS~和~PDF~可以选择是否嵌入字体。 \subsubsection{Ghostscript} \label{sec:ghostscript} PS~输出时需要一个解释器(Raster Image Processor,RIP)来把它转换为点阵图形。RIP~可以是软件,也可以是固件(firmware)或硬件\footnote{固件~RIP~在打印机内置处理器上运行,硬件~RIP~常见于高端打印设备。}。 Ghostscript~是一个基于~RIP~的软件包,除了~RIP~它还有一些其它功能,比如处理~EPS,把~PS~转换为~PDF~等。Ghostscript~已经被移植到~Windows、Unix/Linux、Mac OS~等多种操作系统,和它匹配的前端图形用户界面(GUI)有\href{http://pages.cs.wisc.edu/~ghost/}{GSview、Ghostview、gv}等。 \subsection{格式转换} \label{sec:convert_format} DVI、PS、PDF~等格式的的转换关系如\Fref{fig:convert_format}所示。 \begin{figure}[htbp] \centering \begin{tikzpicture} \node[box] (tex) {.tex}; \node[box] (dvi) [right=5 of tex] {.dvi}; \node[box] (pdf) [right=6 of dvi] {.pdf}; \node[box] (ps) [above=3 of pdf] {.ps}; \path (tex) edge [arrow] node[auto] {latex} (dvi) (dvi) edge [arrow] node[auto] {dvipdfm} (pdf) (dvi.north) [arrow,draw] to node[above,sloped] {dvips} (ps.west) (ps) edge [arrow] node[right] {ps2pdf} (pdf) (tex) edge [arrow,bloop] (pdf); \node [below=.7 of dvi] {pdflatex}; \end{tikzpicture} \caption{格式转换} \label{fig:convert_format} \end{figure} 最早的~driver~是~\verb|dvips|,它把~DVI~转换为~PS。\verb|dvipdf|~把~DVI~转为~PDF,它后来被~\verb|dvipdfm|~所取代;\verb|dvipdfm|~主要用于处理单字节字符,1999~年之后停止开发;在~\verb|dvipdfm|~基础上发展来的~\verb|dvipdfmx|~可以处理多字节编码(字符编码详见\ref{sec:encoding}节)。 pdf\TeX~是一种特殊的driver,它跳过~DVI,直接用~\TeX~源文件生成~PDF。基于~pdf\TeX~的~pdf\LaTeX~则把\LaTeX~源文件转为~PDF。 包老师倾向于~\verb|dvipdfmx|,因为它对图形格式的兼容性较好,而且擅长处理中文。 得到~DVI~后,我们可以在控制台用以下命令把它转为~PDF。 \begin{code} dvipdfm hello_world(.dvi) \end{code} 我们也可以把它转为~PS,接着用~Ghostscript~的一个命令行程序把它转换为~PDF,注意第二个命令需要~\verb|.ps|~后缀。一般情况下不推荐这种方法,因为它多了个步骤。 \begin{code} dvips hello_world(.dvi) ps2pdf hello_world.ps \end{code} pdf\LaTeX~用法如下。 \begin{code} pdflatex hello_world(.tex) \end{code} \section{\LaTeX~语句} \LaTeX~源文件的每一行称作一条语句(statement),语句可以分三种:命令(command)、数据(data)和注释(comment)。 命令分为两种:普通命令和环境(environment)。普通命令以\verb|\|~起始,大多只有一行;而环境包含一对起始声明和结尾声明,用于多行的场合。命令和环境可以互相嵌套。 数据就是普通内容。注释语句以~\verb|%|~起始,它在编译过程中被忽略。 例如在\ref{sec:hello_world}节例1中,第一行是注释,第二行是普通命令;第三、五行是环境的起始和结尾声明;第四行是数据。 \section{文档结构} \subsection{文档类、序言、正文} \LaTeX~源文件的结构分三大部分,依次为:文档类声明、序言(可选)、正文。 文档类声明用来指定文档的类型;序言(preamble)用来完成一些特殊任务,比如引入宏包,定义命令,设置环境等;文档的实际内容则放在正文部分。这里的正文指得是\verb|\begin{document}|和\verb|\end|~\verb|{document}|之间的部分,和通常人们心目中的“正文”概念有所出入。 这三部分的基本语法如下: \begin{code} \documentclass[options]{class} %文档类声明 \usepackage[options]{package} %引入宏包 ... \begin{document} %正文 ... \end{document} \end{code} 常用的文档类(documentclass)有三种:\verb|article、report、book|,它们的常用选项见\fref{tab:class_options}。 \begin{table}[htbp] \centering \caption{文档类常用选项} \label{tab:class_options} \begin{tabularx}{350pt}{lX} \toprule 10pt, 11pt, 12pt & 正文字号,缺省10pt。\LaTeX~会根据正文字号选择标题、上下标等的字号。\\ letterpaper, a4paper & 纸张尺寸,缺省是~letter。\\ notitlepage, titlepage & 标题后是否另起新页。article~缺省~notitlepage,report~和~book~缺省有~titlepage。\\ onecolumn, twocolumn & 栏数,缺省单栏。\\ oneside, twoside & 单面双面。article~和~report~缺省单面,book~缺省双面。\\ landscape & 打印方向横向,缺省纵向。\\ openany, openright & 此选项只用于~report~和~book。report~缺省~openany~,book~缺省~openright。\\ draft & 草稿模式。有时某些行排得过满,draft~模式可以在它们右边标上粗黑线提醒用户。\\ \bottomrule \end{tabularx} \end{table} \LaTeX~的核心只提供基本的功能,系统以宏包(package)的形式提供附加功能或增强原有功能。其它一些编程语言也有类似的模块化机制,比如~C/C++~的~\verb|#include|,Java~的~\verb|import|。 \subsection{标题、摘要、章节} 一份文档正文部分的开头通常有标题、作者、摘要等信息,之后是章节等层次结构,内容则散布于层次结构之间。 标题、作者、日期等命令如下,注意\verb|\maketitle|~命令要放在最后。 \begin{code} \title{标题} \author{作者} \today \maketitle \end{code} 摘要环境用法如下: \begin{code} \begin{abstract} ... \end{abstract} \end{code} 常用的层次结构命令如下, \begin{code} \chapter{...} \section{...} \subsection{...} \subsubsection{...} \end{code} 每个高级层次可以包含若干低级层次。\verb|article|~中没有~\verb|chapter|,而~\verb|report|~和~\verb|book|~则支持上面所有层次。 \subsection{目录} 我们可以用~\verb|\tableofcontents|~命令来生成整个文档的目录,\LaTeX~会自动设定目录包含的章节层次,也可以用~\verb|\setcounter|~命令来指定目录层次深度。 \begin{code} \tableofcontents \setcounter{tocdepth}{2} \end{code} 如果不想让某个章节标题出现在目录中,可以使用以下带~\verb|*|~的命令来声明章节。 \begin{code} \chapter*{...} \section*{...} \subsection*{...} \end{code} 类似地,我们也可以用以下命令生成插图和表格的目录,插图和表格功能将在后面章节中介绍。 \begin{code} \listoffigures \listoftables \end{code} 当章节或图表等结构发生变化时,我们需要执行两遍编译命令以获得正确结果。\LaTeX~之所以设计成这样可能是因为当时的电脑内存容量有限。 \section{文字排版} \subsection{字符输入} 文档中可以输入的内容大致可以分为:普通字符、控制符、特殊符号、注音符号、预定义字符串等。而这些内容有两种输入模式:文本模式(缺省)和数学模式,普通的行间(inline)数学模式用\verb|\$...\$|来表示。 \LaTeX~中有些字符(例如~\verb|# $ % ^ & _ { } ~ \|~等)被用作特殊的控制符,所以不能直接输入,多数需要在前面加个~\verb|\|。而~\verb|\|~本身则要用~\verb|\textbackslash|~命令来输入,因为~\verb|\\|~被用作了换行指令。很奇怪为什么不用~C~语言的~\verb|\n|,也许是因为~\TeX~的编程语言是~Pascal。 \begin{code} \# \$ \% \^{} \& \_ \{ \} \~{} \textbackslash \end{code} \Fref{tab:symbol}~提供了一些符号的输入方法示例,完整的符号列表见~Scott Pakin的《The Comprehensive \LaTeX~ Symbol List》\citep{Pakin_2008}。 \begin{table}[htbp] \centering \caption{一些符号和预定义字符串} \label{tab:symbol} \begin{tabular}{llllll} \toprule \multicolumn{2}{c}{特殊符号} & \multicolumn{2}{c}{注音符号} & \multicolumn{2}{c}{预定义字符串} \\ \cmidrule(lr){1-2} \cmidrule(lr){3-4} \cmidrule(lr){5-6} \textcopyright & \verb|\textcopyright| & \aa & \verb|\aa| & \today & \verb|\today| \\ \textregistered & \verb|\textregistered| & \AA & \verb|\AA| & \TeX & \verb|\TeX| \\ $^\circ$C & \verb|$^\circ$C| & \ae & \verb|\ae| & \LaTeX & \verb|\LaTeX| \\ \textyen & \verb|\textyen| & \o & \verb|\o| & \LaTeXe & \verb|\LaTeXe| \\ \pounds & \verb|\pounds| & \"o & \verb|\"o| & \MF & \verb|\MF| \\ \texteuro & \verb|\texteuro| & \^o & \verb|\^o| & \MP & \verb|\MP| \\ \dots & \verb|\dots| & \~o & \verb|\~o| & \\ \bottomrule \end{tabular} \end{table} \subsection{换行、换页、断字} 通常~\LaTeX~会自动换行、换页。用户也可以用~\verb|\\|~或~\verb|\newline|~来强制换行;用~\verb|\newpage|~来强制换页。 一般情况下~\LaTeX~会尽量均匀地断字(Hyphenate),使得每一行的字间距分布整齐。但有时我们也需要显式指明断字位置,比如下例就指明~BASIC~这个词不能断开,而~blar-blar-blar~可以在-处断开。 \begin{code} \hyphenation{BASIC blar-blar-blar} \end{code} \subsection{字样、字号} \LaTeX~会自动调整正文、标题、章节、上下标、脚注等的字样\footnote{关于字样详见\ref{sec:typeface}节}、字号。我们也可以用\fref{tab:typeface_command}中的命令来设置字样;用\fref{tab:fontsize_command}中的命令来设置相对字号,比如正文字号是~10pt、11pt、12pt~时,tiny的字号就分别是~5pt、6pt、6pt。 \LaTeX~有一个特别的字样强调命令:\verb|\emph|,它在不同字样和装饰环境下有不同效果。比如周围文字是正体,它就是斜体;反之它就是正体。 \begin{table}[hbtp] \centering \caption{字样命令} \label{tab:typeface_command} \begin{tabular}{llll} \toprule \verb|\textrm{...}| & \textrm{roman} & \verb|\textbf{...}| & \textbf{bold face} \\ \verb|\textsf{...}| & \textsf{sans serif} & \verb|\textit{...}| & \textit{italic} \\ \verb|\texttt{...}| & \texttt{typewriter} & \verb|\textsl{...}| & \textsl{slanted} \\ \\ \verb|\emph{...}| & \emph{emphasized} & \verb|\underline{...}| & \underline{underline} \\ \verb|\textsc{...}| & \textsc{Small Caps} & & \\ \bottomrule \end{tabular} \end{table} \begin{table}[htbp] \centering \caption{字号命令} \label{tab:fontsize_command} \begin{tabular}{llll} \toprule & \multicolumn{3}{c}{正文字号} \\ \cmidrule(lr){2-4} 命令 & 10pt & 11pt & 12pt \\ \midrule \verb|\tiny| & 5pt & 6pt & 6pt \\ \verb|\scriptsize| & 7pt & 8pt & 8pt \\ \verb|\footnotesize| & 8pt & 9pt & 10pt \\ \verb|\small| & 9pt & 10pt & 11pt \\ \verb|\normalsize| & 10pt & 11pt & 12pt \\ \verb|\large| & 12pt & 12pt & 14pt \\ \verb|\Large| & 14pt & 14pt & 17pt \\ \verb|\LARGE| & 17pt & 17pt & 20pt \\ \verb|\huge| & 20pt & 20pt & 25pt \\ \verb|\Huge| & 25pt & 25pt & 25pt \\ \bottomrule \end{tabular} \end{table} \section{常用命令环境} \subsection{列表} \LaTeX~中有三种列表环境:\verb|itemize、enumerate、description|,它们的一般用法如下: \begin{demo} \begin{itemize} \item C++ \item Java \item HTML \end{itemize} \end{demo} \begin{demo} \begin{enumerate} \item C++ \item Java \item HTML \end{enumerate} \end{demo} \begin{demo} \begin{description} \item{C++} 一种编程语言 \item{Java} 另一种编程语言 \item{HTML} 一种标记语言 \end{description} \end{demo} \subsection{对齐} \LaTeX~中的段落缺省两端对齐(fully justified),我们也可以让段落居左、居右或居中对齐。 \begin{demo} \begin{flushleft} 本段落\\ 居左 \end{flushleft} \end{demo} \begin{demo} \begin{flushright} 本段落\\ 居右 \end{flushright} \end{demo} \begin{demo} \begin{center} 本段落\\ 居中 \end{center} \end{demo} \subsection{摘录} \LaTeX~中有三种摘录环境:\verb|quote、quotation、verse|。\verb|quote|~两端都缩进,\verb|quotation|~在~\verb|quote|~的基础上增加了首行缩进,\verb|verse|~比~\verb|quote|~多了第二行起的缩进。 \begin{demo} 正文 \begin{quote} 引文两端都缩进。 \end{quote} 正文 \end{demo} \begin{demo} 正文 \begin{quotation} 引文两端缩进,首行缩进。 \end{quotation} 正文 \end{demo} \begin{demo} 正文 \begin{verse} 引文两端缩进,第二行起缩进。 \end{verse} 正文 \end{demo} \subsection{原文照排} 一般文档中,命令和源代码通常使用等宽字样来表示,也就是原文照排。对此~\LaTeX~提供了~\verb|\verb|~命令(一般用于在正文中插入较短的命令)和~\verb|verbatim|~环境。后者有带~\verb|*|~的版本用来标明空格。 \begin{demo} 正文中插入\verb|command| \begin{verbatim} printf("Hello, world!"); \end{verbatim} \begin{verbatim*} printf("Hello, world!"); \end{verbatim*} \end{demo} \subsection{交叉引用} 我们常常需要引用文档中~\verb|section、subsection、figure、table|~等对象的编号,这种功能叫作交叉引用(cross referencing)。 \LaTeX~中可以用~\verb|\label{marker}|~命令来定义一个标记,标记名可以是任意字符串,但是在全文中须保持唯一。之后可以用~\verb|\ref{marker}|~命令来引用标记处章节或图表的编号,用~\verb|\pageref{marker}|~来引用标记处的页码。 \begin{demo} 被引用处\label{sec}\\ ...\\ 第\pageref{sec}页\ref{sec}节 \end{demo} 文档中新增交叉引用后,第一次执行~\verb|latex|~或~\verb|pdflatex|~编译命令时会得到类似下面的警告信息。因为第一次编译只会扫描出有交叉引用的地方,第二次编译才能得到正确结果。 \begin{code} LaTeX Warning: There were undefined references. ... LaTeX Warning: Label(s) may have changed. Rerun to get cross- references right. \end{code} \subsection{脚注} 脚注(footnote)的一般用法如下: \begin{demo} 这里是一段正文。\footnote{这里是一段脚注。} \end{demo} \section{长度单位} \LaTeX~中的常用长度单位如\Fref{tab:unit}~所示。point~是个传统印刷业采用的单位,而~big point~是~Adobe~推出~PS~时新定义的单位。em~是个相对单位,比如当前字体是~11pt~时,1em~就是~11pt。 \begin{table}[htbp] \caption{常用长度单位} \label{tab:unit} \centering \begin{tabular}{llllll} \toprule in & 英寸 & pt & point, 1/72.27 in & em & 当前字体中字母M的宽度 \\ cm & 厘米 & bp & big point, 1/72 in & ex & 当前字体中字母x的高度 \\ mm & 毫米 & pc & pica, 12 pt & mu & math unit,1/18 em \\ \bottomrule \end{tabular} \end{table} \section{盒子} \LaTeX~在排版时把每个对象(小到一个字母,大到一个段落)都视为一个矩形盒子(box),我们在~HTML~和~CSS~中也可以见到类似的模型。 \subsection{mbox~和~fbox} \LaTeX~中最简单的盒子是~\verb|\mbox|~和~\verb|\fbox|。前者把一组对象组合起来,后者在此基础上加了个边框。 \begin{demo} \mbox{010 6278 5001} \fbox{010 6278 5001} \end{demo} \subsection{makebox~和~framebox} 稍复杂的~\verb|\makebox|~和~\verb|\framebox|~提供了宽度和对齐方式控制选项。这里用~l、r、s~分别代表居左、居右和分散对齐。 \begin{demo} %语法:[宽度][对齐方式]{内容} \makebox[100pt][l]{居左} \framebox[100pt][r]{居右} \end{demo} \subsection{parbox~和~minipage} 大一些的对象比如整个段落可以用~\verb|\parbox|~命令和~\verb|\minipage|~环境,两者语法类似,也提供了对齐方式和宽度的选项。但是这里的对齐方式是指与周围内容的纵向关系,用~t、c、b~分别代表居顶、居中和居底对齐。 \begin{demo} %语法:[对齐方式]{宽度}{内容} \parbox[c]{90pt}{锦瑟无端五十弦,\\一弦一柱思华年。}李商隐 \end{demo} 细心的读者会发现~\verb|\parbox|~和~\verb|\minipage|~的选项排列顺序和~\verb|\makebox|~和~\verb~\framebox|~的不一致,可能出自不同的作者。 \bibliographystyle{unsrtnat} \bibliography{reading} \newpage