LaTeX 常用宏包与技巧
前几个章节用到的宏包已经不少,本篇做个系统收口:宏包速查、自定义命令、代码排版、多文件工程、latexmk 与排错心法。
掌握这些「工具箱」内容,你就从会写 LaTeX 进化到会管理 LaTeX 项目。
常用宏包速查
宏包用 \usepackage[选项]{宏包名} 加载,全部放在导言区。
| 宏包 | 用途 | 本系列出现 |
|---|---|---|
| geometry | 页面边距与纸张 | LaTeX 文档结构与排版 |
| fancyhdr | 页眉页脚 | LaTeX 文档结构与排版 |
| amsmath / amssymb | 数学公式增强 / 扩展符号 | LaTeX 数学公式基础、LaTeX 数学公式进阶 |
| graphicx | 插图 | LaTeX 插图与表格 |
| booktabs / multirow | 三线表 / 纵向合并单元格 | LaTeX 插图与表格 |
| enumitem | 列表定制 | LaTeX 文字格式与列表 |
| xcolor | 颜色定义 | 本章节介绍 |
| listings | 代码排版 | 本章节介绍 |
| hyperref | 超链接与书签 | LaTeX 交叉引用与文献管理 |
| biblatex | 参考文献(现代方案) | LaTeX 交叉引用与文献管理 |
| float | 图表强制定位 [H] | LaTeX 插图与表格 |
本地环境提示 File 'xxx.sty' not found 时,用 tlmgr install xxx 安装(TeX Live),MiKTeX 则会自动下载。Overleaf 自带几乎所有宏包,无此烦恼。
自定义命令:\newcommand
当同样的内容写了三遍以上,就该定义命令了。\newcommand{\命令名}[参数个数]{定义}。
实例:三种自定义命令
\newcommand{\R}{\mathbb{R}} % 以后写 $\R$ 就是 $\mathbb{R}$
% 一个参数:封装固定格式
\newcommand{\email}[1]{\texttt{#1}} % #1 表示第一个参数
% 带默认值的可选参数:[参数个数][默认值]
\newcommand{\vecn}[2][n]{x_1, \dots, x_#1}
% 用法:$\vecn{...}$ 得到 x_1, …, x_n
% $\vecn[5]{...}$ 得到 x_1, …, x_5
\begin{document}
定义在 $\R$ 上的函数,向量 $\vecn$ 与 $\vecn[5]$,
联系邮箱 \email{service@runoob.com}。
\end{document}
| 命令 | 用途 | 注意 |
|---|---|---|
| \newcommand | 定义新命令 | 命令名不能与已有命令冲突 |
| \renewcommand | 重定义已有命令 | 改造默认样式时用,慎改基础命令 |
| \newenvironment | 定义新环境 | 语法同上,给出开始与结束代码 |
自定义环境的语法一并认识一下:
实例:自定义「注意」环境
{\par\medskip\noindent\textbf{注意:}\itshape} % 开始代码
{\par\medskip} % 结束代码
\begin{note}
这里的内容会自动以「注意:」开头并排成斜体。
\end{note}
代码排版:listings 宏包
技术文档里贴代码,用 listings 宏包,语言高亮、行号、边框全自动。
实例:带高亮和行号的代码块
\usepackage{listings} % 代码排版宏包
\usepackage{xcolor} % 颜色支持
\lstset{ % 全局代码样式设置
basicstyle=\ttfamily\small, % 等宽字体、稍小字号
keywordstyle=\color{blue}, % 关键字蓝色
commentstyle=\color{gray}, % 注释灰色
stringstyle=\color{purple}, % 字符串紫色
numbers=left, % 行号在左侧
numberstyle=\tiny\color{gray},
showstringspaces=false, % 不显示字符串内空格标记
frame=single % 单线边框
}
\begin{document}
\begin{lstlisting}[language=Python, caption=计算斐波那契数列]
# 计算第 n 项斐波那契数(中文注释测试)
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(10)) # 输出 55
\end{lstlisting}
\end{document}

lstlisting 是「原样环境」:内部内容不做任何 LaTeX 解释,&、% 都不用转义。caption 同样自动编号(Listing 1)。常见语言名有 Python、C、Java、HTML、SQL、bash 等,不指定 language 则纯文本着色。
listings 对 UTF-8 中文的支持依赖编译器:XeLaTeX 下中文注释正常;老引擎(latex/pdfLaTeX)下会乱码。中文文档请坚持用 XeLaTeX 编译。
多文件工程:\input 与 \include
文档超过几百行就该拆文件——main.tex 只做骨架,内容分而治之。
实例:main.tex 骨架
\usepackage{amsmath, graphicx, booktabs, hyperref}
\begin{document}
\input{chapters/intro} % 引言(文件名不带 .tex)
\input{chapters/method} % 方法
\input{chapters/experiment} % 实验
\input{chapters/conclusion} % 结论
\bibliographystyle{plain}
\bibliography{refs}
\end{document}
两条命令看着相似,行为有明确分工。
| 对比项 | \input{文件} | \include{文件} |
|---|---|---|
| 能否嵌套 | 可以(子文件里再 \input) | 不可以 |
| 是否强制换页 | 不换页 | 每个文件前强制 \clearpage |
| 配合 includeonly | 不支持 | 支持,只编译指定章节(提速利器) |
| 适用粒度 | 任意片段(宏定义、图表、封面) | 章级大块内容 |
常见坑:\include 会强制换页,用它拼「同一页的几个小节」会发现莫名分页——小片段一律用 \input。
latexmk:一键编译
第 9 篇的四遍编译流水线,手动敲四条命令很折磨人,latexmk 全自动代劳。
$ latexmk -xelatex main.tex # XeLaTeX 引擎编译,自动跑满所有遍数 $ latexmk -xelatex -c main.tex # 清理中间文件(保留 PDF) $ latexmk -xelatex -C main.tex # 连 PDF 一起清理
latexmk 会自动判断:有 .bib 就跑 bibtex,目录引用有变动就多编译几遍,直到所有编号稳定。编辑器里配置「构建命令」为 latexmk,是本地环境的最佳实践。
排错心法
LaTeX 报错信息以叹号开头、附带行号,格式固定,看懂前几行就够了。
! Undefined control sequence.
l.42 \secton{方法}
l.42 指出出错行号——本例第 42 行把 \section 拼成了 \secton。修这一处,后面一串连锁错误往往一起消失。
| 报错信息 | 含义 | 处理 |
|---|---|---|
| Undefined control sequence | 命令不存在:拼写错误或缺宏包 | 对照行号查拼写;确认宏包已加载 |
| Missing $ inserted | 数学命令出现在文本模式 | 把 _ ^ \alpha 等放进 $ 内 |
| File 'xxx' not found | 找不到文件或宏包 | 检查路径;tlmgr install xxx |
| Runaway argument | 环境没闭合(少了 \end) | 对照行号补 \end{...} |
| LaTeX Error: Environment xxx undefined | 用了未定义的环境 | 检查环境拼写与宏包 |
| ! Emergency stop | 编译彻底中止 | 往上翻日志找第一个错误 |
| Reference undefined(警告) | 引用是 ?? | 多编译一遍 |
永远只修日志里的第一个错误——后面的错误多半是第一个错误的连锁反应。修完重编译,比一口气改十处靠谱得多。
小结
| 需求 | 方案 |
|---|---|
| 减少重复输入 | \newcommand 定义命令与环境 |
| 贴代码 | listings + \lstset 全局样式 |
| 大文档拆分 | \input(片段)/\include(章级) |
| 一键编译 | latexmk -xelatex |
| 排错 | 读日志第一个 ! 错误的行号 |
