记一次epub转pdf


偶然在b站看见好多人推这本Japanese-English Bilingual Visual Dictionary,用的是尚雯婕推荐这本书的微博,不过大多都是引流骗关注的,想找书自然有我们自己的途径。

zlib上能找到这本书的3个版本,2011,2018和2024的,2011的封面就是b站引流用的那版,后面两个版本只有epub,没有pdf,下载下来之后发现排版完全是乱掉的(我用的是SumatraPDF看的,不确定是否有其他阅读器能正常显示,不过把2024版的epub解压之后,可以看到每个网页都是正常的,于是考虑把它转成pdf格式试试。

首先考虑epub直接转pdf的工具,可惜免费的网络工具基本都不支持这么大的文件,况且本身这个epub排版可能也有问题,所以这个方法没试多久我就放弃了。
其次考虑网页转pdf,直接打印的话能控制的细节太少,搜索一下可以找到wkhtmltopdf这个工具,总之先尝试一下

C:\Users\lenovo\Downloads\jebvd>bin\wkhtmltopdf.exe OEBPS\page027.xhtml 27.pdf
Loading pages (1/6)
Warning: Blocked access to file C:/Users/lenovo/Downloads/jebvd/OEBPS/css/FontSrc.css
Warning: Blocked access to file C:/Users/lenovo/Downloads/jebvd/OEBPS/css/Styles.css
Warning: Blocked access to file C:/Users/lenovo/Downloads/jebvd/OEBPS/images/bg027_00.jpg
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Error: Failed to load about:blank, with network status code 301 and http status code 0 - Protocol "about" is unknown
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
Exit with code 1 due to network error: ProtocolUnknownError

似乎是失败了,搜索一下错误信息,发现要加上这个参数--enable-local-file-access

C:\Users\lenovo\Downloads\jebvd>bin\wkhtmltopdf.exe --enable-local-file-access OEBPS\page027.xhtml 27.pdf
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done


这下好像是成功了,不过观察转换后的pdf,可以发现右边被切掉了一部分,可能是页面尺寸的问题,查找wkhtmltopdf的文档,用--page-size指定页面尺寸,默认是A4,试试A3

C:\Users\lenovo\Downloads\jebvd>bin\wkhtmltopdf.exe --enable-local-file-access --page-size A3 OEBPS\page027.xhtml 27.pdf
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

这回显示倒是完整了,但上下的白边太多了,所以正常的尺寸应该和A4相差不大,可是文档里也没有现成的合适的页面尺寸,所以正确的尺寸到底是多少呢?

虽然手动尝试,找到一个差不多的尺寸也可以,但这也太不优雅了,观察页面,发现它是用一张图片当背景,然后在上面添加文字来实现排版的,所以图片的尺寸应该就是页面的尺寸了,看下图片的属性,1603 x 193196dpi,换算一下就是424 x 511mm,好像太大了?不过折半之后和A4差不多,试试212 x 256mm,记得把上下左右的边距设成0,结果正好。另外用这个尺寸测试下封面和目录,也完美适配,下面就是想办法把所有的页面转成pdf了。
这个倒是不难,cmd内置的for就支持遍历文件,可惜我向来是记不住它的语法的,一般遇到这种需求,我的做法是在需要处理的目录下打开cmd,运行dir /b > 1.txt,得到文件列表,删除多余的文件,然后用正则处理一下得到bat脚本,再运行脚本即可。

bin\wkhtmltopdf.exe --enable-local-file-access -T 0 -B 0 -L 0 -R 0 --page-width 212mm --page-height 256mm OEBPS\cover.xhtml pdf\001.pdf
bin\wkhtmltopdf.exe --enable-local-file-access -T 0 -B 0 -L 0 -R 0 --page-width 212mm --page-height 256mm OEBPS\page002.xhtml pdf\002.pdf
bin\wkhtmltopdf.exe --enable-local-file-access -T 0 -B 0 -L 0 -R 0 --page-width 212mm --page-height 256mm OEBPS\page003.xhtml pdf\003.pdf
……

转换完成后再用pdftk合并一下,pdf差不多就做好了,浏览一下,效果很不错。
不过现在只能算是完成了80%,但众所周知剩下的20%才是最费事的。原始的epub文件内部是有超链接的,转换成pdf后超链接自然也保留了下来,可是现在它连接的对象是一个xhtml文件而非pdf的页面,关键是它的路径还是一个指向本地文件的绝对路径,这种事情我这个强迫症怎么能忍呢?所以要如何修改这些超链接的目标呢?

用pdf编辑器应该是可以解决这个问题,不过pdf编辑器基本上都很大,而且大多数都收费,平时我也不太用得上,所以就没装,并且要修改的超链接还挺多的,用编辑器一个个改也挺花时间的。还有其他方法吗?
当然是有的,也许你不相信,其实pdf文件是可以用文本编辑器编辑的。首先用pdftk的uncompress语法将pdf处理成未压缩的状态,然后我们就可以用vim打开了,需要注意的是vim要加上-b参数,这样保存的时候不会对非打印字符做任何处理。

pdftk.exe *.pdf output out1.pdf
pdftk.exe out1.pdf output out2.pdf uncompress
gvim.exe -b out2.pdf


不用太费劲就可以找到超链接的部分了,怎么把它改成链接到pdf页面呢?这个我也试了很久,总之略去过程,把上图中的5581行到5587行改成/Dest [n]即可。依然是一顿正则替换,试一下改过的pdf,可以跳转页面了,但是要跳转的页面似乎都多了一页,这是因为/Dest [n]其实链接到的是n+1页,为什么是n+1?因为是从0开始数的。而最开始的pagexxx.xhtml则正好是第xxx页,所以要怎么把这些数字都减1呢,好在vim正擅长做这种事,录一个宏,操作是查找下一个/Dest,然后按Ctrl+X,这个按键是把当前行光标后的第一个数字减1。

/\/Dest
qqnCtrl-xq

上次替换的时候提示替换了175次,由于录制宏的时候已经修改了第一处,所以把宏再执行174次,

174@q

这下就改完了。
pdf的内容已经处理好了,但是注意到epub本身是带目录的,我希望pdf也有书签,给pdf加书签倒是不复杂,用PDFPatcher就可以,epub的目录在toc.ncx里,而PDFPatcher可以导入xml格式的书签,先随便手动加几个书签,导出xml,接下来仍然是一顿正则替换,把toc.ncx处理成对应的格式,导回PDFPatcher,保存最终的pdf文件,这下终于算是处理完了。

最终的成果,书签齐全,内部链接跳转正常,图片质量和原epub一致,文字也都是可复制的。这下pdf可以收藏起来了。什么,看书?谁说找书一定是为了看呢(

4 个赞

高人啊 :+1:

用calibre转pdf会不会更简单?

上传一份到zlib回馈下呗

1 个赞

这么复杂。我有一问:原epub有这些问题么?

我用的SumatraPDF打开排版是乱的(另外一个临时下的阅读器也是),装了calibre的可以试一下是阅读器的问题还是epub文件的问题

好主意,我还从来没想过,我研究一下怎么往zlib上传书
——————
已经上传了,应该24小时之后就可以在zlib上搜到了

下载下来试了下,Sumatra、YACReader、稻壳打开都是偏页、缺失文字,Calibre打开更是除了封面全都看不了
——
但 Calibre Editor 的预览却是正常的…… :joy:

——
更新:
Readest 可以正常显示(虽然刚打开的时候好像一直都没显示,但其后台其实还在载入),根据窗口的大小会自动切换单页还是对开页,不过无法放大缩小,无法滚动,也就是直接锁定了显示模式(适应窗口大小显示)。
Jane Reader 打开后长时间卡住无法操作阅读器窗口(书架窗口不受影响),强制关闭再次打开后载入了一会能看了,但文字是错位的。

其实我更好奇为什么原始的equb是无法正常显示的,但是只需要转换为PDF就好了,
毕竟如果这个文件本身有严重问题让所有阅读器都无法正常显示,那应该转换出的PDF也是存在同样问题的。毕竟转换行为本身就是对文档格式代码的解释和翻译。

更新一下进度:

  • 通过Calibre 阅读器打开确实会出现排版问题
  • 通过Calibre 编辑器打开则一切正常

可以很明显看到,左侧阅读器窗口为缩放的书籍页面,其中的文字距离和大小和右侧编辑器内的原始页面完全一致。所以推测为原始文件的排版CSS部分部分写成绝对位置与大小而不是相对位置,导致如果显示分辨率小于width:1603.51px;height:1932.43px则会因为错误的自动排版导致出错,而转换PDF则会将画面等比缩小解决了这个bug

2 个赞

感谢各位回复解惑,写这个文章主要是做这个pdf花了不少功夫,感觉不分享一下太可惜了 :joy:
其实我用到的方法可能走了很多弯路,也许有其他的工具能更好、更快捷的处理这个问题,但我的理念是如果手上的工具可以解决问题,就尽量不要引入额外的工具,除了wkhtmltopdf是现下的,其他都是我经常用的。
这种想法的来源是因为近年来的工具逐渐向订阅制、基于网络服务的方向发展,相比之下,传统的开源、命令行式的工具更符合我的品味。毕竟能免费解决的事情为什么要花钱呢?能在自己电脑上运行的程序为什么要依赖网络服务呢?也许你的时间可能更值钱,但是折腾本身也是一种乐趣,要不然这里就不是小众软件了。
另外一点就是我对epub这种格式的一些质疑,它实际上具有完整的网页的功能,并不像markdown(虽然markdown其实也可以插入html,这里指的是纯markdown),所以它并不能保证在任何设备上都能有合适的阅读体验,作为电子书,这种格式过于灵活了。
当然epub可以很灵活并不意味着制作epub电子书一定要用到这么复杂的特性,只使用基本的功能也就不会出什么问题了。究其根本,还是排版本身就是一件复杂度很高的事,具体到这本书上,使用绝对坐标定位也是不得以而为之,本质上还是这本书相比epub,更适合使用pdf格式。但pdf也算不上比epub更适合的电子书形式。虽然它能保证排版的稳定性,但也牺牲了自动适应不同屏幕尺寸的优势。
也许以后会有更好的电子书格式,既能保证排版的一致性,又足够灵活,能适应不同的屏幕尺寸吧。

vim也是一种pdf编辑器(逃

1 个赞

那winhex也算(笑

1 个赞

epub推荐论坛内提过的readest,是我见过目前还有人在更新维护的最高的epub阅读器。