MusiXTeX 官方手册开篇就强调一点:乐谱不像散文那样是一行排开的符号,而是一个二维矩阵。正是这一点,让能把数学公式排得极其漂亮的 LaTeX,唯独在 五线谱乐谱 上无法独力完成。音符的水平位置要等到知道这一行能放几小节才能定下来,而一行能放几小节又要等音符有了宽度才知道——这是个先有鸡还是先有蛋的循环。本页要看的,是用 三遍处理 打破这个循环的 MusiXTeX,是对同一问题给出「离开 TeX」这一答案的 LilyPond,以及轻便的 ABC 记谱法;并且会实打实地说明,你的 TeX Live 里究竟装了什么、没装什么。
为什么单靠 LaTeX 排不出乐谱
答案是:音符既横向排列,也纵向排列。TeX 的排版模型是把盒子横向排成一行,再把行纵向叠成一页;对散文和公式来说这就够了。可是乐谱有多行五线同时推进,而且音符之间的间距还会随着你决定每个「行系统」放几小节而伸缩。MusiXTeX 手册把这称为「把竖直的梳子横向累加」,它的输入方式正是如此:从 \notes 到 \en 是一把梳子,其中用 & 分隔,自最下方乐器起依次落在不同的五线上。LaTeX 没有这套机制,所以乐谱总是需要额外一层东西。
这一层大致有两种形态。一种是 留在 TeX 内部:加入字体和宏,让 TeX 自己来制谱——这就是 MusiXTeX。另一种是 走到 TeX 之外:让专门的程序制谱,再用 \includegraphics 把结果作为图像取回——这正是 LilyPond 和 ABC 系工具的做法。有意思的是,这两条路在历史上是连着的:LilyPond 的起点,恰恰是两个人放弃了原本要为 MusiXTeX 写前处理器的计划。
MusiXTeX 的三遍处理:为什么中间夹着 musixflx
MusiXTeX 的标准处理路线是 etex → musixflx → etex 三遍,中间的 musixflx 根本不是 TeX,而是一个 专门做换行(分段)的独立程序。按顺序说:第一遍 TeX 运行时,\startmuflex 打开 作业名.mx1,逐小节写出每小节包含多少「固定空白」和多少「可伸缩空白」。接着 musixflx 读取这个 .mx1,决定每个行系统放几小节,并把各系统的伸缩系数写入 作业名.mx2。第三遍 TeX 读入这两个文件,最终间距才确定下来。开头说的鸡生蛋问题,就是这样 借助一次文件往返 被打断的。
这三遍不必手动跑。TeX Live 里带有一个名为 musixtex 的包装脚本:只要输入 musixtex score.tex,它就会按顺序执行三遍处理,并在需要时调用 dvips 和 ps2pdf。加上 -p 会走短路线,用 pdfetex 直接生成 PDF;加上 -i 则会保留中间文件 .mx1 和 .mx2 而不删除——打开 .mx2 就能看到形如 \lineset{1}{2}{...} 的行,那正是「第一个行系统放两小节」这一决定的原样记录。另外,TeX Live 中的 musixflx 本身就是一个 texlua 脚本,所以这个「独立程序」其实跑在 TeX 二进制自带的 Lua 解释器上。
musixtex score.tex # 3 passes: etex -> musixflx -> etex, then dvips + ps2pdf
musixtex -p score.tex # same 3 passes, straight to PDF via pdfetex
musixtex -i score.tex # keep score.mx1 and score.mx2 so you can read them
musixtex -1 score.tex # single pass: fast draft, spacing NOT final有个陷阱:用 -1(单遍)生成的 PDF 尚未确定行系统的划分。写作过程中快速查看很方便,但交付版本绝不能用 -1 生成。另外一点,MusiXTeX 需要的引擎不是原始的 tex,而是 e-TeX。这一改变是在 1.15 版(2011 年 4 月)为解决寄存器不足而做出的,也正因如此,musixtex 脚本默认调用 etex。
为什么是三遍?答案就在 MusiXTeX 自己的来历里。随包附带的手册中「A very brief history」一章,把用 TeX 排乐谱的想法追溯到 1987 年前后——波恩大学 Andrea Steinbach 与 Angelika Schofer 的硕士论文 Automatisierter Notensatz mit TeX。她们的宏包 MuTeX 只能处理单行谱,却留下了两个关键思路:用大量字体字符拼出符杠与连线,以及借 TeX 的粘连(glue)控制水平间距与均排。1991 年前后,Daniel Taupin 把它扩展到多行谱,做出 MusicTeX,代价是水平间距的自由度没了,要避免小节线前后过空或过挤只能反复试错——因为 MusicTeX 是单遍的。唯一的解法是改成多遍:1997 年前后,Taupin 与 Ross Mitchell、Andreas Egler 一起,正是照着这个结论写出了第一版 MusiXTeX。今天编译流程中间那个 musixflx,就是当年那个决定留下来的样子。
Taupin 的本行是物理学家。他 于 2003 年在一次登山事故中去世——TeX Live 2024 所附带的 README 和手册前言都记载了这一点。此后由 Don Simons、Hiroaki Morimoto、Bob Tennent 等人继续维护。至于中间那个 musixflx,最初是 Ross Mitchell 在 1992 至 1997 年间写的程序;2011 年 Nikhil Helferty 用 Lua 重写,那份重写就是今天使用的 musixflx.lua。
最小的 MusiXTeX 文档:为什么 \begin{music} 会报 Undefined control sequence
MusiXTeX 有 plain TeX 和 LaTeX 两套写法,混用就会出问题。用 \input musixtex 载入的 plain TeX 版本里并不存在 \begin{music}——写了会报 ! Undefined control sequence.,而且「music」这个词还会被当作正文排出来。music 环境定义在另一侧的 musixblx.tex 中,也就是用 \usepackage{musixtex} 载入的 LaTeX 版本。plain TeX 版的骨架如下:乐谱放在 \startpiece 与 \endpiece 之间,这一对再由 \startmuflex … \endmuflex 包住,文件以 \bye 结束。
% plain TeX form: run it with musixtex -p score.tex
\input musixtex
\instrumentnumber{1}
\setclef1\treble
\generalmeter\meterC
\startmuflex
\startpiece
\NOtes\qa{cdef}\en\bar
\NOTes\ha{g}\en
\endpiece
\endmuflex
\bye% LaTeX form: the music environment exists only here.
% Run it with musixtex -p -l score-latex.tex
\documentclass{article}
\usepackage{musixtex}
\begin{document}
\begin{music}
\instrumentnumber{1}
\setclef1\treble
\generalmeter\meterC
\startpiece
\NOtes\qa{cdef}\en\bar
\NOTes\ha{g}\en
\endpiece
\end{music}
\end{document}记住少量词汇,后面就好读了。\NOtes … \en 是一把「梳子」,而大写字母递增的写法——\notes、\Notes、\NOtes、\NOTes、\NOTEs——正是在选择 与音符时值对应的基本间距,从十六分音符到全音符依次变宽。\qa{cdef} 表示「在 c d e f 上放无符干的四分音符」,\ha{g} 是 g 上的无符干二分音符,\bar 是小节线。\instrumentnumber 指定乐器数量,\setclef1\treble 把第一件乐器设为 高音谱号,\generalmeter\meterC 设为 四四拍(C)。正因为原始宏是这个样子,下面要讲的前处理器才成了大家真正会写的输入。
pmx、M-Tx、autosp:不必手写 MusiXTeX
MusiXTeX 手册自己就写道:大多数工作完全可以只用前处理器完成,无需学习 MusiXTeX 的命令和语法。器乐用 PMX,带歌词的声乐用 M-Tx 是两个标准,而后者会调用前者,于是形成 M-Tx → PMX → MusiXTeX 的分级链条。TeX Live 2024 带有这些可执行文件,只是名字有点别扭:PMX 的本体是 pmxab,M-Tx 的本体是 prepmx(m-tx 是它的别名)。
省心的是,musixtex 脚本会 根据扩展名决定入口。传入 .mtx 就从 prepmx 开始,.pmx 从 pmxab 开始,.aspc 从 autosp 开始,然后一路跑完三遍处理。autosp 这个前处理器会自动完成「按音符时值选择 \notes / \Notes / \NOtes」,于是上面那套大写字母就不必手写了。再配合 xml2pmx,还可以从 MusicXML 进入——从其他打谱软件导入的材料走的就是这条路。
musixtex piece.pmx # pmxab -> etex -> musixflx -> etex
musixtex song.mtx # prepmx -> pmxab -> etex -> musixflx -> etex
musixtex draft.aspc # autosp -> etex -> musixflx -> etex
musixtex score.xml # xml2pmx -> pmxab -> etex -> musixflx -> etex
musixtex -m song.mtx # stop after producing the .pmx, to inspect or hand-edit还有一点:字体是单独的包。MusiXTeX 的音符字体被拆分为 musixtex-fonts,所以只装宏是编译不过的。正常安装的 TeX Live 两者都有,但精简安装的环境会在这里卡住。此外还附带若干扩展:歌词用 musixlyr.tex(Rainer Dunker),和弦标记用 musixcrd(Robert Hennig)。
LilyPond 与 lilypond-book / lyluatex:调用 TeX 之外的制谱引擎
LilyPond 是与 TeX 完全无关的另一个程序,有自己的输入语言,在制谱质量上享有最高声誉。它的起点竟是 MusiXTeX,今天读来颇有讽刺意味:Han-Wen Nienhuys 与 Jan Nieuwenhuizen 于 1995 年开始合作开发 MPP(MusiXTeX PreProcessor),随后放弃了它,在 1996 年另起 LilyPond。1998 年的 1.0 版完成了与 MusiXTeX 的彻底分离,如今 LilyPond 自行输出经 PostScript 的 PDF,以及 SVG、PNG。二人曾在 2003 年的 CIM(Colloquium on Musical Informatics)上发表《LilyPond, a system for automated music engraving》。
把它接入 LaTeX 文档的标准做法是 lilypond-book。在扩展名为 .lytex 的文件里,把 LaTeX 正文和 LilyPond 片段混写——短片段用 \lilypond{…},长片段用 lilypond 环境,外部文件用 \lilypondfile{…}——再用 lilypond-book 处理,每个片段都会由 LilyPond 渲染,并输出一个 普通的 .tex 文件,其中片段已被替换为 \includegraphics。之后照常编译即可。乐谱的行宽会从导言区读取正文宽度并自动匹配。
\documentclass{article}
\begin{document}
A short phrase:
\begin{lilypond}[quote,fragment,staffsize=26]
c'4 d' e' f' g'2 g'
\end{lilypond}
\end{document}lilypond-book --pdf score.lytex # renders the fragments, writes score.tex
pdflatex score.tex # compile the generated document更新的选择是 lyluatex。它专为 LuaLaTeX 设计,省去前处理这一步,在编译过程中直接调用 LilyPond。它本来的写法是 ly 环境(短片段则用 \lily 命令),然后以 --shell-escape 启动 lualatex 即可。此外它还提供 \lilypond 和 \lilypondfile,用于从 lilypond-book 迁移,因此已有的 .lytex 稿件几乎可以原样搬过来。由于只有一份源文件,需要反复修订的稿件管理起来更省心。TeX Live 2024 收录的是 v1.1.5(2023/04/18),采用 MIT 许可证。
% compile with: lualatex --shell-escape document.tex
\documentclass{article}
\usepackage{lyluatex}
\begin{document}
\begin{ly}
\relative c' { c4 d e f g2 g }
\end{ly}
\end{document}这里有一个 必须知道的陷阱。lyluatex 的 .sty 确实在 TeX Live 里,但 LilyPond 本体(lilypond 命令)和 lilypond-book 并不在 TeX Live 中。实测 TeX Live 2024 的可执行文件目录,lilypond 和 lilypond-book 都不存在。也就是说,仅仅载入 lyluatex 是跑不起来的,必须 另行安装 LilyPond 并加入 PATH。宏包装好了,和外部程序装好了,是两回事。
abc 宏包:最快地放入民歌与单旋律
ABC 记谱法 是一种以「人易读易写」为第一原则设计的文本音乐格式,广泛用于记录爱尔兰、英格兰、苏格兰等地的 民歌和主旋律谱(单旋律)。用 X:、T:、M:、L:、K: 这类单字母标头写出曲名、拍号和调号,然后像 CDEF|GABc| 这样把音符排开即可——作为乐谱它很朴素,但轻到可以直接贴进邮件。LaTeX 一侧的入口是 abc 宏包(Enrico Gregorio;TeX Live 2024 中为 v2.0b)。
% compile with: pdflatex -shell-escape tune.tex
\documentclass{article}
\usepackage{abc}
\begin{document}
\begin{abc}
X:1
T:Simple Tune
M:4/4
L:1/8
K:C
CDEF|GABc|
\end{abc}
\end{document}机制与 lilypond-book 相同,都是外部转换。宏包会把 abc 环境的内容写到临时文件,通过 \write18(shell 执行)交给 abcm2ps 生成 PostScript,再用 ps2eps 整理成 EPS 后插入。所以 必须加 -shell-escape——而且这里也有和 LilyPond 一样的问题:abcm2ps 并不在 TeX Live 中。很容易出现「有 abc.sty 却没有转换器」的局面,所以使用前请先装好 abcm2ps(用 mup 选项则改为调用 Mup)。把 ASCII 的 ABC 转成 MusicTeX/MusiXTeX 输入的经典工具 abc2mtex,同样需要另行获取。
TeX Live 里有什么、没有什么,以及该选哪一个
判断标准只有一条:在 TeX 内部制谱的工具,TeX Live 全都带;在 TeX 外部制谱的工具,一个都不带。 MusiXTeX 全套(musixtex、musixflx、pmxab、prepmx、autosp、xml2pmx)以及 LaTeX 一侧的入口(lyluatex.sty、abc.sty)都在其中。而真正绘制乐谱的外部引擎——lilypond、lilypond-book、abcm2ps——都不在。下表是在 TeX Live 2024 上实测的结果。
| 程序 / 文件 | TeX Live 2024 是否自带 | 作用 |
|---|---|---|
musixtex | 自带 | 驱动三遍处理的包装脚本,也会调用前处理器 |
musixflx | 自带 | 第二遍处理;决定行系统划分的 texlua 脚本 |
pmxab / prepmx / autosp / xml2pmx | 自带 | PMX、M-Tx、自动间距和 MusicXML 前处理器 |
lyluatex.sty / abc.sty | 自带 | LaTeX 一侧的入口;它们要调用的外部程序则不在 |
lilypond / lilypond-book | 不自带 | 需另行安装;LilyPond 本体及其插入脚本 |
abcm2ps / abc2mtex | 不自带 | 需另行安装;ABC 的转换器 |
据此可以给出实用的判断。如果 完全不想额外安装,或者已确定构建环境只有 TeX Live,就用 MusiXTeX——但不要手写原始宏,从 pmxab / prepmx 进入。如果 以制谱质量为第一优先,就用 LilyPond:已经在用 LuaLaTeX 就选 lyluatex,否则用 lilypond-book。如果只是 快速放几首单旋律小曲,用 abc。三者有一条共同教训:凡是要调用外部程序的方案(lyluatex、abc)都需要 -shell-escape,所以在共享构建机或 CI 上落地之前,请先确认权限设置。若你想把乐谱导出成独立图像交给其他应用,请看 TeX2img 那一页。