在 LyX 中定义和管理宏

2022-10-03
2023-07-27
Header: lyx-macro

虽然 LyX 是 WYSIWYM 的,但是还是有很多 LaTeX 命令是不能很好地显示和直观编辑的。在这篇文章中我会教你如何创建和管理 LyX 中的数学宏,并避免一些常见的坑。

LyX 是一个强大的 LaTeX 编辑器,它的最大的一个亮点就是支持 WYSIWYM(what you see is what you mean,所见即所想)。尽管它理论上支持所有的 LaTeX 命令(毕竟实在不行可以插入 Raw TeX),但不是所有命令都是支持 WYSIWYM 的。不过好消息是,LyX 留有很大的自定义空间,很多问题可以通过自定义解决。比如可以告诉 LyX 如何显示本来不支持的 LaTeX 命令。

Rendering ket. Image in light theme.

如何插入宏#

在 LaTeX 中, 你可以在导言区导入宏包、定义命令,但 LyX 并不认识它们。原因很简单,LaTeX 复杂起来可以非常复杂,去实现一个简单可靠的动态解析的算法几乎不可能。所以我们需要用 LyX 明白的方式告诉它这个命令应该长啥样。

在继续介绍之前,如果你还没有阅读 LyX 的用户手册,请务必先浏览一遍。点击 HelpMath,然后点 Navigate22 User-defined Commands22.2 Math Macros,就能看到。它介绍的非常详细,这里不会一一重复。本文只是对其的适当沿伸。

简单来说,点击 InsertMathMacros,然后输入命令的名称,在标有 TeX 的输入框内输入命令的 TeX 定义,然后在标有 LyX 的输入框内输入它在 LyX 中应该长啥样。如果 LyX 其实是支持你所要的定义式的,你只是需要一个快捷的输入方式,你可以之间在 TeX 框里按照平常的 LyX 数学输入即可,不需要在 LyX 框里再输入。

作为一个例子,我们看看如何在 LyX 中加入狄拉克的右矢符号,不依赖其他的 LaTeX 宏包。你需要把光标定在 TeX 框里,点 "Insert delimiters" 按钮,取消 "Keep matched",然后在左右分别选择 |\rangle。然后点击 "Append argument" 按钮,并在右矢里输入 \#1 参数。因为我们在 TeX 框里输入的东西 LyX 都认识,所以不需要在 LyX 框里输入。

Define ket macro in LyX

再次强调,一定要阅读用户手册,那里介绍了更多的细节。

如何让 LyX 支持宏包里的命令?#

从 LyX-2.4.0-beta3 开始,事情已经变得简单了。你只需要填 LyX 框里的内容,保持 TeX 框空白,就可以了。

macro screenshot

* Format incremented to 616: Do not output LaTeX for a macro if the LaTeX part is empty
- This allows the user to define the LyX display for LaTeX commands
  that are already defined (e.g., in user preamble or a package).

这就不是很直接了。因为 LyX 底层是用的 \def 命令,比如上面我们定义的 \ket 会生成如下 TeX 代码:

\global\long\def\ket#1{\left|#1\right\rangle }%
tex

这就意味着,如果你定义了一个叫做 \ket 的宏,你想让它指向 braket 包里的 \ket 命令,是不行的。因为这会生成

\global\long\def\ket#1{\ket{#1} }%
tex

这回导致无穷递归,文档也无法编译。你会看到这样的报错:

TeX capacity exceeded.

所以,根据网友的建议,我们应该先在导言区定义一个新的命令 \let\realket\ket,然后在 LyX 宏的定义里使用 \realket 而非 ket,就可以绕开无穷递归的问题。因为 \let 相当于是静态的,它是让 \realket 等于定义时的 \ket;而 \def 相当于是动态的,它会让 \ket 等于运行时的 \ket

好像在 TeX 框里输入花括号会被转义?#

想要不被转义的 {,输入 \{ 就可以了。当然也可以用复制粘贴等土办法。

宏太多了,怎么管理?#

很显然,把所有的宏都写在文档里,随着宏数量的增多,很快会造成一定的视觉污染。一般有两种管理的方法:折叠或者放到另一个文件里。

折叠宏#

很可惜,现在 LyX 没有自带的折叠功能,但还是有办法的。你可以使用 LyX 的 Branch 功能。具体操作就是点击 InsertBranchInsert New Branch...,输入分支的名称比如“宏”。然后右键新插入分支然后点 "Activate Branch"。这样就可以实现在框里输入、点击标签进行折叠了。

外置文件#

你可以新建一个 LyX 文档,把所有的宏都放到那里。然后在主文档里,选择 InsertFileChild Document... 来引用。(来源

这个方法的一个缺点就是引入了一个新的文件,管理起来会更麻烦一些,主要是不方便移动和分享文档。所以我个人还是喜欢折叠宏的方式。

Leave your comments and reactions on GitHub