博客里既有自己写的文章,也有整理进来的长篇资料。我希望它同时成为一个可以反复阅读、留下痕迹的地方:在电脑上读到一半,换到手机能接着读;遇到值得留意的段落,可以划线、写几句笔记,之后再找回来;不知道读什么时,随机打开一篇从未读过的文章。

这些功能只供我个人使用。文章继续公开,笔记、收藏和阅读记录由自己的账户保存。本文记录需求、现有架构和第一轮选型;功能尚未实现,下面的技术设计是后续实现的候选方案。

我希望怎样阅读

一个完整的使用场景是:在电脑打开文章,读到某段后划线,写下自己的理解,再收藏这段文字。晚上用手机打开同一篇文章,可以回到对应段落,也能看到先前的高亮和笔记。读完后标为已读,下一次“随机未读”便不再抽到它。

功能期望行为
划线与笔记选中文字即可高亮,并能添加、修改、删除笔记
阅读位置再次打开文章时,可以继续上次阅读的位置
阅读状态区分从未开始、阅读中、已读,允许手动调整
跨设备同步电脑和手机使用同一份位置、状态、笔记与收藏
随机未读从未开始阅读的文章中随机抽取,最好能限定专栏
整篇收藏保存值得回看的文章,集中检索
段落收藏保存某段原文、出处和自己的备注,支持跳回原文
私人使用普通访客正常阅读,不能读取我的私人记录

这里有两个容易混淆的地方。

第一,“知道读了百分之多少”和“回到上次读的那句话”是两种能力。电脑与手机的行宽、字号、图片高度不同,相同的滚动像素位置没有可比性。

第二,“尚未读完”包含阅读中的文章,而“从未读过”不包含它们。我倾向于让随机入口默认选择从未开始的文章,把读了一半的内容放在“继续阅读”中。

桌面端希望支持快捷键和可搜索的入口,例如呼出阅读面板、输入几个字筛选收藏、回车打开。手机则需要适配长按选字和触屏操作,不依赖只能在桌面使用的浏览器扩展。

博客现在怎样工作

无常笔记使用 Hugo 和 PaperMod。普通文章的权威来源是 Org,经 Emacs 的 ox-hugo 导出 Markdown,再由 Hugo 构建静态页面。

content-org/:Org 原稿与图片
    ↓ Emacs / ox-hugo
content/:生成的 Markdown
    ↓ Hugo / PaperMod
静态 HTML
    ↓ 服务器合成发布与阅读布局增强
Caddy 提供 HTTPS 页面

但线上内容并不完全等于一次本地 Hugo 构建。ABAP Cheat Sheets 由服务器定时生成,日报和部分专栏采用合并发布。因此新功能必须覆盖最终发布的文章,而不能只考虑本地生成的普通博文。

当前相关的维护入口如下,路径均相对于博客仓库:

路径职责
hugo.yamlHugo、PaperMod、导航与输出配置
content-org/posts/按年存放的 Org 原稿
scripts/blog.ps1导出、检查、构建与发布入口
deploy/reader.py在静态页面上统一增加阅读布局
deploy/reader.css阅读布局样式
deploy/managed-publish.py合并独立内容、取得发布锁并原子切换版本

现有阅读布局已经包含目录、同专栏侧栏和上下篇导航。搜索使用 index.json 与 Fuse.js;这个索引可以作为文章清单的基础,但还需要筛掉目录页,并核对服务器生成内容是否完整收录。

目前没有个人登录、笔记存储或阅读状态同步后端。主题保存的明暗偏好也不能承担这些职责。标题有锚点,普通段落则没有现成的稳定 ID。

现成开源工具能做到哪一步

选型的第一个分界是:标注发生在原博客页面,还是发生在工具抓取的文章副本中。后者可以提供完整阅读器,但也需要重新验证中英对照、代码块、图片和段落结构。

以下依据 2026 年 10 月 30 日查阅的官方文档与项目说明整理,尚未逐个部署试用。

Hypothesis:最贴近原网页划线

Hypothesis 支持把客户端嵌入网站,读者可以直接在页面上选择文字、添加高亮和注释。Only Me 模式用于只有本人登录后可见的私人注释。

它适合先验证“在现有文章上划线”的操作感受。不过,博客的精确阅读位置、整篇收藏、已读状态和随机未读仍需要另外实现。使用官方服务与自托管也是两种部署选择,不能把嵌入脚本等同于完成自托管;开源服务端位于 hypothesis/h。

如果采用它,需要认真处理私人注释的默认可见范围,以及手机浏览器上的登录、选字和侧栏体验。

wallabag:阅读状态和收藏比较接近需求

wallabag 的官方界面文档列出了未读、收藏、归档、注释筛选和随机文章入口。它是一条可优先试用的独立阅读器路线。

但它主要面向保存后的文章。当前文档确认有随机入口和未读筛选,尚不足以证明随机入口在当前版本中始终只选未读文章;这一点要实际测试。精确阅读位置是否能在所选桌面与手机客户端之间恢复,也需要单独验收。

Linkwarden:收藏与保存文章,附带阅读器标注

Linkwarden 的 Readable 格式支持多色高亮和附在高亮上的笔记。文档明确说明这些注释对本人私有,即使文章位于共享集合中,其他成员也看不到。

它的标注范围是 Readable 阅读器中的内容,因此要接受保存并解析后的文章视图。对我的需求而言,收藏和摘录很有吸引力,但原网页定位、精确进度同步和随机未读还需要进一步核实或补充。

Omnivore:功能接近,但需要按自托管重新评估

Omnivore 官方仓库列出高亮、笔记、键盘操作、长文章位置保存以及不同客户端。仓库同时说明,原云服务已于 2024 年 11 月停止,目前采用自托管路线。

因此不能沿用旧教程中注册云账户即可使用的流程。若选择它,需要先验证部署成本、客户端连接自己的实例以及实际同步行为。

几种方案的取舍

路线优点需要接受的代价
原网页嵌入 Hypothesis,再补充阅读状态能较快试验现成标注能力笔记与进度可能分属两套数据和身份系统
使用 wallabag、Linkwarden 等独立工具复用已有收藏与阅读界面阅读对象主要变成抓取后的副本,需要维护导入
给博客开发统一私人阅读层原文布局、状态和交互可以统一需要实现前端、同步规则和定位机制

倾向的方案:静态文章加私人阅读层

我目前更倾向于保留现有博客,在文章上加一个只在个人使用时启用的阅读界面。静态页面继续负责展示正文,独立的服务保存个人数据。

电脑 / 手机浏览器
    ├── 读取博客静态文章
    └── 私人阅读界面
           ├── 划线、笔记、收藏
           ├── 继续阅读、标记已读、随机未读
           └── 登录后访问同步 API
                    ↓
              独立的个人数据库

后端可以优先评估 PocketBase。它提供 SQLite、认证和数据 API,能够减少基础设施工作,但并不是现成的阅读插件:划线界面、阅读位置恢复、同步冲突处理仍然需要开发。部署前也要核对所选版本的升级与迁移要求。

私人数据应该保存在静态发布目录之外。博客重新构建、发布新版本或回滚时,文章内容会变化,个人笔记不应随之被覆盖。普通账户需要明确的数据访问规则,不能把管理凭据放进网页脚本。

前端接入点优先考虑 deploy/reader.py 。它已处于本地构建和服务器合成发布的公共路径,可以为最终文章注入同一套资源。这样更容易覆盖服务器生成的专栏,也能避免直接修改 PaperMod 子模块。具体实现仍需验证页面识别、重复注入防护和新旧页面兼容。

真正需要设计的细节

用文字和上下文定位高亮

只保存 DOM 路径或某个段落的序号很脆弱:文章前面增加一段,后面的编号就可能整体变化。

候选做法是一起保存选中文字、前后文、文章内的位置,以及可用的标题或段落锚点。重新打开页面时先用精确位置匹配,再用引用和上下文寻找对应内容。重复句子需要消歧,不能只匹配第一处相同文字。

文章改动后确实找不到原文时,应保留摘录和笔记,显示“原文位置待重新关联”,允许手动重新定位。错误地把笔记挂到另一段,比暂时没有位置更难发现。

阅读进度保存“最后位置”与“最远位置”

继续阅读应该优先恢复最后一次主动阅读的位置。最远读到的位置可以辅助展示进度,但不能简单取所有设备的最大百分比,否则回头复习时会被强行送回后面。

候选记录包括段落或文本锚点、段内偏移、百分比、设备标识和版本信息。图片加载、字体变化和小屏重排后,还需要再次校准位置。读到底部也不必立即等同于已读,第一版可以使用显式“标记已读”。

收藏整篇与收藏段落分开保存

文章收藏保存文章标识、标题和收藏时间。段落收藏还需要原文引用、定位信息、备注,以及与高亮记录的关联。

划过线不一定代表值得长期收藏。两种操作可以共享定位结构,但应允许独立取消收藏或删除高亮,避免一个动作意外删除另一份信息。

同步不能靠覆盖整个 JSON 文件

多设备会同时修改数据,也可能离线后再联网。每条笔记和高亮需要独立 ID,服务端需要版本检查;删除操作也需要留下可同步的删除标记,避免旧设备把它重新上传回来。

第一版应至少保证:旧设备不能用一份过期快照覆盖所有新数据;有冲突的笔记保留可恢复版本;未同步操作有明确提示。浏览器本地缓存负责临时可用,服务器数据和独立备份负责长期保存。

随机未读使用最终发布的文章清单

候选清单应来自服务器合成后的文章索引,剔除专栏目录、搜索页和失效链接,再减去已经开始阅读的文章集合。还可以加上专栏过滤,避免想读技术文章时抽到日报。

点击随机入口后,不要在页面尚未成功打开时就写成已读。没有候选文章时应说明当前范围已无未读文章,让人主动切换范围或选择重读。

第一版怎样落地和验收

实现可以分两步,先把状态同步跑通,再处理更复杂的文本定位。

  1. 建立个人登录、文章标识和阅读状态,完成整篇收藏、继续阅读、随机未读以及导出备份。
  2. 加入高亮、笔记和段落收藏,再验证文字变更、手机选字、离线修改与冲突恢复。

最终验收应使用两台真实设备,而不是只看数据库里出现了一条记录:

场景通过标准
电脑读到中段,手机打开恢复到对应内容附近,而不是相同滚动像素
电脑添加高亮和笔记手机可见、可编辑,修改能同步回来
收藏文章与段落私人列表都能找到,并能跳回原文
标记阅读中或已读随机“从未读过”不再选中它
普通访客打开文章文章可读,私人数据不可访问
两台设备先后离线修改新笔记不被整包覆盖,删除不复活
在文章前增加一段原高亮仍能定位,或明确提示待关联
重新发布和回滚博客笔记、收藏和状态保留
导出并恢复个人数据能重建收藏、笔记和阅读状态

给其他 Agent 的需求摘要

下面这段可以作为后续评估或实现的起点。

我有一个 Hugo + PaperMod 静态博客,Org 经 ox-hugo 导出 Markdown。
服务器用 Caddy 提供 HTTPS,合成发布器合并独立专栏和日报,
deploy/reader.py 负责最终页面的阅读布局增强。
目前没有个人登录或阅读数据同步后端。

我要个人使用的原网页划线、笔记、整篇/段落收藏、阅读位置恢复、
未读/阅读中/已读状态、跨设备同步,以及随机打开从未读过的文章。
优先保持原博客布局,桌面支持键盘与搜索,手机支持触屏,私人数据不公开。

请比较开源工具与轻量自建方案,区分原生支持、需要开发和待验证能力。
重点检查:原网页还是抓取副本、手机兼容、跨屏幕位置恢复、
文章更新后的定位、离线冲突、删除同步、数据备份和导出。

候选方案是博客内嵌私人阅读界面,配合 PocketBase 等轻量同步后端。
个人数据库独立于静态发布目录;文章清单以最终发布结果为准。
请给出最小实现、部署组件和两设备验收步骤,不把选型描述成已经实现。

这篇先把需求和边界固定下来。接下来的判断标准是:能否自然地继续阅读、留下笔记,再在另一台设备上找回它们。