Skip to content

00 · 设计总览

1. 产品定位

Mosu(下文简称 Mosu)是一个桌面优先、本地优先的 Markdown 编辑器, 交互范式是「无缝实时预览」: 单一编辑区域,内容以渲染后的形态呈现;光标所在的那个元素(且仅那个元素)就地展开为 Markdown 源码,可以直接改。

它要服务的人:

  • 用 Markdown 写长文档、技术文档、笔记的人;
  • 在意「文件就是我的资产」、不接受私有格式或云端锁定的人;
  • 需要把同一份稿子导出成 HTML / PDF / Word 交付的人。

打算成为:知识库(双链图谱、卡片盒)、协作文档平台、通用富文本编辑器。 这些可以由插件生态去做,不进内核。

2. 目标(Goals)

G1 · 编辑体验

  • 实时预览下的输入延迟 p95 < 16ms(一帧),10k 行文档打开到可编辑 < 300ms。 (✅ 已建基准并达标,实测 0.1ms / 36ms。注意这个指标量法有坑, 第一版量出来的数字下限由帧率决定 —— 见 07 §2.2。)
  • 中日韩输入法(IME)在任何装饰区域内都不丢字、不错位 —— 这是硬性门槛,不是「后续优化」。 (✅ 有专门的回归用例。)
  • 键盘可完成全部高频操作;命令面板可达全部命令。(✅)
  • 界面可读、可被读屏软件正确使用;对比度满足 WCAG AA。 (✅ 六套主题全过;axe 违规数为 0 且直接卡用例。一处明知故犯的例外: 专注模式的变暗只有 2.1:1,取舍见 07 §3.1。)

G2 · 格式保真

  • 任意合法 Markdown 文本,经「打开 → 不做任何编辑 → 保存」后与原文件逐字节相同
  • 局部编辑只产生局部 diff:改一个词不会重排整个文档的缩进 / 引号 / 换行风格。
  • 遵循 CommonMark + GFM;遇到不认识的语法按纯文本原样保留,绝不吞掉内容。

G3 · 可扩展

  • 主题只用 CSS,有稳定的类名与变量契约,升级不炸。
  • 插件可以注册命令、快捷键、面板、以及完整的语法扩展(解析 + 渲染 + 序列化三件套)。
  • 内置的数学公式、图表、脚注等能力自身就用插件 API 实现,保证 API 不是二等公民。

G4 · 交付

  • macOS / Windows / Linux 三平台,安装包体积 < 180MB,冷启动 < 1.5s。 (原定 120MB,M1.5 放宽 —— Electron 运行时本身就占去 100MB 上下, 余量太小会逼着在语法高亮这类真实需求上做无谓妥协。 ✅ 冷启动实测 807ms;Linux AppImage 113.6MB。 ⚠️ 空闲内存 550MB,超出 300MB 的预算,见 07 §2.3。)
  • 导出 HTML(自包含单文件)、PDF(✅);检测到 Pandoc 时额外支持 DOCX / ePub / LaTeX(⏸ 未做,见 06 §4)。
  • 界面语言:简体中文 / English / 日本語,设置里切换,不重启(✅ 见 07 §4)。

3. 非目标(Non-Goals)

明确不做,避免范围蔓延:

  • 不做实时协作(至少 v1 不做)。但内核选型要保证以后能加(见 ADR-0002)。
  • 不做云同步 / 账号体系。同步交给 Git、iCloud、Syncthing 等既有工具。
  • 不做通用富文本。不支持字号、字色这类 Markdown 表达不了的排版属性。
  • 不做移动端。内核是纯 Web 库,将来别人要做是可能的,但不在本项目范围。
  • 不复刻 Typora。不抄袭其代码、图标、主题资源、界面截图;只借鉴公开的交互范式。

4. 设计原则

P1 · 文本是唯一真相(Text is the source of truth)

编辑器缓冲区里存的就是磁盘上的字符序列。没有「文档模型 → 序列化成 Markdown」这一步, 因此不存在序列化偏差、不存在「保存后格式被改写」这类问题。渲染是投影,不是转换

这条原则是整个架构的地基,第 02、03 号文档都是它的推论。

P2 · 渲染失败必须优雅降级

公式写错、图表语法错、图片路径不存在 —— 显示错误提示,但源码文本必须仍然可编辑, 且保存时原样写回。任何渲染器崩溃都不能吃掉用户的字。

P3 · 内核不认识 Electron

@mosu/editor 是纯浏览器代码,不 import 任何 Node / Electron API。所有文件、对话框、 菜单能力通过注入的 HostBridge 接口获得。这样才能有 Web 版、才能被别的壳复用、 才能在纯 jsdom/Playwright 里测。

P4 · 能力最小化

渲染进程不开 nodeIntegration,开 contextIsolation,跑严格 CSP。 Markdown 里的原始 HTML 一律经过消毒;本地图片走自定义协议并限定在工作区内。 细节见 01 架构 · 安全模型

P5 · 先做对,再做全

宁可 v1 只支持 CommonMark + GFM 但做到零损耗,也不要支持二十种语法但每种都有边角 bug。 路线图(08)按这个顺序排。

这条原则在实践中最常见的形态不是「少做一个语法」,而是换一种做法把问题绕开。 三个真实例子:

  • 表格没有做网格编辑器,改成「每条命令是一次纯文本变换」(02 §6.4);
  • 行内 HTML 没有做消毒器,改成「一个字节的 HTML 都不进 DOM」(02 §5.1);
  • 块级 HTML 决定不做 —— 它的意义几乎全在属性里,而属性正是上面那条绕不开的 地方(03 §3.1)。

放弃的东西要写下来放弃的理由,不能只留一个「⏸」。

5. 与既有方案的取舍

方案为什么不直接用
VS Code + 预览插件分屏范式,不是本项目要的交互
Obsidian闭源、且定位是知识库;其 Live Preview 证明了本项目的技术路线可行
Typora闭源、付费;本项目提供开源替代
纯 ProseMirror 方案(如多数 WYSIWYG)富文本模型与 Markdown 源码往返有固有损耗,违反 G2 / P1,见 ADR-0002

6. 现在做到哪一步

一句话:M2 / M3 / M4 完成,M4.5 六件硬骨头全部落地,M6 提前做了四项 (专注 / 打字机模式、国际化、无障碍整改、性能基准)。下一步是插件系统(M5)。

逐个里程碑的「计划与实际的偏差」写在 08 路线图 每一节末尾。 那份偏差清单是这套文档里最该读的部分 —— 它记的是被推翻的结论, 而不是完成的功能。

分发相关(签名、公证、Mac App Store 的可行性、定价)单独在 09 分发

7. 命名与法律提示

  • 产品名为 Mosu(M1 之后确定)。仓库名 open-typo-md 与内部包名 @mosu/* 暂不跟随改动 —— 它们不是用户可见的东西,改动只会制造无谓的迁移成本。 改名涉及的具体位置与副作用见 08 路线图 · M1.5
  • Typora 是他人商标。本项目名称、图标、宣传语都不得与之近似。 Mosu 与之毫无字面或读音上的关联,混淆风险已经不成问题; 但正式发布前仍应确认这个名字在目标市场没有冲突。
  • 不得移植、反编译或参考 Typora 的源码与私有资源。所有实现从公开规范与开源库出发。
  • 依赖许可要与 MIT 兼容;GPL 组件(例如 Pandoc)只能作为外部可选进程调用,不能打包进发行版。

MIT 许可发布。与 Typora 无关联,是一个独立实现。