跳到主要内容

common-packages-tips

常用宏包与技巧

前几个章节用到的宏包已经不少,本篇做个系统收口:宏包速查、自定义命令、代码排版、多文件工程、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,\dots,x_n$
% $\vecn[5]$ 得到 $x_1,\dots,x_5$

\begin{document}
定义在 $\R$ 上的函数,向量 $\vecn$ 与 $\vecn[5]$。
联系邮箱 \email{uniresearch@email.uniplore.com}。
\end{document}

定义在 R\mathbb{R} 上的函数,向量 x1,,xnx_1, \dots, x_nx1,,x5x_1, \dots, x_5

联系邮箱 uniresearch@email.uniplore.com

命令用途注意
\newcommand定义新命令命令名不能与已有命令冲突
\renewcommand重定义已有命令改造默认样式时用,慎改基础命令
\newenvironment定义新环境语法同上,给出开始与结束代码

自定义环境的语法一并认识一下:

实例:自定义「注意」环境

\newenvironment{note}
{\par\medskip\noindent\textbf{注意:}\itshape} % 开始代码
{\par\medskip} % 结束代码

\begin{note}
这里的内容会自动以「注意:」开头并排成斜体。
\end{note}

**注意:**这里的内容会自动以「注意:」开头并排成斜体。

代码排版:listings 宏包

技术文档里贴代码,用 listings 宏包,语言高亮、行号、边框全自动。

实例:带高亮和行号的代码块

\documentclass{ctexart}
\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}

Listing 1: 计算斐波那契数列

# 计算第 n 项斐波那契数(中文注释测试)
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)

print(fib(10)) # 输出 55

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 骨架

\documentclass{ctexart}
\usepackage{amsmath, graphicx, booktabs, hyperref}

\begin{document}

\input{chapters/intro} % 引言(文件名不带 .tex)
\input{chapters/method} % 方法
\input{chapters/result} % 实验
\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 # 连中间文件一起清理
$ latexmk -xelatex -c main.tex # 连PDF一起保留,清理附属文件

latexmk 会自动判断:有 bibtex、目录引用有变动就多编译几遍,直到所有编号稳定。编辑器里配置「构建命令」为 latexmk -xelatex main.tex

排错心法

LaTeX 报错信息以叹号开头、附带行号,格式固定,看懂前几行就够了。

! Undefined control sequence.

l.42 \section{方法}

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
排错读日志第一个 ! 错误的行号