VS Code + HyperSnips + $\LaTeX$笔记速记
你是否想要在上课的时候随着老师讲课写出笔记?你是否钦慕电子笔记工整漂亮的公式?或者你只是想快点写 \(\LaTeX\) 公式?本教程将试着教你如何使用 VS Code + HyperSnips + \(\LaTeX\) 记数学笔记。
内容包括:
- TeX Live 在 Windows 或 Linux 下的安装。
- VS Code 的配置。
- HyperSnips 的配置,并详细解释为什么要这样配置。
我们的目标是在 VS Code 中达到与 Gilles Castel 相当的速度(与手写一样快)。
在用本教程方法之前,您应当注意:
- markdown 与 typst 也可以用来记笔记,并且远没有 \(\LaTeX\) 这样复杂。如果您的笔记没有「高度定制」的内容,请优先考虑它们。
- 本教程的配置内容相当繁琐,并且您(至少)需要 1-2 周的练习才能达到上课跟记笔记的速度。
- 本教程的配置相当私人化(部分配置基于我自己认为更舒服的习惯或感受),您可能需要根据自己的需求进行修改。
TeX Live 安装(Linux)
本节内容根据王然老师的教程对 Linux 的安装进行了修改。
若您是 Windows 或 macOS 用户,请参考他的教程。
请不要使用
sudo apt install texlive-full,因为远挰的包并不一定是最新的,因此
tlmgr 会出错,并且它会导致本地环境相当混乱。因此,推荐通过
.iso 安装。
建议在 TUNA 下载镜像,你可以在主页右侧“获取下载链接”——“应用软件”——“TeX 排版系统”找到,或是在这个页面找到最新的镜像。
同时,执行以下命令安装必要的软件:
1 | sudo apt install fontconfig gedit vim -y |
下载后,进入下载目录(文件管理器找到位置,右键终端打开),挂载
.iso 文件,并执行 install-tl。
1 | sudo mkdir /mnt/texlive |
点击 I 进行默认安装,然后等待安装完成。
安装完成后,执行
1 | sudo umount /mnt/texlive |
即可卸载镜像。
配置环境变量
接下来,我们需要配置环境变量。复制以下代码到终端中并执行(注意,要修改第 19 行的年份):
1 | # 检测当前用户的 shell |
此时,在终端中执行
tex --version,若输出类似如下的内容,则说明安装成功:
1 | TeX 3.141592653 (TeX Live 2024) |
配置字体
接下来刷新处理字体缓存:
1 | year=2024 # 请替换为你的年份 |
tlmgr 配置
建议直接处理好 tlmgr 的设置:
1 | sudo visudo |
在打开的文件中找到 Defaults secure_path,在引号最后加上
:/usr/local/texlive/2024/bin/x86_64-linux,然后使用
Ctrl + S, Ctrl + X 退出。
对该命令的解释
sudoers
是一个配置文件,它规定了哪些用户可以以怎样的身份运行什么程序。sudoers
文件的位置在
/etc/sudoers,但是不要直接编辑这个文件,因为这个文件的语法很复杂,而且一旦出错,就无法使用
sudo 命令了。visudo 是一个编辑 sudoers
文件的工具,它会检查语法错误,避免出现错误。所以,我们使用 visudo 来编辑
sudoers 文件。
在 PATH 变量环境中不同的路径之间用 : 分隔。
最后执行
1 | sudo tlmgr option repository ctan |
即可完成 TeX Live 的安装。
VS Code 配置
首先,安装 VS Code。
然后,安装以下插件(Ctrl + Shift + X
打开插件商店):
- LaTeX Workshop
- HyperSnips for Math
接下来,我们需要配置 VS Code 的设置。
Ctrl + Shift + P 打开命令面板,输入
首选项:打开用户设置(JSON),打开
settings.json。
复制以下代码到 settings.json:
1 | "latex-workshop.latex.autoBuild.run": "onSave", |
此时,你的 .tex
文件应该可以正常编译了。找个文件夹,新建一个 .tex
文件,输入以下内容:
1 | \documentclass{article} |
编译器的选择
当你不知道该用什么时选择 xelatex 配方。
LaTeX 是一个排版系统,而不是一个编程语言。因此,它需要一个编译器来将
.tex 文件编译成 .pdf 文件。常见的编译器有
pdflatex, xelatex,
lualatex。我们安装的 TeX Live
包含了这三个编译器,以及一些其他的工具。
pdflatex是旧的 TeX 语言的实现,并不支持 Unicode 字符和 OpenType 字体。但是,它的兼容性很好(可以使用一些老的包),因此在一些老的模板中仍然使用。xelatex是基于 XeTeX 的实现,支持 Unicode 字符和 OpenType 字体。它是现在最常用的编译器。lualatex是基于 LuaTeX 的实现,支持 Unicode 字符和 OpenType 字体,同时还支持 Lua 语言。它的速度比xelatex快,但是在一些包的兼容性上不如xelatex。
我们的配方还提供了 xelatex-minted 和
pdflatex-minted,这两个配方支持 minted
包,这是一个用于代码高亮的包。该配方编译时多了
--shell-escape 参数,因为该包通过调用外部
pygments
程序来进行代码高亮。但是,该参数使得编译过程中可以执行外部程序,因此可能会有一些安全问题,因此平常不建议使用这两个配方。
配方中还有一些链配方,如
xelatex -> bibtex -> xelatex*2,这种配方可以在编译时自动编译参考文献。这种配方在第一次编译时会生成
.aux 文件,第二次编译时会生成 .bbl
文件,第三次编译时会将参考文献插入到文档中。在没有参考文献的情况下这个配方会报错,因此在没有参考文献的情况下使用
xelatex 配方即可。
此外,本人没有用过 biblatex,因此没有配置
biber,如果你需要使用
biblatex,请自行配置。
保存后编译,VS Code 下方栏应该出现一个
√,表示编译成功,并生成了一个 .pdf
文件。焦点在 .pdf 文件上,按
Ctrl + Alt + V,应该可以看到预览。
双向检索
双向检索是指在 PDF
中双击可以跳转到源文件,而在源文件中按快捷键可以跳转到
PDF。这个功能需要在编译时生成 .synctex.gz
文件,因此需要在编译时添加 -synctex=1 参数。
LaTeX workshop 默认的使用 Ctrl + Alt + J 进行
.tex 文件到 .pdf
文件的跳转,并且我们在上面的配置中将双击 PDF 文件作为 .pdf
文件到 .tex 文件的跳转。
编译纠错
若编译出错,VS Code 底部会出现一个 ×。在
.tex
文件中,错误的行会被标记出来。但是,有时候错误信息并不明确,这时可以使用
Ctrl + Alt + X 打开 LaTeX Workshop
的侧边栏,选择 “查看日志消息” - “查看 LaTeX
编译日志”,可以找出错误的原因。
HyperSnips 配置
Ctrl + Shift + P 打开命令面板,输入
HyperSnips: Open Snippets Directory,打开
snippets 文件夹。在其中新建 latex.hsnips
文件,并输入以下内容:
1 | global |
使用说明
代码片段的核心思想就是通过能够较快输入的字符(触发字符,最好短、并且不容易与其他字符冲突)来触发代码片段的生成,从而减少输入时间。
HyperSnips 的代码片段是通过正则表达式来匹配触发字符的,并且由 Orange X4 大佬开发的版本支持代码片段只在数学环境下触发。
每个代码片段的格式如下:
1 | snippet 触发字符 "代码片段描述" 触发条件 |
其中:
- 触发字符:触发代码片段的字符,可以是一个字符串,也可以是一个正则表达式。
- 代码片段描述:代码片段的描述,用于在代码片段提示框中显示。
- 触发条件:触发代码片段的条件,可以是
i(在词语内部也会触发)、A(自动展开)、m(数学模式)。 - 代码片段内容:代码片段的具体内容,支持使用光标位置、传入参数、使用函数等。
光标位置是由 vscode-snippet 的语法来实现的,可以通过
${1}、${2} 等来表示光标位置,${0}
表示最终的光标位置。
传入的参数是片段中类似 ``rv = m[1]`` 这样的代码,其中
m[1] 表示第一个传入的参数,rv
表示返回的结果。
这里提供了一些常用的代码片段的速查表,可以根据自己的需求进行修改。代码现已经过编辑尽可能不冲突,并符合 LaTeX 的语法习惯。
代码片段速查表
| 触发方式 | 代码片段描述 | 说明 |
|---|---|---|
| lm | Inline Math | 生成行内数学公式,即 $...$。 |
| eqt | Equation | 生成 equation 环境,即
\begin{equation} ... \end{equation}。 |
| eqs | Equation* | 生成 equation* 环境,即
\begin{equation*} ... \end{equation*}。其为不编号的行间公式。 |
选中文本后按 // |
Fraction | 将选择的文本放在分子上,\frac{分子}{分母}
在数学环境中生成分式 |
输入一个变量名后按 / |
Fraction no () | 变量符合“数字 字母 (下滑线)数字”的格式,如 11x_{31} |
(内容)/ |
Fraction with () | 将括号内的文本放在分子上,分母为括号,即生成
\frac{括号内的内容}{} |
| 文字+hbar | Bar | 效果如 \(\overline{a}\)(Overline 的 上划线更长,适合长文本) |
| 文字+htd | Tilde | 效果如 \(\tilde{a}\) |
| 文字+bar | Bar | 效果如 \(\bar{a}\) (Bar 的 上划线更短,适合单字母) |
| 文字+hat | Hat | 效果如 \(\hat{a}\) |
| 文字+hvec | Vector postfix | 效果如 \(\vec{a}\) (Vector 的箭头更短) |
| 文字+rta | Vector postfix | 效果如 \(\overrightarrow{a}\) |
| dot | Dot | 效果如 \(\dot{a}\) |
| hdd | Ddot | 效果如 \(\ddot{a}\) |
| hsq | Sqrt | 效果如 \(\sqrt{a}\)
(其中,\sqrt[n]{a} 为 n 次根号) |
| dig | Degree | 效果如 \(a^{\circ}\) |
| pow | Power | 效果如 \(a^{b}\) |
| sb | Subscript | 效果如 \(a_{b}\) |
| }xx(xx 为相同数字) | Auto subscript | 将相同数字的内容自动转换为下标,如 }11 变为
_{1} |
a2 |
Auto subscript | 将字母后跟的数字自动转换为下标,如 a1 变为
a_{1} |
a_{2}3 |
Auto subscript | 将字母后跟的两个数字自动转换为下标,如 a_{1}2 变为
a_{12} |
| taa | Auto subscript 2 | 将字母后跟的相同小写字母自动转换为下标,如 aaa 变为
a_a |
| 希腊字母+aa(两个相同字母) | Auto subscript for greek letter | 将希腊字母后跟的小写字母自动转换为下标,如 \alphaaa
变为 \alpha_{a} |
| txt | Text | 效果如 \(\text{a}\),用于普通文本 |
| tit | Text it | 效果如 \(\textit{a}\),用于斜体文本 |
| mbb | Mathbb | 效果如 \(\mathbb{A}\),用于黑板粗体字母 |
| RR、NN、ZZ、QQ、CC | R、N、Z、Q、C | 数集符号 \(\mathbb{R N Z Q C}\),即黑板粗体字母的快速写法 |
| 文字 + bf 或 BF | Mathbf | 效果如 \(\mathbf{a}\),用于正体加粗 |
| 文字 + bm 或 BM | Mathbm | 形成 \bm{a} ( markdown 不含此效果) |
| 文字 + bs | Boldsymbol | 效果如 \(\boldsymbol{a}\),用于粗体符号 |
| 文字 + sf | Mathsf | 效果如 \(\mathsf{a}\),用于无衬线体 |
| 文字 + frak | Mathfrak | 效果如 \(\mathfrak{a}\),用于斯拉夫字体 |
| 文字 + cal | Mathcal | 效果如 \(\mathcal{A}\),用于花体字母。由于花体只支持大写字母,因而自动转大写 |
| 文字 + rm | Mathrm | 效果如 \(\mathrm{a}\),用于正体字母 |
| 文字 + opn | Operatorname | 效果如 \(\operatorname{a}\),用于定义算子(例,如默认无 \(\operatorname{rank}\) 算子,可使其以算子字体渲染) |
| oo | infinity | 生成 \(\infty\) |
| ... | cdots | 生成 \(\cdots\),对应代码为
\codts。 |
| cdots; | vdots | 生成 \(\vdots\),对应代码为
\vdots。即,先按 ...,再按 ;
就等效输入 vdots |
| vdots; | ddots | 生成 \(\ddots\),对应代码为
\ddots。同上理。 |
| 12;; | 0, 1, 2, ..., n | 按n和n+1连续增加数字,生成
a_1 b_1, a_2 b_2, \ldots, a_n b_n,其中 a
b n 可以分别修改。 |
| 12.. | 0, 1, 2, ..., n | 同上理,生成 a_1, a_2, \ldots, a_n |
| 12,, | 0, 1, 2 | 类似地,生成 a_1, a_2 |
| <> | Diamond | 生成 \(\diamond\) |
+... 或 -... |
Smart cdots | 生成
\cdots,用于表示省略号。若前面有空格,则保留空格。 |
,... |
Smart ldots | 生成
\ldots,用于表示省略号。若前面有空格,则保留空格。 |
| ** | Dot multiply | 生成 \(\cdot\),用于表示点乘。 |
| +- | pm | 生成 \(\pm\),用于表示正负号。 |
| -+ | mp | 生成 \(\mp\),用于表示负正号。 |
| xx | Cross | 生成 \(\times\),用于表示乘号。 |
| eps | Epsilon | 生成 \(\epsilon\),用于表示希腊字母 epsilon。 |
| veps | Varepsilon | 生成 \(\varepsilon\),用于表示希腊字母 varepsilon。 |
| ell | Ell | 生成 \(\ell\),用于表示希腊字母 ell。 |
| log | Log | 生成 \(\log\),用于表示对数函数。 |
| bin | Binom | 生成 \(\binom{a}{b}\),用于表示二项式系数。 |
| oth | Otherwise | 生成 \(\text{otherwise}\),用于表示其他情况。 |
| star | Star | 生成 \(^{*}\),用于表示上标星号。 |
| U | tocorret | 生成 \(\Upsilon\),用于表示希腊字母
Upsilon。此条是为了纠正由于打一半 psi 展开为
\psi 导致的错误。 |
| u | tocorret | 生成 \(\upsilon\),用于表示希腊字母 upsilon。同上。 |
| (空格)in | notin | 生成 \(\notin\),用于表示不属于。由上片段输入
not 会自动变为
\not带空格的版本,因而加此条。 |
| (空格)EE | notexists | 生成 \(\nexists\),用于表示不存在。由上片段输入
not 会自动变为
\not带空格的版本,因而加此条。 |
| inn | in | 生成 \(\in\),用于表示属于。 |
| (空格)ot | lnot | 生成 \(\lnot\),用于表示逻辑非。 |
| varGamma | varGamma | 生成 \(\varGamma\),用于表示希腊字母 varGamma。 |
\pii |
p_i | 生成 \(p_i\),用于表示下标 i 的
p。为 \pi 的纠正。 |
| sse | Subseteq | 生成 \(\subseteq\),用于表示子集等于。 |
| sqs | Sqs | 生成 \(\sqsubseteq\),用于表示平方子集等于。 |
| tto | To | 生成 \(\to\),用于表示箭头符号。 |
| -< | Leftrightarrow | 生成 \(\leftrightarrow\),用于表示双向箭头符号。 |
| <- | Leftarrow | 生成 \(\leftarrow\),用于表示左箭头符号。 |
| li | Limits | \sin\limits_{a}^{b} 生成如 \(\sin\limits_{a}^{b}\),用于表示上下限。 |
| -> | To | 生成 \(\to\),用于表示箭头符号。 |
| !> | Mapsto | 生成 \(\mapsto\),用于表示映射到符号。 |
| => | Implies | 生成 \(\implies\),用于表示蕴含符号。 |
| =< | Implied by | 生成 \(\impliedby\),用于表示被蕴含符号。 |
| iff | If and only if | 生成 \(\iff\),用于表示当且仅当符号。 |
| EE | Exist | 生成 \(\exists\),用于表示存在符号。 |
| AA | Forall | 生成 \(\forall\),用于表示全称量词符号。 |
| bec | Because | 生成 \(\because\),用于表示因为符号。 |
| thr | Therefore | 生成 \(\therefore\),用于表示所以符号。 |
| >= | Greater than | 生成 \(\geqslant\),用于表示大于等于符号。 |
| dis | Displaystyle | 生成
\displaystyle,此命令加在行内的数学公式前,可以使其显示为行间公式(更高的版本)。 |
| <= | Less than | 生成 \(\leqslant\),用于表示小于等于符号。 |
| != | No equals | 生成 \(\neq\),用于表示不等于符号。 |
| == | Constant equals | 生成 \(\equiv\),用于表示恒等符号。 |
| sim | Sim | 生成 \(\sim\),用于表示相似符号。 |
| eq | Simeq | 生成 \(\simeq\),用于表示约等于符号。 |
| ~~ | Approx equals | 生成 \(\approx\),用于表示近似等于符号。 |
| ~= | Congruent equals | 生成 \(\cong\),用于表示全等符号。 |
| >> | Much greater than | 生成 \(\gg\),用于表示远大于符号。 |
| << | Much less than | 生成 \(\ll\),用于表示远小于符号。 |
| and | & | 生成 &,用于表示对齐符号。 |
| case | Cases | 生成 cases 环境,即
\begin{cases} ... \end{cases}。 |
| ali | Aligned | 生成 aligned 环境,即
\begin{aligned} ... \end{aligned}。 |
| ceil | Ceil | 生成
\left\lceil ... \right\rceil,用于表示向上取整。 |
| floor | Floor | 生成
\left\lfloor ... \right\rfloor,用于表示向下取整。 |
| set | Set | 生成 \{ ... \mid ... \},用于表示集合。 |
| norm | Norm | 生成 \left\| ... \right\|,用于表示范数。 |
| abs | Absolute value | 生成
\left\lvert ... \right\rvert,用于表示绝对值。 |
| Vert | Verts | 生成
\left\Vert ... \right\Vert,用于表示双竖线符号。 |
| beg | Begin | 生成 \begin{,搭配 VS code
的自动补全功能,可以快速生成环境。 |
| taylor | Taylor | 生成 \(\sum_{k=0}^{\infty} c_k (x-a)^k\),用于表示泰勒级数。 |
| lim | Limit | 生成 \(\lim_{n \to \infty}\),用于表示极限。 |
| sum | Sum | 生成 \(\sum_{min}^{max}\),用于表示求和。 |
| SUM | Common sum | 生成 \(\sum\),用于表示求和符号。 |
| prod | Product | 生成 \(\prod_{n=1}^{\infty}\),用于表示连乘。 |
| part | Partial derivative | 生成 \(\frac{\partial V}{\partial x}\),用于表示偏导数。 |
| ndiff | d/dx | 根据 n 生成 \(\frac{\mathrm{d}y}{\mathrm{d}x}\),用于表示导数。n
表示 n 次导。 |
| dd | dd | 生成 \(\mathop{}\!\mathrm{d}\),用于表示微分符号。使用
\mathop{}\!\mathrm{d} 代替 \mathrm{d}
的好处是可以正确的显示微分号前的空格。 |
| buu | Bigcup | 生成 \(\bigcup_{i \in I}\),用于表示大并集符号。 |
| bnn | Bigcap | 生成 \(\bigcap_{i \in I}\),用于表示大交集符号。 |
| dint | Integral | 生成 \(\int_{-\infty}^{\infty} \, \mathrm{d}x\),用于表示积分符号。 |
| label | label | 生成形如 \label{randlabel:kgy0ntirtd}
的标签,用于交叉引用。标签中有 10 位随机字符。 |
代码片段补充说明
可以搜索中间的名称直接找到对应的代码片段,例如搜索
Fraction就可以找到分式的代码片段。除了lm、eqt、eqs三个片段,其余片段都按照在原文件中的顺序排列。自 710 行后部分不常用的片段,没有在表格中列出,可以自行查看。
支持自动为算符和希腊字母等添加反斜杠,由
integrate、min|max|argmin|argmax|sup|inf、function、greek、logic operator、logic symbols、math function片段定义。其中,
min|max|argmin|argmax|sup|inf一条片段在符号后自动上空格,这是考虑到这些符号通常后面会有空格,并且如果不加空格易触发其他片段。部分片段是为了纠正错误出现的,例如
U\psilon、u\psilon是由于打一半psi展开为\psi导致的错误。\(\LaTeX\) 的数学符号和环境非常多,这里只列出了一部分常用的片段,如果有其他需要,可以自行添加。
在 \(\LaTeX\) 中,
\left和\right用于生成自适应大小的括号,可以用于生成各种括号,如圆括号、方括号、大括号等。不过,其大小大于公式高度(括号稍低于公式符号会美观些),并且不能换行,因此提供了 big、Big、bigg、Bigg 四种大小的括号(大小依次增大,固定高度),其用法为:)big,生成\bigl( \bigr)。其余}、]、|同理。如 \(\displaystyle\bigl( \frac{a}{b}\bigr)\)。)Big,生成\Bigl( \Bigr)。如 \(\displaystyle\Bigl( \sum_{min}^{max}\Bigr)\)。)bbig,生成\biggl( \biggr)。)BBig,生成\Biggl( \Biggr)。
问题
VS code 默认的补全提示是允许使用 Tab 或者 Enter 键进行选择的,但是在打大量公式时,Enter 键有时会导致换行,有时导致补全(取决于补全提示框是否加载出来),因此建议使用 Tab 键进行选择。关闭 Enter 键的选择功能可以在设置中搜索
editor.acceptSuggestionOnEnter,将其设置为off。但是 Tab 键本身也和代码片段的光标位置有冲突,还没有解决方案。由于不少片段需要在数学环境外触发,同时又出现在英文单词内(如
lm、eqt、eqs等),因此在输入这些单词时可能会触发代码片段。这里没有解决方案,只能尽量不在.tex文件中输入英文。输入法切换还有点麻烦的。有插件vscode-smart-ime可以解决这个问题,但由于 ibus 无法改切换输入法键,只能在 fcitx 下使用。