Files
mmd-pdf/validation/QpdfSweep.ps1
kua-agent 6610acfa44 feat: rebrand to MMD PDF, single corporate theme, and remove original text under an edit
- Services/PdfRedactText.cs: strip text whose origin falls inside a CoverAnnotation
  from the page content stream at save time, hooked into PdfBurn.DrawAnnotationsIntoDoc.
  Fixes edited values staying recoverable by text extraction.
- Themes/MMD.xaml replaces all thirteen themes; picker and accent strip removed; no dark mode.
- Rename KillerPDF -> MMD PDF across code, resources, packaging and locale strings; new icon.
- Remove the upstream author credit and the in-app install button.
2026-08-27 07:37:09 +02:00

86 lines
3.3 KiB
PowerShell

<#
.SYNOPSIS
qpdf structural sweep: runs `qpdf --check` on every original/resave pair and flags any
file whose exit code worsened.
.DESCRIPTION
The second half of the release validation (Compare-VeraPDF.ps1 is the first). Reads the
resave log written by `MmdPdf.exe --batch-resave` and checks only the rows marked OK -
skipped files were never written and have nothing to compare.
qpdf exit codes: 0 = clean, 2 = errors, 3 = warnings only. "Worsened" is any pair whose
after-code is higher than its before-code. The release bar is zero worsened.
.\QpdfSweep.ps1 -Corpus C:\pdf-corpus -Resaved C:\pdf-corpus-resaved `
-ResaveLog ..\resave.csv -CsvOut qpdf-results.csv
Exit code 0 = no worsened pairs, 1 = worsened pairs found, 2 = usage/input error.
.NOTES
Compatible with Windows PowerShell 5.1 and PowerShell 7.
Part of the MmdPdf validation harness (validation/).
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)] [string]$Corpus,
[Parameter(Mandatory = $true)] [string]$Resaved,
[Parameter(Mandatory = $true)] [string]$ResaveLog,
[Parameter(Mandatory = $true)] [string]$CsvOut
)
$ErrorActionPreference = 'Stop'
if (-not (Get-Command qpdf -ErrorAction SilentlyContinue)) { Write-Error 'qpdf not on PATH'; exit 2 }
if (-not (Test-Path -LiteralPath $ResaveLog)) { Write-Error "Resave log not found: $ResaveLog"; exit 2 }
function Get-QpdfCheckCode {
param([string]$Path)
# qpdf writes ordinary exit-3 warnings to stderr. Under Windows PowerShell, redirecting
# native stderr while ErrorActionPreference is Stop turns that expected diagnostic into a
# terminating NativeCommandError before the sweep can record the exit code.
$oldPreference = $ErrorActionPreference
try {
$ErrorActionPreference = 'Continue'
& qpdf --check $Path *> $null
return $LASTEXITCODE
} finally {
$ErrorActionPreference = $oldPreference
}
}
$rows = Import-Csv -LiteralPath $ResaveLog | Where-Object { $_.Status -eq 'OK' }
$results = New-Object System.Collections.Generic.List[object]
$i = 0
foreach ($r in $rows) {
$i++
if ($i % 100 -eq 0) { Write-Host ("{0} / {1}" -f $i, $rows.Count) }
$o = Join-Path $Corpus $r.File
$n = Join-Path $Resaved $r.File
if (-not (Test-Path -LiteralPath $n)) {
$results.Add([pscustomobject]@{ File = $r.File; Before = -1; After = -1; Worsened = 'MISSING' })
continue
}
$b = Get-QpdfCheckCode $o
$a = Get-QpdfCheckCode $n
$results.Add([pscustomobject]@{ File = $r.File; Before = $b; After = $a; Worsened = ($a -gt $b) })
}
$results | Export-Csv -LiteralPath $CsvOut -NoTypeInformation -Encoding UTF8
Write-Host ''
Write-Host ('Pairs checked : {0}' -f $results.Count)
$results | Group-Object { '{0} -> {1}' -f $_.Before, $_.After } | Sort-Object Count -Descending |
ForEach-Object { Write-Host (' {0,-10} {1}' -f $_.Name, $_.Count) }
$worse = @($results | Where-Object { $_.Worsened -eq $true -or $_.Worsened -eq 'MISSING' })
Write-Host ('Worsened : {0}' -f $worse.Count)
if ($worse.Count -gt 0) {
Write-Host 'RESULT: FAIL - structural health worsened on at least one file.' -ForegroundColor Red
exit 1
} else {
Write-Host 'RESULT: PASS - no file''s structural health got worse.' -ForegroundColor Green
exit 0
}