Notion、飞书文档那样的表格:好看,点格子就能改,底色、列宽一拖一点就好。文件里仍然是标准的 Markdown 表格,没装插件、在手机上、在 GitHub 上打开都是正常表格。
界面语言跟随 Obsidian 的语言设置,支持简体中文和英文。桌面端和移动端都能用。
用法
装好就生效:笔记里的 Markdown 表格在实时预览和阅读视图里都换成 gogoga Table 的样子,不用改任何写法。
- 改内容:单击格子选中,直接打字替换;双击或按 Enter 在原内容上改。编辑中 Enter 完成并走到下一行,Shift+Enter 在格子里换行,Tab / Shift+Tab 左右走,Esc 取消。最后一格按 Tab 自动加一行。
- 选中时:方向键移动,Delete 清空,⌘Z / ⌘⇧Z 撤销重做(和编辑器是同一条历史)。第一行再往上、最后一行再往下、Esc,光标回到表格外面的正文。
- 选一片:按住拖过几个格子、Shift+点、Shift+方向键。选中一片后可以一起设底色、对齐、清空(Delete),右键在选区里菜单对整片生效,Esc 收回成一格。
- 复制粘贴:⌘C / ⌘X 复制选中的格子,纯文本是制表符分隔(Excel、Numbers 认),同时带有样式的 HTML 表格(底色、文字颜色、加粗、对齐、列宽、合并),粘到飞书、Word、邮件里保留样子;粘回 gogoga 表格时用 Markdown 原文,链接、加粗不丢。⌘V 能粘 Excel、飞书、网页复制来的表格,制表符分隔的文字,或者一段 Markdown 表格源码,从选中的格子开始贴,超出范围自动加行加列;复制一格、选中一片再粘,每格都填上。
- 粘贴生成表格:在正文里粘贴从 Excel、WPS、Numbers、飞书、Google 表格或网页上复制的表格,直接生成一张表,第一行当表头,前后自动空行。只有剪贴板里整段就是一张表(至少 2 行 2 列)时才这样;在代码块、公式、frontmatter 里照常粘贴原文。
- 合并单元格:选中一片右键「合并单元格」,合并后的格子显示各格的全部内容(不丢字),取消合并后各格内容原样回来;合并的格子右键「取消合并」。在合并区域中间插行插列,区域跟着变大;删行删列跟着变小。
- 加行加列:鼠标移到表格上,右边和下边出现加号。
- 行、列手柄:鼠标停在格子上,这一行的左边框、这一列的上边框出现手柄。按住拖动调整行列顺序(底色、列宽、合并跟着走),点一下是行 / 列菜单:插入、上下左右移动、整行整列设底色、删除;列菜单里还有对齐和自动列宽。
- 右键格子:插入行列、对齐、底色、清空、删除行列。
- 列宽:拖表头的右边缘,双击恢复自动。
- 底色:灰、红、橙、黄、绿、蓝、紫七种,取主题的颜色调淡,深浅色模式下都合适。
- 下拉填充:选中格子后拖右下角的小方块,按规律往下 / 往右填:数字递增、带编号的文字(第 1 期)、日期、周几、月份按顺序续,其他照抄;按住 ⌥ 一律照抄。拖出表格自动加行加列。
- 表格左上角菜单:单独给这张表设样式(默认、斑马纹、极简线、三线表)和行距,第一列作为标题列,整表对齐,平均分布列宽、撑满页面宽度,所有列恢复自动宽度,清除所有颜色。
- 排序:列菜单里按此列升序 / 降序,数字按数值、日期按时间、中文按拼音,空格子排最后;有合计行时合计行不动。
- 复制行列、一次插入多行:行 / 列菜单里「复制此行」「复制此列」;选中几行再插入,一次插入同样多的行(列也一样)。
- 勾选框:格子里写
[ ]或[x]就显示成能点的勾选框,选中后按空格也能切换;右键「变成勾选框」。 - 文字颜色:右键菜单里底色下面一排「A」是文字颜色。
- 合计行:列菜单「合计」选求和、平均、计数、最大、最小,表格最后自动加一行「合计」,数据改了跟着重算;新加的行加在合计行前面。
- 状态列:列菜单「设为状态列」,这一列的值画成彩色标签,编辑时下拉选已有的状态,新状态自动分颜色;右键状态格可以改这个状态的颜色。
- 编辑格子时:⌘B 加粗、⌘I 斜体、⌘⇧X 删除线、⌘⇧H 高亮、⌘K 链接;输入
[[补全笔记链接,输入#补全标签。光标在表格里时,Obsidian 的编辑器快捷键不会改到正文。 - 命令:插入表格(悬停网格选行列数)、把选中的文字(CSV、制表符分隔)转成表格,以及插入、复制、删除行列,排序,合并,对齐等,都能在命令面板里用、绑快捷键。
- 长表格、宽表格:往下滚时表头贴在顶端;横向放不下时左右出现淡淡的阴影,提示还能滚。
- 手机:点一下格子就进入编辑,长按出菜单,滑动照常滚动;点了格子后行列手柄出来,手指按住拖动换位置。
- 格子里的加粗、链接、
[[双链\|别名]]、标签、公式照常显示,点链接直接打开。
设置
- 接管 Markdown 表格(默认开):关掉后完全恢复 Obsidian 原生表格。
- 样式:默认(参考 Notion:直角、极淡的分隔线、表头浅底)、斑马纹、极简线。
- 行距:舒适、紧凑。
文件里存的是什么
表格本身是标准 GFM 表格,对齐用标准的 :---: 写法。Markdown 写不出来的列宽、底色、合并,放在紧跟表格下面的一行 HTML 注释里:
| 方案 | 月费 | 存储 |
| :--- | :---: | ---: |
| 基础 | 10 元 | 5 GB |
<!-- gogoga-table: {"w":[120,null,200],"bg":{"B2":"yellow"},"merge":["A3:B3"]} -->
- 合并的格子在别处显示为普通格子:左上角那格有内容,其余是空的,内容不丢。
- 坐标按 Excel 的习惯:列是 A、B、C,第 1 行是表头。增删、移动行列时,注释里的坐标跟着改。
- 注释在别的编辑器里看不见;在 Obsidian 里由插件藏起来。注释放在表格下面,是因为放在上面紧贴着时,没装插件的 Obsidian 实时预览不把它当表格。
- 没有列宽、底色时不写注释。注释坏了或被删掉,表格照常显示,只是没有列宽和底色。
- 原来补了空格对齐的表格,改完仍然对齐(中文按两个字宽算);两头没写竖线的表格,写回时也不加。
性能
结论
- 几百行、几千个格子以内的表格都很流畅:200 行 × 10 列(2000 格)上,所有操作都在 0.3 秒以内,点选和方向键在 20 毫秒左右。
- 上万个格子的表格能打开、能看、能选、能改格子,但改结构会慢:1000 行 × 20 列(2 万格)上,打开约 0.4 秒,点选约 0.15 秒,改一个格子约 0.1 秒;插入行、排序、撤销要 0.5~10 秒。慢的主要是 Obsidian 自己的原生表格,不装本插件也一样慢(见下面「瓶颈」)。
- 建议:一张表尽量控制在几千个格子以内。数据更多时,可以拆成几张表,或者改用 Obsidian 的 Bases、CSV。
压测结果
在 Obsidian 1.15(macOS,Apple Silicon)里用真实鼠标、键盘事件操作,量从输入事件到下一帧画完的时间。
| 操作 | 200 行 × 10 列 | 1000 行 × 20 列 |
|---|---|---|
| 打开笔记到表格画完 | 0.05 秒 | 0.4 秒 |
| 切到阅读视图 | 0.1 秒 | 0.7 秒 |
| 点选一格 | 0.02 秒 | 0.15 秒 |
| 方向键挪一格 | 0.01 秒 | 0.1 秒 |
| 框选 50 行 | 0.01 秒 | 0.1 秒 |
| 十字高亮跟着鼠标 | — | 0.06 秒 |
| 滚动时最长的一帧 | 0.02 秒 | 0.09 秒 |
| 改一格并写回 | 0.1 秒 | 0.1 秒(笔记刚打开几秒内的第一次改动 2~3 秒) |
| 插入一行 | 0.15 秒 | 3.2 秒 |
| 按列排序 | 0.1~0.26 秒 | 3.4~10.5 秒 |
| 撤销 | 0.2 秒 | 0.5~14 秒 |
同一张 1000 × 20 的表,不装本插件时在 Obsidian 原生表格上做同样规模的改动:
| 改动 | 原生表格耗时 |
|---|---|
| 改一个格子里的几个字 | 0.16~3.1 秒 |
| 插入一行 | 3.1~3.4 秒 |
| 整张表的正文换顺序(相当于排序) | 0.07~11 秒 |
0.4.0 及更早的版本里,同一张 1000 × 20 的表打开要 1.6 秒,切到阅读视图 2.4 秒,点选 0.2 秒,撤销最长 9.5 秒。这一版做的优化:
- 纯文字、数字的格子直接显示,不再逐格走 Markdown 渲染;
- 选中、方向键、十字高亮只更新变了的格子;
- 十字高亮改成盖在表格上的色带,不再逐格加样式;
- 写回笔记时只改变了的那几个字,不再整张表替换。Obsidian 的原生表格因此只更新那一格,不整张重建:2 万格的表上改一格从约 3 秒(最慢 10 秒以上)降到约 0.1 秒。
表格的解析、写回、增删、移动、排序等处理本身很快:2000 行 × 20 列的表,每项都在几毫秒内;在一篇有 200 张表的笔记里找出所有表格,约 3 毫秒。
瓶颈和限制
Obsidian 自己的原生表格(改内容慢的主要原因)。 实时预览里,Obsidian 会给每张表格建一个它自己的原生表格对象,被本插件的表格盖住、根本不显示时也照建。表格文字一变:
- 改动全落在单个格子里,它只更新那几格(本插件改格子时只写回变了的字,走的就是这条路);
- 插行、删行、排序、整张替换这类改动,它会立刻把整张表重建一遍。
这一步在 2 万格的表上要 3~10 秒,耗时还取决于 Obsidian 当时有没有把整篇笔记解析完,波动很大。不装本插件时也一样:原生表格本身就是这个速度。Obsidian 只有两种情况会跳过:一是它自己的表格编辑器发出的改动(带一个内部标记),二是表格范围里有搜索高亮。这两样都是 Obsidian 内部的东西,插件拿不到。借用它们会让插件在 Obsidian 更新后失效,甚至出现表格显示不出来之类的问题,所以本插件不这么做。
点选、方向键在大表格里约 0.1 秒。 选中一格时,浏览器要把整张表重新排版、重画一帧。2 万格的表上,这一步本身就要几十毫秒。用来接收输入的隐藏输入框要跟着放进选中的格子里,这样中文输入法的候选框才会出现在正确的位置,但这一挪就会触发整表重排。
所有行都会画出来。 没有做只画看得见的那几行,所以表格越大,打开和切换视图越慢,大约每 1000 个格子 20 毫秒。阅读视图同理。
自己跑压测
- 处理逻辑的压测在
scripts/tests/perf.test.ts,随npm test一起跑(CI 也跑)。时间上限放得很宽,只用来拦住成倍变慢的改动。 - 界面压测在仓库外的 e2e 脚本里(
t_perf.py),要在 Obsidian 里跑。会打印上面那张耗时表,并在同一张表上关掉插件,量原生表格的耗时作对照。
目前的范围
- 表格下面已有 Advanced Tables 的公式注释(
<!-- TBLFM -->)或块标识(^id)时原样保留,我们的注释排在后面,公式和块引用照常有效。 - 接管顶格写的表格,和列表项下面缩进写的表格(紧跟着列表项或隔一个空行,每行缩进一样)。代码块、引用和 callout(
>开头)里的表格,以及不在列表里的缩进,仍由 Obsidian 原生显示。 - 紧跟在一段文字后面(中间没空行)的表格不接管,交给 Obsidian 原样处理。