PDF/A i PDF/UA odgovaraju na dva pitanja koja nemaju nikakve veze jedno s drugim, a njihovo tretiranje kao jedinstvenog okvira za provjeru pristupačnosti i arhiviranja razlog je zašto neispravne datoteke stižu u arhivu noseći oznaku sukladnosti. PDF/A se pita hoće li se datoteka vjerno iscrtavati za dvadeset godina. PDF/UA se pita može li je pomoćna tehnologija čitati danas. Dokument može proći jedno, a pasti na drugom, pa jedina poštena presuda dolazi od pokretanja oba testa, i to prije nego što se datoteka zapiše, a ne nakon što nizvodni sustav povjeruje identifikatoru sukladnosti ugrađenom u njegove metapodatke. Taj identifikator je vlastita deklaracija. Ništa u formatu ne zahtijeva da on bude istinit, a aplikacija koja piše "PDF/A-1b" u XMP bez provjere prema standardu proizvodi datoteku koja izgleda usklađeno svakom potrošaču koji čita samo oznaku. losLab PDF Library (PDFlibPas) zatvara taj jaz za Delphi i C++Builder ugrađivanjem oba validatora u knjižnicu, tako da se provjera izvodi unutar procesa bez potrebe za postavljanjem vanjske usluge.
Dva standarda koja odbijaju datoteke iz suprotnih razloga
ISO 19005 (PDF/A) je ugovor o reprodukciji. Usklađena datoteka mora se iscrtavati identično desetljećima od sada na softveru koji nikada nije vidio sustav koji ju je proizveo, pa pravila napadaju vanjske ovisnosti: svaki font mora biti ugrađen, boja usidrena na ugrađeni ICC OutputIntent ili izražena u prostoru neovisnom o uređaju, nema šifriranja u PDF/A-1, no JavaScripta, a XMP metapodaci moraju se slagati s rječnikom informacija o dokumentu. ISO 14289 (PDF/UA) je umjesto toga ugovor o semantici. Pomoćna tehnologija mora proći kroz dokument i izvući značenje, koje živi u potpuno drugom sloju: kompletno stablo strukture, alternativni tekst na slikama, naslov dokumenta postavljen za prikaz, razine naslova koje ne preskaču korake, odnosi zaglavlja tablice koji preživljavaju nakon što se stranica makne sa zaslona.
Budući da ova dva standarda nadziru različite slojeve, datoteke koje vas najviše muče su one koje sjede između njih. Dokument savršen za arhivu može biti potpuno nijem za čitač zaslona. Prekrasno označen dokument može upućivati na font s radne površine koji neće postojati za deset godina. Izdavaštvo u javnom sektoru je uobičajeno mjesto gdje oba zahtjeva dolaze odjednom, a cjevovod tamo ih ne može spojiti u jedinstvena vrata. Nalazi idu različitim ljudima. Neugrađeni fontovi su nedostatak u kodu koji generira PDF, dok nedostajući alternativni tekst pripada onome tko posjeduje predloške sadržaja, a izvješće koje miješa to dvoje jednostavno se prosljeđuje dvaput.
Koji dio PDF/A ciljate važno je jednako kao i to hoćete li ga pogoditi. PDF/A-1 je zamrznut na PDF-u 1.4 i odbacuje prozirnost i JPEG2000, za kojima moderni izvještaji posežu bez razmišljanja. PDF/A-2 (ISO 19005-2, izgrađen na ISO 32000-1) prihvaća oboje i razumna je zadana postavka za novu arhivu. PDF/A-3 ide dalje i dopušta ugrađene datoteke bilo koje vrste, na što se oslanjaju regulirani formati e-računa. Tim koji se u 2026. godini još uvijek standardizira na PDF/A-1b obično nosi zahtjev koji je netko napisao prije petnaest godina, a ponovno pregovaranje o ciljnom dijelu često je jeftinije od uklanjanja prozirnosti iz svakog grafikona koji sustav emitira.
Strukturirani nalazi u vrijeme unosa
Polazište ravnog API-ja je CheckFileCompliance, s selektorom testa 1 za PDF/A i 2 za PDF/UA. Vraća ručku popisa nizova čije su stavke pojedinačni nalazi, jedna po liniji, što je upravo oblik kroz koji automatizirani sustav želi prolaziti:
function GateArchiveUpload(Pdf: TPDFlib; const FileName: string): Boolean;
var
ListId, I: Integer;
begin
ListId := Pdf.CheckFileCompliance(FileName, '', 1, 0); // 1 = PDF/A
if ListId = 0 then
begin
// 0 means "no findings" OR "file unreadable" -- disambiguate before passing
Result := Pdf.LastErrorCode = 0;
Exit;
end;
for I := 0 to Pdf.GetStringListCount(ListId) - 1 do
LogFinding(FileName, Pdf.GetStringListItem(ListId, I));
Pdf.ReleaseStringList(ListId);
Result := False;
end;
Dva detalja odlučuju hoće li ovo raditi bez nadzora. Prvi je povratna vrijednost koja znači dvije suprotne stvari. CheckFileCompliance vraća 0 kada je datoteka potpuno usklađena, a također i kada se datoteka uopće nije mogla otvoriti, jer se interno prazan popis rezultata svodi na 0 u oba slučaja. Sustav koji čita 0 kao prolaz propustit će oštećene prijenose ravno u arhivu, stoga razlučite situaciju s LastErrorCode prije nego što povjerujete nuli, kao što to radi gornji sustav. Drugi se detalj odnosi na to gdje se datoteka nalazi u svom životnom vijeku. Provjera radi na čitaču strujanja knjižnice umjesto na punom modelu dokumenta, otvarajući datoteku izravno s dijeljenjem čitanja i nikada ne pozivajući LoadFromFile, zbog čega može proći kroz ulaz od više gigabajta bez izgradnje stabla objekata. To isto otvaranje strujanja ne uspijeva dok drugi proces još uvijek drži datoteku za pisanje, a prijenos u tijeku je upravo to stanje. Postavite provjeru nakon završetka prijenosa.
Dizajn strujanja se isplati pod opterećenjem. Svaka provjera otvara svoj ulaz samo za čitanje i dijeli ga za čitanje, pa se revizija skupa dokumenata skalira kroz radne dretve ili procese s jednom instancom TPDFlib po radniku i bez sukoba između njih. Resurs koji zahtijeva disciplinu je sama ručka. Svaki ne-nulti rezultat iz CheckFileCompliance ostaje dodijeljen sve dok ne pozovete ReleaseStringList, a sustav koji dugo radi i zaboravi ih osloboditi ne ruši se, već samo polako gubi memoriju dok netko ne krene tražiti uzrok.
Izvješća za ljude, razlike za sustave izgradnje
Popis nalaza je pravi oblik za sustav provjere, a pogrešan oblik za e-poštu poslanu timu za predloške. CreatePreflightReport prikazuje istu analizu kao čitljiv tekst, CreatePreflightReportEx dodaje selektor formata izvješća, a SavePreflightReport je zapisuje na disk kako bi izvješće moglo putovati unutar isporučenog paketa dokumenata. Mnogi arhivski ugovori čine to izvješće isporukom samom za sebe, a ne samo internim artefaktom.
Član ove obitelji koji tiho zarađuje svoje mjesto je ComparePreflightReports. Usklađenost je površina regresije kao i bilo koji drugi dio ponašanja. Prilagodba predloška, novi licencirani korporativni font ili nadogradnja knjižnice mogu uvesti nalaz koji nije bio prisutan u prošlom izdanju, a nijedan od njih se ne najavljuje sam. Držite referentna (golden) izvješća za skup reprezentativnih dokumenata pod kontrolom verzija, ponovno ih generirajte nakon svake promjene i pokrenite ComparePreflightReports za izračun razlike. Prazna razlika je artefakt izdanja koji vrijedi čuvati. Neočekivani nalaz ruši izgradnju, što je daleko jeftinije mjesto za njegovo otkrivanje od same revizije.
Generiranje izlaza koji prolazi pri prvom pokretanju
Prethodna provjera zarađuje svoju plaću na datotekama koje dolaze s drugih mjesta. Za dokumente koje proizvodi vaš vlastiti kôd, pronalaženje kršenja nakon generiranja i njihovo naknadno krpanje je sporiji put. PDFlibPas nosi način rada na strani generiranja za svaki standard, a oba možete uključiti za isti dokument:
var
Pdf: TPDFlib;
Diag: WideString;
begin
Pdf := TPDFlib.Create;
try
Pdf.NewDocument;
Pdf.SetPDFAMode(1);
Pdf.LoadOutputIntentProfile('sRGB-IEC61966-2.1.icc', 'RGB');
Pdf.SetPDFUAMode('en-US');
Pdf.SetInformation(1, 'Quarterly Statement'); // /Title: required for PDF/UA
// ... draw tagged content here ...
Diag := Pdf.GetPDFUADiagnostics;
if Diag <> '' then
Writeln('fix before shipping: ', Diag);
Pdf.SaveToFile('statement.pdf');
// the preflight that counts runs on the saved file:
Writeln(Pdf.CreatePreflightReport('statement.pdf', '', 1, 0));
finally
Pdf.Free;
end;
end;
Zamka se skriva u vrijeme spremanja. Nekoliko popravaka usklađenosti događa se dok se dokument serijalizira, a ne kada omogućite način rada: prisiljavanje zastavice ispisa na bilješkama, pisanje zadanog AFRelationship-a za PDF/A-3 ugrađene datoteke, normalizacija redoslijeda tabulatora i opisa polja obrazaca za PDF/UA. Dokument koji sjedi u memoriji nije bajt-identičan onome koji slijeće na disk, pa je jedina presuda o prethodoj provjeri koja išta znači ona izračunata iz spremljene datoteke. Validaciju izvršite na samoj datoteci statement.pdf. Nemojte zaključivati o usklađenosti na temelju objekta koji je još u memoriji, jer bajtovi koje biste procjenjivali nisu bajtovi koje ste isporučili.
Scenariji računa koji nose strojno čitljiv XML uz vizualni dokument slijede uzorak ZUGFeRD i Factur-X, koji je izgrađen na PDF/A-3. Oni bi trebali eksplicitno postaviti odnos privitka s SetPDFA3DefaultAFRelationship, budući da ISO 19005-3 zahtijeva da svaka ugrađena datoteka deklarira svoju ulogu u odnosu na dokument. Ostavite to nepostavljenim i ugrađeni XML bit će samo komad podataka bez navedene svrhe, što validator primjećuje.
Neovisni suci: veraPDF i Acrobat
Proizvođač ne bi trebao biti jedini sudac vlastitog izlaza. PDFlibPas provjere daju vam brze, strukturirane presude unutar procesa, što je ono što želite na vrućoj stazi, ali vrata za izdanje arhivske serije ipak bi trebala provesti izlaz kroz validator koji nitko iz vašeg tima nije napisao. veraPDF je zajednički održavana referentna implementacija za PDF/A i alat koji većina arhiva navodi u svojim kriterijima prihvaćanja, tako da je on onaj s kojim se treba uskladiti. Acrobatovi profili prethodne provjere čine korisnog suca za izjednačenje kada se veraPDF i in-process provjera ne slažu. Zapišite naziv validatora i njegovu verziju uz svako pohranjeno izvješće. Tvrdnja da je datoteka prošla veraPDF govori vrlo malo bez broja verzije (build) koji ju je propustio, budući da alat pooštrava svoja pravila između izdanja.
Validatori se doista ne slažu na rubovima standarda, a kada se to dogodi, rješenje nije odabrati alat koji vam se sviđa. Smanjite datoteku na minimalni uzorak koji još uvijek pokreće neslaganje i pročitajte ga u odnosu na tekst standarda. Sat vremena toga obično na površinu iznese jednu od dviju stvari: stvarni bug u alatu koji vrijedi prijaviti uzvodno ili klauzulu koju je vaš tim pogrešno tumačio i koju bi trebao zapisati u bilješke o usklađenosti kako je sljedeća osoba ne bi ponovno sporila.
Šifrirani ulaz dobiva prečac. Obje provjere primaju argument lozinke, ali PDF/A-1 datoteka s rječnikom šifriranja već je nesukladna, jer ISO 19005-1 izričito zabranjuje šifriranje, pa se šifrirani unos može odbiti prije nego što se pokrene bilo kakva dublja analiza. Otkrivanje onoga što rječnik šifriranja zapravo dopušta je zadatak za sebe, pokriven u reviziji PDF šifriranja i dopuštenja.
Nalazi za PDF/UA gotovo uvijek se prate natrag do načina na koji je stablo strukture prvotno kreirano, a tehnike označavanja koje stoje iza toga žive u izgradnji označenih PDF stabala strukture u Delphiju. Arhivi koji također zahtijevaju digitalne potpise trebali bi upariti ova vrata s tijekom rada u PAdES potpisivanju i validaciji. Cjelovita referenca preflight API-ja nalazi se na stranici proizvoda losLab PDF Library za Delphi.