ConvertToPDFA omdanner et almindeligt dokument til et arkivdokument i ét kald: det fjerner det, den valgte del forbyder, tilføjer det, delen kræver, angiver den del, dokumentet giver sig ud for at være, og tjekker derefter resultatet. Kravet rapporteres kun som opfyldt, når tjekket bestås, og GetPDFAConversionReport opregner, hvad der blev gjort, og hvad der stadig står i vejen
Den sidste egenskab er den designbeslutning, der er værd at dvæle ved. En konverter, der stempler kravet uden at tjekke, er værre end slet ingen konverter, fordi en fil, der siger, at den er arkivmæssig uden at være det, passerer lige gennem de systemer, der ellers ville have fanget den. Fejlen dukker op flere år senere, i en revision, på et dokument, ingen kan regenerere
Hvorfor fejler en gyldigt udseende PDF et PDF/A-tjek?
Oftest fordi de to steder, en PDF siger, hvem der skrev den, er uenige. En validator læser både dokumentets information-dictionary og XMP-pakken og afviser en fil, hvor de afviger — og de fleste filer, der fejler på dette punkt, havde aldrig fået skrevet XMP-halvdelen overhovedet
RepairDocumentMetadata bringer dem i overensstemmelse og returnerer, hvor mange poster den reparerede. Hvor kun den ene halvdel bærer en værdi, udfyldes den anden fra den, så intet, der allerede er registreret, bliver kasseret. Ingen skal beslutte, hvilken kopi der er autoritativ, for i praksis er den ene kopi tom
Der er en anden reparation i samme kald, der fanger et mere subtilt tilfælde. Et dokument sat i en PDF/A-tilstand får genoprettet sin standard-identifikation, hvis den var gået tabt, hvilket sker, når en kalder leverer en XMP-pakke selv. Uden den identifikation læser en validator filen som en almindelig PDF og rapporterer hver regel i den pågældende del som uopfyldt — en spektakulært udseende fejl med én lille årsag
var
Lib: TPDFlib;
Repaired: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.LoadFromFile('incoming.pdf', '');
Repaired := Lib.RepairDocumentMetadata;
Log(Format('%d metadata entries brought into agreement', [Repaired]));
Lib.SaveToFile('incoming-fixed.pdf');
finally
Lib.Free;
end;
end;
Valg af del før du konverterer
SetPDFAMode og ConvertToPDFA deler samme tal for tilstande, og tre af værdierne er nylige. Tilstand 9 er PDF/A-4, den del der bygger på PDF 2.0. Tilstand 10 er PDF/A-4e, der yderligere tillader 3D og rich media, og tilstand 11 er PDF/A-4f, der tillader en indlejret fil i ethvert format
Del 4 identificerer sig selv anderledes end delene før den: ved del-nummer og det år, dens del blev udgivet, uden noget conformance-bogstav for almindelig PDF/A-4 og med bogstavet E eller F for de to udvidelser. Tjekket genkender del 4, bedømmer dens filer mod PDF 2.0 frem for 1.7, og rapporterer en del 4-fil, der ikke angiver sit revisionsår
Hver indlejret fil i et del 4-dokument angiver, hvordan den relaterer sig til dokumentet, som både del 3 og 4 kræver. Det er den regel, der plejede at fange almindelige vedhæftninger: relationen blev kun skrevet for vedhæftninger efter den første og aldrig for den sidste, så et dokument med en enkelt vedhæftning — det almindelige tilfælde — bar slet ingen og fejlede validering på netop det punkt
var
Verdict: Integer;
begin
Lib.LoadFromFile('report.pdf', '');
Verdict := Lib.ConvertToPDFA(9); // 9 = PDF/A-4, 10 = 4e, 11 = 4f
Memo1.Lines.Text := Lib.GetPDFAConversionReport;
if Verdict = 1 then
Lib.SaveToFile('report-pdfa4.pdf')
else
Log('conversion incomplete - see the report for what stands in the way');
end;
Hvad konverteringsrapporten er til
At beslutte, hvad man gør herefter. En konvertering, der lykkes, behøver ingen rapport; en konvertering, der ikke gør, er hele grunden til, at rapporten findes. Nogle forhindringer kan fjernes af en konverter, og andre kan ikke — kryptering, forbudt indhold, der bærer mening, et skrifttype-program, der simpelthen ikke findes noget sted på maskinen. Rapporten skelner mellem, hvad der blev gjort, og hvad der resterer, hvilket forvandler "konvertering fejlede" til et arbejdspunkt
Behandl dommen som porten i en batch-pipeline. Konverter, læs dommen, og rutér filen: arkivér dem, der bestod, sæt resten i kø til et menneske med rapporten vedhæftet. Hvad du ikke skal gøre, er at gemme outputtet af en mislykket konvertering i arkivet, fordi det ser bedre ud end inputtet — det bærer nu et krav, som tjekket nægtede at bekræfte
Læsning af det mærke, en fil allerede bærer
Før du konverterer noget som helst, så ved, hvad dokumentet siger om sig selv. Et PDF/A-tjek, der ikke kan læse det eksisterende standard-mærke, bedømmer hver fil mod del 1 uanset hvad den erklærer, hvilket betyder, at et perfekt gyldigt PDF/A-2- eller PDF/A-3-dokument rapporteres som om det bærer intet mærke og som værende af for høj en version — det modsatte af sandheden
Mærket læses, uanset om producenten skrev det som et XMP-element eller som en attribut. Begge former er almindelig XMP, og at acceptere kun den ene efterlader filer fra andre producenter tilsyneladende umærkede. Har du nogensinde undret dig over, hvorfor et dokument, der validerer andre steder, fejler i din egen pipeline, er det et godt sted at kigge først
Sanering før arkivering, og den fejl det kan betale sig at kende
Arkivkonvertering og sanering løber ofte sammen, fordi det indhold, en sikkerhedspolitik ønsker fjernet, overlapper kraftigt med det indhold, PDF/A forbyder. SanitizeDocument fjerner JavaScript, og at fjerne det sidste script fjerner også det tomme navnetræ, det efterlader — et træ, der ellers stadig ville fortælle en læser, at dokumentet bar scripts
Den anden halvdel blev lært på den hårde måde: en off-by-one i pakke-listen betød, at sanering rapporterede at fjerne scripts uden at fjerne nogen, så et dokument, der var blevet saneret, stadig kørte sine scripts, når det blev åbnet. Det er et godt argument for det generelle princip, hele denne artikel hviler på — verificér resultatet frem for at stole på operationen, i din egen pipeline lige så meget som i biblioteket
For det omgivende arkivarbejde, se gennemgangene af PDF/A- og PDF/UA-preflight, sand redaktion og indholds-fjernelse, og PDF/A-3 XMP-udvidelsesskemaer til Factur-X, som dækker metadata-siden, når det arkiverede dokument også bærer strukturerede fakturadata
PDFlibPas er et Pascal-baseret PDF-bibliotek til Delphi, C++Builder og Lazarus, så konvertering, reparation og validering sker alt sammen inde i din egen proces uden noget eksternt værktøj i kæden — se PDFlibPas-produktsiden for de understøttede PDF/A-dele og platforme