☰
Foliate 使用与维护 FAQ 全解析:locations、自定义主题、TTS 与数据存储机制详解
2026/9/25 1:38:44 网站建设 项目流程
  • 桌面应用

【免费下载链接】foliate

Read e-books in style

项目地址:https://gitcode.com/gh_mirrors/fo/foliate
点击查看免费下载

本文是一份面向 Foliate(开源电子书阅读器)用户的深度技术 FAQ 指南,聚焦官方 FAQ 中涉及的核心机制:位置(locations)与 EPUB CFI 引用、阅读时间估算、文本转语音(TTS)、自定义主题与用户样式表、书签与笔记的数据存储结构、书籍标识符生成算法,以及安全性保障与 Flatpak 权限说明。读完本文,你将不仅掌握每一项功能的实际操作步骤,还能理解其底层实现原理,可直接用于日常使用、数据备份迁移与二次开发。

通用问题:遇到故障怎么办?

Foliate 的官方文档为常见故障专门维护了一份排查指南。如果你在使用过程中遇到任何异常,比如书籍无法打开、界面显示异常、TTS 无声等,请优先查阅 docs/troubleshooting.md。这份指南按问题现象分类,给出了对应的排查步骤与解决方案,是处理 Foliate 故障的第一手参考。

阅读机制:locations 是什么?

locations 的定义与长度单位

在 Foliate 中,一本书被划分为若干个location(位置)。每个 location 的长度固定为1500 字节。这种设计提供了一种粗略的"页数"度量方式,其核心优势在于:该度量与视口(viewport)大小基本无关——无论你如何调整窗口尺寸、缩放字体,一本书的 location 总数都不会随之改变,因此可以稳定地用于进度显示、跳转定位等场景。

在源码中可以看到这一常量的实际使用。src/library.js在计算书籍缩略图上的阅读进度条时,直接以1500作为除数:

const bookSize = Math.min((progress?.[1] + 1) / 1500, 0.8)

也就是说,进度条按"当前 location 序号 + 1"与1500的比值计算(并限制最大值不超过 0.8),这从实现侧印证了 location 计数单位的确为 1500 字节。

locations 不是精确引用

需要注意的是,locations 并不精确。如果需要在书籍中精确引用某个位置(例如在笔记、书签或外部工具中),应当使用 Foliate 提供的identifiers(标识符),即标准的 EPUB Canonical Fragment Identifiers (CFI)。CFI 是 EPUB 规范中"引用 EPUB 出版物内任意内容的标准化方法",能够精确到段落、句甚至字符偏移,且不随阅读器布局变化而失效。

版本兼容性警告

Foliate 的 1.x 和 2.x 版本曾经使用一种完全不同的算法来计算 locations——这种方法更慢但更精确。新旧算法计算出的 location 不兼容。如果你手头有旧版本生成的进度、书签或基于 location 的记录,迁移到当前版本后这些数据并不能直接对应到新版本的 location 体系中。

阅读时间估算的原理

Foliate 的"预计阅读时间"计算方式非常简单直接:直接使用 location 的数量作为基础——本质上就是字符数——来做一个粗略估计。它并不基于你的实际翻页速度、阅读习惯或单页停留时长。

因此,这个估算值只是一个数量级的参考,对于阅读速度较快的用户会高估时长,对慢速阅读者则会低估。它不是个性化统计工具,而是基于"全书约有多少字符内容"的静态换算。

文本转语音(TTS):如何启用与优化

前置依赖

Foliate 的 TTS 功能依赖系统的speech-dispatcher服务,因此使用前需要确保系统中已安装:

  • speech-dispatcher(语音调度服务本身)
  • 输出模块,例如espeak-ng(最常用的合成引擎之一)

从源码看,Foliate 实现了完整的 SSIP 协议客户端(SSIPClient与SSIPConnection类),通过 Unix Socket 与 speech-dispatcher 通信。启动时会尝试执行speech-dispatcher --spawn(可通过环境变量SPEECHD_CMD覆盖命令),并默认连接用户运行时目录下的speech-dispatcher/speechd.sock(可用SPEECHD_ADDRESS环境变量指定替代地址)。连接建立后,客户端依次发送SET SELF CLIENT_NAME、SET SELF SSML_MODE on、SET SELF NOTIFICATION ALL on等初始化命令,随后即可用SPEAK、PAUSE self、RESUME self、STOP self等命令控制朗读,并支持SET self RATE(语速)与SET self PITCH(音调)调节、LIST SYNTHESIS_VOICES枚举可用语音。

使用方法

在阅读界面中,将鼠标悬停(或触摸屏上点按)页面底部区域会显示导航栏(navbar),点击其中的Narration(旁白)按钮——带有耳机图标的那个——即可启动朗读。

有一个重要的限制需要注意:如果当前书籍内嵌了音频(即 EPUB Media Overlays 媒体覆盖),那么 Narration 按钮会变为控制内嵌媒体的播放控件,此时 TTS 将不可用。

另一种启动方式是:选中一段文本,在弹出的选择菜单中点击Speak from Here(从当前位置朗读)。不过需要注意,即使是通过这种方式启动的朗读,停止朗读仍然需要使用 Narration 按钮。

改善音质

默认语音听起来可能比较机械。官方 FAQ 建议使用Pied(一个用于配置 Piper 的前端图形工具)来替换为更自然的神经网络合成语音,具体操作细节可参考其官方文档中的说明。Piper 系列语音模型支持多种语言,能让 TTS 朗读体验有质的提升。

自定义主题(Custom Themes)

主题的 JSON 格式

Foliate 的自定义主题以JSON 文件定义。一个完整的示例主题如下:

{ "label": "Ghostly Mist", "light": { "fg": "#999999", "bg": "#cccccc", "link": "#666666" }, "dark": { "fg": "#666666", "bg": "#333333", "link": "#777777" } }

字段说明:

  • label:主题在设置界面中显示的名称(若省略,则回退为文件名去除.json后缀,见 src/themes.js);
  • light:浅色配色方案,包含fg(前景/文字色)、bg(背景色)、link(链接色)三个十六进制颜色值;
  • dark:深色配色方案,字段与light相同,在系统/阅读器处于深色模式时生效。

从源码实现看,src/themes.js 启动时会遍历配置目录中所有.json文件并解析合并到内置主题列表;解析失败(如 JSON 语法错误、字段缺失)会被catch捕获并在控制台输出错误,但不会导致整个应用崩溃。内置的九个主题(Default、Gray、Sepia、Grass、Cherry、Sky、Solarized、Gruvbox、Nord)同样以该结构定义在源码中,可作为自定义主题的配色参考。此外,主题还支持"反转"(invert)模式,源码通过invertTheme对深色方案的fg、link做颜色反转计算,见 src/themes.js 与 src/utils.js 中的invertColor(反色 + 180 度 hue-rotate)实现。

各安装方式的主题目录

将主题 JSON 文件放入对应配置目录即可安装(不同发行方式目录不同):

安装方式主题目录
原生安装(包管理器、源码运行)~/.config/com.github.johnfactotum.Foliate/themes/
Flatpak~/.var/app/com.github.johnfactotum.Foliate/config/com.github.johnfactotum.Foliate/themes/
Snap~/snap/foliate/current/.config/com.github.johnfactotum.Foliate/themes/

底层实现上,Foliate 通过pkg.configpath('themes')构造该目录路径(见 src/main.js 的configpath定义),因此不同发行方式的路径差异本质上是 XDG 配置目录映射位置的不同。

自定义 CSS 样式(User Stylesheet)

如果你希望更进一步地定制阅读排版(而不仅仅是配色),可以创建用户样式表文件:

  • 原生安装:~/.config/com.github.johnfactotum.Foliate/user-stylesheet.css
  • Flatpak:~/.var/app/com.github.johnfactotum.Foliate/config/com.github.johnfactotum.Foliate/user-stylesheet.css

该文件中的 CSS 会被注入到阅读器页面中,用于覆盖书籍自带样式。需要特别注意的是:修改后必须重启 Foliate 才能生效。这是因为源码在应用启动时就一次性读取了该文件内容并缓存在内存中:src/book-viewer.js第 45-46 行通过utils.readFile(Gio.File.new_for_path(pkg.configpath('user-stylesheet.css')))读取,随后在#applyStyle()中作为userStylesheet属性传给阅读器视图(src/book-viewer.js),最终由src/reader/reader.js将它与书籍内容一同注入渲染。

实用技巧:官方 FAQ 特别推荐使用 CSS 的:lang()选择器,针对不同语言的书籍应用不同的样式。例如可以基于html:lang(zh)、html:lang(en)等来分别调整中西文混排、字体族或段落间距,实现多语言阅读体验的精细化控制。

书签与标注:数据如何存储

数据目录

你的阅读进度、书签和标注都保存在 Foliate 的数据目录中:

安装方式数据目录
原生安装~/.local/share/com.github.johnfactotum.Foliate
Flatpak~/.var/app/com.github.johnfactotum.Foliate/data/com.github.johnfactotum.Foliate
Snap~/snap/foliate/current/.local/share/com.github.johnfactotum.Foliate

每本书的数据单独存放在一个以书籍标识符(identifier)命名的 JSON 文件中。想要同步或备份进度与笔记,直接复制这些 JSON 文件即可,无需依赖 Foliate 内置的导出功能。

从实现角度,这些文件由 src/utils.js 中的JSONStorage类管理:它以path + encodeURIComponent(name) + '.json'定位文件,写入时自动创建父目录,保存操作做了 1000ms 的防抖(debounce),并且注册了Gio.FileMonitor监听外部修改——如果你在 Foliate 运行期间手动改动了这些文件,它会重新读取并发出externally-modified信号。这意味着手动编辑 JSON 文件进行"批处理"(如批量改色、合并笔记)是可行的,且应用会感知变化。

JSON 文件内部结构

书籍数据文件的内部结构示例如下:

{ "lastLocation": "epubcfi(/6/12!/4/2/2/2/1:0)", // 你的阅读进度 "annotations": [ { // 高亮文本对应的 EPUB CFI "value": "epubcfi(/6/12!/4/2/2/2,/1:0,/1:286)", // 高亮颜色 "color": "aqua", // 被高亮的文本内容 "text": "Good sense is, of all things among men, the most equally distributed; for every one thinks himself so abundantly provided with it, that those even who are the most difficult to satisfy in everything else, do not usually desire a larger measure of this quality than they already possess.", // ... 以及你的笔记 "note": "Very droll, René." }, // ... ], "bookmarks": [ /* 书签存储在这里 */ ], "metadata": { /* 书籍的元数据 */ } }

各字段说明:

  • lastLocation:上次阅读位置,值为 EPUB CFI 字符串;
  • annotations:标注数组,每个元素包含value(高亮范围的 CFI)、color(高亮颜色)、text(高亮文本原文)和可选的note(笔记内容);
  • bookmarks:书签数组;
  • metadata:书籍元数据对象。

其中所有epubcfi(...)都是 EPUB Canonical Fragment Identifiers (CFI),即 EPUB 规范中"引用 EPUB 出版物内任意内容的标准化方法"。使用 CFI 而非页码或 location 的好处是:引用不依赖视口布局、字体大小或分页结果,即使在设备之间迁移也能精确定位到同一段文字。

书籍标识符:foliate:前缀的生成算法

对于没有唯一标识符的格式或书籍,Foliate 会为其生成一个标识符,规则为:foliate:前缀 + 文件内容的 MD5 哈希。

为了加速计算,只取文件前 10000000 字节(10 MB)参与哈希。你可以在终端运行以下命令得到完全相同的哈希:

head -c 10000000 $YOUR_FILE_HERE | md5sum

源码实现位于 src/book-viewer.js 的makeIdentifier函数:它用file.read()打开文件流,读取前10000000字节,再通过 GLib 的GLib.compute_checksum_for_bytes(GLib.ChecksumType.MD5, bytes)计算 MD5,拼接为foliate:${md5}返回;读取失败时返回null并记录警告。代码注释中还保留了一句说明:这个字节上限"可能不是最优值,但为了与旧版本保持兼容而保留"。该标识符会在导入书籍时写入书籍元数据(book.metadata.identifier ||= makeIdentifier(currentFile)),并作为数据 JSON 文件名的依据——因此同一文件生成的标识符在不同机器上一致,这也正是"复制数据文件即可完成备份迁移"能够成立的前提。

安全性:Foliate 安全吗?

威胁模型

EPUB 文件本质上是打包在 Zip 中的 HTML 文件,因此它可以包含 JavaScript 等具有潜在危险的代码和内容。

当前版本的 Foliate 在阅读器 WebView 中默认阻止 JavaScript 和外部资源的加载。这是第一道防线。

推荐做法:沙箱化运行

为了进一步防御潜在漏洞,官方明确建议在沙箱化环境中运行 Foliate——例如使用 Flatpak 打包版本。Flatpak 的沙箱隔离了文件系统、网络与其他系统资源,即便书籍内容触发 WebView 漏洞,攻击面也被大幅收窄。

历史版本警告

在 1.x 和 2.x 版本中,JavaScript 是可以手动开启的。如果你正在使用这些旧版本,切勿开启该选项——开启后阅读不可信 EPUB 书籍的风险极高,相当于直接在你的电脑上执行书籍自带代码。

Flatpak 权限说明:为什么需要这些权限?

Foliate 的 Flatpak 清单申请了以下权限,每一项都对应具体功能:

  • 网络访问(--share=network):用于在线词典、百科和翻译工具(即src/selection-tools/下的查找、翻译功能所依赖的网络请求);
  • --filesystem=xdg-run/speech-dispatcher:ro:以只读方式挂载 speech-dispatcher 的运行时目录,以便连接宿主机上的 speech-dispatcher 服务,支撑 TTS 朗读;
  • --add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Documents:允许访问宿主机上的 Tracker 文件索引数据库,从而在从图书馆视图打开书籍时获取文件的真实位置。

以上权限全部是可选的(optional)。如果你不使用对应的功能(比如不需要网络查词、不用 TTS、不依赖 Tracker 索引),可以考虑用flatpak override命令或 Flatseal 等图形工具覆盖这些权限,遵循最小权限原则收紧沙箱。

面向出版方与开发者:WebKit 开发者工具

Foliate 内置了WebKit 的 Developer Tools(开发者工具),可通过以下任一方式打开:

  • 进入主菜单 > Inspector;
  • 直接按F12快捷键。

使用建议:将开发者工具面板分离(detach)到独立窗口。原因在于,如果面板停靠在阅读器窗口内,阅读器窗口上注册的快捷键会干扰你在开发者工具中的按键输入(例如书页翻页快捷键可能与 DevTools 调试快捷键冲突)。分离窗口后,调试 EPUB 内 HTML/CSS 的体验与常规网页调试一致,这对于出版方验证电子书排版、开发者排查阅读器渲染问题都非常有价值。

总结

从位置定位与 CFI 引用、TTS 与自定义主题,到 JSON 数据文件的结构与foliate:标识符算法,再到安全模型与 Flatpak 权限设计,Foliate 在保持界面简洁的同时,为用户留下了大量可控的扩展点:JSON 主题、用户样式表、可直接复制迁移的数据文件。理解这些机制后,你既能更高效地日常使用(如备份同步、多语言排版、自然语音朗读),也能安全地评估书籍来源与权限配置,还能基于 src/themes.js、src/speech.js、src/utils.js 等源码深入理解其内部实现,为二次开发或贡献补丁打下基础。更多故障处理细节可继续查阅 docs/troubleshooting.md。

  • 桌面应用

【免费下载链接】foliate

Read e-books in style

项目地址:https://gitcode.com/gh_mirrors/fo/foliate
点击查看免费下载

相关推荐

上一篇:开源工具革新:突破网盘下载限速的直链解析技术实践指南
下一篇:资源获取效率如何提升80%?智能解析工具重构网盘下载体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询