VK-Sight

一套书喂三台墨水屏:booklib 能帮你做什么

目录

我手上有三台墨水屏:Kindle Paperwhite 12 代签名版、掌阅 iReader Ocean 5 Pro、reMarkable Paper Pro Move。书是同一批,几十本小说加几套漫画,来源五花八门。把同一本书分别丢给三台设备,常见的情况是:

  • 在阅读器里把字号调大,正文纹丝不动,因为书里把字号写死了;
  • 漫画四周留一圈白边,明明屏幕还有空,图就是不肯铺满;
  • 点一个注释号跳到章末,看完却回不去原来那一页;
  • Kindle 干脆不认 EPUB,USB 拷进去也看不到。

booklib 是我在电脑上用的一个小工具,专门对付这些问题。它的思路很简单:书还是放在你自己的文件夹里,booklib 照着每台设备的脾气,各生成一份"优化过的版本",你拷过去读就行。这篇不讲代码,只讲它能帮你做什么,以及每件事为什么要这样做。

一张图看懂

一张图看懂:书目录里放原书,booklib 给三台设备各出一份

整个流程就三步:

  1. 登记书目录:告诉 booklib 你的书放在哪个文件夹,只需要登记一次。
  2. 同步并生成:运行一条命令,booklib 发现新书、改过的书,给三台设备各生成一份。
  3. 自己拷到设备上:生成的书就放在书目录旁边的 kindle/、ireader/、xochitl/ 三个文件夹里,子目录结构和原来一模一样,整个文件夹拷过去即可。
booklib track ~/Documents/ereader/books   # 登记书目录(一次)
booklib sync                              # 同步进书库,按三台设备各生成一份
booklib list                              # 看每本书的产物在哪、是不是最新

之后往书目录里加书、改名、挪位置,再跑一次 booklib sync 就跟上了。不想手动跑,也可以让它一直在后台盯着(booklib sync --watch),有变化才动手,没变化时几乎不耗电。

先说三条底线

动手之前,我给这个工具定了三条不能碰的线:

  • 书的内容一个字不多、一个字不少。 排版可以改,字一个都不能动。每次改了处理规则,我都会拿几十本真书逐字符对一遍账,原书多少个字、生成出来还是多少个字。
  • 原书不动。 你的书目录里的文件,booklib 只读不写。生成的书都是新文件,删了随时能重新生成。
  • 拿不准就不处理。 遇到认不出的结构,宁可原样保留,也不去猜。

后面所有的功能,都是在这三条线里面做的。

书库:像图书馆的卡片目录

booklib 有一个"书库",但它不复制你的书。打个比方,它更像图书馆的卡片目录:每本书一张卡片,卡片上记着书在哪个书架(文件路径)、书的"指纹"(内容的哈希值)、书名作者,书本身还在你的书架上。几十本书的书库只有几百 KB。

书库只记卡片,不搬书;生成前先核对书还是不是那一本

这样做带来几个好处:

  • 改名、挪位置都认得出。 卡片按内容认书,不按文件名。你把《白夜行》从"小说"挪到"东野圭吾"文件夹,booklib 知道还是同一本,只把生成好的书跟着挪过去,不会重新生成,也不会在设备上多出一本。
  • 只重建有变化的书。 每份产物都记着一个"指纹":原书内容、处理规则的版本、设备参数……任何一项变了才重建。28 本小说给三台设备一共生成 84 份,从零开始大约 15 秒;什么都没变时再跑一次,瞬间结束。
  • 不会拿改过的书冒充原书。 生成前先核对原书还是不是登记时那一本,内容变了就停下来提示你,不会悄悄用新内容覆盖。
  • 不会误删你的文件。 产物文件夹里只删它自己生成的书,你自己放进去的文件一概不碰。

收书目前只收 EPUB 和 CBZ 漫画(也能收一个网页链接,抓成 EPUB)。带 DRM 的书会被拒收。

文字书:解锁字号,排得像一本书

文字书要解决的问题,大多是"书里写死了东西,阅读器的设置不起作用",以及"阅读器对某些写法支持得不好"。

同一页书,优化前后的区别

1. 解开字体、字号、行距的锁。 很多书的样式表把字体、字号、行高写成固定值,阅读器里怎么调都没用。booklib 只把这几项"锁"解开,交还给阅读器;颜色、粗体、斜体、对齐这些作者的排版意图一律保留。标题、小字这种相对大小也保留,所以调大字号时,标题还是比正文大。

2. 按中文、英文各自的习惯排版。 中文段落首行缩进两个字;英文缩进略小,每章第一段顶格,这是英文书的传统排法。中文书段首用全角空格"凑"出来的缩进,换成精确的样式缩进,因为有的阅读器会把段首的全角空格吞掉,缩进就没了。

3. 章标题独立一页,节与节之间分页。 这是我最在意的一点:每一章开头单独占一页,看着像一本正经的书。阅读器对"分页"这条样式的支持参差不齐,所以 booklib 用了最笨也最可靠的办法:按标题把章节文件切开,每个文件天然从新的一页开始。切开之后,书里所有的链接、目录都跟着改指过去。

4. 注释:点得过去,也回得来。 注释统一搬到本章末尾,比正文小一号(相当于五号字换小五)。正文里的注释标号一个字都不加,只是改成书内跳转链接。有些书的注释号是一个小图标,在某些阅读器上图标根本点不动,这种就换成上标数字。"回得来"这件事三台各不相同:Kindle 点完注释没有可靠的"返回",就保留原书注释里那个跳回正文的链接;Move 自带"返回"按钮,反而遇到这种双向链接会出问题,就去掉。

5. 修目录。 有的书目录整体错位,点"第一章"跳进了登场人物表;有的书目录漏了节;有的书干脆没有目录。booklib 只修能核实的:标题文字对得上、只有一处,才改;核实不了就不动。没有目录的书按标题生成一份。

6. 统一升级到 EPUB 3,修好不合规的地方。 很多书的内部文件其实不是合法的 XML,靠阅读器"宽容"才能打开。booklib 把它们修规范,升级到 EPUB 3 标准,同时保留老式的目录文件,兼顾旧阅读器。

漫画:保留画质,离屏幕边缘只差 1 像素

漫画的目标是:图尽可能大,离屏幕边缘只留 1 像素,画质不打折扣。

每一页大致是这几步:先把原图扫描时留下的白边裁掉,再按设备真正能显示内容的区域等比缩放,最后居中放在白底上,四周留 1 像素。只等比缩放,不拉伸、不压扁。

黑白屏的 Kindle 和掌阅上,彩色页转成 256 级灰度,不做抖动:设备显示时自己会把灰度换算成屏幕能显示的级数,提前抖动只会多一层损失。全彩漫画转灰度后体积能小四分之一(《哆啦A夢》全彩版卷一:灰度 105.8MB,保留彩色 141.0MB),画面上的差别只在"某种颜色变成多深的灰"。彩色屏的 Move 保留彩色。

画质方面,图片编码一律用高质量,然后再做一步无损的压缩优化:只重新打包图片数据,解码出来的像素和原来逐个相同,文件却能小 7%~16%。每一页处理完都会把新旧两份解码对比一遍,有一个像素不同就用原来的。

几百页、几百 MB 的漫画也不怕:图片一张一张处理、处理完立刻丢掉,同时只占用"几张图"的内存,跟书有多大没关系。一卷 280MB 的《死亡笔记》给三台设备各生成一份,不到 10 秒。

三台设备,三个怪癖,三种办法

"离屏幕边缘 1 像素"说起来简单,三台设备各有一个怪癖挡在中间,只能各用一种办法绕过去:

三台设备各有一个怪癖挡着,各用一种办法让漫画贴边

  • Kindle:普通排版下,它强制留页边距,调到最小还有 101 像素。办法是把漫画写成"固定版式":告诉 Kindle 这本书每一页就是一张 1272×1696 的画布,Kindle 就按 1:1 整屏显示。真机截图和原图逐像素对得上。
  • 掌阅:整页大图本来能铺满整屏,但如果书声明了"从右往左翻"(日漫基本都这样写),它就会在四周留出 92/124 像素的边。试了很多写法,只有这一个属性有影响。最后的取舍是把漫画改成从左往右翻,换来整屏铺满。
  • Move:它会在四周留一圈白,书里的样式改不动,只有阅读器的"页边距"设置管用,可界面上最小也只有 28。办法是借助 Move 上一个现成的小工具,在打开漫画时把页边距设成 1,漫画也按这个尺寸来排。左右做到了 1 像素,上下的留白是阅读器固定的,没办法。

这三条在 booklib 里都写成了设备配置里的一个开关,不在代码里写"如果是 Kindle 就怎样"。以后换一台新设备,多写一份配置文件就行。

Kindle:自己写了一个 AZW3 转换器

Kindle 通过 USB 传书只认 AZW3 格式,不认 EPUB。常见的做法是借用 Calibre 转换,但我不想依赖它,于是照着公开的格式资料,加上对样本文件的分析,自己写了一个 EPUB → AZW3 的转换器(全程没有参考任何现成转换工具的代码)。

给 Kindle 的书,先按和另外两台完全相同的规则优化出 EPUB,再转成 AZW3,只换格式,不改内容。每次转完都会把 AZW3 里的文字和 EPUB 逐字比一遍,28 本小说加一卷漫画全部一致。

还有两个小细节:

  • 重新生成后阅读进度不丢。 每本书在 AZW3 里有一个唯一编号,booklib 让它只跟书本身挂钩,规则升级、重新生成,Kindle 仍然认作同一本书,覆盖旧文件后还停在原来读到的地方。
  • 修掉了一个 Kindle 独有的坑。 有本书每章开头的隐藏区域里混进了一段样式代码,别的阅读器不显示,Kindle 却原样印在章首,满满一页代码。现在转换时会把这块区域清理干净。

封面和简介:联网补缺的

有些书没有封面,在书架上就是一块灰。booklib meta --fetch 会联网帮这些书找元数据:

封面和简介从哪来:按顺序找,找到就停;只补书里没有的

  1. 先找豆瓣:中文版封面最贴近你手上的书,顺带拿到内容简介、标签、原作名。书名会做繁简转换后再比对,作者也要核对上。
  2. 豆瓣没有就找原作:去 Wikidata 找这部作品,再到 Open Library 找原版封面。
  3. 都找不到就生成一张:书名在上、作者照片居中、作者名在下,配色按书挑,在黑白屏上也清楚。

它只补书里没有的东西,书名、作者、正文一律不动;补的内容写进生成的新书里,你的原书不碰。我用好读的 18 本没封面的书试过:11 本用上了豆瓣的中文版封面,2 本用了原作封面,5 本(多是台湾出版社自编的选集)生成了封面。

如果想直接改某个 EPUB 文件本身的书名、作者、标签、封面,用 booklib meta --edit 书.epub --title 新书名 --tag 小说。不带参数就是查看。

在三台真机上验证过什么

这个项目有一条规矩:没在真机上看过,就不算完成。一台设备上没问题,不代表另一台也没问题,"标准允许"也不代表阅读器真的支持。目前的情况:

功能Kindle掌阅Move
阅读器里调字号、换字体生效✓✓✓
章标题独立一页、节与节分页✓✓✓
目录里节缩进在章下面、点了能跳✓✓✓
注释点得过去、回得来✓✓✓
漫画离屏幕边缘 1 像素✓✓左右 ✓
英文书每章首段顶格✓✓✓

做不到的事

也记下几件试过但做不到的,省得以后再踩:

  • 英文自动断字:三台阅读器都不支持。可以往正文里插"软连字符"强行断词,但那等于给书加字,违反第一条底线,所以不做。
  • 三台设备同步阅读进度:Kindle 的进度文件读得到、写不进去,掌阅不 root 连读都读不到,没有互通的路。
  • 带 DRM 的书:目前直接拒收。

最后

booklib 做的事说穿了很朴素:原书不动,照着每台设备的脾气各出一份,内容一个字不改。我最满意的不是哪个具体功能,而是"加一本书、改个名、换台设备"这些日常操作都不用再操心,跑一条命令,拷一个文件夹,打开就能读。

三台设备的那些怪癖,几乎每一条都是在真机上一张张截图、一个个像素量出来的。如果你手上也有一台以上的墨水屏,希望这篇里的经验对你有用。

添加新评论