学习
实践
活动
专区
工具
TVP
写文章

世界上最好的编辑器Vim:1700多页数学笔记是如何实时完成的

选自 castel.dev

作者:Gilles Castel

机器之心编译

一般你是用手写还是 MarkDown 做数学笔记?在这篇文章中,作者介绍了如何用 LaTex 和 Vim 实时做数学笔记,通过一系列炫酷的技巧,不论是表达式板书还是图像绘制,我们都能实时跟得上。

机器学习

的学习过程中,很多时候都需要手动推导目标函数或最优化过程。这些推导很可能是老师在黑板上一边写一边解释,有时候我们会仔细听解释,并顾不上记笔记与注解。因此课程音频与视频就很重要了。但如果我们能跟得上老师的手写速度,那么以后回忆这些笔记就方便很多。

例如在最近结课的 CS224n 2019 中,Christopher Manning 在第一节课就手动推 Word2Vec 的最优化与权重更新过程。由此可见,飞一般地记数学笔记还是很有必要的。

图片截图来自 CS224n 2019

在这篇文章中,作者在攻读数学专业学士学位的第二个学期开始用 LaTex 做课堂笔记,自此以后一直在使用,总共记下了 1700 多页的笔记。以下是一些例子,你可以看看用 LaTex 做出笔记是什么样子的。

这些包括图表在内的笔记,都是在上课期间完成的,之后没有修订过。为了使 LaTex 做笔记可行,作者在头脑中设下以下四个目标:

利用 LaTex 记文本和数学公式应与讲师在黑板上写字的速度保持一致:不允许延误。

画图的速度应尽量与讲师保持一致。

做笔记,如添加注解、编辑所有注解、整合最后两堂课的内容、搜索注解等,应方便快捷。

当我们想在 pdf 文件旁边添加注释时,利用 LaTex 应能够实现这一目的。

以下从 Vim+LaTex 到 Snip­pets,作者介绍了如何科学地记数学笔记。

Vim 和 LaTex

我使用 Vim 在 LaTex 中记文本和数学公式。Vim 是一个功能强大的通用文本编辑器,可扩展性很强。我使用 Vim 写代码、LaTex、mark­down 等一切基于文本的东西。Vim 具有一个非常陡峭的学习曲线,一旦你弄清楚了基本原理,则很难再使用那些缺少 Vim 快捷键绑定的编辑器。以下是我编辑 LaTex 时屏幕的样子:

左边是 Vim,右边是我的 pdf 查看器 Zathura(也有类似于 Vim 的快捷键绑定)。我正使用带有 bspwm 的 Ubuntu 作为自己的窗口管理器。我在 Vim 使用的 LaTex 插件是 vimtex。该插件提供句法高亮显示、内容图表以及 synctex 等。使用 vim 插件的设置如下所示:

最后两行的设置隐藏属性。这是一个特征,当你的光标不在那一行时,LaTex 代码会被替代或隐藏。通过隐藏 \[、\] 和$等标志符,你可以更舒服地浏览文件。这一特征也以∩替代\bigcap,以∈替代\in 等。以下动画应能够使这一过程更清楚。

这篇博客要解决的核心问题是:用 LaTex 做笔记如何与讲师在黑板上写字的速度保持一致。这都要归功于 snippet。

Snippets

一个 snippet 是一段可重复使用的短文本,可用来编辑其他文本。例如,当我键入 sign 并按下 Tab 时,单词 sign 将会补全为一个自定义的签名。

Snippet 也可以是动态的:当我键入 today 并按下 Tab 时,单词 today 将会被当前日期替代;键入 box Tab 变成一个可以自动增大的框。

你甚至可以在另一个 snippet 中使用 snippet。

利用 UltiSnip 创建 Snippet

我使用插件 UltiSnip 来管理我的 snippet,其设置如下:

定义 sign 的 snippet 的代码如下所示:

对于动态 snippet,你可以在倒引号``之间输入代码,并在 snippet 扩展时运行。我在这里使用 bash 编译器格式化当前日期:date + %F。

你也可以在`!p ... `块内部使用 Python。你可以看一下定义 box 的 snippet 代码:

这些 Python 代码块将会被变量 snip.rv 的值替代。在这些代码块内部,你可以访问 snippet 的当前状态,如 t[1] 包含第一个制表位,fn 表示当前文档名称。

LaTeX snippet

借助于 snippet,利用 LaTeX 做笔记要比手写快得多。一些复杂的 snippet 可以为你节省大量时间并消除做笔记的挫败感。让我们开始了解一些简单的 snippet。

环境

为了嵌入环境,我必须在一行开端键入 beg。之后我键入环境名称,后者会直接在\end{} 指令中映出。按下 Tab 使光标位于新创建的环境中。

该 snippet 的代码如下所示:

b 意味着该 snippet 将只能在一行开端扩展,并且 A 代表自动扩展,这意味着我不需要键入 Tab 就可以扩展 snippet。制表位--即可以通过按下 Tab 和 Shift+Tab 跳转到的地方--以$1、$2 等表示,同时最后一个为$0。

inline math 和 display math

我最常使用的两个 snippet 是 mk 和 dm。这些 snippet 负责数学代码的开始。第一个是 inline math snippet,第二个是 display math snippet。

in­line math snippet 是「智能的」:它知道何时在$符号后嵌入一个位置。当我在结尾$的正后方开始键入一个单词时,它添加一个位置。但是,当我键入一个非单词字符时,它不添加一个位置,例如下图的$p$-value。

该 snippet 的代码如下所示:

第一行结尾处的 w 意味着该 snippet 将在词边界扩展,所以举例而言,hellomk 不会扩展,而 hello mk 会扩展。

diaplay math snippet 更简单,但同时也相当方便;该 snippet 使我在一段时间内不会忘记结束方程式。

上下标

另一个有用的 snippet 主要针对下标,该 snippet 自动将 a1 更改为 a_1 以及 a_12 更改为 a_。

该 snippet 代码使用正则表达式作为触发器。当你在 [A-Za-z]\d 编码的数字后面键入一个字符,或者在 _以及两个数字 [A-Za-z]_\d\d 后面键入一个字符时,触发器会扩展该 snippet。

当你在使用圆括弧包装部分正则表达式时,如 (\d\d),你可以通过 Python 中的 match.group(i) 在扩展 snippet 中使用它们。

对于上标而言,我使用 td 自动扩展为 ^{} 的。但是,对于平方、立方、以及一小部分其他常见上标,我使用 sr、cb、comp 等专门的 snippet。

分数

用于分数的 snippet 是我使用最方便的自动扩展方法之一,它可以进行以下扩展:

第一个的代码非常简单:

第二和第三个例子使用正则表达式匹配 3/、4ac、 6\pi^2/、a_2/等表达式。

如你所见,正则表达式可能非常复杂,这里有个图表可以解释:

在第四、第五个例子中,它试图找到匹配圆括弧。由于不能使用 Ul­tiSnips 的正则表达式引擎,我转向了 Python:

最后一个与分数有关的 snippet 即使用你的选择来制作分数。你可以先用它选择一些文本,然后按下 Tab,打出/,然后再按下 Tab。

这些代码用到了 $ 变量表示你的选择。

sympy 和 Math­e­mat­i­ca

另一个很酷但不太常用的 snippet 是利用 sympy 评估数学表达式。例如,sympy Tab 键扩展为 sympy | sympy,sympy 1 + 1 sympy Tab 键扩展为 2。

Math­e­mat­i­ca 用户也可以进行类似的操作:

后缀 snippet

值得分享的还有后缀 snippet,如 phat \hat,zbar \overline 等。一个类似的 snippet 是后缀向量,如 v \vec。这些 snippet 真的非常节省时间,因为你可以借此跟上老师板书的节奏。

注意,我还是可以用 bar 和 hat 前缀,我以较低的优先级将它们添了进去。那些 snippet 的代码如下:

其他 snippet

我还有 100 多个其他常用的 snippet,其中多数非常简单。例如,!>变成 \mapsto,->变成\to 等。

下载地址:https://castel.dev/tex-e0c2e8b64036f77db00411d562750c12.snippets

上下文管理

写这些 snip­pet 的时候需要考虑:这些 snippet 和普通文本有冲突吗?例如,我的词典里有大约 72 个英文单词、2000 个包含 sr 的荷兰语单词,也就是说,如果我打出 disregard,sr 就会变成^2,我会得到 di^2egard。

解决方案是在 snippet 中加入一个上下文管理文(Con­text)管理方法。使用 Vim 的句法高亮,就可以根据你是在写数学还是文本来决定 Ul­tiSnips 是否应该扩展 snippet。我的想法如下:

现在你可以将 context "math()"添加到你只想在数学上下文中扩展的 snippet 了。

注意,「数学上下文」这个说法也很微妙。有时候你通过使用\text{...} 将一些文本添加到数学环境中。在那种情况下,你不想让 snip­pet 扩展。然而,在\[ \text{$...$} \] 中,你又需要扩展。所以「数学上下文」这个说法有点不好界定,如下图所示:

实时纠正拼写错误

尽管学习数学是我做笔记的一个重要部分,但大部分时间我都在打英语单词。我的打字技术还不错,每分钟 80 词左右,但我还是会时不时地出错。所以我在 Vim 上添加了快捷键绑定,纠正拼写错误,以免打断我的工作流程。我按下 Ctrl+L 键就可以纠正之前的拼写错误,就像这样:

我的拼写检查设置如下:

它跳转到之前的拼写错误 [s,然后选取第一个建议 1z=,接下来跳回 `]a。中间的u 使得快速纠正拼写错误成为可能。

结论

使用 Vim 中的 snip­pet 使得书写 LaTeX 不再那么头疼,反而成为一种享受。与实时拼写检查结合之后,记数学笔记变得非常舒服。后续博文将讨论数字绘图及将图嵌入 LaTex 文本等内容。虽然前期学习成本会有一些,但熟悉后板书推导就能飞一般地记载。

本文为机器之心编译,转载请联系本公众号获得授权。

------------------------------------------------

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190401A0851W00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

关注

腾讯云开发者公众号
10元无门槛代金券
洞察腾讯核心技术
剖析业界实践案例
腾讯云开发者公众号二维码

扫码关注腾讯云开发者

领取腾讯云代金券