mindoc 文档下载二三事

mindoc 的文档,是可以下载的。

mindoc 的作者一直坚持把整个项目作为导出/下载的最小单位,而不是单篇文档,这是我很难接受的状况,事实上,我觉得很反人性。于是在他转换器改变的前后,我都对代码进行了增订,加入可以单篇导出的能力。后一次的修改起手是由一个已经离开团队的兄弟主刀的,里面的代码被我后来 review 的时候改了不少,因为实在是看不下去那种复制粘贴的路子。

下载支持若干种格式,例如 PDF、Word、ePub 甚至 mobi。从 markdown 转换到这些其他的格式,所用的转换器经历过一次大替换,现在的后端转换程序是 Calibre,之前应该是 pandoc 吧,记不清了。当然,首要支持的,必须是 markdown 本身。我修订代码时主要关注于逻辑本身,没想到在一个小地方遗漏了原来代码一直存在的一个 bug。由于 markdown 可能会引用到图片,因此下载时就要把图片和文档 zip 到一起。生成的 zip 文件所处的路径,原代码里设定的访问权限为 0644,然而,这会导致 beego 框架里 BeegoOutput 的 Download 方法失败,看信息是访问被拒绝,改成 0755 就好了。

在上面的调试过程中,还发现当 beego 返回给客户端浏览器的下载文件名里如果有空格的话,会导致 Firefox 只采用第一个空格前的那部分,而 Chrome 浏览器无此问题(均在 Ubuntu 18.04 下操作的)。找了一下资料,原来此问题由来已久。根本原因在于,当服务器组装 HTTP 头中的 Content-Disposition 值的时候,没有在文件名前后添加双引号所致。在 beego 项目的 context/output.go 里的 Download 方法中可以找到代码。鉴于此项目是个框架,我忍住没上手修补。

说回到文件格式转换。新一代使用了 Calibre 的 convertor 的作者是另一位代码贡献者,他从 mindoc 分叉出了叫 bookstack 的项目以及同名站点。Calibre 看上去支持很多种格式转换,但是转换的结果却非常勉强,把一个不是很大的项目生成为 PDF 要花好长时间,最郁闷的是,生成的文件极大,可能是把字体全部嵌进去了,字体的体积占用接近 50MB。这简直是噩梦,即使是在内网。我寻找了一下解决方案,自动化的还没有眉目,需要手工操作的步骤见下,但需要 Adobe Acrobat 的协助。

用 Acrobat 把 PDF 打开,然后在文件菜单里选择导出内嵌式 PostScript,这样的话,这个 PDF 会被分拆为单页的 eps 格式。打开 Acrobat 自带的 Distiller,在界面里把“默认设置”选择设为“最小文件大小”,从文件菜单把刚才生成的所有 eps 文件添加进来,它们都会被自动转换为对应的单页 PDF 文件。最后再用 Acrobat 把这些单页 PDF 合并为一个 PDF。如何才能自动化地做到这些事,依然需要探索。

我注意到 Acrobat 的“优化 PDF”功能有一个“高级优化”,从界面上看是有对嵌入字体的专门处理的,但是操作中发现,此处不会列出文档内实际内嵌的哪怕一种字体。理论上产品不应该存在如此巨大的缺陷,我只能推测 Calibre 生成的 PDF 可能在某些地方对 Acrobat 造成了判断上的干扰,尽管后者的文件成分分析功能能够准确显示出字体部分占据了整个文件体积的 99%+。

另外,尽管我在编译 mindoc 时已经制定了 -w -s 的 ldflags,但是当用十六进制编辑器打开生成的最终可执行文件时,仍然能看到其“密实”程度是非常差的。

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注