做了三年 ProseMirror 后,我用四个月自研排版引擎实现 WPS / Google Docs 替代品,整套框架 MIT 开源
英文标题:做了三年 ProseMirror 后,我用四个月自研排版引擎实现 WPS / Google Docs 替代品,整套框架 MIT 开源
做了三年 ProseMirror 后,自研排版引擎做出浏览器里真正分页的文档编辑器,还有块编辑器、Markdown 编辑器,背后两套 Tiptap 风格的编辑器框架 MIT 开源,附在线体验。
86.0 KB
90.6 KB
48.1 KB
33.6 KB
74.0 KB
35.6 KB
139.6 KB
7.4 KB
中文
先别急着划走,这不是概念图,也不是拼出来的截图。
打开 quirekit.com/demo/classi…,首屏就是一个真实的编辑器:一页一页的纸,打字、换行、表格跨页、切换 Canvas / SVG 渲染,全都是实时的。
演示里的 DOCX 导出、页眉页脚等是商业 Word 组件,编辑器框架、排版引擎和编辑器本身是开源的。
这是我过去四个月在做的 QuireKit 。它不是某一个编辑器,而是一整套编辑器生态 :
- 最底层 是两套编辑器框架,写法都是 Tiptap 风格:一套基于 ProseMirror,API 兼容 Tiptap;一套基于 CodeMirror,专门做 Markdown;
- 中间 是自研的排版引擎、Canvas / SVG / HTML 等多种视图,以及一套统一的 UI 组件库;
- 最上层 是能直接用的编辑器:分页文档、块编辑器、Markdown 编辑器,还有公式、思维导图、白板、流程图这些周边编辑器。
每一层都可以单独拿去用,也可以整套组合起来。一句话说它能干嘛:用它,你可以在自己的网页应用里嵌入一个像 WPS、Google Docs 那样的文档编辑器。
先说做出了什么
1. 浏览器里真正分页的文档编辑器
做过在线文档的都知道,浏览器只会排一条无限长的页面。想要“一页一页的纸”,常见做法是排完再量高度、手动切页,内容一改就全乱。
QuireKit 的分页编辑器不靠 DOM 排版:断行、分页、光标、选区全部自己算,再画到 Canvas 或 SVG 上 。屏幕上看到的分页,就是打印出来的分页。
- 表格可以跨页,表头自动重复
- 公式、流程图、思维导图、白板直接放进页面里一起排版
- 暗黑模式、中英文界面切换
- 长文档只绘制看得见的页,滚动不卡
操作面板也不是摆设。我按 Word 的功能区逐项对过一遍:开始、插入、页面、引用、审阅、视图,加上右键菜单、格式设置面板、表格和图片的上下文工具,已经有 350+ 功能能直接在界面上点出来用 ,还在继续补。
DOCX 往返也打通了 :Word、WPS 写的文档导进来,可以接着改,再导出成 DOCX,拿回 Word 里继续用。
PDF 和 OFD 导出也是自研的 :不走浏览器打印,直接复用分页排版画出来的那一份绘制指令,屏幕上一页什么样,导出的 PDF / OFD 就是什么样。OFD 是国产版式文件格式,政务、公文场景用得多。
DOCX 往返和 PDF / OFD 导出属于商业的 Word 组件,开发和评估免费。
2. 块编辑器
不需要分页的场景,比如笔记、知识库,用块编辑器:拖拽、斜杠菜单、表格、目录都有。
它解决了一个用过 contenteditable 的人都踩过的坑:你选中一段字,去工具栏输个链接,选区就没了。 在 QuireKit 里,光标和选区是自己画的,焦点跑到输入框,选区照样在。
3. Markdown 编辑器:原文一个字不丢
MD Editor 有四种视图:文档、实时预览、源码、阅读。前三种都能直接编辑,改的都是同一份 Markdown 原文 ,中间没有转成 JSON 再转回来,所以保存时你没碰过的行,一个字符都不会变。
大文档也不怕。我给 Markdown 解析器加了一个“复用证明”,编辑时直接跳过没变的部分。1 MiB 的文档连续输入 20 次,实测:
| 工作量 | 优化前 | 优化后 |
|---|---|---|
| 语法树访问 | 107,760 | 1,380(少了 98.7% ) |
| 语法树比较 | 153,940 | 660(少了 99.6% ) |
4. 一整套周边编辑器,单独也能用
公式、思维导图、白板、文本绘图(Mermaid / PlantUML / Graphviz)、流程图、图表、多维表格,每一个都是独立的包,不用整个编辑器也能单独装。
5. 自己设计的 UI 组件库
编辑器的操作界面比一般后台复杂得多:字体菜单、颜色选择、表格右键菜单、格式设置对话框、缩放、快捷键提示……为了让分页文档、块编辑器、Markdown 编辑器和这些周边编辑器用起来是同一种手感,我单独设计了一套 UI 组件库(Vue + UnoCSS),颜色、间距、字号都由同一套设计令牌管理,亮色和暗黑两套主题一键切换。
上面截图里所有的按钮、菜单和面板,都来自这套组件库,它同样是 MIT 开源的,可以单独用在你自己的项目里:design.quirekit.com
再说说最难的一块:中文输入法
Canvas 上没有输入框,中文输入法是最难啃的骨头 。拼音还没确认的时候,字要先显示出来、把后面的内容往后推,但又不能进撤销历史、不能同步给协作者。
我的做法是:输入法组合期间,用一份“临时文档状态”去排版和绘制,等你按下确认才真正写进文档。
浏览器在输入法上的坑非常多,事件数据为空、组合结束事件不来、确认后重复插入……这套处理我单独做成了 @quirekit/ime 包,其他 Canvas 编辑器也能直接拿去用。
底层:两套 Tiptap 风格的编辑器框架
- ProseMirror 线:
@quirekit/core。保留 ProseMirror 的文档模型、命令、插件、协同,API 兼容 Tiptap,目标是迁移一个 Tiptap 扩展时,主要只需把@tiptap/core的导入换成@quirekit/core。不同的是视图层:除了原生的 DOM 视图,还能挂自己排版的 Canvas / SVG 视图(分页文档用的就是它),以及自己管光标和选区的 HTML 视图(块编辑器用的就是它)。 - CodeMirror 线:MSFE 。基于 CodeMirror 和 Lezer,Markdown 原文就是文档,扩展和命令的写法也是 Tiptap 风格。MD Editor 构建在它上面。
两套框架的成品共用一套 UI 组件库,所以分页文档、块编辑器、Markdown 编辑器看起来是一家人。熟悉 Tiptap 的话,两条线都能很快上手。
能用吗?怎么用?
几行代码就能把 Markdown 编辑器放进 Vue 项目:
npm install @quirekit/md-editor@alpha
<script setup lang="ts">
import { MdEditor } from '@quirekit/md-editor/vue'
import '@quirekit/md-editor/styles.css'
</script>
<template>
<MdEditor markdown="# Hello" label="Document" />
</template>
块编辑器和分页编辑器分别是 @quirekit/block-editor、@quirekit/classic-editor。
整套生态里开源的部分 ,MIT 许可,闭源商用也可以:两套编辑器框架、Canvas / SVG 排版引擎和各种视图、UI 组件库、分页 / 块 / Markdown 三个编辑器,以及公式、导图、白板这些周边编辑器。Word 兼容能力(DOCX 往返、PDF/OFD 导出、审阅等)是单独的商业组件,开发和评估免费,不用它们也能完整使用编辑器。
目前是 alpha,API 还会变,欢迎来试、来挑刺:
觉得有意思的话,点个 Star 就是对我最大的支持。
English / 原文
先别急着划走,这不是概念图,也不是拼出来的截图。
打开 quirekit.com/demo/classi…,首屏就是一个真实的编辑器:一页一页的纸,打字、换行、表格跨页、切换 Canvas / SVG 渲染,全都是实时的。
演示里的 DOCX 导出、页眉页脚等是商业 Word 组件,编辑器框架、排版引擎和编辑器本身是开源的。
这是我过去四个月在做的 QuireKit 。它不是某一个编辑器,而是一整套编辑器生态 :
- 最底层 是两套编辑器框架,写法都是 Tiptap 风格:一套基于 ProseMirror,API 兼容 Tiptap;一套基于 CodeMirror,专门做 Markdown;
- 中间 是自研的排版引擎、Canvas / SVG / HTML 等多种视图,以及一套统一的 UI 组件库;
- 最上层 是能直接用的编辑器:分页文档、块编辑器、Markdown 编辑器,还有公式、思维导图、白板、流程图这些周边编辑器。
每一层都可以单独拿去用,也可以整套组合起来。一句话说它能干嘛:用它,你可以在自己的网页应用里嵌入一个像 WPS、Google Docs 那样的文档编辑器。
先说做出了什么
1. 浏览器里真正分页的文档编辑器
做过在线文档的都知道,浏览器只会排一条无限长的页面。想要“一页一页的纸”,常见做法是排完再量高度、手动切页,内容一改就全乱。
QuireKit 的分页编辑器不靠 DOM 排版:断行、分页、光标、选区全部自己算,再画到 Canvas 或 SVG 上 。屏幕上看到的分页,就是打印出来的分页。
- 表格可以跨页,表头自动重复
- 公式、流程图、思维导图、白板直接放进页面里一起排版
- 暗黑模式、中英文界面切换
- 长文档只绘制看得见的页,滚动不卡
操作面板也不是摆设。我按 Word 的功能区逐项对过一遍:开始、插入、页面、引用、审阅、视图,加上右键菜单、格式设置面板、表格和图片的上下文工具,已经有 350+ 功能能直接在界面上点出来用 ,还在继续补。
DOCX 往返也打通了 :Word、WPS 写的文档导进来,可以接着改,再导出成 DOCX,拿回 Word 里继续用。
PDF 和 OFD 导出也是自研的 :不走浏览器打印,直接复用分页排版画出来的那一份绘制指令,屏幕上一页什么样,导出的 PDF / OFD 就是什么样。OFD 是国产版式文件格式,政务、公文场景用得多。
DOCX 往返和 PDF / OFD 导出属于商业的 Word 组件,开发和评估免费。
2. 块编辑器
不需要分页的场景,比如笔记、知识库,用块编辑器:拖拽、斜杠菜单、表格、目录都有。
它解决了一个用过 contenteditable 的人都踩过的坑:你选中一段字,去工具栏输个链接,选区就没了。 在 QuireKit 里,光标和选区是自己画的,焦点跑到输入框,选区照样在。
3. Markdown 编辑器:原文一个字不丢
MD Editor 有四种视图:文档、实时预览、源码、阅读。前三种都能直接编辑,改的都是同一份 Markdown 原文 ,中间没有转成 JSON 再转回来,所以保存时你没碰过的行,一个字符都不会变。
大文档也不怕。我给 Markdown 解析器加了一个“复用证明”,编辑时直接跳过没变的部分。1 MiB 的文档连续输入 20 次,实测:
| 工作量 | 优化前 | 优化后 |
|---|---|---|
| 语法树访问 | 107,760 | 1,380(少了 98.7% ) |
| 语法树比较 | 153,940 | 660(少了 99.6% ) |
4. 一整套周边编辑器,单独也能用
公式、思维导图、白板、文本绘图(Mermaid / PlantUML / Graphviz)、流程图、图表、多维表格,每一个都是独立的包,不用整个编辑器也能单独装。
5. 自己设计的 UI 组件库
编辑器的操作界面比一般后台复杂得多:字体菜单、颜色选择、表格右键菜单、格式设置对话框、缩放、快捷键提示……为了让分页文档、块编辑器、Markdown 编辑器和这些周边编辑器用起来是同一种手感,我单独设计了一套 UI 组件库(Vue + UnoCSS),颜色、间距、字号都由同一套设计令牌管理,亮色和暗黑两套主题一键切换。
上面截图里所有的按钮、菜单和面板,都来自这套组件库,它同样是 MIT 开源的,可以单独用在你自己的项目里:design.quirekit.com
再说说最难的一块:中文输入法
Canvas 上没有输入框,中文输入法是最难啃的骨头 。拼音还没确认的时候,字要先显示出来、把后面的内容往后推,但又不能进撤销历史、不能同步给协作者。
我的做法是:输入法组合期间,用一份“临时文档状态”去排版和绘制,等你按下确认才真正写进文档。
浏览器在输入法上的坑非常多,事件数据为空、组合结束事件不来、确认后重复插入……这套处理我单独做成了 @quirekit/ime 包,其他 Canvas 编辑器也能直接拿去用。
底层:两套 Tiptap 风格的编辑器框架
- ProseMirror 线:
@quirekit/core。保留 ProseMirror 的文档模型、命令、插件、协同,API 兼容 Tiptap,目标是迁移一个 Tiptap 扩展时,主要只需把@tiptap/core的导入换成@quirekit/core。不同的是视图层:除了原生的 DOM 视图,还能挂自己排版的 Canvas / SVG 视图(分页文档用的就是它),以及自己管光标和选区的 HTML 视图(块编辑器用的就是它)。 - CodeMirror 线:MSFE 。基于 CodeMirror 和 Lezer,Markdown 原文就是文档,扩展和命令的写法也是 Tiptap 风格。MD Editor 构建在它上面。
两套框架的成品共用一套 UI 组件库,所以分页文档、块编辑器、Markdown 编辑器看起来是一家人。熟悉 Tiptap 的话,两条线都能很快上手。
能用吗?怎么用?
几行代码就能把 Markdown 编辑器放进 Vue 项目:
npm install @quirekit/md-editor@alpha
<script setup lang="ts">
import { MdEditor } from '@quirekit/md-editor/vue'
import '@quirekit/md-editor/styles.css'
</script>
<template>
<MdEditor markdown="# Hello" label="Document" />
</template>
块编辑器和分页编辑器分别是 @quirekit/block-editor、@quirekit/classic-editor。
整套生态里开源的部分 ,MIT 许可,闭源商用也可以:两套编辑器框架、Canvas / SVG 排版引擎和各种视图、UI 组件库、分页 / 块 / Markdown 三个编辑器,以及公式、导图、白板这些周边编辑器。Word 兼容能力(DOCX 往返、PDF/OFD 导出、审阅等)是单独的商业组件,开发和评估免费,不用它们也能完整使用编辑器。
目前是 alpha,API 还会变,欢迎来试、来挑刺:
觉得有意思的话,点个 Star 就是对我最大的支持。