文件等值

文件等值

对于两个任意输入文件,确定它们是否会产生相同的编译文档(忽略时间戳信息和外部文件)的最佳方法是什么?

语境

我正在尝试实现一个不平凡的改变LaTeX 代码生成器. 代码库由集成测试:输入具有预期输出的文档。不幸的是,我即将实施的更改是到处摆弄空格(希望只摆弄那些空格!)。我正在寻找一种很好的自动方法来证明(或反驳)空格更改无关紧要。

例子

初始版本

\documentclass{scrartcl}\pagestyle{empty}
\begin{document}

    Hello
    World!

    \begin{verbatim}
    Whitespace  are
    relevant


    here!!!
    \end{verbatim}

\end{document}

无操作修改

\documentclass{scrartcl}
\pagestyle{empty}

\begin{document}
    Hello World!

    \begin{verbatim}
    Whitespace  are
    relevant


    here!!!
    \end{verbatim}
\end{document}

有意义的修改

\documentclass{scrartcl}
\pagestyle{empty}

\begin{document}
    Hello World!

    \begin{verbatim}
    Whitespace are
    relevant

    here!!!
    \end{verbatim}
\end{document}

比较(底部对齐)

点击<>图片之间的链接显示文件的文本差异。

最初的 <> 毫无意义的改变 <> 有意义的改变

问题

那么:实现这种比较的最佳方法是什么?当然,一种可能的解决方案是渲染为 PNG(如https://tex.stackexchange.com/a/55323/8057)删除时间戳信息,例如,pngcrush,并在字节级别进行比较。PDF 时间戳可以用同样的方式删除吗?在 TeX 级别还有其他解决方案吗?

答案1

我们在 latex2e 回归测试套件中所做的(本质上)是添加\showoutput到文档中,然后比较日志文件的相关部分。

2e 测试套件在这里

http://latex-project.org/svnroot/latex2e-public/testfiles/

lvt作为 tex 输入的文件和作为tlg日志文件的文件略微标准化,日期和文件路径被删除,因此结果在所有系统上应该完全相同。

测试中使用的辅助宏是

http://latex-project.org/svnroot/latex2e-public/testfiles/test2e.tex

弗兰克和我写了一篇关于基本机制的拖船文章,或者至少我认为我们写了,无论如何,这是弗兰克的一篇论文:-)

http://www.tug.org/TUGboat/tb18-4/tb57mitt.pdf

答案2

如果您正在寻找某种“观察等效性”,即如果您想直接比较 LaTeX 的输出,我建议您使用 Postscript 而不是 PDF。通过使用以下脚本来编译您想要比较的 LaTeX 文件,您可以强制 Postscript 输出包含相同的文件名信息和相同的创建日期:

#!/bin/bash

TMPDATE=`date +"%a %b %d %X %Y"`
TMPFILE=`mktemp doceq.XXXXXX --suffix=".tex"`

while [ "$1" != "" ]; do
  cp -f "$1" $TMPFILE
  latexmk --quiet -ps $TMPFILE
  TARGET=${1/.tex/.ps}
  cat ${TMPFILE/.tex/.ps}                                  \
    | awk "BEGIN { found = 0; }                            \
           /^%%CreationDate: / {                           \
             if (!found) {                                 \
               printf(\"%%%%CreationDate: $TMPDATE\\n\");  \
               found = 1;                                  \
               next;                                       \
             }                                             \
           }                                               \
           { print; }"                                     \
    > "$TARGET"
  latexmk --quiet -C $TMPFILE
  rm -f $TMPFILE
  shift
done

例如,如果您的三个示例包含在中doceq1.texdoceq2.tex并且doceq3.tex并且./doceq.sh是上面的脚本,那么您将获得以下内容:

$ ./doceq.sh doceq1.tex doceq2.tex doceq3.tex
Latexmk: Run number 1 of rule 'latex'
(snip)
$ diff doceq1.ps doceq2.ps
$ diff doceq1.ps doceq3.ps
802c802
< 405 y Fa(Whitespace)93 b(are)335 518 y(relevant)335 857
---
> 405 y Fa(Whitespace)45 b(are)335 518 y(relevant)335 744

如果您出于某种原因而不得不使用 PDF,那么您可以在那里执行相同的操作,但这会比较棘手,因为 PDF 文件包含您必须跳过的二进制部分。您必须更改的行是以 和 开头的/CreationDate/ModDate

相关内容