Emacs (AUCTeX / YaTeX)

在一个未装任何扩展的 GNU Emacs 里打开 .tex,你已经处在一个 LaTeX 模式中了——它作为 lisp/textmodes/tex-mode.el 随 Emacs 一起发布。AUCTeX 就是你为替换这个模式而安装的包,而两者从一开始就纠缠在一起,因为 AUCTeX 正是从那个文件长出来的。1986 年,在丹麦的奥尔堡大学,有人开始往 Emacs 的 tex-mode.el 里添加插入字体命令与丹麦语字符的函数;名字里的 AUC,来自这所大学当时的丹麦语名称 Aalborg Universitetscenter。本页依次讲:AUCTeX 在内置模式之上添了什么、C-c C-c 为何每次按下都问不同的问题、并不属于 AUCTeX 的 RefTeX、你可能早已在用却不自知的 preview.stypreview-latex,以及日语圈的替代方案 YaTeX(野鸟)

内置 LaTeX 模式与 AUCTeX:同样的按键,不同的命令

即便是裸装的 Emacs,打开 .tex 也会进入 latex-modeC-c C-b 排版,C-c C-o 插入一对 \begin\endC-c C-e 闭合最内层尚未闭合的块,C-c C-v 打开阅读器。至于进入哪个模式,是靠读文件内容决定的:tex-mode 会找出第一个不在注释里的反斜杠,看它后面是不是 documentclassdocumentstylebeginsectionchapternewcommandRequirePackage 等词之一。是,就进 latex-mode;不是,就落到 plain-tex-mode。若什么都没找到,则采用 tex-default-mode 的值,其默认正是 latex-mode

装上 AUCTeX 之后,同一副键盘接到了另一件乐器上。按键大体不变,背后的命令却换了——这正是「同样的键,手感却和从前不同」的由来。内置模式里的 C-c C-f 是排版整份文件的 tex-file,而 AUCTeX 的 C-c C-f 是插入字体命令的 TeX-font。内置的 C-c C-e 是闭合已开环境的 latex-close-block,AUCTeX 的 C-c C-e 则是询问并插入环境的 LaTeX-environment。把这两对并排一看,区别便自己说了出来:内置模式是一个能调用 TeX 的编辑模式,而 AUCTeX 是一个了解文档结构的环境。

这两者如何共存,其实在 2024 年被理顺了。AUCTeX 14.0.1 把自己的模式改名为首字母大写的 LaTeX-modeplain-TeX-modedocTeX-mode,正是为了不再与内置名称相撞。此后,打开 .tex 会落到哪个模式,在 Emacs 29 及以后由 major-mode-remap-alistmajor-mode-remap-defaults 的转发决定。AUCTeX 这一侧的入口是面向用户的选项 TeX-modes,用它可以把 plain TeX 交还给内置模式,同时让 LaTeX 留给 AUCTeX。手册建议自定义 TeX-modes,而不要直接改 major-mode-remap-*。有一个坑:在 Emacs 29 及以后直接敲 M-x latex-mode,得到的是内置模式而非 AUCTeX。 配置代码里若还在调用旧的小写名字,就会正好撞上。

AUCTeX 的安装,以及那份落后两年的手册

AUCTeX 并不随 GNU Emacs 一起发布。 它是一个 GNU 项目,以软件包形式在 GNU ELPA 上分发,采用 GPL v3。GNU ELPA 自 Emacs 24.1 起就默认启用,所以安装只需 M-x list-packages,给 auctex 打上 i,再按 x——等价写法是 M-x package-install RET auctex RET。有两个前提。其一是终端里 latexmk --version 能跑,也就是 TeX 命令位于 PATH 上:真正排版的是你装的 TeX Live、MacTeX 或 MiKTeX,Emacs 只是把它作为子进程启动。其二是 Emacs 自身的版本——当前的 AUCTeX 要求 Emacs 28.1 或更新

这里有一处不知道就会白白耗掉一个下午的落差:GNU ELPA 发布的 AUCTeX 与 gnu.org 上那份手册并不是同一个版本。 在 2026 年 8 月核对时,GNU ELPA 上最新的是 2026 年 1 月 14 日的 14.1.2,而 gnu.org 的在线手册开头仍写着它记述的是 2024 年 1 月 14 日的 13.3 版。相差整整两年。网站上也没有发布新闻页。所以,当你想弄清某个设置或某个按键到底如何表现时,正确做法是用 C-h i 读你本机所装版本的 Info 手册。搜索引擎给你的那一页,未必在讲你这台机器的事。

init.el(多半是 ~/.emacs.d/init.el)里最先该写的,是把 PDF 设为默认输出的 TeX-PDF-mode、让补全了解你文档的 TeX-parse-selfTeX-auto-save,以及开启 SyncTeX 对应关系的 TeX-source-correlate-modeTeX-parse-selfTeX-auto-save 让 AUCTeX 去读文档,把你用 \usepackage 载入的宏包里的命令也收进补全候选,并把结果缓存在 auto/ 目录里。SyncTeX 本身的原理留给专页,这里只放配置。

init.el
;; package.el reads GNU ELPA, enabled by default since Emacs 24.1.
(require 'package)
(package-initialize)

(use-package tex
  :ensure auctex
  :hook ((LaTeX-mode . TeX-source-correlate-mode)   ; SyncTeX
         (LaTeX-mode . reftex-mode)                 ; cross-references
         (LaTeX-mode . LaTeX-math-mode))            ; backquote math shortcuts
  :config
  (setq TeX-auto-save t      ; cache parse data in the auto/ directory
        TeX-parse-self t     ; scan the file for \usepackage and friends
        TeX-PDF-mode t)      ; produce PDF, not DVI
  ;; Tie source lines to PDF positions and run a server for inverse search.
  (setq TeX-source-correlate-method 'synctex
        TeX-source-correlate-start-server t))

C-c C-c 每次按下都问不同的问题

C-c C-cTeX-command-master)不是「执行这个」的命令,而是「接下来执行什么」的提问。迷你缓冲区会来问,并按文档当前状态提出默认值:还没排过就是 LaTeX;从 .aux 看出引用尚未解析就再来一次 LaTeX;有参考文献就 BibTeX;一切就绪则是 View。按 Enter 接受并重复,就是基本循环。这很能体现 AUCTeX 的设计思路:不指望按键的人记住步骤,而是让文档的状态决定下一步。 若不想盯着一步步看,C-c C-aTeX-command-run-all)会自动串起整条链,直到出错或完成,成功后还会替你打开阅读器。

按键命令作用
C-c C-cTeX-command-master询问接下来运行什么,并按文档状态给出默认值
C-c C-aTeX-command-run-all一口气跑完整条链,直到完成或出错,成功后打开阅读器
C-c C-rTeX-command-region只排版选中的区域,适合试一小段
C-c C-zLaTeX-command-section只排版当前这一节
C-c `TeX-next-error跳到下一个错误处(C-c 之后再按反引号)
M-g pTeX-previous-error回到上一个错误;需要解析整份日志(TeX-parse-all-errors
C-c C-lTeX-recenter-output-buffer滚动输出缓冲区,让最后一行可见
C-c C-kTeX-kill-job中止正在运行的外部进程,无论是 TeX 还是阅读器
C-c C-eLaTeX-environment询问环境名并插入 \begin\end
C-c C-sLaTeX-section插入分节命令;接上 RefTeX 还会顺手加上标签
C-c C-fTeX-font插入字体命令;C-c C-f C-d 删除最内层的字体指定
C-c C-mTeX-insert-macro补全命令名并逐个询问参数(C-c RET 亦可)
C-c ~LaTeX-math-mode把反引号变成输入数学符号的前缀键
C-c C-o C-fTeX-fold-mode切换折叠模式;C-c C-o C-b 折叠整个缓冲区

表外还有两点补充。M-g n 并非 AUCTeX 的绑定,而是 Emacs 自带的 next-error,AUCTeX 并未覆盖它。向前回溯的 M-g pTeX-previous-error)以解析完整份日志为前提,而 TeX-parse-all-errors 默认开启。其次,若希望打下 $ 时自动成对插入,请设置 TeX-electric-math默认值是 nil,也就是 $ 就只是 $;设为 ("$" . "$") 得到 TeX 风格的行内公式,设为 ("\\(" . "\\)") 则是 LaTeX 风格。

latexmk 已不再需要插件:LaTeXMk 就在 AUCTeX 本体里

C-c C-c 给出的选项里,本来就有 LaTeXMk 它是在 2024 年 5 月 19 日发布的 AUCTeX 14.0.5 中被加入 TeX-command-list 的,此后的版本又完善了输出目录的处理与 XeTeX 选项。过去那个标准答案式的外部包 auctex-latexmk 已经不需要了——更准确地说,不装为好。它上游最后一次提交停在 2017 年,早于 AUCTeX 14 的模式改名。所以在照抄某份旧配置里的 (auctex-latexmk-setup) 之前,请先按一次 C-c C-c,看看列表里有什么。

若想让 latexmk 成为默认动作,把 TeX-command-default 设成 "LaTeXMk" 即可(注意拼写:大写的 M 与 K)。latexmk 会检查依赖并按需重复运行,因此你无需自己数「为了交叉引用或目录该跑几遍」。引擎的选择仍在 AUCTeX 一侧,由 TeX-engine 掌管,内置的四个值是 defaultxetexluatexomegaLaTeXMk 这一项会读取该值,据以拼出交给 latexmk 的参数。文献处理与更细的引擎调整,写在项目根目录的 .latexmkrc 里最为顺手,这也意味着在 Emacs 之外或 CI 中都能复现同一份 PDF。latexmk 自身的配置归自动构建那一页管。

init.el
;; AUCTeX 14.0.5 and later ship a LaTeXMk entry in TeX-command-list.
;; Note the spelling: capital M, capital K.
(setq-default TeX-command-default "LaTeXMk")

;; Engine selection stays on the AUCTeX side and is buffer-local.
;; M-x TeX-engine-set, or in a file-local variables block:
;;   %%% TeX-engine: luatex

RefTeX 属于 Emacs 本体,而不是 AUCTeX

照料 \label\ref\cite 的是 RefTeX,而它并不属于 AUCTeX。它就在 Emacs 的源码树里,lisp/textmodes/ 下的 reftex.el 及十来个同伴,无需另行安装。 它最早出现在 1997 年的 Emacs 20.1etc/NEWS.20 的「Changes in Emacs 20.1」一节里,当年的按键表原样在册:C-c (C-c )C-c [C-c &C-c =——四分之一个世纪过去,仍是同样的键。作者是 Carsten Dominikreftex.el 头部的邮件地址与 org.el 作者行里的那个完全一致,也就是说,写 Org mode 的是同一个人。如今由 AUCTeX 项目接手维护。

它真正带来的好处是:你再也不必自己去想标签该叫什么。 C-c (reftex-label)会看你身处图、表、公式还是章节,提出一个带合适前缀的标签——fig:tab:eq:——并插入。回过头引用时,C-c )reftex-reference)只需从已有标签里挑一个。文献方面,C-c [reftex-citation)用正则表达式搜索你的 .bib 并插入 \cite{...}C-c =reftex-toc)会在另一个窗口打开整份文档的目录缓冲区,C-c &reftex-view-crossref)则就地显示光标下的引用究竟指向什么。若文档带索引,C-c / 可把选中的词变成索引项。即便文档拆成多个文件,RefTeX 也会沿着主文件把所有标签与所有文献一网打尽。

要让它与 AUCTeX 深度咬合,请设置 reftex-plug-into-AUCTeX。它是一个由五个布尔值组成的列表,分别控制:新建章节与环境时是否供给标签,以及是否为 \label\ref\cite\index 供给参数。想全部打开就赋 t,想全部关掉就赋 nil。打开之后,用 C-c C-s 新建一节时会立刻问你标签,用 C-c C-m 插入 \ref 时会弹出 RefTeX 的选择缓冲区——两个包之所以让人觉得浑然一体,正是这项设置的功劳。

init.el
(use-package reftex
  :ensure nil                 ; part of Emacs itself, nothing to fetch
  :hook (LaTeX-mode . turn-on-reftex)
  :config
  (setq reftex-plug-into-AUCTeX t    ; t turns all five flags on
        reftex-cite-format 'natbib))  ; or 'biblatex, 'default, ...

preview-latex,以及你多半早已在用的 preview.sty

preview-latex 会用 LaTeX 真的把公式、插图与 tikzpicture 排出来,再把结果当作图像原地叠在源码缓冲区上。它在 AUCTeX 11.81 从独立发布并入了 AUCTeX,此后无需另装。$…$\[…\]equation 环境的源码仍可编辑,只有想确认时才显示为排好的公式——文件依旧是纯文本,手感却近乎所见即所得。命令以 C-c C-p 开头:C-c C-p C-p 处理光标处的对象,C-c C-p C-e 处理环境,C-c C-p C-s 处理小节,C-c C-p C-r 处理选区,C-c C-p C-b 处理缓冲区,C-c C-p C-d 处理整份文档。要清除,就在中间插入 C-c C-c——C-c C-p C-c C-p 清掉光标处的预览。用 mouse-2 点击图像同样可以切换。

init.el
;; The preview commands, by their Lisp names.
;; C-c C-p C-p   preview-at-point       C-c C-p C-c C-p  preview-clearout-at-point
;; C-c C-p C-e   preview-environment    C-c C-p C-c C-s  preview-clearout-section
;; C-c C-p C-s   preview-section        C-c C-p C-c C-b  preview-clearout-buffer
;; C-c C-p C-r   preview-region         C-c C-p C-c C-d  preview-clearout-document
;; C-c C-p C-b   preview-buffer         C-c C-p C-f      preview-cache-preamble
;; C-c C-p C-d   preview-document       C-c C-p C-i      preview-goto-info-page

这里有一个多少令人意外的事实:preview-latex 在底层用的 preview.sty,正是 standalone 文档类为裁切插图而载入的同一个文件。 本机 TeX Live 2024 里的 preview.sty 是 2024 年 1 月 17 日的 13.3 版,头部写明它「作为 AUCTeX 的一部分开发」,而 \ProvidesPackage 行里的标识字符串就是 (AUCTeX/preview-latex)standalone.cls 的第 571 行正是 \RequirePackage{preview};由于 preview 选项默认为真,只要写下 \documentclass{standalone},它就已经在跑了。哪怕你从未打开过 Emacs,只要曾把一幅 TikZ 图裁成单独的文件,你就用过一个 Emacs 包的一部分。 LyX 的预览与 pst-pdf 也踩在同一块石头上。

实用层面有两个前提。preview-latex 需要 Ghostscript(7.07 或更新)来生成图像,无论走 DVI 还是 PDF 路线都要。走 DVI 路线时还需要 Dvips 或 dvipng 之一——dvipng 并非额外的必需品,而是 Dvips 的替代,手册说它比「Dvips 加 Ghostscript」的组合快得多。另一个前提是,你的 Emacs 在编译时带上了图像支持。它最见效的地方是长公式或交换图密集的稿件:能一眼确认排版结果,就省掉了「编译、再去看 PDF」的整个往返。

AUCTeX 本来就会说日语:japanese-LaTeX-mode 与 pTeX 系引擎

在为日语另寻一个模式之前,有件事值得先知道:AUCTeX 本来就带着 tex-jp.el,提供 japanese-LaTeX-modejapanese-plain-TeX-mode 这个文件会把 ptexjtexuptex 加进引擎列表,并由 japanese-TeX-engine-default(默认为 ptex)决定用哪一个。更进一步:只要启用了 TeX-parse-self,它就会根据文档类名自动挑选合适的引擎——看到 jbookjsarticletjreport,便判断该调 platex 还是 uplatex。手册之所以向日语 LaTeX 用户推荐 TeX-parse-self,原因正在这里。默认文档类由 japanese-LaTeX-default-style 给出,初值是 "jarticle"

自动判断也会失手。手册自己举的例子是 j-article:AUCTeX 会为它挑 NTT jLaTeX,而作者想用的其实是 ASCII pLaTeX。遇到这种情况,就在文件末尾的局部变量块里显式覆盖。若想让日文文档成为默认,把 TeX-default-mode 设为 japanese-LaTeX-mode 即可。另外值得一提:AUCTeX 手册明白写着,它的主要维护者中没有人懂日语——正因如此,这一块才一直靠日语使用者的反馈维持着。

latex
%%% Local Variables:
%%% mode: japanese-LaTeX
%%% TeX-engine: uptex
%%% End:

YaTeX(野鸟)——一整族以鸟为名的模式

YaTeX 是广濑雄二为 Emacs 编写的 LaTeX 主模式,版权行从 1991 年一直延续至今。它的日文名 野鸟 读作 yachou,手册把它译作 Wild Bird,并说明这是一个日语的谐音双关。有趣的正在后面:这个双关催生了一整族——面向 Vz 编辑器的 LaiTeX(Thunder Bird)、面向 Wz 的 HackTeX(Swan)、面向 xyzzy 的 HiTeX(Flying Bird),还有 KaTeX,其作者称之为「fj 野鸟会」。在 1990 年代的日本 TeX 圈里,给编辑器辅助工具起个鸟名几乎是一种惯例。许可证是 两条款 BSD(自 2017 年 9 月 9 日的 1.80 版起),最新版是 2026 年 8 月的 1.84.1,至今仍由作者本人更新。

它的理念与 AUCTeX 略有不同,更强调「先打头几个字母,再补全」以快速插入命令与环境。前缀默认是 C-cC-c b 是 begin 型补全(环境,\begin{...}...\end{...}),C-c s 是 section 型(\section 之类),C-c l 是 large 型(\large 这样的字号与字体),C-c m 是 maketitle 型(\maketitle\item 等不带参数的命令)。此外 C-c SPC 是「任意补全」:先打 \ 再打命令名开头,按下它便就地补全。排版以 C-c t 开头——C-c t j 排版,C-c t p 预览,C-c t b 跑 BibTeX,C-c t i 跑 makeindex,C-c t d 走完从 latex 到 dvipdfmx 的整条链,C-c t r 只排选区,C-c t k 中断。移动用 C-c g(跳到对应对象——\begin\end\label\ref\include 与它指的文件),改写则用 C-c c(更改)与 C-c k(删除)。

这里要留意一点:C-c t j 里的 t不带修饰键的裸 t。在 Emacs 中,C-c 字母 是留给用户的地盘,所以有人不喜欢 YaTeX 占用它。把 YaTeX-inhibit-prefix-letter 设为 t,所有 C-c 字母 的默认键都会移到 C-c C-字母,于是排版变成更有 Emacs 味的 C-c C-t j(用大写字母的按区域补全仍会保留;若连这些也想去掉,就填 1 而不是 t)。默认值是 nil,也就是说什么都不做时,确实是 C-c t j 网上找到的配置片段是按哪种流派写的,看这个变量就知道。

日语这一侧有几个关键变量。YaTeX-kanji-code 是保存时的汉字编码:nil 表示「不做转换,保留文件原本的 coding-system」,0 是 no-conversion,1 是 Shift JIS,2 是 JIS,3 是 EUC,4 是 UTF-8。nil0 并不是一回事——当前源码的默认值是 nil,正契合今天「不希望文件被悄悄重新编码」的习惯。tex-command 是实际调用的排版命令,可写 "latexmk""uplatex""lualatex -synctex=1"。把 bibtex-commandmakeindex-command 设为 upbibtexupmendex,日文的文献与索引便能正常工作。此外,YaTeX 的同一份发布物里还附带面向 HTML 的姊妹模式 yahtml;MELPA 上的 yatex 包则直接从作者本人的 Mercurial 仓库构建。

init.el
(use-package yatex
  :ensure t                     ; from MELPA, built from the author's repo
  :mode ("\\.tex\\'" . yatex-mode)
  :config
  (setq YaTeX-kanji-code nil    ; keep the file's own coding system
        tex-command "latexmk"   ; or "uplatex", "lualatex -synctex=1"
        bibtex-command "upbibtex"
        makeindex-command "upmendex"
        ;; t moves C-c <letter> bindings to C-c C-<letter>.
        YaTeX-inhibit-prefix-letter t))

该选哪一个?AUCTeX 与 YaTeX 最好择一而从,而不是混用。 想要 preview-latex 与 RefTeX 在内的整套,就选 AUCTeX;想以少量、快捷的补全键法快速写日文文档,就选 YaTeX。日语支持本身如上一节所述在 AUCTeX 里也有,所以今天诚实的判断方式是:不是「因为写日文所以用 YaTeX」,而是「因为这套敲键方式合我的手所以用 YaTeX」

头半小时里该定下来的事

  • 先决定由谁负责构建。 要么用 C-c C-c 一步步走,要么把 TeX-command-default 设成 "LaTeXMk",整条链交给 latexmk。这件事排在主题与配色之前。
  • 先在一个小小的 main.tex 上把循环跑通一遍。C-c C-a 一路推到底;PDF 打开后,用 C-c ( 给公式或插图打标签,用 C-c ) 在正文里插入引用,出错时用 TeX-next-error 跳到下一处。
  • 跑不通时,从外部去切分问题。 在终端里把同一个项目构建一次。若 latexmk 在那里就失败,改再多 init.el 也无济于事;若在那里能通,可疑的就是 Emacs 继承到的 PATH。
  • 读你手上那一版手册。 想弄清某个设置的含义,用 C-h i 打开已安装版本的 Info。网上的手册可能落后好几个版本。
  • 把构建固定在项目里。 当各章分成不同文件后,在项目根目录放一份 .latexmkrc,这样 Emacs、别的编辑器与 CI 都会产出同一份 PDF。