[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