[latex3-commits] [git/LaTeX3-latex3-l3build] master: Use a text-based approach to PDF comparison (64825da)

Joseph Wright joseph.wright at morningstar2.co.uk
Tue Jul 31 10:09:23 CEST 2018


Repository : https://github.com/latex3/l3build
On branch  : master
Link       : https://github.com/latex3/l3build/commit/64825daddadcc72af7a5c212adfcad971da3e12e

>---------------------------------------------------------------

commit 64825daddadcc72af7a5c212adfcad971da3e12e
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Tue Jul 31 09:09:11 2018 +0100

    Use a text-based approach to PDF  comparison
    
    See issue #10 and issue #61) for discussions.
    
    This first pass only strips out a minimal amount of data:
    more normalization may well be needed.


>---------------------------------------------------------------

64825daddadcc72af7a5c212adfcad971da3e12e
 l3build-check.lua                          |  115 ++++++++++++----------
 l3build-file-functions.lua                 |    4 -
 l3build-variables.lua                      |    3 +-
 l3build.dtx                                |   31 +++++-
 testfiles/{00-test-1.lvt => 00-test-2.pvt} |    0
 testfiles/00-test-2.tpf                    |  146 ++++++++++++++++++++++++++++
 6 files changed, 241 insertions(+), 58 deletions(-)

diff --git a/l3build-check.lua b/l3build-check.lua
index d2af793..2fc01e7 100644
--- a/l3build-check.lua
+++ b/l3build-check.lua
@@ -482,6 +482,31 @@ local function formatlualog(logfile, newfile, luatex)
   close(newfile)
 end
 
+local function normalise_pdf(pdffile,npdffile)
+  local file = assert(open(pdffile, "rb"))
+  local contents = gsub(file:read("*all") .. "\n", "\r\n", "\n")
+  close(file)
+  local newcontent = ""
+  local skip = false
+  for line in gmatch(contents, "([^\n]*)\n") do
+    if skip then
+      if match(line,"endstream") then
+        skip = false
+        line = ""
+      end
+    elseif match(line,"currentfile eexec") then
+      skip = true
+    end
+    if not match(line, "^ *$") and not skip then
+      newcontent = newcontent .. line .. os_newline
+    end
+  end 
+  local newfile = open(npdffile, "w")
+  output(newfile)
+  write(newcontent)
+  close(newfile)
+end
+
 -- Run one test which may have multiple engine-dependent comparisons
 -- Should create a difference file for each failed test
 function runcheck(name, hide)
@@ -531,33 +556,28 @@ end
 
 function setup_check(name, engine)
   local testname = name .. "." .. engine
-  local pdffile = locate(
-    {testfiledir, unpackdir},
-    {testname .. pdfext, name .. pdfext}
-  )
   local tlgfile = locate(
     {testfiledir, unpackdir},
     {testname .. tlgext, name .. tlgext}
   )
+  local tpffile = locate(
+    {testfiledir, unpackdir},
+    {testname .. tpfext, name .. tpfext}
+  )
   -- Attempt to generate missing reference file from expectation
-  if not (pdffile or tlgfile) then
+  if not (tlgfile or tpffile) then
     if not locate({unpackdir, testfiledir}, {name .. lveext}) then
       print(
-        "Error: failed to find " .. pdfext .. ", " .. tlgext .. " or "
+        "Error: failed to find " .. tlgext .. ", " .. tlpext .. " or "
           .. lveext .. " file for " .. name .. "!"
       )
       exit(1)
     end
     runtest(name, engine, true, lveext, true, false)
-    pdffile = testdir .. "/" .. testname .. pdfext
-    -- If a PDF is generated use it for comparisons
-    if not fileexists(pdffile) then
-      pdffile = nil
-      ren(testdir, testname .. logext, testname .. tlgext)
-    end
+    ren(testdir, testname .. logext, testname .. tlgext)
   else
     -- Install comparison files found
-    for _,v in pairs({pdffile, tlgfile}) do
+    for _,v in pairs({tlgfile, tpffile}) do
       if v then
         cp(
           match(v, ".*/(.*)"),
@@ -567,33 +587,21 @@ function setup_check(name, engine)
       end
     end
   end
-  if pdffile then
-    local pdffile = match(pdffile, ".*/(.*)")
-    ren(
-      testdir,
-      pdffile,
-      gsub(pdffile, pdfext .. "$", ".ref" .. pdfext)
-    )
-  end
 end
 
-function compare_pdf(name, engine)
+function compare_pdf(name,engine,cleanup)
   local errorlevel
   local testname = name .. "." .. engine
-  local cmpfile    = testdir .. "/" .. testname .. os_cmpext
-  local pdffile    = testdir .. "/" .. name .. pdfext
-  local refpdffile = locate(
-    {testdir}, {testname .. ".ref" .. pdfext, name .. ".ref" .. pdfext}
-  )
-  if not refpdffile then
-    return
+  local difffile = testdir .. "/" .. name .. os_diffext
+  local pdffile  = testdir .. "/" .. testname .. pdfext
+  local tpffile  = testdir .. "/" .. name .. tpfext
+  if not tpffile then
+    return 1
   end
-  errorlevel = execute(
-    os_cmpexe .. " " .. normalize_path(refpdffile)
-      .. " " .. pdffile .. " > " .. cmpfile
-  )
-  if errorlevel == 0 then
-    remove(cmpfile)
+  errorlevel = execute(os_diffexe .. " "
+    .. normalize_path(tpffile .. " " .. pdffile .. " > " .. difffile))
+  if errorlevel == 0 or cleanup then
+    remove(difffile)
   end
   return errorlevel
 end
@@ -691,6 +699,8 @@ function runtest(name, engine, hide, ext, pdfmode, breakout)
   end
   local logfile = testdir .. "/" .. name .. logext
   local newfile = testdir .. "/" .. name .. "." .. engine .. logext
+  local pdffile = testdir .. "/" .. name .. pdfext
+  local npffile = testdir .. "/" .. name .. "." .. engine .. pdfext
   local asciiopt = ""
   for _,i in ipairs(asciiengines) do
     if realengine == i then
@@ -726,16 +736,27 @@ function runtest(name, engine, hide, ext, pdfmode, breakout)
     )
     -- Break the loop if the result is stable
     if breakout and i < checkruns then
-      formatlog(logfile, newfile, engine, errlevels)
-      if compare_tlg(name,engine,true) == 0 then
-        break
+      if pdfmode then
+        normalise_pdf(pdffile,npffile)
+        if compare_pdf(name,engine,true) == 0 then
+          break
+        end
+      else
+        formatlog(logfile, newfile, engine, errlevels)
+        if compare_tlg(name,engine,true) == 0 then
+          break
+        end
       end
     end
   end
   if pdfmode and fileexists(testdir .. "/" .. name .. dviext) then
     dvitopdf(name, testdir, engine, hide)
   end
-  formatlog(logfile, newfile, engine, errlevels)
+  if pdfmode then
+    normalise_pdf(pdffile,npffile)
+  else
+    formatlog(logfile, newfile, engine, errlevels)
+  end
   -- Store secondary files for this engine
   for _,filetype in pairs(auxfiles) do
     for _,file in pairs(filelist(testdir, filetype)) do
@@ -865,9 +886,6 @@ function checkdiff()
   for _,i in ipairs(filelist(testdir, "*" .. os_diffext)) do
     print("  - " .. testdir .. "/" .. i)
   end
-  for _,i in ipairs(filelist(testdir, "*" .. os_cmpext)) do
-    print("  - " .. testdir .. "/" .. i)
-  end
   print("")
 end
 
@@ -883,9 +901,6 @@ function showfaileddiff()
     print(content)
     print("-----------------------------------------------------------------------------------")
   end
-  for _,i in ipairs(filelist(testdir, "*" .. os_cmpext)) do
-    print("  - " .. testdir .. "/" .. i)
-  end
 end
 
 function save(names)
@@ -908,11 +923,13 @@ function save(names)
               .. " file overrides unpacked version of the same name")
           end
         else
-          -- Create one or more reference .pdf files
-          print("Creating and copying " .. pdfext)
-          local pdffile  = name .. pdfext
+          -- Create one .tpf file
+          print("Creating and copying " .. tpfext)
+          local tpffile  = name .. tpfext
+          local newfile  = name .. "." .. engine .. pdfext
           runtest(name,engine,false,pvtext,true)
-          cp(pdffile,testdir,testfiledir)
+          ren(testdir,newfile,tpffile)
+          cp(tpffile,testdir,testfiledir)
         end
         return 0
       end
diff --git a/l3build-file-functions.lua b/l3build-file-functions.lua
index 83b4bfb..34ff927 100644
--- a/l3build-file-functions.lua
+++ b/l3build-file-functions.lua
@@ -130,8 +130,6 @@ os_setenv  = "export"
 os_yes     = "printf 'y\\n%.0s' {1..200}"
 
 os_ascii   = "echo \"\""
-os_cmpexe  = getenv("cmpexe") or "cmp"
-os_cmpext  = getenv("cmpext") or ".cmp"
 os_diffext = getenv("diffext") or ".diff"
 os_diffexe = getenv("diffexe") or "diff -c --strip-trailing-cr"
 os_grepexe = "grep"
@@ -139,8 +137,6 @@ os_newline = "\n"
 
 if os_type == "windows" then
   os_ascii   = "@echo."
-  os_cmpexe  = getenv("cmpexe") or "fc /b"
-  os_cmpext  = getenv("cmpext") or ".cmp"
   os_concat  = "&"
   os_diffext = getenv("diffext") or ".fc"
   os_diffexe = getenv("diffexe") or "fc /n"
diff --git a/l3build-variables.lua b/l3build-variables.lua
index 1321535..5a56c5a 100644
--- a/l3build-variables.lua
+++ b/l3build-variables.lua
@@ -172,9 +172,10 @@ logext = logext or ".log"
 lveext = lveext or ".lve"
 lvtext = lvtext or ".lvt"
 pdfext = pdfext or ".pdf"
-pvtext = pvtext or ".pvt"
 psext  = psext  or ".ps"
+pvtext = pvtext or ".pvt"
 tlgext = tlgext or ".tlg"
+tpfext = tpfext or ".tpf"
 
 -- Manifest options
 manifestfile = manifestfile or "MANIFEST.md"
diff --git a/l3build.dtx b/l3build.dtx
index c7dab0d..46074e8 100644
--- a/l3build.dtx
+++ b/l3build.dtx
@@ -104,6 +104,7 @@
 \luavarset{dviext}{".dvi"}{Extension of DVI files}
 \luavarset{lvtext}{".lvt"}{Extension of log-based test files}
 \luavarset{tlgext}{".tlg"}{Extension of test file output}
+\luavarset{tpfext}{".tpf"}{Extension of PDF-based test output}
 \luavarset{lveext}{".lve"}{Extension of auto-generating test file output}
 \luavarset{logext}{".log"}{Extension of checking output, before processing it into a \texttt{.tlg}}
 \luavarset{pvtext}{".pvt"}{Extension of PDF-based test files}
@@ -1100,12 +1101,15 @@
 %
 % In most cases, testing is best handled by using the text-based methods
 % outlined above. However, there are cases where the detail of output structure
-% is important. This can only be fully tested by comparing PDF files on a binary
-% level. To support this, \pkg{l3build} can be instructed to build and compare
-% PDF files by setting up tests in \texttt{.pvt} files.
+% is important. This can only be fully tested by comparing PDF structure.
+% To support this, \pkg{l3build} can be instructed to build and compare
+% PDF files by setting up tests in \texttt{.pvt} files. The resulting
+% \texttt{.tpf} output is a digested form of the PDF, which can be compared
+% as text.
 %
 % Testing on the result of typesetting \texttt{.pvt} files is carried out using
-% only the standard engine, as PDFs are not identical between individual engines.
+% only the standard engine, as aspects of PDF files are not indentical between
+% engines.
 %
 % \section{Release-focussed features}
 %
@@ -1905,6 +1909,25 @@
 \fi
 %    \end{macrocode}
 %
+% Disable compression in PDF output.
+%    \begin{macrocode}
+\ifnum 0%
+  \ifx\pdfoutput\@undefined\else\ifnum\pdfoutput>0 1\fi\fi
+  \ifx\outputmode\@undefined\else\ifnum\outputmode>0 1\fi\fi
+  >0 %
+  \ifx\pdfvariable\@undefined
+    \pdfcompresslevel=0 %
+    \pdfobjcompresslevel=0 %
+  \else
+    \pdfvariable compresslevel=0 %
+    \pdfvariable objcompresslevel=0 %
+  \fi
+\else
+  \special{dvipdfmx:config z 0}% Compress level
+  \special{dvipdfmx:config C 0x40}% Object compression
+\fi
+%    \end{macrocode}
+%
 % Finish up.
 %    \begin{macrocode}
 \reset at catcodes
diff --git a/testfiles/00-test-1.lvt b/testfiles/00-test-2.pvt
similarity index 100%
copy from testfiles/00-test-1.lvt
copy to testfiles/00-test-2.pvt
diff --git a/testfiles/00-test-2.tpf b/testfiles/00-test-2.tpf
new file mode 100644
index 0000000..2eecdb4
--- /dev/null
+++ b/testfiles/00-test-2.tpf
@@ -0,0 +1,146 @@
+%PDF-1.5
+%ÐÔÅØ
+3 0 obj
+<<
+/Length 73        
+>>
+stream
+BT
+/F15 9.9626 Tf 92.921 759.927 Td [(#$%&)]TJ 0 -23.91 Td [(#$%&)]TJ
+ET
+endstream
+endobj
+2 0 obj
+<<
+/Type /Page
+/Contents 3 0 R
+/Resources 1 0 R
+/MediaBox [0 0 595.276 841.89]
+/Parent 5 0 R
+>>
+endobj
+1 0 obj
+<<
+/Font << /F15 4 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+6 0 obj
+[525 525 525 525]
+endobj
+7 0 obj
+<<
+/Length1 1438
+/Length2 7042
+/Length3 0
+/Length 8480      
+>>
+stream
+%!PS-AdobeFont-1.0: CMTT10 003.002
+%%Title: CMTT10
+%Version: 003.002
+%%CreationDate: Mon Jul 13 16:17:00 2009
+%%Creator: David M. Jones
+%Copyright: Copyright (c) 1997, 2009 American Mathematical Society
+%Copyright: (<http://www.ams.org>), with Reserved Font Name CMTT10.
+% This Font Software is licensed under the SIL Open Font License, Version 1.1.
+% This license is in the accompanying file OFL.txt, and is also
+% available with a FAQ at: http://scripts.sil.org/OFL.
+%%EndComments
+FontDirectory/CMTT10 known{/CMTT10 findfont dup/UniqueID known{dup
+/UniqueID get 5000832 eq exch/FontType get 1 eq and}{pop false}ifelse
+{save true}{false}ifelse}{false}ifelse
+11 dict begin
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0 ]readonly def
+/FontName /TZCMOM+CMTT10 def
+/FontBBox {-4 -233 537 696 }readonly def
+/PaintType 0 def
+/FontInfo 9 dict dup begin
+/version (003.002) readonly def
+/Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050<http://www.ams.org>\051, with Reserved Font Name CMTT10.) readonly def
+/FullName (CMTT10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle 0 def
+/isFixedPitch true def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 38 /ampersand put
+dup 36 /dollar put
+dup 35 /numbersign put
+dup 37 /percent put
+readonly def
+currentdict end
+endobj
+8 0 obj
+<<
+/Type /FontDescriptor
+/FontName /TZCMOM+CMTT10
+/Flags 4
+/FontBBox [-4 -233 537 696]
+/Ascent 611
+/CapHeight 611
+/Descent -222
+/ItalicAngle 0
+/StemV 69
+/XHeight 431
+/CharSet (/ampersand/dollar/numbersign/percent)
+/FontFile 7 0 R
+>>
+endobj
+4 0 obj
+<<
+/Type /Font
+/Subtype /Type1
+/BaseFont /TZCMOM+CMTT10
+/FontDescriptor 8 0 R
+/FirstChar 35
+/LastChar 38
+/Widths 6 0 R
+>>
+endobj
+5 0 obj
+<<
+/Type /Pages
+/Count 1
+/Kids [2 0 R]
+>>
+endobj
+9 0 obj
+<<
+/Type /Catalog
+/Pages 5 0 R
+>>
+endobj
+10 0 obj
+<<
+/Producer (pdfTeX)
+/Creator (TeX)
+/Trapped /False
+>>
+endobj
+xref
+0 11
+0000000000 65535 f 
+0000000257 00000 n 
+0000000146 00000 n 
+0000000015 00000 n 
+0000009183 00000 n 
+0000009320 00000 n 
+0000000325 00000 n 
+0000000358 00000 n 
+0000008935 00000 n 
+0000009377 00000 n 
+0000009426 00000 n 
+trailer
+<< /Size 11
+/Root 9 0 R
+/Info 10 0 R
+ >>
+startxref
+9498
+%%EOF





More information about the latex3-commits mailing list