PDFlibPas pripne vgrajeno datoteko eni konkretni strani namesto dokumentu kot celoti, tako da v slovar strani zapiše polje /AF, medtem ko vsebina sama ostane prijavljena v imenskem drevesu EmbeddedFiles dokumenta. To ločnico opisuje ISO 32000-2 §14.13 in prav ona bralniku omogoči odgovoriti na vprašanje, ki ga priloga na ravni dokumenta ne more: kateri stran pripadajo ti podatki
Primeri uporabe so bolj specifični kot splošne priloge. Poročilo meritve, kjer vsaka stran nosi surove merilne vrste za svojim grafikonom. Skenirana serija, kjer vsaka stran hrani rezultat OCR, iz katerega je nastal njen besedilni sloj. Zbirka risb, kjer vsak list nosi CAD izvleček, iz katerega je bil izrisan. V vsakem od teh primerov bi bil seznam prilog na ravni dokumenta kup datotek, katerih imena kodirajo številke strani — to je konvencija, ne struktura
En sam tovor, dve točki sklica
Pomembna strukturna točka je, da povezava na ravni strani ne ustvari drugega izvoda česa koli. Datoteka je vgrajena enkrat in prijavljena v imenskem drevesu EmbeddedFiles natanko tako kot priloga na ravni dokumenta, z istim mehanizmom specifikacije datoteke. Razlika je le v tem, kam se zapiše sklic in njegov ključ razmerja: v slovar strani namesto v katalog dokumenta
Sledita dve posledici. Prva: bralnik, ki pozna le priloge na ravni dokumenta, vsebino vseeno najde, ker je v imenskem drevesu, kjer tak bralnik išče. Druga: brisanje povezave na ravni strani odstrani vez, ne datoteke. ClearPageAssociatedFiles odpeti stran od njenih povezanih datotek in pusti tovor dosegljiv skozi imensko drevo, kar je konzervativno vedenje: operacija, ki pravi odstrani povezavo, ne sme tiho uničiti podatkov, na katere se lahko sklicuje drug del dokumenta
Ta funkcija ima en namerno ozek pogoj uspeha, vreden pozornosti. Uspeh sporoči le, ko je stran dejansko nosila ključ /AF. Stran, ki nikoli ni imela povezav, vrne napako in ne veselo potrdilo, tako da klicatelj ne more no-op zamenjati za opravljeno čiščenje
var
Lib: TPDFlib;
Idx, I: Integer;
begin
Lib := TPDFlib.Create(nil);
try
Lib.LoadFromFile('survey-report.pdf');
// Pripni merilne vrste, ki so izdelale grafikon na strani 3
Idx := Lib.AddPageAssociatedFileFromFile(3,
'series-03.csv', // datoteka na disku
'measurements.csv', // prikazano ime znotraj PDF
'text/csv', // vrsta MIME
'Raw measurement series for figure 3',
'Data'); // AFRelationship, ISO 32000-2 14.13
if Idx < 0 then
raise Exception.Create('page association refused');
for I := 0 to Lib.GetPageAssociatedFileCount(3) - 1 do
Writeln('page 3 associated file, embedded index ',
Lib.GetPageAssociatedFileEmbeddedIndex(3, I));
Lib.SaveToFile('survey-report-with-data.pdf');
finally
Lib.Free;
end;
end;
Niz razmerja v praksi ni prosto besedilo. ISO 32000-2 definira besedišče — Source, Data, Alternative, Supplement, EncryptedPayload, FormData, Schema in Unspecified — in potrošniki se opirajo nanj. Data za številke za grafikonom, Source za dokument, iz katerega je stran nastala, Alternative za enakovredno predstavitev. Izberite iz besedišča, tudi ko ga v vašem cevovodu še nič ne bere, ker ga bo morda naslednje orodje v verigi
Zakaj isto iskanje potrebuje FollowRef v obeh smereh?
Ker sledenje sklicev odgovarja na dve različni vprašanji in mora koda vedeti, katero si zastavlja. Iskanje po ključu, ki sledi indirektnim sklicem, vrne objekt, na katerega sklic kaže. Iskanje, ki ne sledi, vrne sam sklic. Oboje je pravilno, uporaba napačnega pa proizvede tiho napačno vedenje namesto napake
Branje povezane datoteke prikaže prvo smer. Za pridobitev številke objekta vgrajenega toka za ključema specifikacije datoteke /EF in /F iskanje ne sme slediti, ker sledenje razreši sklic v objekt toka in številka objekta je izgubljena. Pravilo se posplošuje: vsaka kodna pot, ki potrebuje identiteto objekta in ne vsebine, mora vzeti surovi sklic
Izbirna vsebina (optional content) kaže nasprotno smer in stala je več iskanja. Slovar lastnosti izbirne vsebnosti se v katalog zapiše kot indirektni objekt, zato koda, ki ga prebere brez sledenja, dobi sklic namesto slovarja. Preverjanje tipa na tej vrednosti potem odpove, zažene se naravna veja rezerve — če konfiguracije ni, jo ustvari — in prepiše konfiguracijo, ki je bila že tam. Nič ne javi napake. Sloji, opisani v skupinah izbirne vsebnosti in slojih, preprosto izgubijo svoje privzeto stanje vidnosti
Pouk gre čez oba primera. Kadar iskanje lahko vrne sklic ali objekt, golo preverjanje tipa ni ravnanje z napakami: je veja, ki bo sčasoma začeta iz napačnega razloga. Odločite se izrecno, kaj potrebuje vsako mesto klica, in rajši izberite javni API, ki vprašanje odgovori neposredno — na primer lastnost štetja izbirne vsebnosti — kot da bi segli v zaščiten dostopovalec do katalogovega slovarja
// Priloge na ravni dokumenta in povezave na ravni strani sobivajo. Tudi
// vgrajena datoteka je lahko označena kot povezana na ravni dokumenta
if Lib.IsEmbeddedFileAssociated(0) = 0 then
Lib.SetEmbeddedFileAssociated(0, 1, 'Supplement');
Writeln('document associated files: ', Lib.GetAssociatedFileCount);
Writeln('page 3 associated files : ',
Lib.GetPageAssociatedFileCount(3));
// Brisanje odveže vez strani; vsebina ostane v imenskem drevesu
if Lib.ClearPageAssociatedFiles(3) > 0 then
Writeln('page 3 associations removed, payloads still reachable');
Kaj profilni načini skladnosti naredijo s prilogami
Arhivski profili omejujejo, kaj sme biti vgrajeno, in omejitev se uveljavi na vstopni točki, ne ob shranjevanju. PDF/A-1 vgrajene datoteke popolnoma prepove, PDF/A-2 dovoli le vgrajene dokumente PDF/A, PDF/A-3 pa je profil, ki je vgrajevanje odprlo za poljubne vrste datotek — natanko zato nanj gradijo hibridni računski formati
PDFlibPas zavrne prilogo, ko aktivni način skladnosti tega ne dopušča — ob klicu, ne stotine operacij kasneje med izhodom. To je odločitev o mestu, kjer je z napako najceneje ravnati: zavrnitev na mestu klica poimenuje datoteko, ki ste jo dodajali, zavrnitev ob shranjevanju pa poimenuje dokument in vas pusti ugotavljati, katera od štiridesetih prilog jo je povzročila
Zato se povezane datoteke v elektronskem izstavljanju računov pojavljajo tako pogosto. Hibridni račun je PDF, ki ga prebere človek, z nanj pritrjenim strojno berljivim tovorem XML, označenim s pravim razmerjem, in tako profil vsebnika kot ključ razmerja sta del specifikacije, ne konvenciji. Ta izgradnja je obravnavana v gradnji hibridnih računov Factur-X in ZUGFeRD, stran metapodatkov pa v shemi razširitev XMP za PDF/A-3
Kdaj naj bo povezava na stran, ne na dokument?
Takrat, ko potrošnik potrebuje vedeti, kateri stran podatki pripadajo — in samo takrat. Priloge na ravni dokumenta so preprostejše, širše podprte s strani pregledovalnikov in zadostne, kadar tovor opisuje celoten dokument: XML računa, manifest podpisa, arhiv virov. Po povezavi na ravni strani posežite, ko je tovor resnično vezan na stran in je identiteta strani del njegovega pomena
Podpora je praktična omejitev. Povezane datoteke na ravni strani so konstrukcija PDF 2.0, podpora pregledovalnikov pa je bolj skromna kot za priloge na ravni dokumenta. Ker tovor v vsakem primeru sede v imenskem drevesu, pregledovalnik, ki ignorira /AF na straneh, datoteko vseeno pokaže v seznamu prilog, tako da upadanje poteka milostno. Če pa je vez na stran za vašega potrošnika bistvena in ne le uporaben metapodatek, preverite bralnik, ki ga dejansko ciljate, namesto da bi sklepali
Povezane datoteke na ravni strani, priloge na ravni dokumenta in arhivski profilni prehodi, ki upravljajo oboje, so del PDFlibPas Delphi PDF library. Če med sprejemanjem hkrati tudi popravljate starejše datoteke, je delo z metapodatki in skladnostjo v pretvorbi v PDF/A s popravilom metapodatkov tisto, ki odloči, katera od teh poti prilog vam je sploh na voljo