ISO/JIS 数学排版规则

理工科数学有一套国际约定,规定哪些内容排成斜体、哪些排成直立体(罗马体),这套约定就是 ISO 80000-2,在日本被采用为 JIS Z 8000-2。规则本身一句话就能说完:会变的量用斜体,含义固定的用直立体。然而在 LaTeX 中照常书写时,这些规则会清晰地分成两堆。\sin\partial 和数字默认就已正确,而 自然对数的底 e、虚数单位 i、微分的 d、圆周率 π 默认都是斜体——也就是不合规。本页梳理标准的要求,以及如何用 \mathrm{d}x\uppiisomathunicode-mathmath-style=ISO 让 LaTeX 达成合规,并通过从 PDF 中取出实际字符编码来核实结果。

ISO 80000-2 与 JIS Z 8000-2(原 JIS Z 8201)

ISO 80000-2(Quantities and units — Part 2: Mathematics)是同时规定数学符号含义与 排版方式(书体)的国际标准。现行文本为 2019 年第二版(第一版为 2009 年),并于 2021 年 11 月发布了更正版。日本以等同标准的形式采用了它:JIS Z 8000-2:2022「量及单位—第2部:数学记号」于 2022 年发布,而沿用四十余年的 JIS Z 8201:1981 则在 2022 年 3 月 22 日废止。旧教科书和企业内部规范中仍会出现 JIS Z 8201,或其源头 ISO 31-11,但今天应依据的是 ISO 80000-2 / JIS Z 8000-2。

为什么标准要管到书体?因为在数学中,书体本身承载含义e 视上下文既可能是变量 e,也可能是自然对数的底 2.718…;把变量写成斜体、把常数写成直立体,读者无需注释即可区分。标准把这种区别固定为全球通用规则,使论文、教材与技术文档之间的记法不发生漂移——而这种漂移会造成实际损害:若量的符号与单位符号共用一种书体,谁也说不清 m 是质量还是米。用 LaTeX 排数学是遵守标准的良好起点,因为在数学模式中字母会自动倾斜,而 \sin 这类函数名和普通数字从一开始就是直立体。

核心规则 —— 会变的用斜体,固定的用直立体

标准的核心只有一个想法:值会随上下文变化的量用斜体;含义或数值唯一固定的用直立体。xy 这样的变量,像 ab 这样暂时视为常数的参数,以及一般函数符号 fg,其值都不固定,所以都用 斜体——而这恰好就是 LaTeX 数学模式的默认行为,因此不必额外做什么就已合规。另一边,数值确定的 数学常数(e、i、π)、微分运算符 d 及其相关符号(偏微分 ∂ 等)、系统定义的函数名(sin、exp、ln、Γ),以及 数字单位符号,都用直立体。标准的立场很简单:既然这些都不是变量,就不得使用变量的书体。

遇到拿不准的情况时,最快的检验是:这个符号能不能改名为另一个字母?x 改成 t,公式的含义不变——所以它是变量,用斜体。但积分 dx 中的 d 不能换成别的字母;它是含义固定的运算符,因此用直立体。同一检验也解释了为什么 \sin 中的 s 不能替换,\mathrm{kg} 中的 k 也不能替换。

直立体与斜体速查 —— LaTeX 的默认能走多远

先说结论:LaTeX 默认已经满足函数名、偏微分符号 ∂、数字和大写希腊字母,而 需要你自己处理的是 e、i、π、微分运算符 d、单位以及向量/张量。下表中「默认 OK」表示普通数学模式已按标准排版,「需要处理」表示必须显式改成直立体——或粗斜体。

对象标准规定的书体LaTeX 中的写法
variables变量与量 x, y, t 为斜体x(数学模式默认 — OK)
parameters参数与一般函数 a, b, f, g 为斜体a, f(x)(默认 — OK)
\mathrm{e}自然对数的底 e 为直立体\mathrm{e}。普通 e 为斜体,不合规。需要处理
\mathrm{i}虚数单位 i(电气工程中为 j)为直立体\mathrm{i} / \mathrm{j}。需要处理
\uppi作为常数的 π 为直立体\uppi(来自 upgreek 或 unicode-math)。普通 \pi 为斜体。需要处理
\mathrm{d}微分运算符 d 为直立体\mathrm{d}x。普通 d 为斜体,不合规。需要处理
\partial偏微分符号 ∂ 为直立体\partial(默认已是直立体 — OK)
\sin已定义函数 sin, exp, ln 为直立体\sin, \exp, \ln(默认已是直立体 — OK)
\Gamma作为函数名的大写希腊字母 Γ 为直立体\Gamma(标准 LaTeX 默认直立 — OK;但请参见下节)
digits数字 0–9 为直立体123(默认已是直立体 — OK)
\unit单位符号 m, kg, s 为直立体siunitx 的 \unit{} / \qty{}{}。需要处理
\vectorsym向量与矩阵 a, A 为粗斜体\bm{a},或 isomath 的 \vectorsym{a}。需要处理
\tensorsym张量 T 为无衬线粗斜体isomath 的 \tensorsym{T}。需要处理

\mathrm{d}x —— 让微分的 d 与常数 e、i 变成直立体

对最常见问题的回答很短:\mathrm{…} 包起来。在 LaTeX 数学模式中,eid 只是普通字母,会排成斜体变量;写成 \mathrm{e}\mathrm{i}\mathrm{d} 就成了直立体,与变量 e 或 d 清楚区分。在积分中惯例是加一个细空格,例如 \int_0^1 x^2 \,\mathrm{d}x(标准并不规定空白的量,但为了易读,这种做法几乎通行)。顺带更正一点:你有时会看到 \mathup 这个命令,但它 并非由 isomath 定义unicode-math\mathup 定义为 \mathrm 的别名,而 kpfontsmismath 等也各有自己的版本。实测中,在 unicode-math 环境下 \mathrm{d}\mathup{d}\symup{d} 三者都输出 U+0064——一个普通的直立 d,只有裸写的 d 得到 U+1D451,即数学斜体的 d。可见 \mathup\mathrm 的同义词,而不是另一种东西。

每次都敲 \mathrm{d} 既麻烦,也一定会在某处漏掉。因此惯常做法是 在导言区一次性定义一个简短命令。写下 \newcommand{\dd}{\mathrm{d}} 之后,正文里只需 \dd x;日后若方针改变,改一行定义整篇文档就会跟着变。反之,把 \mathrm{d} 直接散写在正文各处,等到有人说「还是改回斜体 d 吧」时就无从下手。请把遵守标准这件事,理解成 给约定起名字并集中管理

document.tex
% define once in the preamble
\newcommand{\dd}{\mathrm{d}}   % upright differential operator
\newcommand{\eu}{\mathrm{e}}   % base of the natural logarithm
\newcommand{\iu}{\mathrm{i}}   % imaginary unit
% ...
\[
  \eu^{\iu\uppi} + 1 = 0, \qquad
  \frac{\dd}{\dd x}\,\eu^{x} = \eu^{x}, \qquad
  \int_0^{\infty} \eu^{-x}\,\dd x = 1.
\]

\uppi 的陷阱 —— 直立的 π 会带来另一套书体

按标准把圆周率 π 排成直立体,通行做法是 upgreek 宏包的 \uppi,但它有一个容易被忽视的代价:upgreek 默认使用 Euler Roman。宏包内的 \ExecuteOptions{Euler} 正是这么写的;实际上,在 \usepackage{upgreek} 之后排出 $\uppi$ 并用 pdffonts 查看,会看到嵌入了 EURM10——赫尔曼·察普夫设计的 Euler 家族字体。于是一份 Computer Modern 的文档里,偏偏这一个 π 出自另一位设计师之手。若在意这一点,可以写 \usepackage[Symbol]{upgreek},改从 URW Symbol(StandardSymL)取字。孰优孰劣取决于你的正文书体,所以 务必看过输出再决定

另有一点值得知道:upgreek 只提供 希腊小写字母\upalpha\upomega 一应俱全,但 \upGamma 并未定义,写出来会得到 ! Undefined control sequence.。这是设计而非疏漏——标准 LaTeX 中大写希腊字母本来就是直立体。另外,若使用 unicode-math,则完全不需要 upgreek:该宏包会自动生成 \uppi\upGamma,作为 \symup{…} 的简写。

大写希腊字母为直立体,是 TeX 的惯例而非 ISO 的规定

标准 LaTeX 把 \Gamma\Omega 等大写希腊字母排成直立体。这是高德纳定下的 TeX 传统,并非 ISO 80000-2 的要求。按标准的想法,用作变量的大写希腊字母(例如角度 Θ)应当像其他变量一样倾斜,只有像 Γ 函数那样 名称确定的函数 才有资格保持直立。其机制简单得出奇:标准 LaTeX 中 \Gamma\mathchar"7000,即第 0 族——直立的 operators 族。isomath 内部载入的 fixmath(Walter Schmidt 所作)只是把它改成 \mathchar"7100一个十六进制位的变化,就把大写希腊字母移进了第 1 族,即数学斜体的 letters——顺带还让 \mathbf 等数学字母表命令能作用于大写希腊字母。

若不想整包引入 isomath,在 pdfLaTeX 下往往可以通过 数学字体宏包的选项 得到同样效果。newtxmath 提供 slantedGreekuprightGreek;实测中,载入 \usepackage[slantedGreek]{newtxmath} 会把 \Gamma 改成 \mathchar"7100(其默认为 \mathchar"7400)。此外还有面向法式排版的 frenchmath 选项。无论选哪条路,关键都是 在整篇文档中一次性定下大写希腊字母的倾斜与否,中途不变。若同一篇论文里 Θ 时而斜体时而直立,读者会以为那是两个不同的量。

math-style=ISO 究竟改变了什么 —— 实测的字符编码

若在 XeLaTeX 或 LuaLaTeX 上使用 unicode-math,整套书体方针可以由 math-style= 这一个键整体切换。可取值有五个:TeX(默认)、ISOfrenchuprightliteral。效果可以测量,不必猜测——下表来自在 LuaLaTeX 下排出 $\Gamma\ \alpha\ A\ a\ \partial\ \pi$,再从 PDF 中取出字符并列出其 Unicode 码位。切换到 math-style=ISO 后,可以一眼看出大写希腊字母 Γ 从 U+0393(直立)移到了 U+1D6E4(数学斜体)。这正是标准与 TeX 传统正面相撞的那一点。

设置大写希腊 Γ小写希腊 α偏微分 ∂拉丁小写 a
math-style=TeXU+0393 直立U+1D6FC 斜体U+1D715 斜体U+1D44E 斜体
math-style=ISOU+1D6E4 斜体U+1D6FC 斜体U+1D715 斜体U+1D44E 斜体
math-style=frenchU+0393 直立U+03B1 直立U+2202 直立U+1D44E 斜体
math-style=uprightU+0393 直立U+03B1 直立U+2202 直立U+0061 直立

从这张表可以读出两件事。其一,即使设为 math-style=ISO,π 仍是斜体(U+1D70B)。标准要求常数 π 为直立体,但 unicode-math 无法判别某个 π 是常数还是变量,所以设为 ISO 之后,上一节的 \uppi(或 \symup{\pi})依然必要。其二,math-style=french 这个取值本身就很有意思——法国的排版惯例把希腊字母大小写都排成直立体,拉丁大写也是直立体。「正确的书体」并非只有一种,而是存在地域传统,宏包以一个取值的形式承认了这一点。粗体另有一个键 bold-style=;在默认值 TeX 下,\symbf{v}粗体直立(U+1D42F)。若要得到标准要求的粗斜体向量,请设置 bold-style=ISO,或使用 \symbfit(U+1D497)。

document.tex
% compile with xelatex or lualatex
\usepackage{amsmath}
\usepackage[math-style=ISO,bold-style=ISO]{unicode-math}
\setmathfont{STIX Two Math}
% ...
\[
  \symup{e}^{\symup{i}\uppi} + 1 = 0, \qquad
  \int_0^1 x^2 \,\symup{d}x = \frac{1}{3}, \qquad
  \symbfit{v} = \symbfit{A}\,\symbfit{x}.
\]

向量用粗斜体,张量用无衬线粗斜体

标准还按量的「类型」规定书体:向量与矩阵的符号用粗斜体张量的符号用无衬线粗斜体。这里最大的陷阱是,常用的 \mathbf{v} 给出的是 粗体直立,而非标准所要求的粗斜体。省事的办法是 bm 宏包的 \bm{v},它在保持斜体的同时只增加字重。若想更忠实于标准,可用 isomath,它提供 \vectorsym{v}\matrixsym{A}\tensorsym{T} 这类 按含义命名的命令。这种命名在实务中很有用——半年后重读源码时,\bm{A} 不会告诉你 A 是矩阵、向量还是单纯的强调,而 \matrixsym{A} 一眼就清楚。

不过 isomath 会悄悄做两件事。其一,它 \mathbf 重新定义为粗斜体OML 编码的 bx/it)。这符合标准,但会改变把 \mathbf 当作「直立粗体」使用的既有稿件的外观,因此中途引入时请通读全文复核。其二,由于内部载入 fixmath大写希腊字母会变成斜体。还有一点:Computer Modern 没有数学用的无衬线粗斜体,所以使用 \tensorsym 时日志中会出现 Font shape OML/cmbr/bx/it in size <10> not available 这样的 字体替换信息(这是信息,不是错误)。实测中由 cmbright 系列顶替。在大量使用张量的文档里,值得看一眼替换后的书体是否可接受。

document.tex
\usepackage{isomath}   % loads fixmath: capital Greek becomes italic
% NOTE: isomath also redefines \mathbf as bold ITALIC (OML bx/it)
% ...
\[
  \vectorsym{v} = \matrixsym{A}\,\vectorsym{x},
  \qquad
  \tensorsym{T}_{ij}.
\]

实务方针 —— 遵守到什么程度,在哪里妥协

要严格遵守标准还是贴近本地习惯,取决于文档的性质。判断依据很清楚:投稿的期刊或企业规范是否要求 ISO/JIS 合规? 若要求,按下面的方针整理即可。若不要求,部分采用也完全合理——比如只引入 \mathrm{d},这在任何领域都能提升可读性。但无论选什么,方针都要在一篇文档内保持统一。同一个符号这一页斜体、下一页直立,最容易让读者困惑。

  • 把 e、i、d 变成直立体。 在导言区把 \dd\eu\iu 定义为 \mathrm{…},正文中只写这些简短命令。
  • 若要严格处理 π,使用 upgreek\uppi——但其默认会引入 Euler Roman 的字形,请与 [Symbol] 选项比较后再定。
  • 单位交给 siunitx。 避免手写 \mathrm{…},改用 \unit{}\qty{}{},间距和复合单位天然就符合标准。
  • 向量与矩阵用粗斜体。 不用 \mathbf(粗体直立),而用 \bm,或符合标准的 isomath\vectorsym / \matrixsym / \tensorsym
  • 函数名、偏微分符号和数字无需处理。 \sin\cos\log\lim\partial123 本来就满足标准。要添加自己的函数名时,用 amsmath\DeclareMathOperator{\rank}{rank} 即可得到同样的直立体与间距。
  • 大写希腊字母一次定好,不再更改。 要让它倾斜,可用 isomath(经由 fixmath)、newtxmathslantedGreek,或 math-style=ISO

最后谈一句 physics 宏包。它能轻松给出直立的微分 \dd 和导数 \dv,看起来很吸引人,但其命令名与其他宏包冲突已是众所周知。实测中同时载入 physicssiunitx,两者争夺 \qty 的定义,产生了 ! Missing $ inserted.! Extra }, or forgotten $.(存在用于修补的 physics-patch,近年也常使用 derivative 等替代方案)。这件事在 physics 专页中有详细叙述。单位本身则是 siunitx 那一页的主题,若需要复合单位或有效数字,请前往那里。意识到书体的 含义 并始终一致地应用它——归根结底,合规的本质就在于此。