现在位置: 首页 > LaTeX 教程 > 正文

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定义新环境语法同上,给出开始与结束代码

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

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

\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
}

listings 代码块的编译效果

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