Notion上打行内公式|网页端和Mac电脑端

已是废文,Notion已经可以用行间公式了。这是Notion还未开发行间公式(Inline Math)时的曲线救国方案。

1 前言

这里说一下 1. 为什么需要行内公式 2. 为什么写这篇东西

马上想看结果的请直接跳转正文

Notion只能打一整行数学公式,没法打行内公式

1.1 为什么需要行内公式

虽然Notion内置有一个叫Math equation的block选项可以用来打Latex,但是一段公式必须占用一个block,也就是必须占用一行,很不方便。笔记的一些数学符号或者一小段公式没必要占用一行,不然会浪费空间而且搞的笔记不易读。

然而,没有数学类笔记需要的人这个功能也没什么意义。

1.2 为什么写这篇东西

  1. 总结下已有的行内公式实现方法
  2. 分享Mac电脑端的行内公式糙代码
  3. 记录第一次js编程

2 正文

直接上方法

2.1 如何在网页端打行内公式

这里主要以Chrome为例子,其他浏览器应该是相似的。

  1. 安装浏览器扩展程序Tampermonkey或者暴力猴
  2. notion-inline-latex或者Notion-Inline-Math/Web/ 复制相关的js代码
  3. Tampermonkey或者暴力猴中添加新脚本,粘贴刚刚复制的js代码
  4. 查看脚本是否启动。
  5. 尝试打公式,按下alt/option就能变成公式了。

2.2 如何在Mac电脑端打行内公式

  1. denosawr/inlinemath-userscript.js 或者 Notion-Inline-Math/Mac desktop/ 下载js代码

  2. 在下载的文件夹内打开终端(右键文件夹选择新建位于文件夹位置的终端窗口)

  3. 运行以下代码

    1
    2
    chmod 777 patcher.sh
    ./patcher.sh
    > 如果没有第一句直接运行./patcher.sh, 可能会报错「permission denied」。

  4. 重启一下Notion,就可以尝试写行间公式了,还挺快的。

只希望官方快点出个更快的

2.3 找方法的过程

2.3.1 网页端行间公式记录

在网上找了下,网页端的实现已经有了(Notion Inline Math)。不过这个方法有2个问题, 1. 触发公式转换的符号是 「math:」而不是我们平时打latex时常用的两边「$」。 2. 触发公式转换的按钮是 F2,对用touchbar的Mac用户不太友好。

这个在Xiang Jiang的博客Use inline math in Notion on a Mac上也提到并改进了。

其实早就有直接实现网页端用「$」打行内公式的js代码在notion-inline-latex,当时没发现....

但是他们的方法都还是网页端,这个优点还没在Mac电脑端实现(当然也可能是我还没找到),所以需要。

说回一开始找到的老代码,上面那两个功能可以体现在代码的这两个位置

1
2
3
4
5
6
7
8
function rerender_all() {
console.log("rerender all!")
var mathElement = Array.from(document.querySelectorAll("span[style*=\"monospace\"]"))
var filtered = mathElement.filter(el => el.textContent.startsWith("math:"))
filtered.forEach(function(el) {
render_one(el)
})
}
1
2
3
4
5
window.addEventListener('keydown', function(e) {
if (e.key == "F2" && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
rerender_all()
}
}, true)
Xiang Jiang的博客Use inline math in Notion on a Mac也是直接修改了这两个地方就实现了 1. 网页端的「$」符号触发 2. option/alt键触发

为什么要讲这个呢?因为这个关乎于我怎么把Mac电脑端的代码也以同样的方式从「math:」触发改成「$」触发,记录分享一下第一次js代码经验,也许对别人有启发。

2.3.2 Mac电脑端行间公式记录

Mac电脑版已有的Notion行间公式实现代码在Github Gist的denosawr/inlinemath-userscript.js

仿照之前的做法,我们把符号触发和按键触发的相应代码找出来,就是这两个地方

1
2
3
4
5
if (document.activeElement.contains(el)) {
if (e.key != "F2") {
return;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if (s.startsWith("math:")) {

el.style.color = null;
el.style.background = null;
s = s.slice(5).trim();
katex.render(s, el, {throwOnError: true, font: "mathit"});

} else if (s.startsWith(",")) {
el.style.color = null;
el.style.background = null;
s = "\\mathrm{" + s.slice(1).trim() + "}";

var match;
while (match = s.match(subscript)) {
s = s.replace(subscript, "_{$1}$2");
}

while (match = s.match(superscript)) {
s = s.replace(superscript, "^{$1}$2");
}

katex.render(s, el, {throwOnError: true, font: "mathit"});
} else if (s.startsWith("$")) {
el.style.color = null;
el.style.background = null;
s = s.slice(1).trim();
katex.render(s, el, {throwOnError: true, font: "mathit"});
}

其实也没啥改的必要,稍微记录一下。

当时把这两个地方修改为

1
2
3
4
5
if (document.activeElement.contains(el)) {
if (!e.altKey) {
return;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if (s.startsWith("$") && s.endsWith("$")) { //
el.style.color = null;
el.style.background = null;
s = s.substring(1, s.length-1) //
// s = s.slice(5).trim();
console.log("rendering ", s)
katex.render(s, el, {throwOnError: true, font: "mathit"});
} else if (s.startsWith(",")) {
el.style.color = null;
el.style.background = null;
s = "\\mathrm{" + s.slice(1).trim() + "}";

var match;
while (match = s.match(subscript)) {
s = s.replace(subscript, "_{$1}$2");
}

while (match = s.match(superscript)) {
s = s.replace(superscript, "^{$1}$2");
}

katex.render(s, el, {throwOnError: true, font: "mathit"});
}
这样就可以: 1. 用option/alt触发公式 2. 不用「math」符号而用两边的「$」来触发公式

2.4 参考

  1. https://medium.com/@xiangjiang.dal/use-inline-math-in-notion-e26c500fd98
  2. https://www.notion.so/Notion-Inline-Math-9c5047a4e7c84643848b3630db8d5a5e
  3. https://gist.github.com/denosawr/8a5e434bd97154fba81ea91e79a8c99b
  4. https://github.com/Penguinlay/notion-inline-latex

3 后记

沉迷Notion