Če odstranimo opise strani, ostane le tanek sloj strukture, ki je nihče ne tiska, a so od nje odvisni vsi bralniki, iskalniki in arhivski sistemi. Objekt strani ne ve ničesar o poglavju, ki mu pripada, avtorju, ki ga je napisal, ali o opombi pod črto, ki vodi drugam. To znanje se nahaja en nivo višje, v treh strukturah, pripetih na katalog dokumenta: tokovi metapodatkov, drevo zaznamkov (outline tree) in polje opomb (annotations) za vsako stran. Te strukture imajo skupno lastnost, zaradi katere je z njimi enostavno narediti napako. Nobena izmed njih ne ustvarja vidnih sledi na strani, zato se lahko datoteka izriše brezhibno, čeprav ji manjkajo zaznamki, nasprotuje lastnemu polju avtorja ali pa povezavo usmerja na objekt strani, ki ne obstaja več.
To je plast, ki jo knjižnica za PDF izpostavi kot lastnosti dokumenta, vmesnike API za zaznamke ter klice za povezave ali opombe. Hkrati je to plast, ki jo iskalni pajki berejo, ko ugotavljajo, o čem govori vaš dokument. Model objektov pod to plastjo je opisan v podrobnem pregledu strukture dokumentov PDF. Tukaj se bomo osredotočili izključno na to, kar izhaja iz kataloga.
Vse tri strukture so povezane pri katalogu. Celoten katalog, ki jih povezuje, izgleda takole:
1 0 obj
<< /Type /Catalog
/Pages 2 0 R
/Outlines 3 0 R
/Names << /EmbeddedFiles 4 0 R >>
/Metadata 5 0 R
>>
endobj
Štirje vnosi predstavljajo štiri neodvisne podsisteme. /Pages je vidni dokument, /Outlines je drevo zaznamkov, /Metadata kaže na tok XMP, /Names pa doseže dokumentni slovar imen, ki med drugim hrani vgrajene priloge. Vsak vnos je neobvezen in bralnik, ki ne najde nobenega od njih, še vedno prikaže strani. Ta neobveznost je glavni razlog, da se navigacijski sloj najprej poškoduje, ko datoteko urejajo orodja, ki razumejo le strani.
Dve shrambi metapodatkov, ki se ne ujemata
PDF hrani metapodatke dokumenta na dveh mestih hkrati, težave pa se začnejo, ko ta mesta prikazujejo različne podatke. Prvotni mehanizem je slovar informacij o dokumentu (document information dictionary), na katerega kaže vnos /Info v napovedniku: raven nabor parov ključ-vrednost za /Title (naslov), /Author (avtor), /Subject (zadeva), /Keywords (ključne besede), /Creator (ustvarjalec), /Producer (proizvajalec) in dva datuma. Je preprost in bere ga vsak pregledovalnik. Standard PDF 2.0 opušča večino teh polj v korist drugega mehanizma: toka metapodatkov XMP.
XMP je samostojen dokument XML, zapisan v formatu RDF in shranjen kot tok, ki ga katalog doseže prek /Metadata z oznakami /Type /Metadata /Subtype /XML. Za razliko od slovarja Info, ki je skrit v strukturi objektov PDF, je paket XMP zasnovan tako, da ga lahko samostojno izvozijo in razčlenijo orodja, ki o formatu PDF ne vedo ničesar. Tukaj je primer takšnega paketa:
5 0 obj
<< /Type /Metadata /Subtype /XML /Length 1235 >>
stream
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
<dc:title><rdf:Alt><rdf:li xml:lang="x-default">Quarterly Report</rdf:li></rdf:Alt></dc:title>
<dc:creator><rdf:Seq><rdf:li>A. Author</rdf:li></rdf:Seq></dc:creator>
<xmp:CreateDate>2026-06-16T10:46:27+08:00</xmp:CreateDate>
<xmp:CreatorTool>Reporting Service 4.2</xmp:CreatorTool>
<pdf:Producer>losLab PDF Library</pdf:Producer>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
endstream
endobj
Tri podrobnosti v tem bloku določajo, ali bodo metapodatki preživeli stik z orodji. Procesni ukazi xpacket niso le okras: določajo meje paketa, tako da ga orodje za izvoz lahko najde znotraj večjega bajtnega toka. Pisalnik, ki izpusti zaključek <?xpacket end="w"?>, ustvari datoteko, ki se sicer odpre brez težav, a ne prestane strogih preverjanj skladnosti. Pomembni so tudi podatkovni tipi lastnosti. Polje dc:title je jezikovna alternativa, ovita v rdf:Alt, medtem ko je dc:creator urejen seznam, ki zahteva rdf:Seq; izpis obeh kot običajnega besedilnega vozlišča je najpogostejša napaka pri XMP, ki jo večina pregledovalnikov sicer dopušča, dokler ne naletite na tistega, ki je ne. Predpone imenskih prostorov (namespaces) so običajne, vendar so njihovi naslovi URI normativni: parser se orientira po naslovu URI in ne po predponi.
Strogo pravilo dveh shramb je, da se morata ujemati. Če slovar /Info trdi, da je avtor ena oseba, dc:creator pa navaja drugo, pošiljate dokument, ki na isto vprašanje odgovarja na dva različna načina. Kateri odgovor bo prevladal, je odvisno od tega, katero polje prebere orodje prejemnika. Knjižnica običajno zapiše oba dela samodejno, ko pa enega urejate ročno ali združujete datoteke iz različnih generatorjev, se podatka razideta. Slovar Info obravnavajte kot združljivost s starejšimi sistemi, XMP pa kot edini vir resnice. Oba posodobite iz enega nabora vrednosti, namesto da bi ju spreminjali neodvisno. Za format PDF/A je to celo zahteva po skladnosti: standard ISO 19005 predpisuje uporabo XMP in prepoveduje katero koli lastnost Info, ki je v nasprotju s pripadajočo lastnostjo XMP.
Drevo zaznamkov v ozadju plošče z zaznamki
Tisto, kar pregledovalnik prikaže kot ploščo z zaznamki, je v datoteki dvojno povezano drevo slovarjev, imenovano oris dokumenta (document outline). Katalog kaže na korenski slovar orisa prek /Outlines; koren kaže na svoj prvi in zadnji element na najvišji ravni; vsak element pa je povezan s sosednjima elementoma in staršem. Nikjer v datoteki ni polja zaznamkov. Celotna struktura se rekonstruira s sledenjem referencam, kar je razlog, da lahko ena sama prekinjena povezava povzroči izginotje celotne veje zaznamkov brez kakršnega koli opozorila.
8 0 obj % the outline root
<< /Type /Outlines /Count 4 /First 9 0 R /Last 9 0 R >>
endobj
9 0 obj % top-level: a chapter
<< /Title (Chapter 1: Results)
/Parent 8 0 R /Count 2
/First 12 0 R /Last 15 0 R >>
endobj
12 0 obj % first child
<< /Title (Introduction)
/Parent 9 0 R /Next 15 0 R
/Dest [3 0 R /XYZ 72 720 0] >>
endobj
15 0 obj % second child, last sibling
<< /Title (Methodology)
/Parent 9 0 R /Prev 12 0 R
/Dest [3 0 R /Fit] >>
endobj
Če preberemo povezave, postanejo pravila jasna. Vsak element kaže nazaj na svoj starševski element /Parent. Sosednji elementi (sorodniki) tvorijo verigo prek povezav /Prev (prejšnji) in /Next (naslednji), pri čemer prvi element nima povezave /Prev, zadnji pa nima povezave /Next. Starš poimenuje svojega prvega in zadnjega otroka prek /First in /Last, vsi vmesni otroci pa so dosegljivi le s prehajanjem verige sosednjih elementov. Ena sama napaka povzroči tiho odpoved: napačna povezava /Next odreže preostanek poglavja, starševski element, katerega povezava /Last ne zaključi verige, pa pusti otroke brez povezave, pregledovalnik pa izriše le tisto, kar lahko doseže.
Polje /Count vsebuje stanje, ki marsikoga preseneti. Na korenskem vozlišču in na vseh razširjenih elementih določa število trenutno vidnih potomcev; na zaprtih (strnjenih) elementih pa je to negativno število, katerega absolutna vrednost pove, koliko potomcev bi se prikazalo ob razširitvi. Polje /Count torej ni fiksna strukturna lastnost drevesa, temveč shranjeno stanje odprtosti ali zaprtosti veje. Generator, ki to trdo kodira kot pozitivno vrednost, bo odprl vse veje, ki jih je avtor želil pustiti zaprte.
Vsak element dobi svoj namen s kazanjem na določeno ciljno točko. Polje /Title določa besedilo, ki se prikaže v plošči, vnos /Dest pa cilj, kamor klik vodi. Cilj (destination) je lahko določen neposredno v elementu (kot zgoraj) ali pa z imenom, ki se razreši prek slovarja imen dokumenta. Slednje je boljša izbira, ko več zaznamkov in povezav kaže na isto mesto, saj lahko ob premiku cilja popravek izvedete na enem mestu. Knjižnica običajno skrije to drevo za korenskim objektom orisa in metodami za dodajanje otrok; v knjižnici HotPDF dokument izpostavi lastnost OutlineRoot tipa THPDFDocOutlineObject in samodejno poveže /Prev, /Next, /Parent in /Count povezave, ko dodajate elemente. To je izjemno koristno, saj je ročno vzdrževanje teh pravil med urejanjem glavni razlog za napake v zaznamkih.
Ciljne točke: pravila določanja cilja klika
Tako zaznamki kot povezave kažejo na cilje (destinations), cilj pa je več kot le številka strani. To je polje, ki poimenuje objekt strani in nato z operacijo v drugem mestu določi, kako naj jo pregledovalnik prikaže. Najpogostejša in tudi najbolj napačno uporabljena je nastavitev /XYZ v obliki [page /XYZ left top zoom]. Njeni trije operandi so neodvisni in kateri koli je lahko null, kar pomeni "ohrani trenutno nastavitev pregledovalnika". Zapis [page /XYZ null null null] skoči na stran, ne da bi spremenil položaj drsenja ali povečave, kar je običajno želeno obnašanje povezav. Številke so v privzetem uporabniškem prostoru, merjene od spodaj levo navzgor, kar je enak koordinatni sistem, kot ga uporablja vsebina strani. Avtorji, ki izhajajo iz spletnega oblikovanja zaslonov, koordinate pogosto merijo od vrha navzdol in bralca pošljejo na napačen del strani.
Družina nastavitev /Fit zamenja natančno določanje položaja za večjo prilagodljivost. Zapis [page /Fit] prilagodi celotno stran oknu, [page /FitH top] prilagodi širino strani glede na podan zgornji rob, [page /FitR l b r t] pa poveča določen pravokotnik, da zapolni pogled. Ker te nastavitve računajo povečavo na podlagi geometrije strani in ne fiksnih koordinat, cilj /Fit deluje pravilno tudi po spremembi velikosti strani, medtem ko lahko fiksna povečava /XYZ uporabnika pusti pred praznim robom strani. Za kazalo vsebine se /FitH z zgornjo koordinato razdelka obnese veliko bolje kot fiksna vrednost /XYZ z ugibano povečavo.
Opombe (Annotations): vse interaktivno, kar ni vsebina strani
Opomba (annotation) je objekt, ki prekriva stran, ne da bi bil del njenega toka vsebine. Povezave, lepljive opombe, označevanja, obrazci, ikone prilog, štampiljke: vse to so opombe, navedene v polju /Annots tiste strani, na kateri se nahajajo. Če opombo odstranite iz tega polja, jo odstranite s strani, čeprav vsebina pod njo ostane nedotaknjena. To je bistvo: opombe so plast za urejanje, ločena od same vsebine strani.
Vsaka opomba si deli osnovno strukturo. Vnos /Subtype določa vrsto opombe, vnos /Rect določa njen okvir v koordinatah strani, vnos /Contents pa hrani besedilo, ki služi kot opis za dostopnost. Povezave (link annotations) so najboljši primer za preučevanje, saj se pojavljajo v dveh oblikah: kot samostojen cilj in kot akcija.
12 0 obj % link to a destination
<< /Type /Annot /Subtype /Link
/Rect [100 200 300 250]
/Border [0 0 0]
/Dest [5 0 R /XYZ null null null] >>
endobj
13 0 obj % link that runs an action
<< /Type /Annot /Subtype /Link
/Rect [50 50 200 100]
/Border [0 0 0]
/A << /Type /Action /S /URI /URI (https://www.example.com) >> >>
endobj
Polje /Rect določa klikljivo območje; klik nanj usmeri bralca na cilj po enakih pravilih, kot jih uporabljajo zaznamki. Vnos /Border [0 0 0] opravi pomembno delo, saj odstrani privzeto obrobo, ki jo pregledovalniki sicer narišejo okoli povezav. Druga oblika zamenja cilj /Dest z akcijo /A, kjer vnos /S določa vrsto obnašanja: /GoTo znotraj te datoteke, /GoToR za zunanjo datoteko, /URI za spletni naslov in /Launch za zagon zunanjega programa. Zadnji ukaz je varnostno tvegan, saj zagon izvedljive datoteke predstavlja pot za okužbo z zlonamerno kodo. Zato skladni bralniki to preprečijo ali pa prikažejo opozorilo, povezava pa pri večini bralnikov ne bo delovala. Uporabljajte le ukaza /URI in /GoTo, ukazom /Launch pa se izogibajte.
Označevalne opombe, kot so označevanja besedila in lepljivi listki, ter geometrijske opombe, kot je /Square, prinašajo dodatno težavo: njihov izgled na zaslonu ni vnaprej določen z njihovo vrsto. Pregledovalnik izriše svojo različico, razen če izgled zaklenete s tokom izgleda (appearance stream) v polju /AP, ki se sklicuje na objekt XObject z operaterji za risanje. Če to izpustite, se lahko isto označevanje v dveh bralnikih ali po shranjevanju prikaže različno. Za vse elemente, kjer je natančen izgled pomemben del dokumenta, zagotovite vnos /AP. Priloge (file attachments) prav tako uporabljajo enak mehanizem: vgrajen tok datoteke in slovar specifikacije datoteke, ki se prikaže kot opomba /FileAttachment ali pa se razreši prek drevesa imen /EmbeddedFiles pod vnosom /Names v katalogu.
Kje se ta plast poškoduje in kako to zaznati
Najpogostejša napaka pri vseh teh strukturah je neveljaven sklic (dangling reference). Zaznamki izginejo, če katalog nima vnosa /Outlines ali pa se veriga sosednjih elementov prekine sredi drevesa. Metapodatki so prezrti, če toku XMP manjka oznaka /Type /Metadata /Subtype /XML ali pa je struktura xpacket poškodovana. V vseh teh primerih je vsebina strani nepoškodovana, zato je hiter pregled videti ustrezen, napaka pa se pokaže šele na plošči, ki je ni nihče preveril.
Večino napak lahko preprečite z dvema preprostima navadama. Končano datoteko odprite v pregledovalniku in preklikajte ploščo z zaznamki ter nekaj povezav, kar preizkusi graf sklicev na enak način, kot to počne bralnik. Nato z ločenim orodjem preberite metapodatke in potrdite, da se slovar Info in XMP ujemata, saj tega neskladja s klikanjem ne boste odkrili. Generiranje te plasti prek knjižnice, ki sama upravlja sklice povezav, odpravi večino teh pasti. Knjižnica HotPDF Component za Delphi in C++Builder izpostavlja strukture orisov, opomb in metapodatkov prek vmesnikov API na ravni dokumenta, tako da preprosto opišete hierarhijo zaznamkov in povezav, knjižnica pa sama poveže sklice. Za model objektov, na katerega so te strukture pripete, si preberite tehnični pregled zgradbe datotek PDF, ki opisuje katalog in tabelo navzkrižnih sklicev, od katerih so te strukture odvisne.