化学 (mhchem/chemfig)

在 LaTeX 里排化学式,第一个要定的不是怎么写,而是加载哪个宏包。mhchem\ce{H2O}chemmacros\ch{H2O} 排出的都是同一个 H₂O——但照直把这两个一起加载会以 ! LaTeX Error: Option clash for package mhchem. 失败,换个顺序也一样。本页梳理 \ce{} 如何处理反应式、电荷、状态与同位素,IUPAC 命名法怎么排,以及 chemmacros 在第 6 版丢掉模块机制之后有何变化——全部在 TeX Live 2024 上实际编译。绘制结构式本身的记法(键符号、角度、环的写法)归「化学与物理图」那一页所有;这里关心的是把化学放进文档。

mhchem 怎么用 —— \ce{} 就是「照直打就对」

加载 \usepackage{mhchem},把所有化学内容都写进 \ce{...} 里。设计理念是一贯的:照你在纸上写的样子敲进去,排版就是对的。元素符号紧后面的数字会落成下标(\ce{H2O} 得 H₂O),^ 后的数字与符号成为电荷上标(\ce{SO4^2-} 得 SO₄²⁻),-> 成为反应箭头,<=> 成为平衡箭头。括号里的状态符号 (aq)(s)(l)(g) 原样通过,末尾的 v 成为沉淀的向下箭头,^ 成为逸出气体的向上箭头。TeX Live 2024 同捆的是 v4.10(2024 年 1 月 29 日),作者 Martin Hensel。

latex
\usepackage{mhchem}
% ...
\ce{2 H2 + O2 -> 2 H2O}                          % a balanced reaction
\ce{SO4^2-}                                      % ion with charge
\ce{CO2 + C <=> 2 CO}                            % equilibrium
\ce{NaCl(aq) + AgNO3(aq) -> AgCl(s) v + NaNO3(aq)}  % states, precipitate
\ce{CaCO3 ->[$\Delta$] CaO + CO2 ^}              % labelled arrow, gas evolved
\ce{^{227}_{90}Th+}                              % isotope with mass and atomic number
\ce{CuSO4.5H2O}                                  % the dot becomes a centred dot
\ce{H+ + OH- <=>> H2O}                           % unequal equilibrium

上面每一行都在 TeX Live 2024 上编译过,并用 pdftotext 核对了内容。箭头可以用方括号加标签,写 ->[上][下] 就能在上下分别放条件。同位素写成 \ce{^{227}_{90}Th+},质量数与原子序数叠在符号之前;水合物的间隔号直接来自 \ce{CuSO4.5H2O} 里的那个句点。除 <=> 之外,还有偏向一侧的 <=>><<=>\ce{} 在正文与 $...$ 之中表现一致,因此可以毫不费事地嵌进段落中间。

你写的排出的记法
H2OH₂O元素符号紧后的数字自动变下标
SO4^2-SO₄²⁻^ 之后的数字与符号成为电荷上标
2 H2 + O2 -> 2 H2O带系数与反应箭头的反应式系数用空格隔开写在前面;-> 即箭头
CO2 + C <=> 2 CO平衡箭头<=> 表示均衡,<=>><<=> 表示偏向一侧
AgCl(s) vAgCl(s)↓状态符号原样通过;末尾的 v 是沉淀箭头
CaCO3 ->[$\Delta$] CaO箭头上方载有 Δ->[上][下] 可在箭头上下写条件
CuSO4.5H2OCuSO₄·5H₂O水合物中的句点变成居中的间隔号

插一段小趣闻:打开 mhchem.sty,维护者的联系方式就写在开头的注释里,并且用 ROT13 加密,还附上了理由——为了对付垃圾邮件——以及一句「若不懂 ROT13,请上网搜索」。这是一个维护了二十多年的宏包里最有人情味的角落。底层实现却相当现代:它自行引入 expl3l3keys2ecalcamsmathchemgreekgraphicsamsmath 由 mhchem 替你加载,无需自己再写。

出现 Option clash for package mhchem

mhchemchemmacros 都写进 \usepackage,编译会以 ! LaTeX Error: Option clash for package mhchem. 中断。在 TeX Live 2024 上两种顺序都试过,结果一样。原因是 chemmacros 会在内部挑选化学式引擎,过程中会带着自己的选项去加载 mhchem。正确写法是 \usepackage[formula=mhchem]{chemmacros}——仅此一句冲突就消失,chemmacros 的 \ch{...} 便在底层改用 mhchem。实测中 \ch{2 H2 + O2 -> 2 H2O}\iupac{ethanol} 在同一份文档里无错通过。

latex
% WRONG -- fails with "! LaTeX Error: Option clash for package mhchem."
% \usepackage{chemmacros}
% \usepackage{mhchem}

% RIGHT -- let chemmacros load mhchem itself
\usepackage[formula=mhchem]{chemmacros}
% ...
\ch{2 H2 + O2 -> 2 H2O}
\iupac{ethanol}

顺带记住 chemmacros 裸加载时会给出的两条消息,心里会踏实些。第一条是 Package chemmacros Warning: You haven't loaded any package for upright Greek,意思是没有通过 chemgreek 选定正体希腊字母的机制——写 α-氨基酸的那个 α 时立刻就会用到。第二条是以 Package chemmacros Info: You haven't chosen a formula method so I'm assuming 开头的信息行,正对应上面的 formula= 键。两条都不是错误,但若化学式的样子与预期不符,先查这两行。

chemmacros v6 —— 模块已经没有了

把 chemmacros 描述成「逐个加载模块的综合包」的说法已经过时。TeX Live 2024 同捆的是 v6.2a(2022 年 3 月 11 日,Clemens Niederberger 作),宏包自己就这样说:模块机制在 v6 变了,所有模块已并入主宏包并默认预加载(除非你用 minimal 选项加载 chemmacros),新的默认相当于旧的 modules=all。现在写 \usechemmodule 只会得到那条警告,什么也不做。换言之,\usepackage{chemmacros} 一行就已经把命名法、氧化数、纽曼投影等全部备齐。默认的化学式引擎是 chemformula,这是一个独立宏包,其 \ch{...} 与 mhchem 相似;chemformula 也可以单独以 \usepackage{chemformula} 加载。

对重新编译旧稿的人也备好了退路。chemmacros.sty 开头写有 \DeclareRelease {v4} {2015-02-08}\DeclareRelease {v5} {2020-03-07},而 TeX Live 确实同捆了 chemmacros-2015-02-08.stychemmacros-2020-03-07.sty。借助 LaTeX 的回滚机制,可以按日期点名旧版;若 v5 时代写的论文在 v6 下垮掉,动手重写之前先固定到旧版对照一下。

排 IUPAC 命名 —— \iupac 与斜体立体描述符

有机化合物的名称在「外观由规约固定」这一点上与公式相似。\iupac{...} 负责照料这些规约:其中 \- 是允许换行的连字符,\higher{...} 把立体描述符抬高并置为斜体。写 \iupac{(1\higher{R},3\higher{S})\-camphor} 就能排出 (1R,3S)-樟脑,其中 RS 为斜体。由于位次连字符同时兼作断行点,双栏论文里长名字冲出栏外的事故会大为减少。

latex
\usepackage[formula=mhchem]{chemmacros}
\usepackage{ghsystem}   % needed separately for \ghspic and the H/P statements
% ...
\iupac{2,4,6\-trinitrotoluene}                  % \- is a breakable hyphen
\iupac{(1\higher{R},3\higher{S})\-camphor}      % italic stereodescriptors
\ox{2,Ca} \ox{-2,O}                             % oxidation numbers, roman
\cip{R,S}                                       % Cahn-Ingold-Prelog descriptors
\latin{in situ}                                 % Latin phrases, per house style
\pH{} \pKa{} \pOH{}                             % upright p, italic quantity
\newman{0,60,120,180,240,300}                   % a Newman projection

上面每一条命令都在 TeX Live 2024 上跑通了。\ox{2,Ca} 在 Ca 右上角放罗马数字氧化态,\ox{-2,O} 处理负氧化态。\cip{R,S} 排 Cahn–Ingold–Prelog 描述符,\latin{in situ} 按刊物体例排拉丁短语,\pH\pKa\pOH 给出正体 p 加斜体量符号的标准写法。\newman{...} 接受一串角度并画出纽曼投影。只有一处需当心:GHS 危害象形图。单靠 chemmacros\ghspic{skull} 会报 ! Undefined control sequence.——请另外写上 \usepackage{ghsystem}

结构式与反应式流程 —— \chemname 与箭头标签的陷阱

结构式本身由 chemfig 绘制——它的记法(-=~ 键,0 到 7 的角度,以及 *6(...) 这样的环)在「化学与物理图」那一页有详述。这里关心的是把它们放进文档的那一层。\schemestart ... \schemestop 用来搭反应式流程:排好分子,再用 \arrow 隔开。每个分子都可以用 \chemname{\chemfig{...}}{苯} 附上名称,名称会整齐地落在结构正下方。整体缩放与键的粗细可用 \setchemfig{atom sep=2em, bond style={line width=1pt}} 一并指定。TeX Live 2024 同捆的是 v1.66(2023 年 12 月 28 日),作者 Christian Tellechea。

latex
\usepackage{mhchem}
\usepackage{chemfig}
\setchemfig{atom sep=2em, bond style={line width=1pt}}
% ...
\schemestart
  \chemname{\chemfig{*6(-=-=-=)}}{benzene}
  % arrow labels are ordinary TEXT: bare "FeBr_3" gives "! Missing $ inserted."
  \arrow{->[\ce{Br2}][\ce{FeBr3}]}
  \chemname{\chemfig{*6(-=-(-Br)=-=)}}{bromobenzene}
\schemestop

箭头标签里有一个实测过的陷阱。\arrow{->[...]} 方括号内的是普通文本,不是数学模式。所以写 \arrow{->[FeBr_3]} 会把 _ 丢进正文,编译从 ! Missing $ inserted. 一路连锁到 ! Extra }, or forgotten $.! Undefined control sequence.,最后抱怨 \node 未定义,图也就毁了。需要下标的标签请用 \ce{FeBr3}\chemfig{FeBr_3} 包起来。在同一份文档里同时用 \ce{}chemfig 是被推荐的搭配(与上一节 chemmacros 的冲突是两回事),实测同时加载顺利通过。此外还有 \charge 添加孤对电子与电荷、\chemabove\chembelow 在原子上下加注、\polymerdelim 画出重复单元的括号。

到底该加载哪些

如果只需要化学式与反应式,那就只加载 mhchem。这对绝大多数论文都是正解,学会 \ce{} 一个命令即可。若还要画结构式,就用 mhchemchemfig——这两者并不冲突,惯常做法是正文的反应式用 \ce{},单独排出的骨架结构用 \chemfig{}。若要深入命名法、氧化数、GHS 与热力学,才取用 chemmacros,但要给它传 [formula=mhchem],而不是另起一行加载 mhchem。按这个顺序、只按需求逐级添加,就既不会遇到 Option clash,也不会遇到 Undefined control sequence