继续查看因 TeX Live 升级而出现的变化的最佳方式是什么?,假设我们有两个文件,old.pdf 和 new.pdf,它们来自相同的 LaTeX 源(一篇两栏的论文,字体很小,有一些数学知识和一些图形),但 TeX Live 2020 的安装略有不同。以下是旧文件的一些数据:
$ pdfinfo old.pdf
Title: …
Subject:
Keywords:
Author: …
Creator: LaTeX with hyperref
Producer: pdfTeX-1.40.21
CreationDate: Sat Jan 1 03:21:23 2022 CET
ModDate: Sat Jan 1 03:21:23 2022 CET
Custom Metadata: yes
Metadata Stream: no
Tagged: no
UserProperties: no
Suspects: no
Form: none
JavaScript: no
Pages: 41
Encrypted: no
Page size: 595.276 x 841.89 pts (A4)
Page rot: 0
File size: 873455 bytes
Optimized: no
PDF version: 1.5
根据文件日期和更早的 pdftex 版本以及一些内部知识判断,old.pdf 是由普通的 Debian 或 Ubuntu TeX-Live 发行版(在任何时候都落后于 TUG 的版本)于 2022 年 1 月 1 日生成的。我们不再拥有这些发行版,无法轻易重新生成文件 old.pdf。(一种选择是尝试在某处安装较旧的 Debian 和/或 Ubuntu 版本,这会带来一组全新的问题——即使这样,我们是否能获得与 2022-01-01 相同的 TeX Live 安装和输出也是未知的。有没有地方可以获取最新的 Debian/Ubuntu live,它要么已经有带有 pdfTeX-1.40.21 的普通 TeX Live 包,要么允许安装带有 pdfTeX-1.40.21 的普通 TeX Live 包?)
文件 new.pdf 刚刚使用 TeX Live 2020 final 从相同的旧源生成(其中,遵循 David 的评论,是最后一个包含 pdfTeX-1.40.21 的 TeX Live 版本——如果我们在这里错了,请纠正我们):
$ pdfinfo new.pdf
Title: …
Subject:
Keywords:
Author: …
Creator: LaTeX with hyperref
Producer: pdfTeX-1.40.21
CreationDate: Sun Dec 10 19:54:05 2023 CET
ModDate: Sun Dec 10 19:54:05 2023 CET
Custom Metadata: yes
Metadata Stream: no
Tagged: no
UserProperties: no
Suspects: no
Form: none
JavaScript: no
Pages: 41
Encrypted: no
Page size: 595.276 x 841.89 pts (A4)
Page rot: 0
File size: 1104321 bytes
Optimized: no
PDF version: 1.5
除了日期和文件大小之外,这两部分元数据没有区别。然而,字体有所不同:
$ diff <(pdffonts old.pdf) <(pdffonts new.pdf)
3,60c3,59
< [none] Type 3 Custom yes no no 22 0
< [none] Type 3 Custom yes no no 23 0
< [none] Type 3 Custom yes no no 24 0
< [none] Type 3 Custom yes no no 25 0
< [none] Type 3 Custom yes no no 26 0
< [none] Type 3 Custom yes no no 27 0
< [none] Type 3 Custom yes no no 30 0
< [none] Type 3 Custom yes no no 31 0
< [none] Type 3 Custom yes no no 32 0
< [none] Type 3 Custom yes no no 33 0
< [none] Type 3 Custom yes no no 36 0
< HHFZSL+CMR10 Type 1 Builtin yes yes no 37 0
< AUZFDF+CMMI10 Type 1 Builtin yes yes no 70 0
< CHXOKT+CMSY10 Type 1 Builtin yes yes no 71 0
< EJRJQW+CMR7 Type 1 Builtin yes yes no 72 0
< [none] Type 3 Custom yes no no 74 0
< [none] Type 3 Custom yes no no 75 0
< [none] Type 3 Custom yes no no 76 0
< [none] Type 3 Custom yes no no 78 0
< [none] Type 3 Custom yes no no 113 0
< RQSHZS+CMTT10 Type 1 Builtin yes yes no 230 0
< UFOCKA+BBOLD10 Type 1 Builtin yes yes no 233 0
< WRFUCI+CMTI10 Type 1 Builtin yes yes no 235 0
< SCGGLO+CMMI7 Type 1 Builtin yes yes no 236 0
< [none] Type 3 Custom yes no no 247 0
< CYIPZU+MSAM10 Type 1 Builtin yes yes no 266 0
< NQPTHU+CMEX10 Type 1 Builtin yes yes no 268 0
< BLWZBZ+CMSY7 Type 1 Builtin yes yes no 269 0
< OYQULM+EUFM10 Type 1 Builtin yes yes no 270 0
< HCIFCV+CMR5 Type 1 Builtin yes yes no 271 0
< NLGAUZ+CMSS10 Type 1 Builtin yes yes no 272 0
< LUAFXG+rsfs10 Type 1 Builtin yes yes no 273 0
< HQDOIX+CMMI12 Type 1 Builtin yes yes no 283 0
< ZLOCQH+CMR8 Type 1 Builtin yes yes no 284 0
< LSMQVG+MSBM10 Type 1 Builtin yes yes no 305 0
< SFQIJW+CMSS9 Type 1 Builtin yes yes no 307 0
< ECGVGR+CMR9 Type 1 Builtin yes yes no 308 0
< BHDBNY+CMMI9 Type 1 Builtin yes yes no 309 0
< JIXOQS+CMSY9 Type 1 Builtin yes yes no 312 0
< [none] Type 3 Custom yes no no 332 0
< AUZEEC+TeX-mathb10 Type 1 Builtin yes yes no 377 0
< GZMRBQ+CMSS8 Type 1 Builtin yes yes no 410 0
< BNEURD+stmary10 Type 1 Builtin yes yes no 416 0
< LFVJTS+CMMI8 Type 1 Builtin yes yes no 425 0
< KKQPKP+CMMI5 Type 1 Builtin yes yes no 448 0
< MBBTWW+TeX-mathb7 Type 1 Builtin yes yes no 449 0
< GKIQMS+CMSY5 Type 1 Builtin yes yes no 450 0
< BHHCMF+CMSY8 Type 1 Builtin yes yes no 455 0
< ORHOJI+CMR6 Type 1 Builtin yes yes no 456 0
< [none] Type 3 Custom yes no no 617 0
< IPQGLW+BBOLD7 Type 1 Builtin yes yes no 658 0
< WWCTIW+CMEX7 Type 1 Builtin yes yes no 678 0
< [none] Type 3 Custom yes no no 745 0
< [none] Type 3 Custom yes no no 1013 0
< RRPOFI+MSBM7 Type 1 Builtin yes yes no 1078 0
< RKHRIA+CMEX8 Type 1 Builtin yes yes no 1086 0
< [none] Type 3 Custom yes no no 1135 0
< [none] Type 3 Custom yes no no 1136 0
---
> KYESCI+SFRM1728 Type 1 Custom yes yes no 22 0
> YHWNWE+SFCC1200 Type 1 Custom yes yes no 23 0
> UFXXMG+SFCC0800 Type 1 Custom yes yes no 24 0
> TQJZEA+SFTI0700 Type 1 Custom yes yes no 25 0
> OPFKQH+SFTI0900 Type 1 Custom yes yes no 26 0
> WXDDIU+SFBX0900 Type 1 Custom yes yes no 27 0
> KAKEVM+SFBX1000 Type 1 Custom yes yes no 30 0
> NVPASK+SFCC1000 Type 1 Custom yes yes no 31 0
> GXRPYC+SFRM1000 Type 1 Custom yes yes no 32 0
> URWOJO+SFTI1000 Type 1 Custom yes yes no 35 0
> HHFZSL+CMR10 Type 1 Builtin yes yes no 36 0
> AUZFDF+CMMI10 Type 1 Builtin yes yes no 69 0
> CHXOKT+CMSY10 Type 1 Builtin yes yes no 70 0
> EJRJQW+CMR7 Type 1 Builtin yes yes no 71 0
> CHUDXO+SFRM0700 Type 1 Custom yes yes no 73 0
> GXRPYC+SFRM1000 Type 1 Custom yes yes no 74 0
> ADNPKL+SFRM0600 Type 1 Custom yes yes no 75 0
> LMFIFZ+SFRM0800 Type 1 Custom yes yes no 77 0
> ZYIGPF+SFTT1000 Type 1 Custom yes yes no 112 0
> RQSHZS+CMTT10 Type 1 Builtin yes yes no 229 0
> UFOCKA+BBOLD10 Type 1 Builtin yes yes no 232 0
> WRFUCI+CMTI10 Type 1 Builtin yes yes no 234 0
> SCGGLO+CMMI7 Type 1 Builtin yes yes no 235 0
> RIDLKK+SFRM0900 Type 1 Custom yes yes no 246 0
> CYIPZU+MSAM10 Type 1 Builtin yes yes no 265 0
> NQPTHU+CMEX10 Type 1 Builtin yes yes no 267 0
> BLWZBZ+CMSY7 Type 1 Builtin yes yes no 268 0
> OYQULM+EUFM10 Type 1 Builtin yes yes no 269 0
> HCIFCV+CMR5 Type 1 Builtin yes yes no 270 0
> NLGAUZ+CMSS10 Type 1 Builtin yes yes no 271 0
> LUAFXG+rsfs10 Type 1 Builtin yes yes no 272 0
> HQDOIX+CMMI12 Type 1 Builtin yes yes no 282 0
> ZLOCQH+CMR8 Type 1 Builtin yes yes no 283 0
> LSMQVG+MSBM10 Type 1 Builtin yes yes no 304 0
> SFQIJW+CMSS9 Type 1 Builtin yes yes no 306 0
> ECGVGR+CMR9 Type 1 Builtin yes yes no 307 0
> BHDBNY+CMMI9 Type 1 Builtin yes yes no 308 0
> JIXOQS+CMSY9 Type 1 Builtin yes yes no 311 0
> ECVLCM+SFIT0900 Type 1 Custom yes yes no 331 0
> AUZEEC+TeX-mathb10 Type 1 Builtin yes yes no 376 0
> GZMRBQ+CMSS8 Type 1 Builtin yes yes no 409 0
> BNEURD+stmary10 Type 1 Builtin yes yes no 415 0
> LFVJTS+CMMI8 Type 1 Builtin yes yes no 424 0
> KKQPKP+CMMI5 Type 1 Builtin yes yes no 447 0
> MBBTWW+TeX-mathb7 Type 1 Builtin yes yes no 448 0
> GKIQMS+CMSY5 Type 1 Builtin yes yes no 449 0
> BHHCMF+CMSY8 Type 1 Builtin yes yes no 454 0
> ORHOJI+CMR6 Type 1 Builtin yes yes no 455 0
> QRAQFO+SFTI0800 Type 1 Custom yes yes no 616 0
> IPQGLW+BBOLD7 Type 1 Builtin yes yes no 657 0
> WWCTIW+CMEX7 Type 1 Builtin yes yes no 677 0
> JPVWTM+SFIT1000 Type 1 Custom yes yes no 744 0
> WEZJQK+SFTT0900 Type 1 Custom yes yes no 1012 0
> RRPOFI+MSBM7 Type 1 Builtin yes yes no 1077 0
> RKHRIA+CMEX8 Type 1 Builtin yes yes no 1085 0
> FYOJQA+SFTT0800 Type 1 Custom yes yes no 1134 0
> TBNRHQ+SFSS0800 Type 1 Custom yes yes no 1135 0
让我们把差异缩小一点:
$ diff <(pdffonts old.pdf | sed '1,2d' | cut -c-79 | cut -d '+' -f 2- | sort) <(pdffonts new.pdf | sed '1,2d'| cut -c-79 | cut -d '+' -f 2- | sort)
32,54d31
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
< [none] Type 3 Custom yes no
55a33,54
> SFBX0900 Type 1 Custom yes yes
> SFBX1000 Type 1 Custom yes yes
> SFCC0800 Type 1 Custom yes yes
> SFCC1000 Type 1 Custom yes yes
> SFCC1200 Type 1 Custom yes yes
> SFIT0900 Type 1 Custom yes yes
> SFIT1000 Type 1 Custom yes yes
> SFRM0600 Type 1 Custom yes yes
> SFRM0700 Type 1 Custom yes yes
> SFRM0800 Type 1 Custom yes yes
> SFRM0900 Type 1 Custom yes yes
> SFRM1000 Type 1 Custom yes yes
> SFRM1000 Type 1 Custom yes yes
> SFRM1728 Type 1 Custom yes yes
> SFSS0800 Type 1 Custom yes yes
> SFTI0700 Type 1 Custom yes yes
> SFTI0800 Type 1 Custom yes yes
> SFTI0900 Type 1 Custom yes yes
> SFTI1000 Type 1 Custom yes yes
> SFTT0800 Type 1 Custom yes yes
> SFTT0900 Type 1 Custom yes yes
> SFTT1000 Type 1 Custom yes yes
旧文件混合使用了 Type 1 和 Type 3 字体,而新文件仅使用 Type 1 字体。
尝试比较文本内容会导致一场噩梦,以下是摘录:
$ diff <(pdftotext old.pdf -) <(pdftotext new.pdf -) | head -12298 | tail -39
产量
10571c5813
< abstract interpretation. FPCA, pp. 170181. ACM Press,
---
> abstract interpretation. FPCA, pp. 170–181. ACM Press,
10573c5815
< [70] Jones, N. D. and Muchnik, S. S. (1981) Complexity of ow
---
> [70] Jones, N. D. and Muchnik, S. S. (1981) Complexity of flow
10583c5825
< [72] Perry, D. E., Jeey, R., and Notkin, D. (eds.) (1995)
---
> [72] Perry, D. E., Jeffrey, R., and Notkin, D. (eds.) (1995)
10585c5827
< Seattle, Washington, USA, April 2330, 1995, Proceedings. ACM.
---
> Seattle, Washington, USA, April 23–30, 1995, Proceedings. ACM.
10587c5829
< Softwaretechnik-Trends, .
---
> Softwaretechnik-Trends, 21.
10593c5835
< Université d'Aix-Marseille CNRS, UMR 7279.
---
> Université d’Aix-Marseille — CNRS, UMR 7279.
10597c5839
< Structures in Computer Science, , 329366.
---
> Structures in Computer Science, 14, 329–366.
10601c5843
< Distributed Computing, , 383409.
---
> Distributed Computing, 25, 383–409.
10609,10611c5851,5852
< Proceedings, Lecture Notes in Computer Science,
< ,
< pp. 391407. Springer.
---
> Proceedings, Lecture Notes in Computer Science, 5674,
> pp. 391–407. Springer.
如您所见,与 new.pdf 不同,old.pdf 在文本层中可能没有破折号和连字符(ffi/ff、fl/fl),因此无法手动检查完整的输出:
$ diff <(pdftotext old.pdf -) <(pdftotext new.pdf -) | wc -l
15278
15278 行实在是太多了。该工具差异pdf并没有更好;这是两个文件的第二页并排显示,并且 diffpdf 感知到任何差异的地方,它都会将背景涂成红色:
- 视觉比较使一切变得不同
- 通过字符比较,大多数文本被视为不同的
- 通过词语比较,可以发现大部分文本是不同的
上图,我们为了保护隐私而对图片进行了模糊处理。当我们真正尝试找出内容中的差异时(我们考虑了页面上的第一段),除了 new.pdf 中的字体比 old.pdf 中的字体更平滑之外,我们什么也没发现。不过,我们不确定文档的其余部分。我们显然不希望仅仅为了比较(也许在遥远的未来出于其他目的,但不是为了比较)而重新阅读每个文档的所有页面(这里是 41 页,考虑每个符号、行和空格),看看在 TeX Live 升级时是否有任何更重要的内容(实际字母和数字、参考文献、引文、超链接、表格、图形、数学符号、自绘符号等)发生了变化。
有什么方法可以更好地自动化比较任务吗?我们能否在比较之前均衡一个或两个 PDF 文件中的字体?(顺便说一句,这些 PDF 文件是通过 用 LaTeX 生成的pdflatex
,我们没有旧文件的 Postscript 或 DVI 版本。)或者我们可以pdftotext
在运行 之前修改 的输出diff
?或者我们可以为所用工具提供任何非默认选项,以简化我们的任务?或者,就我们的目的而言,现在的 付费版本diffpdf
是否比免费版本更好?或者是否有任何在线工具擅长此道?
答案1
你不会相信,但是
$ diff <(pdffonts old.pdf | sed '1,2d' | cut -c-79 | cut -d '+' -f 2- | sort) <(pdffonts new.pdf | sed '1,2d'| cut -c-79 | cut -d '+' -f 2- | sort) | grep "> SF" | cut -c3-10 | tr '\n' '|'
SFBX0900|SFBX1000|SFCC0800|SFCC1000|SFCC1200|SFIT0900|SFIT1000|SFRM0600|SFRM0700|SFRM0800|SFRM0900|SFRM1000|SFRM1000|SFRM1728|SFSS0800|SFTI0700|SFTI0800|SFTI0900|SFTI1000|SFTT0800|SFTT0900|SFTT1000|
我们读取输出,并将其用作的参数egrep -iv
,通过以下方式在 LaTeX 文档目录中创建本地文件 mymap.map
$ egrep -vi "SFBX0900|SFBX1000|SFCC0800|SFCC1000|SFCC1200|SFIT0900|SFIT1000|SFRM0600|SFRM0700|SFRM0800|SFRM0900|SFRM1000|SFRM1000|SFRM1728|SFSS0800|SFTI0700|SFTI0800|SFTI0900|SFTI1000|SFTT0800|SFTT0900|SFTT1000" path_to_pdftex.map_from_TeX_Live_2020 > mymap.map
之后我们添加,Ulrike 建议上述内容,
\pdfgentounicode=0
\pdfmapfile{mymap.map}
并使用 TeX Live 2020 重新编译文档。最后,我们运行差异pdf并且观察到任何模式(视觉、字符和文字)均无变化。真是松了一口气!
谢谢@cfr和@Ulrike Fischer为了支持!