Markpad:我给 Markdown 装了一个本地驾驶舱

Posted on 六 27 6月 2026 in Tech

Abstract Markpad:我给 Markdown 装了一个本地驾驶舱
Authors Walter Fan
Category Tech
Status v0.1
Updated 2026-06-27
License CC-BY-NC-ND 4.0

Markdown 很好,但别假装它没有痛点

我写东西越来越离不开 Markdown。博客、README、设计笔记、周报草稿、AI prompt、会议纪要,基本都能塞进去。它像一把趁手的小刀,轻、快、没有太多仪式感。

问题是,小刀再趁手,也不等于拿它切西瓜就舒服。

Markdown 最大的优点是“好写”,可它并不天然“好看”。你在终端里 vim README.md 写得很顺,回头想认真读一遍,眼睛就开始抗议:标题层级不够直观,表格挤成一坨,Mermaid 图还躺在代码块里装睡。更麻烦的是,现在很多内容都要在中文和英文之间来回切换,复制到网页翻译,再复制回来,格式一不小心就散架。

所以我做了一个小工具:markpad

一句话:Markpad 是一个本地 Markdown reader / editor / translator,把“文件索引 + 左右分栏编辑预览 + 图表渲染 + 实时分享 + LLM 翻译”放进浏览器里,但文件仍然留在本地。

它不是要取代 VS Code、Typora 或 Obsidian。我的目标更朴素:打开一个有很多 Markdown 的目录,能舒服地读,直观地改,必要时一键翻译,不要在工具之间来回搬砖。


1. 我到底被什么问题折磨了

这个痛点不是“没有 Markdown 编辑器”。编辑器太多了,少说也够排一支篮球队。

真正烦人的是几个小问题叠在一起:

场景 表面问题 实际消耗
翻 README 或设计文档 源码和预览来回切 注意力被打断
看一堆 Markdown 笔记 不知道文件在哪、哪个更新过 搜索和打开成本高
改表格、列表、标题 写完才发现渲染效果不好 来回试错
文档里有 Mermaid / PlantUML 代码块不直观 图和文字脱节
中文英文互译 复制到翻译工具再粘回来 格式、链接、代码块容易坏
临时给同事看一个 Markdown 发文件、截图或贴聊天 对方看不到最新版本

单独看,每个问题都不大。合在一起,就像鞋里进了一颗小石子。你说它不严重吧,它又能让你一路走得别扭。

我以前的做法也很典型:写的时候用编辑器,看的时候用预览插件,翻译的时候再开一个 LLM 页面。最后一天结束,浏览器 tab 像韭菜一样长了一茬又一茬。

Markpad 想解决的,就是这类不致命、但天天烦你的摩擦。它们不像线上事故那样惊心动魄,可一天硌你十次,也够人心烦。


2. Markpad 是什么

Markpad 本质上很朴素:一个 Python 3.11+ 的本地 CLI 工具。进入一个 Markdown 目录后,运行:

markpad

它会启动一个本地 Web 服务,默认监听在:

127.0.0.1:9526

如果 9526 被占用,它会自动尝试 95279528,直到找到可用端口。浏览器打开后,大概就是三块区域:

  • 左边是 Markdown 文件索引,递归扫描当前目录和子目录。
  • 中间是 Markdown 源码编辑区。
  • 右边是 HTML 预览区。

也可以显式指定目录:

markpad /path/to/markdown
markpad --root /path/to/markdown
markpad serve /path/to/markdown

如果你只想打开某个文件,也可以直接传文件路径:

markpad docs/guide.md
markpad docs/guide.md --open

--open 不是必需参数,它只是让 Markpad 启动后自动打开默认浏览器。不加也可以,命令行会打印访问地址,你自己复制到浏览器即可。

绝对路径也支持:

markpad /Users/me/notes/today.md --open

它会把这个文件放到左侧源码、右侧预览的同一个工作台里。对我来说,这一点很重要:我不是每次都想启动一个“大知识库”,很多时候只是想把某个 Markdown 文件好好看一眼、改两段、翻译一节。


3. 为什么不是直接用现成工具

这类问题当然不是没人管。现成工具能解决一部分,而且不少工具做得很好。

VS Code 很强,插件生态也丰富;Obsidian 很适合个人知识库;Typora 写作体验也很好。问题是,我当时想要的是一个更“窄”的工具:

  • 不要求建立 vault。
  • 不要求打开一个完整 IDE。
  • 不要求把文件导入某个系统。
  • 不要求把文档上传到外部服务。
  • 最好一条命令在任意目录里启动。

这就是 Markpad 的取舍:它不是重型编辑器,而是本地 Markdown 目录的临时驾驶舱。 需要的时候开一下,用完就关,不跟你抢项目主角的位置。

这有点像修车。你不一定每次都要把车开进 4S 店。有时候你只是想打开引擎盖,看一下机油尺,顺手拧紧一个螺丝。Markpad 做的就是这个“打开引擎盖”的动作。


4. 几个我最常用的功能

4.1 文件索引:先把 Markdown 找出来

Markpad 会递归扫描 Markdown 文件,支持 .md.markdown.mdown。像 .git.venvnode_modulesdist__pycache__ 这些明显不该打扰你的目录,它会绕过去。

这听起来很小,但很实用。很多项目里的 Markdown 不只在根目录:

README.md
docs/design.md
docs/api/auth.md
notes/meeting/2026-06-27.md

打开后左侧有一个文件树,搜索框可以过滤文件。大目录里找文档,终于不用在终端和编辑器之间反复横跳。

4.2 左右分栏:源码和效果不要分居

Markdown 最大的问题之一,是“源码很清爽,效果要脑补”。

Markpad 的默认工作方式是左边写、右边看。改一段,预览就跟着变。你可以隐藏文件树、隐藏源码区、隐藏预览区,也可以调整分栏宽度。

我常用的节奏是:

  • 写作时:左边源码宽一点,右边预览检查结构。
  • 审稿时:隐藏源码,只看预览,避免被 Markdown 符号干扰。
  • 改格式时:左右对半,重点看表格、列表、代码块。

这不是花哨功能,而是让大脑少切几次上下文。人脑不是线程池,切多了也会抖,尤其是年纪上来以后。

4.3 阅读主题:让眼睛少加班

Markpad 现在有三个阅读主题:

主题 适合场景
Clear 普通白天阅读,清爽直接
Paper 长文阅读,偏纸张质感
Dark 晚上或低光环境

设置会保存在浏览器的 localStorage 里。这个设计没有什么技术含量,但很符合老程序员的养生需求:代码可以硬,眼睛不能硬扛。

4.4 图表渲染:让图真的像图

很多技术文档里都有 Mermaid 或 PlantUML。直接看源码当然也能看懂,但那种感觉像读菜谱想象红烧肉,理论上没问题,心理上差点意思。

Markpad 支持 Mermaid fenced block 在浏览器里渲染:

```mermaid
sequenceDiagram
  participant User
  participant Markpad
  User->>Markpad: Open markdown folder
  Markpad-->>User: File index + live preview
```

PlantUML 也支持,不过需要本地有 plantuml 命令

这也是一个有意的边界:能在本地解决的,就在本地解决。为了渲染一张图就把文档送到外部服务,我心里总有点不踏实。

4.5 LLM 翻译和改写:别把 Markdown 格式翻烂

这是最贴近我痛点的部分。

Markpad 的工具栏里有 Translate。如果选中了文本,它就翻译选中部分;如果没有选中,就翻译整个编辑器内容。翻译结果会流式写回编辑器,最后刷新预览。

它使用 OpenAI-compatible 的 Chat Completions API,配置来自环境变量或当前目录下的 .env

LLM_BASE_URL=https://api.example.com/v1
LLM_MODEL=your-model
LLM_API_KEY=your-api-key

系统提示里明确要求保留 Markdown 结构、代码块、front matter、链接、表格和图表代码。也就是说,它不是把文档当普通文本翻译,而是尽量把 Markdown 当 Markdown 处理。

旁边还有一个 LLM edit 输入框,可以对选中内容或全文做改写,比如:

把这一段翻译成英文,语气自然一点,保留代码块和链接

这对我写中英文文档很有用。以前的流程是:复制、打开 LLM、粘贴、提示“保留 Markdown”、复制回来、检查格式。听起来只多几步,实际很容易把写作节奏打断。现在至少在一个界面里完成,少搬几次砖。

4.6 临时分享:让同事看到正在看的那一版

还有一个很顺手的场景:临时把一个 Markdown 文件分享给同事看

比如你刚写完一份设计草稿,想让同事快速看一下结构、图表和段落。发 Markdown 文件,对方未必有合适预览;发截图,改一处就要重截;复制一大段到聊天窗口里,格式经常当场去世。

Markpad 本身是一个 Web 服务,所以在可信内网里可以临时绑定到可访问地址:

markpad serve docs/design.md --host 0.0.0.0 --port 9526

然后把链接发给同事:

http://<your-ip>:9526/docs/design.md

你本地保存后,对方刷新浏览器就能看到更新后的渲染效果。对于设计讨论、README 预览、会议纪要同步,这比“我再发你一个最新版”省心得多。

不过这里要划重点:这适合临时、小范围、可信网络下使用。Markpad 目前不是带登录、权限、审计的在线文档平台。你如果用 --host 0.0.0.0 暴露服务,就要默认对方能访问这个 Web UI,也可能触达编辑、保存、删除、关闭服务这些操作。分享前先确认网络范围和文档敏感度,别把临时分享玩成临时事故。


5. 工程上我比较在意的几个边界

小工具也有边界。边界不清楚,小工具很快就会长成一个谁也不敢碰的平台。很多系统不是被需求打败的,是被“顺手再加一个”熬死的。

5.1 本地优先

Markpad 默认绑定 127.0.0.1。也就是说,它不是默认暴露到局域网的服务。它读写的是你指定目录里的 Markdown 文件,所以这个默认值很重要。

当然,CLI 支持 --host,这让临时分享 Markdown 给同事很方便。但我的建议是:除非你清楚自己在做什么,否则保持本地访问即可。真要分享,也优先在可信内网里短时间打开,用完就关。

5.2 路径要管住

服务端对相对路径做了限制,避免通过 ../ 逃出内容根目录。普通文件读写只允许在选定 root 内发生。

同时,它也支持打开绝对路径的单个 Markdown 文件。这是为了方便处理“临时文件”场景,但也做了扩展名检查,只接受 Markdown 文件。

一句话:工具要方便,但不能方便到把家门钥匙挂在门口。

5.3 渲染要消毒

Markdown 转 HTML 后会经过 bleach 清洗,只放行必要的标签和属性。Markdown 预览工具很容易让人放松警惕,尤其是当你打开不完全信任的文档时。

Markpad 不是浏览器安全沙箱的替代品,但至少不应该把“预览 Markdown”变成“随便执行 HTML”。

5.4 密钥不要进仓库

LLM 翻译需要 LLM_API_KEY。如果你把配置写进 .env,请确保它不要进 Git。

我建议在项目根目录加好 .gitignore,或者只在 shell 里临时 export:

export LLM_BASE_URL=https://api.example.com/v1
export LLM_MODEL=your-model
export LLM_API_KEY=your-api-key
markpad

省事不能省到把 token 贴到墙上。墙可能不会说话,Git 历史会。


6. 安装和自检

项目里提供了一个安装脚本:

./install.sh

它会检查 Python 3.11+ 和 Poetry,构建包,安装到:

~/.local/share/markpad/venv

并把 markpad 命令链接到:

~/.local/bin

安装后可以检查:

markpad --help
markpad doctor
markpad doctor --format json

卸载也走同一个脚本:

./install.sh uninstall

开发时常用命令也很直接:

poetry install
poetry run markpad --help
poetry run markpad
poetry run ruff check .
poetry run ruff format .
poetry run pytest

技术栈没搞复杂:FastAPI + Uvicorn 做本地服务,markdown-it-py 做 Markdown 渲染,bleach 做 HTML 清洗,watchfiles 和 WebSocket 处理文件变化,前端就是普通 HTML/CSS/JavaScript。

朴素有朴素的好处。工具越小,越容易理解,也越容易修。


7. 它不是什么

我得把丑话说在前面。

Markpad 现在不是完整的知识管理系统,不负责双链、标签图谱、同步、多端协作,也不负责发布博客。它也不是多人协同编辑器,不是复杂 WYSIWYG 编辑器,更不打算把 Markdown 变成 Word。

至少目前,我还不想把它做成一个 Markdown 在线实时多人编辑工具。那条路当然有价值,但一开这个口,用户登录、权限控制、冲突合并、历史版本、审计日志这些“平台级家伙事”都会排队进门。到那时,它就不是小工具了,是另一份工作。

Markdown 编辑工具栏也还没有加。不是不能做,而是我自己现在更习惯直接写源码,点按钮反而慢半拍。不过,如果你确实需要这些能力,比如多人协同、按钮式插入标题/表格/链接、评论批注、只读分享模式,尽管告诉我。我可以考虑把真正高频的需求加进去,前提是它不把这个小工具变成一艘航空母舰。

它更像一个“本地 Markdown 工作台”:

  • 读:把 Markdown 渲染成舒服的 HTML。
  • 找:把目录里的 Markdown 建索引。
  • 改:左右分栏编辑和保存。
  • 看图:渲染 Mermaid / PlantUML。
  • 翻译:通过 LLM 保留结构地翻译或改写。
  • 分享:在可信网络里临时把当前 Markdown 预览给同事看。

如果以后继续扩展,我会优先考虑这些方向:

  • 更好的全文搜索。
  • 更细的中英文翻译选项,比如目标语言、术语表、风格预设。
  • 更稳的图片和附件处理。
  • 更完善的快捷键。
  • 更好的移动端阅读体验。

但我会尽量克制。工具最怕“初心是瑞士军刀,结局是军火库”。


8. 一个典型工作流

假设我有一个博客目录或项目文档目录:

cd ~/workspace/walter/wfblog
markpad content/journal

然后我会:

  1. 在左侧搜索最近的草稿。
  2. 打开后先只看右侧预览,检查结构是否顺。
  3. 需要改句子时打开左侧编辑区,边改边看。
  4. 遇到英文段落,选中后点 Translate,翻成中文草稿。
  5. 对翻译结果再用 LLM edit 提示“更像技术博客,不要翻译腔”。
  6. 保存文件,回到原来的 Git 流程里提交。

如果要给同事实时看某个文件,我会单独启动一个临时服务:

markpad serve docs/design.md --host 0.0.0.0 --port 9526

讨论结束后,直接关掉服务。它的定位就是“临时给人看一眼”,不是长期挂着当文档站。

这个流程没有什么惊天动地的地方。它的价值就在于:少开几个窗口,少复制几次,少丢几次格式。工具顺不顺手,往往就藏在这些小地方。

很多效率工具并不是让你一小时省下五十分钟,而是每天少烦十次。十次不烦,心情就不一样。


总结:给 Markdown 一张舒服的工作台

Markdown 的美德是简单,但简单不等于只能忍受粗糙。

我做 Markpad,是因为自己每天都在写 Markdown,也每天都被这些小摩擦硌一下:看起来不够直观,图表不够直观,中英文互译容易把格式弄乱,临时发给同事看又总差那么一口气。与其继续抱怨,不如写个小工具,把最常用的动作放到一个本地 Web 工作台里。

一句话:Markpad 不是 Markdown 世界的新大陆,它只是我给自己修的一条小路。路不宽,但每天走,省脚。

使用清单

  • [ ] 进入 Markdown 目录,运行 markpadmarkpad --root /path/to/docs
  • [ ] 用左侧文件树和搜索框快速定位文档。
  • [ ] 用左右分栏检查源码和预览是否一致。
  • [ ] 文档里有 Mermaid / PlantUML 时确认图能正常渲染。
  • [ ] 需要翻译时配置 LLM_BASE_URLLLM_MODELLLM_API_KEY
  • [ ] 需要临时分享时,用 markpad serve file.md --host 0.0.0.0 --port 9526,只在可信网络中短时间打开。
  • [ ] 不要把 .env 和 API key 提交进 Git。
  • [ ] 对外打开 --host 前,先确认访问范围和文件读写风险。

适合谁

如果你符合下面几条,Markpad 可能对你有用:

  • 你有一堆散落在项目里的 Markdown 文档。
  • 你经常在“源码”和“预览”之间切换。
  • 你写技术文档时会用 Mermaid 或 PlantUML。
  • 你经常需要中英文互译,还想保住 Markdown 格式。
  • 你经常需要把正在写的 Markdown 草稿临时分享给同事看。
  • 你偏好本地文件、本地服务,不想为了看文档先上传到某个平台。

如果你只是偶尔写一篇 README,现成编辑器已经够好;如果你需要完整知识管理,Obsidian 之类的工具更合适。工具选型和写代码一样,最怕拿高射炮打蚊子,也怕拿苍蝇拍打飞机。

愿每个写文档的人,都少一点格式搬运,多一点顺手成章。


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。