【论文写作】--LaTeX详细入门教程2

紧接着之前的表格介绍:

目录

[9. LaTeX--交叉引用](#9. LaTeX--交叉引用)

10.LaTeX--数学公式

10.1.数学模式

10.2.行内公式

10.3.行间模式

[10.4.amsmath 宏包](#10.4.amsmath 宏包)

10.5.公式字体

11.LaTeX--字体与间距

11.1.段间距

11.2.强制断行

11.3.设定文本格式

12.LaTeX--引用和参考文献

12.1.引用数据库

12.2.转化信息

[12.3.natbib 工作流](#12.3.natbib 工作流)

[12.4.biblatex 工作流](#12.4.biblatex 工作流)

13.LaTeX--组建源代码

[13.1.使用 \input](#13.1.使用 \input)

[13.2.使用 \include 和 \includeonly](#13.2.使用 \include 和 \includeonly)

13.3.创建目录

13.4.分割文档

[14.LaTeX--字体Unicode 引擎](#14.LaTeX--字体Unicode 引擎)

15.LaTeX--处理报错

[15.1.pdflatex 未找到](#15.1.pdflatex 未找到)

[15.2.TeX 错误信息结构](#15.2.TeX 错误信息结构)

15.2.未配对括号

15.3.未找到文件

15.4.行间公式中的空行​​​​​​​


9. LaTeX--交叉引用

在编写任何长度的文档时,你可能都想引用一些编号过的项目,例如:图片、表格或者公式。幸运的是,我们只需要进行些许设置,LaTeX 便能够自动添加正确的编号。

**\label 和 \ref 机制:**为了让 LaTeX 记住文档中的一个位置,你必须先标记它,然后在其他位置引用它。

Matlab 复制代码
\documentclass{article}

\begin{document}
Hey world!

This is a first document.

\section{Title of the first section}

Text of material for the first section.

\subsection{Subsection of the first section}
\label{subsec:labelone}

Text of material for the first subsection.
\begin{equation}
  e^{i\pi}+1 = 0
\label{eq:labeltwo}
\end{equation}

In subsection~\ref{subsec:labelone} is equation~\ref{eq:labeltwo}.
\end{document}

这里有两个 label{...} 命令,一个在 subsection 之后,一个在 equation 环境内部。它们在最后一句的 \ref{...} 命令中一起出现。当你运行 LaTeX 时,它保存 labels 的信息到辅助文件 (.aux) 中。对于 \label{subsec:labelone} ,LaTeX 知道现在位于 subsection 环境中,所以保存了 subsection 的编号。对于 \label{eq:labeltwo},LaTeX 知道最新关注的环境是 equation,所以它保存了对应 equation 的信息。当你要求引用时,LaTeX 会在辅助文件中得到它。

subsec:eq: 并不被 LaTeX 使用;实际上,它只是为了记下来在这个标签之前最近的位置在处理什么内容。明确地写出它们可以帮助你记住标签的含义。

你或许会看到引用的内容在输出的 PDF 文件中显示为两个加粗的问号,??。这是由于辅助文件的工作性质所导致,在第一次编译文档时标签尚未保存到辅助文件中。再运行一次 LaTeX,你会得到正确的结果。(通常在你编写文档时,无论如何都会多次运行 LaTeX,所以在实践中,这并不是什么麻烦。)

注意引用前的符号带子(~)。你或许不想在 subsection 和它的编号之间、或者是 equation 和它的编号之间产生断行。放一个符号带子表示 LaTeX 不会在这里产生断行。

\label 命令总是引用在此之前编号过的一个对象:一个章节、一个公式、一个浮动体等。这意味着 label 总是添加在你想引用的东西后面。特别地,当你创建浮动体时,\label 应该跟在 \caption 命令后面(或者更好的方式是在里面),并处于浮动体环境内部

10.LaTeX--数学公式

排版复杂的数学公式是 LaTeX 最重要的优势之一。你可以在「数学模式」下通过逻辑标记的方式编写数学公式。

10.1.数学模式

在数学模式下,空格会被省略,字符间(基本上)都会有恰当的空格。

数学模式有两种形式:

  • 行内公式
  • 行间公式
Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
A sentence with inline mathematics: $y = mx + c$.
A second sentence with inline mathematics: $5^{2}=3^{2}+4^{2}$.%行内


A second paragraph containing display math.
\[
  y = mx + c%行间
\]
See how the paragraph continues after the display.
\end{document}

你或许在其他地方看到了「类似 LaTeX 的」数学公式输入系统。比如,可以向网页中放置公式的 MathJax。这些系统之所以通常接受 LaTeX 语法的微小变种作为输入,是因为它们实际上并不使用 LaTeX「后端」。

我们的例子都使用了标准的 LaTeX 语法。如果你在其他地方看到了一些不同的用法,那么可能只是因为你看到的内容用的并不是 LaTeX。

10.2.行内公式

由上文可见,行内数学公式是通过一对美元符号**($...$)**标记的。当然用 \( ... \) 标记也是可行的。输入简单表达式不需要任何特殊的标记,你将看到数学公式会被排版出合适的间隔而且文字会变成斜体。

行内数学模式限制了表达式的纵向高度以使数学公式尽可能不打乱段落的行间距。

注意到所有的数学符号都应被标记成数学模式下的 。即使只是一个字符也应该使用 ... $2$ ... 而不是 ... 2 ...。否则,比如说,你需要输入一个负数,然后需要使用数学模式来输入负号,那么 ... $-2$ ... 可能就会产生与文本模式下不同的数字字体(这取决于文档类的选择)。相反地,要注意从其他地方复制过来的纯文本可能会导致数学模式的构造,比如用于表示金额的美元符号 $ ,或者是表示文件名的下划线符号 _(这些应该分别被标记为 \$\_)。

我们可以很容易地添加上标和下标:分别通过 **^_**标记。

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
Superscripts $a^{b}$ and subscripts $a_{b}$.
\end{document}

(你可能会看到一些不使用大括号来包裹简单上标和下标的例子,但是这并不是标准的语法,而且可能会导致错误。所以永远记得使用大括号。)

LaTeX 里有许多 专有的数学模式命令。它们中有些很容易,比如 \sin\log 用来分别表示正弦符号和对数符号,\theta 用于表示对应的希腊符号。

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
Some mathematics: $y = 2 \sin \theta^{2}$.
\end{document}

10.3.行间模式

你可以在行间模式中使用与行内模式一样的命令。行间数学模式默认设置在居中位置,并为「仍属于该段」的大型公式所准备。注意到行间数学环境不允许在数学模式中结束该段,所以你也许不能够在该模式的源代码中留有空行。

段落都应当在行间公式之前 开始,所以不要在行间数学环境之前留有空行。如果你的数学公式有多行,不要使用多个连续的行间数学环境(这将导致不一致的行间距),而是使用一种多行行间公式环境,比如稍后提及的 amsmath 宏包中 align 环境。

对于积分来说,行间公式尤其有用,来看下面的例子:

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
A paragraph about a larger equation
\[
\int_{-\infty}^{+\infty} e^{-x^2} \, dx
\]
\end{document}

请注意观察这里是如何使用上标和下标设定积分上下限的。

这里我们手动添加了一个间隙:\,,以在 dx 前添加一个小间隙。微分符号的格式各有差别:一些出版商使用直立的「d」而其他出版商使用斜体的「d 」。为了适应这两种方式,编写源代码的一种方法就是定义一个 \diff 命令,这样你就能够根据需要进行调整

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\newcommand{\diff}{\mathop{}\!d}            % 斜体
% \newcommand{\diff}{\mathop{}\!\mathrm{d}} % 直立体
\begin{document}
A paragraph about a larger equation
\[
\int_{-\infty}^{+\infty} e^{-x^2} \diff x
\]
\end{document}

你通常需要对公式编号,使用 equation 环境可以创建这些编号。让我们再次尝试同一个例子:

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
A paragraph about a larger equation
\begin{equation}
\int_{-\infty}^{+\infty} e^{-x^2} \, dx
\end{equation}
\end{document}

公式编号将会自动递增,公式旁或者只有一个数字(就像这个例子一样),或者会加一个目次号码的前缀,比如 (2.5) 表示第 2 节的第 5 个公式。设定编号格式是在文档类内进行的,这里就不再展开了。

10.4.amsmath 宏包

数学符号太多了,就意味着 LaTeX 内核内置的工具并不能提供所有内容。amsmath 宏包拓展了内核以提供更多的方案。amsmath 用户手册提供了比本课更多的例子。

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath}

\begin{document}
Solve the following recurrence for $ n,k\geq 0 $:
\begin{align*}
  Q_{n,0} &= 1   \quad Q_{0,k} = [k=0];  \\
  Q_{n,k} &= Q_{n-1,k}+Q_{n-1,k-1}+\binom{n}{k}, \quad\text{for $n$, $k>0$.}
\end{align*}
\end{document}

align* 环境会让公式在和号 & 处对齐,这和表格的用法是一样的。注意一下我们是如何使用 \quad 添加小间距、以及使用 \text 向数学模式添加正常的文字。我们这里还使用了另一个数学模式命令:二项式 \binom

还注意到我们使用了 align* 环境,让公式不被编号。大部分的数学环境都会默认对公式编号,而带星号(*)的变式关闭了编号功能

该宏包还提供了其他几个很方便的环境,比如说对于矩阵:

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\begin{document}
AMS matrices.
\[
\begin{matrix}
a & b & c \\
d & e & f
\end{matrix}
\quad
\begin{pmatrix}
a & b & c \\
d & e & f
\end{pmatrix}
\quad
\begin{bmatrix}
a & b & c \\
d & e & f
\end{bmatrix}
\]
\end{document}

10.5.公式字体

和正常文本不同的是,数学模式的字体变化通常会蕴含非常特定的意义。因此它们经常被写做特殊的命令。下面就是你需要的一组命令:

  • \mathrm: 罗马字体(直立体)
  • \mathit: 使用普通文本字间隔的斜体
  • \mathbf: 粗体
  • \mathsf: 衬线字体
  • \mathtt: 等宽字体(打字机字体)
  • \mathbb: 双重粗体(黑板粗体,由 amsfonts 宏包提供)

这些命令接受英文字母作为参数,因此如果我们要写出一个矩阵符号的话:

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
The matrix $\mathbf{M}$.
\end{document}

注意默认情况下数学斜体会让字母产生较大的间距,因此它们可能会看起来像是一些变量的乘积。这种情况下,使用 \mathit 来产生斜体文字。

这些数学字体命令 \math.. 针对数学使用了特殊的字体。

有时你可能需要在数学公式中嵌入一个属于外部句子的词,并需要使用当前文段的字体 ,在这种情况下可以使用 \text{...}(由 amsmath 宏包提供)或者是特定的字体比如 \textrm{..}

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\begin{document}

$\text{bad use } size  \neq \mathit{size} \neq \mathrm{size} $

\textit{$\text{bad use } size \neq \mathit{size} \neq \mathrm{size} $}

\end{document}

11.LaTeX--字体与间距

我们已经看到在 LaTeX 中输入一个空行将会另起一个段落,表征为以一个首行缩进开始的段落。

11.1.段间距

一种比较常见的样式是段落首行没有缩进,但要在段落之间插入空行。这种情形我们可以使用 parskip 宏包实现。

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[parfill]{parskip}
\usepackage{lipsum} % 为了填充假文
\begin{document}
\lipsum
\end{document}

11.2.强制断行

大部分情况下,你都不应当在 LaTeX 中强制断行:你几乎只是想另起一段,或者是想在段落之间添加空行(就像我们看到的那样,使用 parskip 宏包就可实现)。

只有很少的 情况下你需要使用 \\ 来另起一行而不另起一段:

  • 在表行的结尾处
  • center 环境中
  • 诗歌(verse 环境)

如果不属于这些情况,大多数时候你就 应当使用 \\

Matlab 复制代码
\documentclass{article}
\usepackage{parskip}
% 使用开源通用字体集,避免宋体缺失问题
\usepackage[fontset=ubuntu]{ctex}

\begin{document}

\section{正确做法:段落之间空行分段,不要随便用\texttt{\textbackslash\textbackslash}}
这是第一段正文。LaTeX 会自动处理换行、对齐、断词,不需要手动干涉。
文字再多也会自动铺满一行然后换行,完全不用加 \textbackslash\textbackslash。

这是第二段,两段之间直接空一行即可,\textsf{parskip} 宏包会自动在两段之间留出间距,阅读更舒服。

这是第三段,用 \verb|\par| 也可以手动分段,效果和空行一样\par
紧跟的第四段,没有首行缩进,段间自带空隙。

\section{仅允许使用 \texttt{\textbackslash\textbackslash} 的三种场景}
\subsection{场景1:表格内部换行}
\begin{tabular}{l l}
姓名 & 专业 \\ % 表格行末尾必须用 \\
张三 & 数学 \\
李四 & 计算机
\end{tabular}

\subsection{场景2:center 等居中环境内手动分行}
\begin{center}
白日依山尽 \\
黄河入海流 \\
欲穷千里目 \\
更上一层楼
\end{center}

\subsection{场景3:verse 诗歌环境分行}
\begin{verse}
床前明月光,\\
疑是地上霜。\\
举头望明月,\\
低头思故乡。
\end{verse}

\section{反面示例:正文段落乱用 \texttt{\textbackslash\textbackslash}(不推荐)}
下面这段强行用 \textbackslash\textbackslash 换行,会造成行间距错乱、对齐难看:
Lorem ipsum dolor sit amet, \\
consectetur adipiscing elit. \\
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

对比上方正常分段,能明显看出强行换行排版非常不美观,正式文档禁止这样写。

\end{document}

11.3.设定文本格式

大部分情况下使用逻辑结构是更好的。但是有些时候,你可能想要对字体做加粗、斜体、等宽等等的处理。这时就有两种命令可用:一种用于小段,一种用于大段。

对于小段而言 ,我们可以使用 \textbf, \textit, \textrm, \textsf, \texttt 以及 \textsc

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
Let's have some font fun: \textbf{bold}, \textit{italic}, \textrm{roman},
\textsf{sans serif}, \texttt{monospaced} and \textsc{small caps}.
\end{document}

对于大段来说 ,我们使用能够更改字体设置的命令:比如说 \bfseries\itshape。因为这些命令设置完毕后不会复原,所以我们需要定义一个「组(group)」用以防止这些设置作用于整个文档。LaTeX 环境是一个组,表格单元格也是一个组,我们也可以使用 {...} 来显式地定义一个组。

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
Normal text.

{\itshape

This text is italic.

So it this: the effect is not limited to a paragraph.

}
\end{document}

我们可以采用类似的方式设置字体大小------这些命令也是持续向后影响的设置。这些命令设置相对字体大小:常见的有 \huge, \large, \normalsize, \small 以及 \footnotesize。请注意要在改回字体大小之前 结束该段:可以从下面的例子看到我们是怎么显式地添加 \par(结束该段)的

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
Normal text.

\begin{center}
{\itshape\large Some text\par}
Normal text
{\bfseries\small Much smaller text\par}
\end{center}

\end{document}

12.LaTeX--引用和参考文献

对于文献引用来说,虽然你可以直接引用当前文档中的内容,但是大部分情况下,你可能会从一个或多个外部文件得到文献信息。这种文件就是文献数据库,以一种便于处理的格式存储。使用一个或多个文献数据库可以让你复用一些信息并避免手动设定格式。

12.1.引用数据库

引用数据库一般被称作「BibTeX 文件」 ,并带有文件扩展名 .bib。它们包含一条或多条记录,每条记录对应一个引用,每条记录中都会有一系列的域(field)。让我们看一个例子:

Matlab 复制代码
@article{Thomas2008,
  author  = {Thomas, Christine M. and Liu, Tianbiao and Hall, Michael B.
             and Darensbourg, Marcetta Y.},
  title   = {Series of Mixed Valent {Fe(II)Fe(I)} Complexes That Model the
             {H(OX)} State of [{FeFe}]Hydrogenase: Redox Properties,
             Density-Functional Theory Investigation, and Reactivity with
             Extrinsic {CO}},
  journal = {Inorg. Chem.},
  year    = {2008},
  volume  = {47},
  number  = {15},
  pages   = {7009-7024},
  doi     = {10.1021/ic800654a},
}
@book{Graham1995,
  author    = {Ronald L. Graham and Donald E. Knuth and Oren Patashnik},
  title     = {Concrete Mathematics},
  publisher = {Addison-Wesley},
  year      = {1995},
}

这两条中一条是文章,另一条是书籍------这些是目前最常见的类型。正如上面所示,每个记录都以 @ 开头,之后所有的信息都会被一对大括号包裹起来。

我们需要的大部分域虽然都以键值对的格式给出,但是与「主键」(key)相区别:「主键」是引用名。你可以使用任意一个名字,毕竟它只是一个标签。而在上面的例子中我们选择使用「作者名+年份」的格式(通常都是这么做的)。

虽然对于需要确切提供什么域,取决于记录类型的选择,但是大部分的域都是顾名思义的。你可能注意到了,在 author 域,每一个作者都以 and 分开。这很重要输出格式需要了解哪一块是这个作者。你可能还注意到了,在文章标题中,有些部分还会被大括号包裹------以避免被作用任何大小写更正规则。

因为手动编写 .bib 可太枯燥了,所以大部分人都会选择一个专用编辑器。JabRef 跨平台并被广泛使用,当然也有很多其他可用软件。 如果引用有 DOI(数字对象唯一标识符,Digital Object Identifier),你可能想要尝试 doi2bib 来方便地得到 BibTeX 记录(译者注:JabRef 也已内置)。但一定要检查记录是不是正确的那个!

这里我们将使用上面的小数据库来做下面的演示------我们已经将其保存为 learnlatex.bib

12.2.转化信息

将信息插入你的文档分三步走。

  • 第一步,使用 LaTeX 编译你的文档,这将会产生包含文档引用列表的文件。
  • 第二步,运行一个从引用数据库获取信息的程序,检索出你使用的引用条目,然后按照顺序将它们排列起来。
  • 第三步,再次编译你的文档,这样 LaTeX 就可以使用这些信息来解析你的引用信息。通常这需要至少两次的编译来解析所有的引用。

对于第二步而言,现在有两种广泛使用的系统:BibTeX 和 Biber。Biber 仅供 LaTeX 中一个叫 biblatex 的宏包使用,而 BibTeX 可以不搭配宏包使用或者搭配 natbib 使用。

LaTeX 与这两者在不同编辑器上运行需要使用不同的方式处理。我们的在线示例有一些后台脚本来一键完成所有的事宜。你的编辑器可能也有「一键完成」按钮,不然的话,你可能需要在不同的 LaTeX 文档编译中手动选择 BibTeX 或 Biber。

引用(citation)和参考(reference)的格式是独立于 BibTeX 数据库的,并且被一种名为 style(样式)的东西所设定。我们将会看到这些东西在 BibTeX 和 biblatex 工作流中有些许差异,但整体思想是一致的:我们可以选择引用显示的方式。

12.3.natbib 工作流

虽然可以在不加载任何宏包的情况下向 LaTeX 文档插入引用,但这还是比较局限的。与之相对的,我们将使用 natbib 宏包,允许我们创建不同类型的引用,并且可以使用许多类型的样式。

我们输入的基本结构如这个例子所示:

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{natbib}

\begin{document}
The mathematics showcase is from \citet{Graham1995}, whereas
there is some chemistry in \citet{Thomas2008}.

Some parenthetical citations: \citep{Graham1995}
and then \citep[p.~56]{Thomas2008}.

\citep[See][pp.~45--48]{Graham1995}

Together \citep{Graham1995,Thomas2008}

\bibliographystyle{plainnat}
\bibliography{learnlatex.bib}
\end{document}

你可以看到我们通过对应的键名引用了数据库里不同的记录。natbib 宏包提供了文本和括号的引用样式:分别是 \citet\citep。参考文献样式是通过 \bibliographystyle 这一行选择的:这里我们使用了 plainnat 样式。参考文献实际上是通过 \bibliography 这一行插入的,同时也选择了使用的数据库(多个数据库采用逗号分隔数据库名)。

页码引用可以通过一个可选参数添加。如果提供了两个可选参数,那么第一个可选参数就被当作引用前的小标记,第二个可选参数就被当作引用标签后的页码引用。

上述设定使用了作者---年份(author-year)样式。但是我们也可以采用数字编码的引用方式。这可以通过向 natbib 行添加 numbers 选项来实现。

12.4.biblatex 工作流

biblatex 宏包和 natbib 运作方式稍有不同,主要体现在导言区内选择数据库和文档正文内的排印上。它会有一些新的命令。

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[style=authoryear]{biblatex}
\addbibresource{learnlatex.bib} % 引用文件

\begin{document}
The mathematics showcase is from \autocite{Graham1995}.

Some more complex citations: \parencite{Graham1995} or
\textcite{Thomas2008} or possibly \citetitle{Graham1995}.

\autocite[56]{Thomas2008}

\autocite[See][45-48]{Graham1995}

Together \autocite{Thomas2008,Graham1995}

\printbibliography
\end{document}

注意到 \addbibresource 需要 数据库文件名的全称,而不是我们对于 natbib 下的 \bibliography 中省略 .bib 的情形。虽然 biblatex 使用了相对更长的引用命令,但是这些基本上都是顾名思义的。

再次地,引用前后的文字可以通过可选参数插入。注意,这里的页码不需要添加 p.~ 或者 pp.~ 前缀,biblatex 可以自动添加合适的前缀。

biblatex 里,加载宏包时文献样式就被选择了。这里,我们使用了 authoryear,当然也可以用 numeric 数字编码和其他许多样式。

对比维度 natbib工作流 biblatex
样式控制机制 依赖外部 .bst 文件(由 \bibliographystyle 指定) 不使用 .bst,通过导言区 LaTeX 命令直接控制
定制化难度 ❌ 较难:需学习 BibTeX 编程语言并修改外部文件 ✅ 更易:使用熟悉的 LaTeX 命令即可修改格式
引用命令丰富度 基础引用命令,功能相对有限 ✅ 提供更广泛的引用命令,支持复杂样式设计
字符排序能力 ❌ 仅支持美式 ASCII 排序,非 ASCII 需变通处理 ✅ 完整 Unicode 排序,完美支持非英语/多语言文献
环境搭建难度 ✅ 简单,兼容性好 相对复杂,配置项较多
期刊/出版社兼容性 ✅ 广泛支持,多数出版社要求或默认接受 ❌ 部分出版社不支持或不期望接收 biblatex 提交
模板/项目约束 若模板附带 .bst 或项目强制要求,必须使用 无法直接使用现有 .bst 文件
适用学科场景 STEM 等对引用样式要求不高的领域 人文学科等需要复杂引用样式的领域

13.LaTeX--组建源代码

当你编写长文档的时候,很可能想将源代码分割成多个文件。比如,很常见的做法是,创建一个 mainroot 文件,然后每一章创建一个源文件(对于一本书或者一篇论文),或者每一个长节创建一个源文件(对于一篇长文档)。

LaTeX 允许我们以可控的方式分割源代码。对此,有两个很重要的命令:\input\include

  • \input 让文件「看起来就是输入在这里一样」,所以(几乎)可以用于任何文档。
  • \include 命令仅对章节有用:从新页开始并做一些内部调整。但它有一个很大的优势:允许我们选择输入哪些章节,这样就可以不用排印全文而只需要排印这一部分的内容。
  • \input{xxx}:嵌入片段,不分页、不生成独立.aux,适合封面、封底、前言、声明这类非章节、可复用短 / 长片段;
  • \include{xxx}:强制分页、生成独立辅助文件,适合第 1 章、第 2 章、附录等独立章节。

一篇长文档可能因此看起来跟下面一样:

Matlab 复制代码
\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage{biblatex}
\addbibresource{biblatex-examples.bib}

\title{A Sample Book}
\author{John Doe \and Joe Bloggs}

\IfFileExists{\jobname.run.xml}
{
\includeonly{
  front,
%  chap1,
  chap2,
%  append
  }
}
{
% 包含全部文件来生成所有的 aux 文件
}

\begin{document}
\frontmatter
\include{front}

% =========================
\mainmatter
\include{chap1}
\include{chap2}
\appendix
\include{append}

% ========================
\backmatter
\printbibliography
\newpage
\input{backcover}
\end{document}

13.1.使用 \input

\input 命令适合于不独立于章节的长文件片段。例如,我们用它来分隔前封面和后封面,来保持主文件的简短清晰,并可以在其他文档中复用。我们也用这个命令来分割书的起始「非章节」目次:比如前言。这也是为了保持主文件的结构清晰。

13.2.使用 \include 和 \includeonly

对于章节而言,\include 很有用,因此我们对于每一个整章都使用了这个命令。我们通过使用 \includeonly 来选择哪一章会被实际排印出来(这个命令接受逗号分隔的文件列表)。当你使用 \includeonly 时,可以缩短排版出来的文件长度并制作出一个「选择后的」PDF 用于校对。而且,\includeonly 的核心优势在于 LaTeX 会使用其他所有包含进来文件的 .aux 辅助文件用于章节间的交叉引用。

13.3.创建目录

\tableofcontents 命令使用目次命令的信息来制作目录。它有着以 .toc 为后缀的专门辅助文件,所以你可能需要运行 LaTeX 两次以解析这些信息。目录将会从目次标题自动生成。还有一些类似的命令比如 \listoffigures 以及 \listoftables,将根据浮动体环境的标题分别生成以 .lof.lot 后缀的文件。

13.4.分割文档

\frontmatter, \mainmatter\backmatter 命令影响着格式。例如,\frontmatter 改变页码为罗马数字。\appendix 命令将改变章节编号为 A, B ......------所以 \appendix 后的第一章被称为 Appendix A

main.tex

Matlab 复制代码
\documentclass{book} % 书籍文档类
\usepackage[T1]{fontenc} % T1字体编码
\usepackage{biblatex} % biblatex参考文献宏包
\addbibresource{biblatex-examples.bib} % 添加bib数据库文件

\title{A Sample Book} % 书名
\author{John Doe \and Joe Bloggs} % 作者(\and分隔多作者)

\IfFileExists{\jobname.run.xml} % 判断run.xml是否存在(非首次编译)
{
\includeonly{ % 仅编译指定章节以加速
  front, % 前言
%  chap1, % 第一章(已注释跳过)
  chap2, % 第二章
%  append % 附录(已注释跳过)
  }
}
{
% 包含全部文件来生成所有的 aux 文件(首次编译时执行)
}

\begin{document}
\frontmatter % 前置部分(罗马数字页码,章节不编号)
\include{front} % 包含前言文件

% =========================
\mainmatter % 正文部分(阿拉伯数字页码,章节编号)
\include{chap1} % 包含第一章
\include{chap2} % 包含第二章
\appendix % 切换为附录模式(章节编号变为A,B,C...)
\include{append} % 包含附录文件

% ========================
\backmatter % 后置部分(章节不编号,页码延续)
\printbibliography % 输出参考文献列表
\newpage % 强制换页
\input{backcover} % 内联插入封底内容(不自动分页)
\end{document}

front.tex

复制代码
\input{frontcover}
\maketitle
\input{dedication}
\input{copyright}
\tableofcontents
\input{pref}

pref.tex

复制代码
\chapter{Preface}
The preface text. See \cite{doody}.

chap1.tex

复制代码
\chapter{Introduction}
The first chapter text.

chap2.tex

复制代码
\chapter{Something}
The second chapter text.

append.tex

复制代码
\chapter*{Appendix}
The first appendix text.

frontcover.tex

复制代码
\begin{center}
The front cover
\end{center}

dedication.tex

复制代码
\begin{center}
\large
For \ldots
\end{center}

copyright.tex

复制代码
\begin{center}
Copyright 2020 learnlatex.
\end{center}

backcover.tex

复制代码
\begin{center}
The back cover
\end{center}

14.LaTeX--字体Unicode 引擎

TeX 和 LaTeX 被广泛使用之前,它们只需内置支持欧洲语言即可。虽然它们对于其他语言(比如德语和俄语)的文字也有一定的支持。

最初重音和重音字母都是通过控制序列(control sequence)或者宏(macro)输入的,

比如:\c{c} 来输入 'ç' 以及 \'e 来输入 'é'。虽然一些人仍然在使用这种输入方式,因为这更容易输入,但是另一些人希望他们能够使用键盘上的按键来直接输入这些符号。

在 Unicode 出现之前,LaTeX 提供了许多种文件编码 来允许很多语言的文字以原生的方式输入------比如:使用 latin1 编码,法国用户就可以输入「déjà vu」,LaTeX 会将重音字母在内部转译为 TeX 命令以产生正确的输出。

这种方法至今仍在 LaTeX 的 pdflatex 引擎中使用。除非另有说明,默认情况下所有的文件都被认为是 Unicode(以 UTF-8 编码)的。纵使这个引擎会限制字体为 8 位长度的,许多欧洲语言仍可被支持。

pdflatex 下的字体使用稳健(robust)的 LaTeX 字体选择方法。现在的标准 LaTeX 发行版中包含了许多开箱即用的字体。例如,TeX Gyre 是一套基于大部分人熟知的 Times, Helvetica, Palatino 等字体而制成的高质量字体。加载这些字体,和通过正确名字加载宏包一样简单。对于 Times 类似字体,TeX Gyre 中的名称为 Termes:

Matlab 复制代码
\usepackage{tgtermes}

对于 pdflatex 而言,许多字体都可以通过宏包加载。你可以查看 LaTeX 字体目录CTAN 中的「字体」主题以查阅一些选择。你也可以在网上搜索需要的字体,并寻找一个 pdflatex 兼容的版本。如果你想要使用一种专有字体,可以尝试搜寻一个合适的副本(大部分情况下都存在与原版足够类似的那种)。

Unicode 时代

因为 pdflatex 被限制为 8 位文件编码和 8 位字体,所以它并不能原生地支持现代 OpenType 字体(使用不同的字母与用于输入专业术语的脚本)来在不同的语言之间切换。当下 pdfTeX 有两个可原生使用 Unicode 输入与现代字体的替代引擎:XeTeX 和 LuaTeX。对于 LaTeX 版本而言,这些引擎通常在你的编辑器中分别通过 xelatexlualatex 调用。

在这些引擎中,字体选择是通过 fontspec 宏包实现的。对于简单的文档可以如下面的例子一样简单

Matlab 复制代码
\usepackage{fontspec}
\setmainfont{texgyretermes-regular.otf}

这个例子选择了 TeX Gyre Termes 字体,和上面的 pdflatex 例子一样。值得注意的是,这种方法对 任何 OpenType 字体都能用。一些对 pdflatex 可用的字体在 xelatexlualatex 中通过对应的宏包也可以使用。或者是和上面一样,通过使用 fontspec 宏包加载你电脑上安装的任何字体。

LaTeX 字体目录展示了可用的 OpenType 字体,因此你也可以用它来查阅字体资源。当然也可以使用前文提到的 CTAN 页面

选择好字体之后,就可以直接向文档里输入普通的 Unicode 文本了。下面的例子展示了一些拉丁字母、德语字母以及中日韩(CJK)表意文字的输入:

Matlab 复制代码
% !TEX xelatex
% 指定使用 XeLaTeX 编译器,因为后续使用了 fontspec 宏包加载系统/本地字体文件

\documentclass{article}
% 基础文档类

\usepackage{fontspec}
% 加载 fontspec 宏包,提供在 XeLaTeX/LuaLaTeX 下自定义 OpenType/TrueType 字体的能力

\setmainfont{texgyretermes-regular.otf}
% 设置西文主字体为 TeX Gyre Termes(Times New Roman 的开源替代)

\newfontfamily\cjkfont{FandolSong-Regular.otf}
% 定义一个新的字体族命令 \cjkfont,指向 Fandol 宋体,用于排版中日韩文字

\begin{document}

ABC → αβγ → {\cjkfont 你好}
% 测试输出:西文字母 → 希腊字母(由主字体渲染)→ 切换至 \cjkfont 输出中文"你好"
% 注意:{\cjkfont ...} 是局部分组写法,仅在大括号内生效,不影响后续文本字体

\end{document}

15.LaTeX--处理报错

与典型的字处理系统不同,LaTeX 是一个编辑、运行、浏览工作循环,一种接近于编程语言编译器的工作方式。程序员输入时会犯错,当然也就需要处理系统报告的错误信息。​​​​​​​

15.1.pdflatex 未找到

'pdflatex' 未被识别为内部或外部命令,可操作程序或批处理文件。

这并不是一个 TeX 错误,而是一个操作系统错误,表明 TeX 并没有被安装或者未被找到。常见的情形是只安装了诸如 TeXworks 或 TeXShop 的编辑器但并没有安装诸如 TeX Live 或 MiKTeX 的 TeX 系统。

15.2.TeX 错误信息结构

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}

\newcommand\mycommand{\textbold{hmmm}}

\begin{document}

My command is used here \mycommand.

\end{document}
Matlab 复制代码
! Undefined control sequence.
\mycommand ->\textbold 
                       {hmmm}
l.8 My command is used here \mycommand
                                      .
?
  • 第一行,! 开头,给出了错误的基本属性(在这个例子中是未定义命令)
  • 接下来两行表明 TeX 正在处理的代码行,以一处断行表明 TeX 已经处理到的地方。未定义的命令就是最后一个被读取的记号(token),所以在这里就是断行前的最后一个单词 \textbold。断行后剩余的记号 {hmmm} 可能就是已经被读取的、但尚未被 TeX 执行的参数。
  • 此处可能还会有几行来展示更多的错误信息。
  • 最后以 l. 开头,并跟随一个行号,之后就是源文件中错误发生的代码行。
  • 最后一行是一个问号 ?。如果 TeX 是以交互模式执行的,那么此时就可以向 TeX 输入指令。但是大部分编辑器和在线系统都会以一种批处理方式运行,所以不会在错误处暂停,而是跳过此处,并尝试处理完文档的剩余部分。如果是交互模式,在命令行输入 s 会让 TeX 以这种批处理模式继续执行。

这里要注意 TeX 并不会在定义处检测到这种错误:实际上,如果 \mycommand 被定义但从未被使用过,那么就不会产生任何错误。所以尽管被报告错误产生在第 8 行,但是「真正的」错误是在第 4 行的定义处出现的。所以看清楚整个错误信息是很重要的。

需要意识到有些编辑器只会展示错误日志的一行「总结」,下面的消息可能很容易会被错误理解:

line 8: undefined command: ...\mycommand

它看起来就像是 \mycommand 没有被定义一样。

15.2.未配对括号

Matlab 复制代码
\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage[leqno}{amsmath}

\begin{document}

\end{document}

15.3.未找到文件

复制代码
\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage{amsmathz}

\begin{document}

\end{document}

这将产生如下错误:

复制代码
! LaTeX Error: File `amsmathz.sty' not found.

注意,两种原因会导致同样的错误:一是和这里一样的误输入,可以通过修正为正确的宏包名解决;二是确实找不到文件,需要安装对应的宏包。

15.4.行间公式中的空行​​​​​​​

复制代码
\documentclass{article}
\usepackage[T1]{fontenc}

\begin{document}

Some text
\begin{equation}

  1=2

\end{equation}

\end{document}

会产生相对隐晦的错误:

复制代码
! Missing $ inserted.

但修复起来是很容易的,行间公式不允许空行,空行应该被删除。

相关推荐
qdkfz1 小时前
JavaScript 如何解析 Outlook .msg 文件 —— @kenjiuno/msgreader
前端·javascript
LuckyDog阿祥1 小时前
卸载Microsoft Edge:EdgeRemover完整操作指南
前端·edge
zhangxingchao1 小时前
AI应用开发九:从 Hermes Agent 学长期记忆
前端·人工智能·后端
xiaofeichaichai2 小时前
Vite原理与Webpack对比
前端·webpack·node.js
_杨瀚博2 小时前
小程序拍证件并局部裁剪
前端
William_Xu3 小时前
React 新旧生命周期对比
前端
PBitW4 小时前
为什么vite中TS报错,可以继续运行?Webpack不行?💡
前端·typescript