摘要
本课是课程第一单元的开篇,这一单元讲的是使用 LaTeX 的入门步骤。本课说明这一单元的用途:让从未用过 LaTeX 的人能够独立写出、编译并修改一份简短的文档;介绍单元的四节课以及贯穿其中的线索,从排版的概念一直到读懂错误;说明单元所假定的为数不多的预备知识,即在电脑上管理文件和文件夹;提出单元要解决的问题,即如何从一个空文件得到一份排好版的文档,以及出了问题时如何从排版引擎的信息追溯到原因;并说明,这同一个循环既适用于实验报告,也适用于哲学论文或拉丁文本的校勘整理。
学习目标
- 描述本单元内容的先后顺序,并说明每节课为下一节课提供了什么。
- 认清本单元所假定的预备知识,并为此准备好电脑,特别是让文件扩展名显示出来。
- 举例说明为什么一份 LaTeX 文档可能得不到任何结果,以及为什么错误报告的位置不一定就是出错的位置。
- 在其他学科和后续单元中认出本单元所建立的“编写、编译、修改”循环。
入门测验
在学习本单元之前,先测一测自己的起点是有益的。这项测评是自我测评:不计分,唯一的目的是为学习指引方向。它的八道题按顺序每两道对应本单元的一节课;从未用过 LaTeX 的人不必指望答对,这也无妨:每个答案,无论对错,都会解释要点,并指出讲解这一要点的那节课。同样的能力会在单元末尾的总结课中再次测量;由于这是本课程的第一单元,所以没有关于前面单元的题目。
开始本单元之前,先测一测你的起点。这是一次简短的自我测评:不计分,结果只保存在你的浏览器中。
第 1 题一位研究者用中文撰写一篇论文,文中引用了多调符希腊语的段落,而期刊要求使用她电脑上已安装的一种 OpenType 字体。按照本课程的标准,应该用哪个排版引擎来编译?
速度弥补不了它做不到的事:pdfLaTeX 不能直接加载系统中的 OpenType 字体,而用 Unicode 输入的希腊字母,如果不事先准备专门的编码和字体,就会使编译中断。它们理解的是同一种 LaTeX,但读取文本的方式和能够使用的字体各不相同;加载系统字体的 fontspec 需要 XeLaTeX 或 LuaLaTeX。Texmaker 是编辑器,不是排版引擎:源文件在其中编写,它再调用已安装的发行版所带的排版引擎。问题是它应该调用其中的哪一个。LuaLaTeX 可以直接写出带重音符和气息符的希腊文,并用\setmainfont加载所要求的字体。XeLaTeX 也可以;本课程采用 LuaLaTeX,是为了让所有文档都以同一种方式编译。复习: 什么是 LaTeX
第 2 题在文档正文中原样写下
全班及格率为 70% 左右。这一行,会印出什么?百分号是 LaTeX 保留的字符之一:原样写出时它不会被印出,而是起某种作用。注释不是错误;正因如此,这种疏忽才危险:排版引擎悄无声息地丢掉半句话,只有在阅读结果时才会发现。注释并不只限于这个符号:它涵盖其后直到行末的全部内容。百分号开始一条注释:排版引擎会忽略它后面直到行末的全部内容,连换行也包括在内,而且不给任何提示。要印出这个符号,应写\%。复习: 什么是 LaTeX
第 3 题一篇学位论文的文件夹里有
thesis.tex、thesis.aux、thesis.log、thesis.toc、thesis.pdf和map.png,最后一个是论文插入的一幅图。一位合作者将在自己的电脑上编译这篇论文。这位合作者至少需要拿到哪些文件?辅助文件在编译时会重新生成,对合作者毫无用处;别人的.aux文件甚至可能把过时的引用一直带到下一次编译。图片不是编译生成的,而是编译要用到的:没有map.png,排版引擎找不到文件就会停下来。目录要靠第二次编译得到,而真正不可缺少的那幅图却被漏掉了。需要的恰好是排版引擎无法生成的东西:作者写下或提供的内容。其余文件都会由编译重新生成。复习: 工作环境
第 4 题一名学生改好源文件后进行编译,但阅读器里的 PDF 没有变化。日志文件的最后一行是
Fatal error occurred, no output PDF file produced!。这名学生看到的是哪个 PDF?这种情况发生在日志无错结束、文件夹里的 PDF 带有最近一次编译时间的时候;而这里日志说的是没有生成任何 PDF。如果它损坏了,阅读器什么也显示不出来;而它显示的是一份完整可读的文档,只不过是旧的。那会是另一种可能的故障,但日志排除了它:日志说没有生成任何 PDF,所以根本不存在新的 PDF。一个严重错误使编译在写出结果之前就中止了;文件夹里的 PDF 是最后一次成功生成的,阅读器照样显示它,仿佛什么都没发生。必须改正日志所指出的错误。复习: 工作环境
第 5 题在文档正文中写了几个段落之后,作者写下
\usepackage{amsmath}。编译时会发生什么?有些声明是这样的,例如\setmainfont,它们在正文中从写下的位置开始起作用;宏包则不然。排版引擎不会重新排列源文件:它按顺序读取,遇到放错位置的内容就报错。的确不排版文字,但这只说明它可以放在正文之前;并不意味着它可以放进正文。到达\begin{document}时,配置即告结束,之后加载的宏包可能改变已经生效的决定;所以宏包只能在导言区加载。复习: 文档的结构剖析
第 6 题文档正文中原样写着这样一句话:
请把文件保存为 final_report.tex。编译时会发生什么?下划线是十个保留字符之一:原样写出时不会被印出。那是百分号的作用,它开始一条注释;下划线的作用不同,是写下标。排版引擎确实会做类似的事,但那是在报错之后,它自行插入它认为漏掉的美元符号;得到的结果并不是想要的。下划线在公式中用来写下标;在正文中,排版引擎认为是漏开了一个公式,于是报错。要印出下划线,应写\_。复习: 文档的结构剖析
第 7 题某次编译的日志中有错误
! Undefined control sequence.,下面一行是l.7 \sectoin。这说明什么?未定义的命令可能源于没有加载的宏包;但\section不需要任何宏包,而日志显示的命令暴露出名称里的笔误。l.7指的是源文件,要修改的正是源文件;日志只负责报告。这个数字是源文件的行号,而不是文档的节号。错误信息说出了故障的性质,即未定义的命令;l.7给出源文件中的行号,其后的文字恰好在那个不认识的命令处结束。复习: 编译与排错
第 8 题编译生成了 PDF,但日志中有这样一行:
Overfull \hbox (3.21451pt too wide) in paragraph at lines 20--24。它是什么意思?错误以感叹号开头;这一行是关于排版的警告,PDF 是有效的。这些数字是源文件的行号,不是 PDF 的页码,超出的是一行文字,而不是一页。段落的长短无关紧要:问题出在一行没能断好,也应当在这一行解决。排版引擎找不到一种可以接受的方式来给该段落的某一行断行,例如因为有一个它不会断字的长词,于是让这一行比版心更宽。PDF 已经生成;应该在 PDF 中查看这个段落,再决定是否需要处理。复习: 编译与排错
本单元的内容
本单元服务于课程的第一个目标,即制作和编译文档,并诊断和改正其中的错误;它也是其他所有目标的前提:用多种语言和文字排版、组织长篇文档、书写数学和逻辑、呈现表格和图形、管理参考文献、为每种学术文体选择合适的文档类,都以“编写、编译、修改”的循环已不成问题为前提。本单元的目标是:从未用过 LaTeX 的人学完之后,能够从一个空文件写出一份简短文档,在 Texmaker 或 Overleaf 中用 LuaLaTeX 编译;编译不通过时,能够独立找到原因并加以改正。单元的四节课构成一条链,每一节都建立在前面各节的基础上。
- 什么是 LaTeX。讲解排版的含义,把标记语言与文字处理软件相比较,介绍 TeX 和 LaTeX 的由来及其内容与形式分离的原则,说明选用 LuaLaTeX 的理由,并展示源文件如何变成 PDF。它确定整个单元的术语:源文件、排版引擎、编译、导言区、正文和日志。
- 工作环境。安装第一节课所描述的东西:一个带有宏包管理器的 TeX 发行版,以及设置为用 LuaLaTeX 编译、以 UTF-8 保存的 Texmaker 编辑器;介绍在浏览器中使用的替代方案 Overleaf,并说明编译会留下哪些文件、哪些需要保留。最后用两份测试文档检验安装是否成功。
- 文档的结构剖析。把源文件拆成各个部分:导言区和正文,命令及其参数,限定声明作用范围的分组,环境,十个保留字符,注释,宏包和文档类。学了这一课,第一节课中的最小文档就不再是一份照抄的配方,而是一个可以逐部分理解的结构。
- 编译与改错。教人阅读日志:区分错误和警告,在源文件中找到每个错误的位置,认出最常见的信息,并在信息不足时隔离出原因。它把前面的内容汇集起来,因为几乎每个错误都是违反了源文件结构的某条规则,而错误的诊断又要依靠工作环境。
本单元以总结与挑战一课结束。这一课把所学内容串成一条概念和操作的链,在结业测验中重测入门测验中的各项能力,并提出综合运用几节课内容的挑战题。
假定已有的知识
本单元几乎从零开始。它不假定学习者用过 LaTeX,不假定会编程,也不假定具备数学知识;它同样不假定懂英语,尽管排版引擎的信息是英文的,因为课程会解释所提到的每一条信息。它只假定会日常使用电脑:新建文件夹,以指定的名称把文件保存到指定的文件夹,之后再找到它,复制、移动和删除文件,安装程序;或者有一个浏览器和一个 Overleaf 账户。
由此只需要事先做一项准备,最好在学习工作环境那一课之前完成。文件名由主名和扩展名组成,扩展名是最后一个点之后的部分:在 report.tex 中,主名是 report,扩展名是 tex。然而,Windows 的文件资源管理器和 macOS 的访达(Finder)默认隐藏已知的扩展名,于是 report.tex 和 report.pdf 都显示为 report,而编译产生的辅助文件只靠扩展名相互区别,这时就无法分辨了。因此,最好打开显示扩展名的选项:在 Windows 中,位于文件资源管理器的“查看”菜单;在 macOS 中,位于访达的高级设置。在 Linux 中,文件管理器默认就会显示扩展名。
本单元要解决的问题
在文字处理软件中写作,边写边能看到结果。在 LaTeX 中,源文件和页面之间隔着一个逐字读取源文件的程序,结果只有在编译后才会出现。这就带来两个问题,也正是本单元的问题。第一个问题是怎样从一个空文件得到一份排好版的文档:需要安装什么,源文件至少要包含什么,排版引擎又如何处理它。第二个问题是当文档出不来,或者出来的样子与预期不同时该怎么办:排版引擎不会把错误显示在页面上,而是用它自己的语言写在日志里,有时报告的位置还离出错的地方很远。下面的例子用一份十五行的文档展示了这两个问题。
下面的源文件是一份完整的文档:它声明文档类,加载宏包,保存标题、作者和一个空日期,并排出两节。第二、三行用于中文:luatexja-fontspec 宏包在 fontspec 的基础上加入汉字排版,\setmainjfont 选择一种含有汉字的字体(这里是 Noto Serif CJK SC),因为默认字体(Latin Modern)不含汉字;中文用户也常用 ctex 宏包集提供的文档类(例如 ctexart),它在 LuaLaTeX 下完成同样的设置。汉字没有斜体,因此这里用 \textbf 以粗体(黑体)表示强调。用 LuaLaTeX 编译后得到如下结果。
如果在第十一行漏掉了结束 \textbf 参数的花括号,排版引擎就不会生成任何 PDF,日志中除其他内容外还有下面这几行。
Runaway argument?{假说。\par \section {回答}回答以上一节为依据。\end {d\ETC.! File ended while scanning use of \textbf ....! ==> Fatal error occurred, no output PDF file produced!错误不是在第十一行报告的,而是在文件末尾:排版引擎一路读取 \textbf 的参数,越过段落、下一节和 \end{document},直到文件结束。不过,日志提供了所缺的线索:“Runaway argument?”下面那一行从头重现了这个失控的参数,而它的开头,即“假说”前面的那个花括号,正是出错的位置。像这样阅读日志,是编译与改错一课所教的内容;理解为什么一个没有闭合的花括号会把后面的一切都卷进去,则是文档的结构剖析一课所教的内容。
因此,本单元对这两个问题的回答分为两部分。对第一个问题,是一个安装好并经过测试的环境,以及一份结构可以逐部分理解的源文件,其中没有任何东西是神秘的咒语。对第二个问题,是一种方法:从第一个错误开始阅读日志,在源文件中定位错误,认出被违反的规则;如果信息不够,就通过停用源文件的某些部分来隔离原因。两部分都不要求死记命令;两部分都要求像排版引擎那样阅读源文件。
各学科中的本单元
本单元所教的循环在所有学科中都是一样的,从一个学科到另一个学科,变的只是所写的内容。一份化学实验报告、一篇带上百条脚注的哲学论文、一篇附有拉丁原文及译文的西塞罗段落评注、一篇带表格的经济学论文、一篇引用档案文献的历史学学位论文和一篇包含定理的数学文章,开头都一样:一个文件夹,一个带有导言区和正文的源文件,一次编译,以及对其日志的阅读。同样,本单元中的错误,如没有闭合的花括号、原样写出的保留字符、放错位置加载的宏包,会出现在上述任何一种文档中,不分学科。
因此,本单元所教的内容在本站的其他课程中都用得上。亚里士多德逻辑或力学基础的作业和笔记从第一周起就可以用 LaTeX 来写;在使用 R 进行数据分析中,分析结果被并入一份排好版的文档;而在C++ 程序设计 I中,循环在本质上也是一样的:写出源文件,由编译器读取,而编译器那些指向行号的信息,正是用本单元所教的方法来阅读的。
通向何处
学完本单元,最小文档将成为一个熟悉的起点,后续各单元都在它的基础上展开。第二单元讨论文字本身:各种语言和文字(其中包括希腊文和拉丁文)、字体、脚注和长引文。第三单元讨论长篇文档的结构,包括章、目录和交叉引用,并把文档分成多个文件。第四单元讨论如何用正确的记号书写数学和逻辑;第五单元讨论表格和图形;第六单元讨论参考文献以及各学科的引用规范;第七单元讨论适合各种学术文体的文档类,从演示文稿到信函和海报。在所有这些单元中,每一条新命令都要经过编写和编译,出错时再用本单元学到的方法加以改正。
已完成
登录账户以保存您的进度