我有一个我认为相当合理和常见的问题,但我仍然无法在任何地方找到答案。
我有两个 .tex 文件,我只是想检查是否pdflatex
会生成完全相同的 pdf。
很容易生成两个不同的 .tex 文件,据我所知,它们会给出完全相同的 pdf。试想一下 - 两个具有不同换行符的 .tex 文件 - 一个 .tex 文件执行\newcommand{c1}{c}
并调用 c1,另一个直接调用 c - 一个 .tex 文件执行\input{blabla.tex}
并包含与 c1 完全相同的内容blabla.tex
背景是我有一个包含 tex 文件的存储库。很多时候,我发现自己所做的更改根本不应该更改输出的 pdf(例如上述示例中的更改),但我无法检查。
我已经想到的事情:
- 使用工具直接比较 pdf:理想情况下,我希望事情更加自动化和彻底。
- 使用 latexdiff:我不能使用 perl,而且我再次想要一些更自动化和更彻底的东西。
- 使用 latexand、flatex、flatten 等工具:不行,因为这只会扩展输入/包含。
我发现的一个有趣的线索是 如何防止不同排版的校验和不同 但我无法让它工作。
当然,我不是计算机专家,所以我不太清楚如何准确定义“两个 pdf 完全相同”。我会这样定义:“如果你把它们一个叠在另一个上面,放在明亮的窗户上,它们看起来就像是其中的一个。”
如果重要的话,我正在使用 Win7 和 pdflatex(通过 TeXnicCenter)。
答案1
本着“将纸张举到光线下”的精神,我们可以使用 Python 脚本精确复制此效果。阅读 PDF,然后叠加页面以查看每个像素是否相同。
import wand.image as w
import itertools
import functools
import sys
def load_pages(filename):
""" Load the PDF file into a sequence of bytes, with dimensions """
pdf = w.Image(filename=filename)
for page in pdf.sequence:
image = w.Image(page)
width, height = image.width, image.height
# Copy raw image data into blob string
blob = image.make_blob(format='RGB')
yield (blob, width, height)
def pages_identical(blob1, blob2, width, height):
""" Check (pixel by pixel) if the pages (blobs) are identical """
for c in range(0, width*height*3, 3):
px1 = (blob1[c], blob1[c+1], blob1[c+2])
px2 = (blob2[c], blob2[c+1], blob2[c+2])
if px1 != px2:
return False
return True
def files_identical(filename1, filename2):
""" Check if the two PDF files 'look' the same """
pages1, pages2 = load_pages(filename1), load_pages(filename2)
for pageno, (page1, page2) in enumerate(itertools.zip_longest(pages1, pages2, fillvalue=None)):
if None in {page1, page2}:
print("Files have a different number of pages")
yield False
return # Break out now
(blob1, width1, height1) = page1
(blob2, width2, height2) = page2
if (width1, height1) != (width2, height2):
print("Pages are different sizes!")
yield False
return # Break out now
if pages_identical(blob1, blob2, width1, height1):
yield True
else:
print("Page {} differs".format(pageno))
yield False
fn1 = sys.argv[1]
fn2 = sys.argv[2]
match = functools.reduce(lambda a, b: a and b, files_identical(fn1, fn2), True)
# print(match)
请注意,这需要 ImageMagick 及其 Python 绑定(wand)。
答案2
您可以使用它\tracingoutput
来获取有关 LaTeX 发送给 pdf 的框的信息。这应该可以让您识别出无法通过测试的差异,“如果您将它们一个放在明亮的窗口上,它们看起来就像其中之一”,尽管对边距/纸张大小的更改可能会悄悄地出现。
\documentclass{article}
\tracingoutput=1
\showboxbreadth=1000
\showboxdepth=1000
\def\foo{Hello World}
\def\bar{World Hello}
\begin{document}
%Hello World
%\foo
\bar
\end{document}
运行后,您需要比较日志文件并查找以下方面的差异:
Completed box being shipped out [1]
\vbox(633.0+0.0)x407.0
.\glue 16.0
.\vbox(617.0+0.0)x345.0, shifted 62.0
..\vbox(12.0+0.0)x345.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x345.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(550.0+0.0)x345.0, glue set 539.94232fil
...\write-{}
...\glue(\topskip) 3.05556
...\hbox(6.94444+0.0)x345.0, glue set 277.47212fil
....\hbox(0.0+0.0)x15.0
....\OT1/cmr/m/n/10 H
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 o
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 W
....\kern-0.83334
....\OT1/cmr/m/n/10 o
....\OT1/cmr/m/n/10 r
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 d
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 23.55556
..\hbox(6.44444+0.0)x345.0, glue set 170.0fil
...\glue 0.0 plus 1.0fil
...\OT1/cmr/m/n/10 1
...\glue 0.0 plus 1.0fil
和
Completed box being shipped out [1]
\vbox(633.0+0.0)x407.0
.\glue 16.0
.\vbox(617.0+0.0)x345.0, shifted 62.0
..\vbox(12.0+0.0)x345.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x345.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(550.0+0.0)x345.0, glue set 539.94232fil
...\write-{}
...\glue(\topskip) 3.05556
...\hbox(6.94444+0.0)x345.0, glue set 277.47212fil
....\hbox(0.0+0.0)x15.0
....\OT1/cmr/m/n/10 W
....\kern-0.83334
....\OT1/cmr/m/n/10 o
....\OT1/cmr/m/n/10 r
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 d
....\glue 3.33333 plus 1.66666 minus 1.11111
....\OT1/cmr/m/n/10 H
....\OT1/cmr/m/n/10 e
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 l
....\OT1/cmr/m/n/10 o
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 23.55556
..\hbox(6.44444+0.0)x345.0, glue set 170.0fil
...\glue 0.0 plus 1.0fil
...\OT1/cmr/m/n/10 1
...\glue 0.0 plus 1.0fil
您可以使用简单的方法diff
来查找差异。
答案3
您可以使用程序比较两个 PDF,以显示这些文件之间的差异。我建议使用 DiffPDF(Mark Summerfield 的 2.1.3 版),它有一个“便携”版本(PortableApps.com)。
答案4
对于 reledmac/reledpar 开发工具,我编写了一个 python 脚本,调用 conver 工具来
- 将 pdf 导出为 png
- 比较 png。
它比tracebox方法慢,但我们不能排除一些框具有相同的大小,但内容不同。
脚本在这里https://github.com/maieul/ledmac/blob/master/examples/check-example.py。