快速拆包读书笔记文件-多语言版

ShadowC

| 本文阅读量: -

手里有个掌阅的阅读器(Smart XS,已停产停售),可以在阅读时划线,并将这部分内容封装成 EPUB 格式的笔记,本文主要关注如何拆解这种笔记文件,以及重新用 markdown 格式输出这些笔记。

Updated 20250804: 从目录读取笔记列表,避免乱序。

拆解 EPUB 文件

EPUB(Electronic Publication) 是常见的电子书格式1,完整的标准可以查阅EPUB 3.2 規格文件中文版。从“最小可用系统”的角度来讲,EPUB 文件是一个用 zip 方式压缩的文件夹,里面包含的是必要的元信息和 html 格式存储的文本内容,以及其他可选的多媒体内容(例如插图等)。

以这次要解析的笔记为例,手动解压后的目录结构是:

.
├── META-INF
│   └── container.xml
├── mimetype
└── OEBPS
    ├── chapter_0.html
    ├── chapter_1.html
    ├── chapter_2.html
    ├── chapter_3.html
    ├── chapter_4.html
    ├── chapter_5.html
    ├── chapter_6.html
    ├── chapter_7.html
    ├── chapter_8.html
    ├── content.opf
    ├── cover_2.png
    ├── cover.png
    ├── cover_thumbnail.png
    ├── item_1.xhtml
    ├── toc.ncx
    ├── zybooknote.css
    └── zybooknote_icon_locate.png

目前需要关注的是这些文件:

  • OEBPS/toc.ncx ,包含了目录信息;
  • OEBPS/chapter_*.html,这就是阅读时划线的所有笔记,每章对应一个文件。

提取笔记

既然笔记都在 html 文件里,只要按顺序读取这些文件的内容,然后根据标签的提取对应信息即可:

  • 章节标题在唯一一个 <h2> 标签内;
  • 每条笔记对应一个 class="zybooknote_summary"<p 标签。

功能实现

有一些细节需要关注:

  • 既然 epub 本质是一个压缩文件,需要解压到一个临时的文件夹中,这里选择了在系统临时文件夹下建立一个随机名称的文件夹,当然在结束后也要记得清理这个文件夹。
    • 以 linux 为例,临时文件夹就是 /tmp 目录;
    • 以 golang 为例,可以通过 os.TempDir() 方法获取系统的临时文件夹位置。
  • 为了让整体结构更清晰,引入笔记和笔记本两个结构体,其中:
    • 笔记本对应整个掌阅生成的笔记文件,这个结构负责解压、获取文件列表、输出到目标文件、清理临时目录;
    • 笔记对应一个具体的 html 文件,负责从文件读取笔记信息、按照 markdown 格式化输出。
  • demo -o <DEST_PATH> <EPUB_FILE> 这样的形式来指定输出的 markdown 文件和输入的笔记文件路径。

代码就不贴在这里了,有兴趣的朋友可以移步 notex-multi Review 代码(欢迎提 issue)。

总结

“So, what we learned from taday?”2

  • 代码本身不复杂,更值得训练的是从框架层面设计流程,避免用 “面条式” 代码来实现,良好的结构有助于扩展(新功能)、迁移(到其他语言或者场景);

  • // TODO 20250804 Done 目前没有用 toc.ncx 中的内容来读取章节列表,而仅仅是通过获取文件列表的顺序,在目前使用中尚且算可用,但后续最好已经修改为根据目录来查找文件;

  • 促使我写下上述文字的动力是 當代學生生存手冊 中的这段话,同时也强烈推荐这本书作者的博客 螺莉莉的数据中心

    “道理誰都懂,但是道理不能說服任何人。因為道理是空洞的結果,探索這些道理的過程才是智慧。我們需要的不是道理,我們需要的是智慧。 智慧是最重要的,所以最後我想用這句話,為今天的分享做一個結尾:不要停止思考。”