熟悉的工作台,专注的“文章表面”
外壳学的是 VS Code Workbench 的分区布局——标题栏、活动栏、侧栏、编辑区、面板、状态栏,打开文件夹、分栏、命令面板的手感都和你习惯的一样。
但编辑区里不是迷你 IDE,而是即写即得的“文章表面”:基于 Milkdown Crepe 的所见即所得 Markdown 编辑器,表格、流程图、幻灯、图版块以卡片形式嵌在正文里。
- 为什么是 Tauri早期路线是 VS Code 扩展和 Code-OSS 分支,体积达 GB 级、扩展与安装包容易不同步。改为独立的 Tauri 桌面应用后,界面复用系统 WebView2,分发轻得多。
- 为什么是纯文本编辑器里看到的一切最终都写回同一份 Markdown 字符串,任何 Markdown 工具都能降级读。
编辑面的五层结构
一份 Markdown 字符串,同时被三种编辑器和几条语法树流水线共享。每层各管一件事。
Tauri 2 + WebView2 渲染界面,通过自定义命令调用 Rust 宿主读写文件、跑 Git、做识字。
标题栏、侧栏、编辑器组网格、面板、状态栏;菜单、快捷键、命令面板共用一张命令注册表。
ProseMirror(经 Milkdown Crepe)——所见即所得正文
CodeMirror 6——源码、纯文本、超长文档
Univer——文内电子表格与表格文件
unified + remark(GFM、frontmatter)负责解析与序列化;另有排版投影、导出变换等流水线。
.hy.md 字符串唯一的真相。编辑器改动经防抖回写到这里,保存时与文首 YAML 合并落盘。
技术栈
尽量选择成熟、许可证清晰的开源组件;AGPL / GPL / LGPL 组件不进安装包。版本号以当前代码为准,会随开发更新。
桌面与界面
- 桌面壳
- Tauri 2,插件 fs / dialog / opener / window-state
- 前端
- React 19、Vite 7
- 图标
- @vscode/codicons
- 界面语言
- 自建轻量 i18n,中英键编译期对齐
编辑与渲染
- 正文编辑
- Milkdown Crepe 7(基于 ProseMirror)
- 源码编辑
- CodeMirror 6
- Markdown 解析
- unified + remark-parse + GFM + frontmatter
- 图表 / 公式
- mermaid 11、KaTeX
- Diff
- diff、markdown-it
文内 Office 能力
- 电子表格
- Univer(只用 sheets-core 预设)
- 表格文件
- exceljs、jszip
- 幻灯
- marp-core 渲染 HTML;modern-screenshot 拍图;pptxgenjs、jsPDF 拼文件
- 图片画布
- Fabric.js 7
- 作图
- JSXGraph(双许可,取 MIT)
文件与本机能力
- Word 导出
- remark-docx(MIT),内置生成
- Office 预览
- docx-preview、pptx-preview
- CAD 字体
- @mlightcad/shx-parser、opentype.js(SHX → TTF,本机生成)
- 本机识字
- Rust
ort(ONNX Runtime)+ PP-OCRv5 mobile - 搜索
- Rust
regex
依赖只向下,规则写进测试
代码分五层,上层可以依赖下层,反过来不行。最底层的宿主无关包既能在浏览器跑、也能在 Node 跑,不碰 Tauri API。
- 一功能一目录每个功能有自己的 Model、Pane 和入口文件,互不缠绕。
- 模块预算新源码文件不超过 600 行;超标文件冻结,只拆不加。
- 加功能七问落点、状态、入口(命令注册表 + 中英文案)、文件与进程守门、大依赖拆包、冻结文件、同轮更新文档——七问答完才能动手。
- 命令单一来源菜单、快捷键、命令面板共用同一份注册表,不会出现“菜单能用、快捷键不行”。
src/parts · overlays · layout · App.tsxsrc/editor/<feature>src/stateservices · commands · i18n · perfpackages/*src-tauri文件 · Git · 识字 · 授权 · CAD 管道六个宿主无关包
解析、排版、导出、视图投影这些核心逻辑都做成独立的包:不依赖界面、不依赖 Tauri,可以单独测试。
| 包 | 职责 | 单元测试(文档记录) |
|---|---|---|
@hymd/parser | 解析与序列化、块注册表(unified + remark-parse + GFM + frontmatter) | 54 |
@hymd/webview-core | Crepe 装配、块卡片、表格与流程图叠层、幻灯栅格、选区工具条、i18n 小词典 | 121 |
@hymd/blocks-sheet | Univer 快照读写与挂载 | 10 |
@hymd/layout | 纸面几何、分页投影、CAD 排版数据导出 | 194 |
@hymd/export | 导出变换、表格转 GFM、幻灯、Word 生成(remark-docx)、打印 HTML | 26 |
@hymd/views | 块索引、锚点、胶片解析、投影(纯函数) | 47 |
规则:packages/* 禁止引用应用代码、禁止调用 Tauri API;Node 内置模块只能出现在独立入口。
从打开到保存:一份文档的旅程
点开文件、编辑、按 Ctrl+S,数据在各模块间这样流动。
超长正文(超过 20 万字)自动改用源码窗编辑,避免卡死;图片、PDF、Word、PPT、表格文件按类型挂各自的预览或编辑面板。
本地图片总能找到
WebView 会把相对路径的图片解析到页面根目录而找不到。HyMd 依次在文档目录、assets、{stem}.assets、工作区和全局图库里查找,命中后只改显示,不改你的 Markdown。
表格快照不塞进正文
文内电子表格的完整状态存为 {stem}.assets/{blockId}.univer.json,正文里留的是可读的表格内容——在别的编辑器里看,依然是一张表。
投影是纯函数,原稿只有一份
每种视图都是 投影(源文本, 本视图胶片) → 视图用的 Markdown。幻灯交给 marp-core 渲染,排版和论文交给 @hymd/layout 分页。
{stem}.assets/views/{kind}.hy.md原稿改了,标记怎么找回?
- 显式 id
- 块指纹
- 原文摘录
- 结构路径
- 失联清单
逐级匹配,全部对不上时进入“失联清单”等你处理,而不是悄悄删掉。每个视图有独立的 50 步撤销。第 5 级“模糊摘录”锚点 规划中
三条导出管线
所有导出都先经过同一个导出变换(把表格块降为普通表格、处理围栏块等),再分流到不同出口。
Word (.docx)
- 导出变换
- remark-docx 直接生成
- .docx
当前代码已改为内置的 remark-docx(MIT)生成,无需另装 Pandoc;公式先成图,原生 Word 公式在规划中。完善中
幻灯 (.pptx / .pdf)
- marp-core 渲染 HTML
- 应用内拍成 PNG
- pptxgenjs / jsPDF 拼文件
无需 Marp CLI。当前导出的 pptx 每页是整页图片,可编辑的原生文本框 pptx 在规划中。界面待走查
整篇 PDF
- 生成打印 HTML
- 本机浏览器无界面打印
借助本机已有的 Chromium 系浏览器打印。PDF 页码与书签在规划中。
预览和图纸,用同一把尺
工程说明贴进 AutoCAD 后最怕“重新折行”:屏幕上一行,图纸上变两行。HyMd 的办法是在自己这边把每一行都量好、锁好,CAD 插件只负责照着画。
- 编辑器正文.hy.md
- 解析parseHymd
- 屏外分页锁定倍率,逐字量位置
- 排版数据每块带已折好的行与基线
- 命名管道只送给已绑定的窗口
- CAD 插件只画不折
毫米与像素的换算
1 mm = 96 / 25.4 CSS 像素。屏外分页时锁定缩放倍率,对每个字取实际渲染位置合成行,再换算成毫米。
字体口径
微软雅黑按 CSS 字号 = 字高 × 4/3 换算;TSSD(天正 SHX)在本机转成网页字体,大写高做成 1 em;宋体口径单独处理。
对齐 AutoCAD 行距
按 AutoCAD 多行文字“固定行距 1.2 倍”换算。“CAD 说明”风格即字高 3.5 mm、行距 7.0 mm。
本地优先:你的文件不离开你的电脑
HyMd 是本地桌面应用,没有云端存储。写作、排版、识字、导出都在本机完成。
离线识字
OCR 用 Rust 的 ONNX Runtime 跑 PP-OCRv5 模型,全部在本机执行,图片和扫描页不会上传。英语音标识别做了专门增强,模型换机无需重训。界面待走查
纯文本落盘
所有内容都是 Markdown 文本和同目录的资源文件。不绑定账号、不锁定格式,换电脑、换工具都带得走。
按需授权目录
应用默认只能访问自己的数据目录;你打开的文件夹才会在运行时放行。系统目录、凭据目录、用户目录根不会被放行。
保守的 Git 操作
Git 命令按形状校验:拒绝强推、强制切换、清空贮藏等危险操作;拉取只做快进。
不执行文档里的代码
条形图围栏只解析数据字面量、不执行代码;外部程序只认 Git 与浏览器等少数几类并按完整路径核对;“系统打开”拒绝可执行文件。
离线授权验证
激活码用 Ed25519 公钥在本机验签;文献校验等联网查询默认不自动发起。
测试很多,但我们只认“看得见”
全仓约 1600 个单元测试,TypeScript 严格模式零错误,Rust 有单测与 clippy 检查。但在 HyMd 的规则里,单测绿了不算通过。
- 包与应用单测证明纯函数与回归
- 构建与类型检查编译通过、中英文案齐全
- GUI 走查证明用户真的看得见
- 干净机冒烟安装包不依赖开发机
这也是为什么网站上很多功能标着“完善中”:代码与单测已就绪,但还没在窗口里逐项走查。我们宁可少说,也不提前说“已验证”。