Skip to content
KevinXC5Public

About

Leafmark · 叶笺:简洁的 Markdown 桌面编辑器

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Leafmark · 叶笺

面向 macOS / Windows 的轻量本地 Markdown 编辑器,支持所见即所得编辑、多标签和本地文件夹导航。

界面不使用 WebView(No WebView):没有 Electron、Tauri 或任何内嵌浏览器,整个窗口由 Go 代码经 GPU 原生绘制,编辑器、公式和图表都是自绘的。

官网:https://kevinxc5.github.io/leafmark/

下载

从官网或 GitHub Releases 下载:macOS 按芯片选择 arm64 或 amd64 的 DMG,Windows 按架构选择 Setup 安装程序。

  • 在设置中检查软件更新、查看版本信息并安装更新。更新包经过签名校验,安装后可重启应用;重启前先处理未保存文档。
  • 安装包尚未配置 Apple 公证与 Windows 代码签名,首次运行时系统可能显示来源验证提示。

功能

  • 文档管理:多标签、本地文件打开、保存、另存为、独立撤销历史、自动保存与草稿恢复。.md、.markdown 文件可从访达的“打开方式”选择 Leafmark,或直接拖入窗口、拖到程序坞图标打开。
  • 文件导航:打开一个文件夹作为工作区,浏览、筛选目录树,新建或重命名其中的文档与文件夹。
  • 编辑:所见即所得,标题、列表、表格、引用、提示块、代码块、图片、公式和流程图都按排版结果显示,编辑时不露出 Markdown 标记;需要时可切到源码模式直接改 Markdown。
  • 导出:HTML、PDF 和 Markdown 副本。
  • 个性化:正文字体、字号、行高、阅读宽度、浅色 / 深色 / 跟随系统主题、专注模式、打字机模式和可自定义的快捷键。
  • 界面:浅色是暖纸色,深色是同一色调的暖灰;面板、代码块与表格靠底色区分层次,不用边框包裹;强调色只标出链接、当前选中、勾选和未保存这类状态。

尚未支持的内容见已知限制。

使用说明

文档与文件夹

  • 每个文档是一个独立标签,各自保留内容、选区和撤销历史;标签上的圆点表示有未保存的修改。
  • 在侧栏“文档”页打开一个文件夹作为工作区,可展开目录、按名称筛选并打开其中的 Markdown 文件。右键目录或文件可以新建文档、新建文件夹、重命名或在文件夹中显示;重命名已打开的文档或其所在文件夹前须先关闭相关标签。工作区不显示隐藏文件、node_modules 和符号链接,最多扫描 10,000 个条目和 64 层目录。
  • 拖动侧栏右缘可调整宽度(200–520,并给正文区至少留出 420),宽度随设置保存,双击右缘恢复默认宽度。
  • 侧栏的“大纲”页以叶脉的形式列出当前文档的标题:一条主脉贯穿全部标题,每个标题由一根侧脉连出,层级越深侧脉越长,并标出 H1、H2 等级别。点击标题跳到对应位置,光标所在章节的侧脉与级别以强调色标出。当前文档没有标题时,大纲页显示一枚线描叶子和提示文字。底部状态栏显示字数、预计阅读时长、保存状态、编码和当前编辑模式。字数按 Markdown 原文统计:汉字逐字计数,其他文字和数字按连续词计数。
  • 文件在其他程序里被修改时,没有本地改动的标签自动换成磁盘上的新内容;有未保存改动的标签暂停自动保存并提示,可从“⋯”菜单选择“从磁盘重新加载”。

编辑

  • 所见即所得:正文直接显示排版结果。选中文字后,选区上方浮出格式栏:加粗、斜体、删除线、行内代码,一至三级标题,无序、有序与任务列表,引用,链接、图片、表格、代码块和分隔线。同样的操作在右上角“⋯”菜单的“格式”里。再点一次同样的块类型会回到正文段落。
  • 可排版的块:标题、段落、引用、提示块(> [!tip] 一类)、围栏代码块、分隔线、表格,以及列表和任务。任务复选框可以点击切换。围栏代码块使用等宽字体,字符串和行注释有区分色,不做完整的语法着色。按 Mod+Enter 可在当前块后新建正文段落。
  • 列表与引用:列表项可以包含多段正文、代码块与嵌套列表,续段对齐到项目正文。引用与提示块支持嵌套结构和多个段落。光标在列表项里时,Tab 缩进一层,Shift+Tab 提升一层。
  • 脚注:[^标签] 显示为上标编号,定义区按引用顺序编号。点击引用跳到定义,点击定义编号或回跳箭头返回引用。
  • HTML 子集:常用的段落、标题、引用、列表、代码、链接、图片与行内样式可在原生界面显示;<details> / <summary> 提供可展开的折叠内容。下划线与按键文字使用 <u> / <kbd>。不执行脚本或 CSS。
  • 引用式链接与图片:支持 [文字][标签] 和 ![说明][标签],定义保存在原文中,正文不显示定义行;行内图片作为不可拆分的内容,与前后文字一起排版。
  • 图片嵌入:支持 Obsidian 的 ![[文件名.png]]、![[文件名.png|说明]] 和 ![[文件名.png|300]],扩展名为 PNG、JPEG、GIF、WebP 或 SVG 时按图片显示,原文按嵌入语法写回。只写文件名时,先在文档所在目录及其子目录里查找,文档属于当前工作区时再查找整个工作区,同名文件取层级最浅的一个。笔记嵌入等其他 ![[…]] 保留原文。
  • 表格:按单元格编辑,Tab / Shift+Tab 在单元格之间移动,在最后一格按 Tab 追加一行。右键单元格可以在上下插入行、在左右插入列、设置列对齐、删除行列或删除整张表格。
  • 行内样式:粗体、斜体、删除线、行内代码、链接、高亮(==文字==)、上下标(H~2~O、x^2^)。
  • 公式:行内公式($s = vt$)和独占一块的块级公式($$…$$)按数学排版显示,支持上下标、分式、二项式、根式、求和与积分、常用 AMS 符号、可伸缩括号、重音与装饰、数学字体、矩阵、分段函数、对齐环境、array 行列分隔线、颜色和 \tag 编号。\text 可包含中文与行内公式。把光标移进行内公式会展开成 TeX 源码以便修改,移出后恢复排版。
  • Mermaid 图表:mermaid 代码块支持流程图(graph / flowchart)、时序图(sequenceDiagram)、甘特图(gantt)、饼图(pie)、类图(classDiagram)、状态图(stateDiagram / stateDiagram-v2)和实体关系图(erDiagram)的常用语法。流程图支持方向、常见节点外形、带文字的连线、子图独立方向,以及 classDef、style、linkStyle 的颜色、线宽和虚线。click 的安全链接可以打开。
  • 图表语法:时序图支持参与者、生命线、消息箭头、备注、自环、循环框、激活条和自动编号;甘特图按日期、时长与依赖排任务;类图显示成员与关系箭头,状态图显示起止与复合状态,ER 图显示实体属性与关系基数。
  • 编辑源码:双击块级公式、图表或任何占位卡片,会打开源码编辑框,确定后整块替换。
  • 源码模式:点击状态栏右侧的“源码”,或按 Mod+Shift+R,当前标签切换为等宽的 Markdown 源码,标题、强调标记、链接、代码围栏和公式使用主题中的语法色;长行按编辑区域宽度换行。再次切换回到所见即所得。切换不改动文档内容,撤销历史从切换后重新开始。源码模式下格式栏与格式菜单不可用。
  • 查找替换:Mod+F 打开查找栏,定位下一处匹配;“替换”和“全部替换”修改可编辑文字。所见即所得模式下,公式、图片与未支持的原文块保持完整,不参与文字替换。一次全部替换可用一次撤销恢复。
  • 阅读模式:“⋯”菜单的“进入阅读模式”锁定正文,仍可选择、复制、查找、滚动和点击链接。退出后恢复编辑;源码模式也遵循只读状态。阅读模式下单击链接打开,编辑模式下使用 Mod+单击。可点击按钮、任务框、脚注跳转和可编辑源码卡片在悬停时显示小手。
  • 图片:支持 PNG、JPEG、GIF、WebP 和 SVG。已保存文档的本地图片经该文档的授权读取,插入的图片复制到 ./assets/<文档名>/;相对路径找不到文件时按文件名在文档目录和所属工作区里查找。http / https 图片有大小和并发限制。编辑器不接受任意本地路径。
  • 保留原文:未编辑的块按原文字节保存。超出支持范围的 HTML、Mermaid 图种和数学命令显示为标明类型的占位卡片,双击可编辑源码。脚本、样式和任意 CSS 不在原生 HTML 支持范围内。

导出

“⋯”菜单的“导出”提供三种格式:

  • HTML:单个文件,自带版式,本地图片内嵌,可以离线打开。
  • PDF:A4 页面,版式与 HTML 一致。导出期间借助系统自带的网页引擎排版分页。
  • Markdown 副本:把当前内容另存一份,不改变标签对应的文件。

HTML 与 PDF 的页面、正文和图表配色跟随导出时的应用主题,与应用内的显示使用同一套色值;选择“跟随系统”时,使用当前实际显示的浅色或深色主题。

导出的 HTML 与 PDF 内嵌公式和已支持图表的 SVG 排版结果,无需联网加载渲染脚本。数学符号使用内嵌 STIX 字体的轮廓;公式中的中文与图表标签使用查看设备的字体回退。无法解析的公式或图表以原文导出。

自动保存与恢复

  • 开启自动保存后,已有路径的文档在停止修改两秒后写入磁盘。未命名文档需先另存为。
  • 意外退出后,未保存内容从本机配置目录恢复为标签。单份草稿不超过 1 MiB,总量不超过 5 MiB。

设置

Mod+, 或“⋯”菜单打开设置,调整即时生效并保存在本机:

  • 编辑器:正文字体(Newsreader、系统衬线、系统无衬线、等宽)、字号(12–28,默认 16,界面文字随之等比缩放)、行高(1.3–2.2)、阅读宽度(窄 / 舒适 / 宽)、自动保存。
  • 外观:浅色、深色或跟随系统。两张预览卡片展示对应主题,当前生效的主题以强调色外圈标出。
  • 快捷键:查看当前绑定,并在“自定义快捷键”里为各个动作录制新的组合键;与系统或基础编辑冲突、或与其他动作重复的组合会被拒绝。
  • 通用:检查与安装软件更新;专注模式淡化光标所在块之外的内容并收起侧栏,打字机模式让光标所在行保持在窗口中部;清理恢复草稿与近期文件记录。

快捷键

Mod 在 macOS 上为 ⌘,在 Windows 上为 Ctrl。表中前七行可以在设置里重新绑定。

动作 默认快捷键
保存 / 另存为 Mod+S / Mod+Shift+S
打开文件 / 新建文档 Mod+O / Mod+N
关闭文档 Mod+W
查找 Mod+F
加粗 / 斜体 / 插入链接 Mod+B / Mod+I / Mod+K
切换源码模式 Mod+Shift+R
设置 Mod+,
撤销 / 重做 Mod+Z / Mod+Shift+Z
在当前块后继续写正文 Mod+Enter
列表缩进 / 提升,表格下一格 / 上一格 Tab / Shift+Tab

已知限制

  • 公式支持常用的 TeX 数学子集。自定义宏、宏包、字号命令及部分高级结构(如 \genfrac、\sideset、CD 环境)保留原文;array 不支持 @{} 和 p{} 列格式。颜色模型支持颜色名、十六进制与 [HTML]。\hdashline 使用实线,\tag 需手动指定编号,中文 \textbf 使用普通字重。
  • Mermaid 支持上述七类图的常用子集。思维导图、旅程图等其他图种保留原文。时序图不支持 box、rect 颜色及创建销毁标记;类图不支持泛型与 namespace 专门布局;状态图不支持分叉、汇合、选择和并发区;甘特图不支持排除日期与 tickInterval。复杂图的布局仍可能较拥挤,饼图超过八个类别后使用中性色。
  • 公式或图表使用超出支持范围的语法时,编辑器保留原文,导出使用原文展示。含中文的 SVG 使用查看设备的字体,字形可能因平台略有差异。
  • SVG 图片支持路径、基本形状及常用 text、定位 tspan 文字,支持字号、字重、字体回退、颜色、对齐、简单 CSS 选择器和平移、等比缩放;中文字体随操作系统回退,跨平台字形可能不同。draw.io 内嵌的文字位图替身也可显示。复杂文字排版、旋转或倾斜文字、滤镜和图案不在支持范围内;文字叠加在矢量形状上。SVG 按浅色配色绘制,深色主题下垫一层纸色。
  • 源码模式为 Markdown 着色,不解析代码围栏内部语言的完整语法。阅读模式禁止修改正文;所见即所得的查找替换针对可编辑文字,不拆分公式、脚注引用或图片。
  • 多个程序同时写入同一文件时仍可能互相覆盖;保存前会校验磁盘内容摘要。
  • Windows 上的安装、文件关联、输入法、真实拖放、PDF 导出及升级重启需人工验收;ARM64 原生运行需在对应设备上验收。

开发

技术栈

技术 职责
Go、internal/richtext Markdown 文档模型:goldmark 识别结构,未编辑的块按原文字节写回
Go、internal/nativeeditor 用 MyGo 的 ui.Shape 与 Painter.Glyphs 自绘所见即所得编辑器
Go、internal/mathlayout TeX 数学子集的解析与排版,使用内嵌的 STIX Two Math 字体
Go、internal/diagram Mermaid 图表的解析、布局、原生绘制与 SVG 输出
Go、internal/desktop 原生窗口、多标签、保存、恢复、工作区、设置、导出、图片授权与更新
MyGo 0.4.1 原生窗口、GPU 绘制、系统对话框、打包与签名更新
goldmark 1.8.6 CommonMark / GFM 结构识别

整个项目只有 Go 代码。应用没有远程服务端,桌面窗口不使用 WebView、不加载网页;只有导出 PDF 时在不可见窗口里临时借用系统网页引擎分页。运行已打包的应用无需安装任何开发工具。

环境与命令

需要 Go 1.27.1+ 和 make。MyGo 命令行由 go.mod 的 tool 指令固定版本,通过 go tool mygo 调用,不需要 Node.js。重新生成官网截图另需 cwebp。

命令 用途
make dev 启动桌面开发应用;Go 代码变化后重新编译
make check 全部 Go 测试,含带 desktoptest 标签的桌面装配测试
make check-release 在 check 之上增加竞态检测、go vet 和验证构建标签
make verify 执行 go run -tags verification .,在真实 GPU 原生窗口中验收
make shots 用示例文档在真实原生窗口中截取浅色、深色官网应用图
make site 在 http://127.0.0.1:4173 预览官网
make build-local 构建当前系统与架构的应用,产物位于 build/<平台>-<架构>/
make build ARGS="-platform …" 发布构建,例如 darwin/arm64,darwin/amd64,windows/amd64,windows/arm64

应用名称、标识、文件关联与更新源在 mygo.json 中配置;其中的 version 只用于本机构建,正式版本号取自发布标签。

安装包沿用 MyGo 的架构命名:Leafmark <版本> <架构>.dmg 与 Leafmark Setup <版本> <架构>.exe。自动更新使用独立的 update-<平台>-<架构>.json 清单、leafmark-<版本>-<平台>-<架构>.tar.gz 完整更新包,以及从最近 3 个已发布版本到新版本的 .delta 增量包。已安装的版本有对应增量包时只下载变化部分,校验每个文件的大小与 SHA-256 后组装出新版本;增量包缺失或校验失败时改为下载完整更新包。所有更新文件都经 Ed25519 签名校验。

项目结构

leafmark/
├── main.go                 调用 desktop.Run
├── mygo.json               应用名称、文件关联与更新配置
├── Makefile                开发、测试、验收与构建入口
├── internal/
│   ├── desktop/            原生窗口装配:界面、设置、快捷键、导出、保存与恢复
│   ├── nativeeditor/       GPU 自绘编辑器
│   ├── richtext/           可编辑的块文档模型
│   ├── mathlayout/         公式排版
│   ├── diagram/            Mermaid 图表解析、布局、绘制与 SVG
│   ├── documents/          文档、标签、保存基线、编码与外部修改检测
│   ├── workspace/          工作区目录树、路径授权与近期文件
│   └── assets/             图片验证、读取与文档附件导入
├── tests/fixtures/samples/ 统一的示例文档
├── scripts/                构建与截图脚本,`tools/` 是构建与官网预览用的 Go 小工具
├── site/                   官网静态页面
├── resources/              应用图标与许可证文件
├── verification/           原生验证输入与运行输出
└── .github/
    └── workflows/          版本发布、Windows 验证与官网发布流程

职责边界:

  • 桌面入口是 desktop.Run。窗口内容由 nativeApp.View 绘制:native_visual.go 是书写界面,native_settings.go 是设置页,native_features.go 是源码模式、工作区操作与导出,native_source.go 扫描源码着色区间,native_reading.go 处理阅读模式的命令约束与替换入口,native_lifecycle.go 负责关闭确认与快捷键分发,native_recovery.go 把设置与未保存草稿写入本机配置目录。
  • 编辑状态在 nativeeditor,文档结构在 richtext。容器上下文描述列表项、嵌套引用、提示块与脚注定义,行内图片和公式保持原子坐标;源码模式使用单块纯文本模型和同一套字形、输入法、选区与撤销逻辑。保存基线、BOM、换行和磁盘摘要以 documents 为准。
  • mathlayout 与 diagram 只负责把源码排成可绘制的结果,不持有文档状态;公式和流程图在文档模型里仍是原文。
  • documents、workspace、assets 不依赖 MyGo。文件访问必须经过授权:相对图片以已打开文档的 ID 为入口,按文件名查找只在文档目录和已授权的工作区内进行,工作区路径由工作区包校验,不接受任意绝对路径。访达打开和拖入窗口的文档由后端从系统事件取得路径并排队。

实现要点

  • 保存:写入同目录临时文件后原子替换,保留原文件的 BOM、CRLF 和权限;保存前校验磁盘内容摘要。
  • 原文:richtext 用 goldmark 识别结构。未编辑的块在写回时逐字节保留;编辑只重写变脏的块。无法识别的块记为原文占位。
  • 绘制:nativeeditor 按块排版并用字形绘制,画面不出现 Markdown 标记。输入法组合文本在光标处绘制,确认后写入文档。
  • 公式:mathlayout 读取字体的 OpenType MATH 表取得间距常数与可伸缩字形,按 TeX 的原子间距规则排版。行内公式在文档模型里是一段带标记的文字,排版时作为一个整体占位;光标进入后改按源码显示。
  • 图表:流程图采用分层布局:去环、最长路径分层、长边拆成虚拟节点、重心法减少交叉、层内对齐,再把连线画成带圆角的折线。时序图按参与者和消息排列,甘特图按时间比例计算任务条,饼图按数据比例计算扇区;类图、状态图和 ER 图复用关系布局并绘制各自的节点与连线。图宽于正文栏时整体等比缩小,原生画面和 SVG 共用绘制指令。
  • 限额:工作区最多扫描 10,000 个条目和 64 层目录;恢复草稿单份 1 MiB、总量 5 MiB;近期文件保留 30 条;流程图最多 2,000 个节点和 6,000 条连线。

测试与验收

  • Go 测试覆盖文档模型、编辑器排版与输入、公式与流程图、文档状态、编码、文件操作、路径授权、图片处理、设置和快捷键。internal/desktop 的界面装配测试带 desktoptest 构建标签,用桩编辑器替换排版实现。
  • make verify 以 verification 构建标签启动真实原生窗口,在 GPU 绘制的界面上断言并截图。数据位于 .verification-data/ 和 verification/,不得修改用户笔记。
  • 验收须读取 verification/native-results.json 确认 passed,并核对其中的 platform 与 arch,再查看 verification/native-window.png、native-format-bar.png、native-source-mode.png 和 native-settings-*.png。不能由 macOS 结果推断 Windows 已验收,也不能由 Windows amd64 结果推断 ARM64 已验收。
  • ui.Tester 在进程内驱动界面,用于 Go 测试,不是原生窗口验收。
  • .github/workflows/windows.yml 在 Windows runner 上运行全部检查与原生窗口验收,并核对 platform 为 Windows Native UI。
  • 以下内容需人工验收:输入法组合输入、系统文件对话框和消息框、右键菜单、安装与文件关联、真实拖放,以及升级后重启。

许可证

Leafmark 使用 MIT 许可证。可以自由使用、修改、分发和商用,但必须保留版权声明和许可声明;软件按“原样”提供,不提供担保。

MyGo 与 goldmark 也是 MIT,go-text/typesetting 为 Unlicense 或 BSD-3-Clause,内嵌字体为 SIL Open Font License 1.1。再分发安装包时须同时提供 第三方声明,并保留各组件自己的版权与许可证。

About

Leafmark · 叶笺:简洁的 Markdown 桌面编辑器

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages