Τεχνικό Άρθρο

Μεταδεδομένα, σελιδοδείκτες και σχολιάσεις PDF

Αφαιρέστε τις περιγραφές των σελίδων και σας μένει ένα λεπτό στρώμα δομής που κανείς δεν εκτυπώνει, αλλά από το οποίο εξαρτάται κάθε πρόγραμμα ανάγνωσης, κάθε ευρετηριαστής και κάθε σύστημα αρχειοθέτησης. Ένα αντικείμενο σελίδας δεν ξέρει τίποτα για το κεφάλαιο στο οποίο ανήκει, για τον συγγραφέα που το έγραψε ή για την υποσημείωση που οδηγεί αλλού. Αυτή η γνώση ζει ένα επίπεδο ψηλότερα, σε τρεις δομές προσαρτημένες στον κατάλογο του εγγράφου: τις ροές μεταδεδομένων, το δέντρο διάρθρωσης και τους πίνακες σχολιάσεων κάθε σελίδας. Μοιράζονται ένα χαρακτηριστικό που τις κάνει εύκολο να πάνε στραβά. Καμιά τους δεν αφήνει ορατά σημάδια στη σελίδα, οπότε ένα αρχείο μπορεί να αποδίδεται τέλεια και να του λείπουν οι σελιδοδείκτες, να αντιφάσκει με το ίδιο του το πεδίο συγγραφέα ή να στρέφει έναν σύνδεσμο σε αντικείμενο σελίδας που δεν υπάρχει πια

Αυτό είναι το στρώμα που μια βιβλιοθήκη PDF εκθέτει ως ιδιότητες εγγράφου, API σελιδοδεικτών και κλήσεις συνδέσμων ή σχολιάσεων, και το στρώμα που διαβάζει ένας ανιχνευτής αναζήτησης για να αποφασίσει με τι καταπιάνεται το έγγραφό σας. Το μοντέλο αντικειμένων από κάτω καλύπτεται στην αναλυτική παρουσίαση της δομής εγγράφου PDF. Εδώ η εστίαση είναι αυστηρά σε ό,τι κρέμεται από τον κατάλογο

Διάγραμμα PDF ενός καταλόγου εγγράφου PDF που συνδέεται με το δέντρο σελίδων, τη ρίζα διάρθρωσης, το λεξικό ονομάτων και τη ροή μεταδεδομένων XMP ως τέσσερα προαιρετικά υποσυστήματα
Ο κατάλογος του εγγράφου συνδέει τέσσερα ανεξάρτητα υποσυστήματα, καθένα προσβάσιμο μέσα από τη δική του καταχώριση. Οποιοδήποτε από αυτά μπορεί να λείπει και οι σελίδες να αποδίδονται κανονικά

Και οι τρεις δομές προσαρτώνται στον κατάλογο. Ένας πλήρης κατάλογος που τις συνδέει μεταξύ τους μοιάζει έτσι:

1 0 obj
<< /Type /Catalog
   /Pages 2 0 R
   /Outlines 3 0 R
   /Names << /EmbeddedFiles 4 0 R >>
   /Metadata 5 0 R
>>
endobj

Τέσσερις καταχωρίσεις, τέσσερα ανεξάρτητα υποσυστήματα. Το /Pages είναι το ορατό έγγραφο· το /Outlines είναι το δέντρο των σελιδοδεικτών· το /Metadata δείχνει στη ροή XMP· το /Names φτάνει στο λεξικό ονομάτων ολόκληρου του εγγράφου, το οποίο μεταξύ άλλων κρατά τα ενσωματωμένα συνημμένα αρχεία. Καθένα είναι προαιρετικό, και ένα πρόγραμμα ανάγνωσης που δεν βρίσκει κανένα από αυτά εξακολουθεί να δείχνει τις σελίδες. Ακριβώς αυτή η προαιρετικότητα είναι ο λόγος που το στρώμα πλοήγησης είναι το πρώτο που σαπίζει όταν ένα αρχείο επεξεργάζεται από εργαλεία που καταλαβαίνουν μόνο σελίδες

Δύο αποθήκες μεταδεδομένων που διαφωνούν

Το PDF κουβαλά μεταδεδομένα εγγράφου σε δύο σημεία ταυτόχρονα, και τα προβλήματα αρχίζουν όταν λένε διαφορετικά πράγματα. Ο αρχικός μηχανισμός είναι το λεξικό πληροφοριών εγγράφου, στο οποίο αναφέρεται το /Info μέσα στο τρέιλερ: ένα επίπεδο σύνολο ζευγών κλειδιού-τιμής για τα /Title, /Author, /Subject, /Keywords, /Creator, /Producer και τις δύο ημερομηνίες. Είναι απλό και το διαβάζει κάθε πρόγραμμα προβολής. Το PDF 2.0 το καταργεί σε μεγάλο βαθμό υπέρ του δεύτερου μηχανισμού, της ροής μεταδεδομένων XMP

Διάγραμμα PDF που συγκρίνει το λεξικό Info του PDF με τη ροή μεταδεδομένων XMP, δύο αποθήκες με επικαλυπτόμενα πεδία που πρέπει να μένουν συγχρονισμένες, με το XMP ως πηγή αλήθειας
Το λεξικό Info και η ροή XMP απαντούν παράλληλα στις ίδιες ερωτήσεις. Κρατήστε τα συγχρονισμένα παράγοντας ξανά και τα δύο από ένα ενιαίο σύνολο τιμών

Το XMP είναι ένα αυτοτελές έγγραφο XML, γραμμένο σε RDF, αποθηκευμένο ως ροή στην οποία ο κατάλογος φτάνει μέσω του /Metadata και σημασμένο με /Type /Metadata /Subtype /XML. Σε αντίθεση με το λεξικό Info που είναι θαμμένο μέσα στη δομή αντικειμένων του PDF, ένα πακέτο XMP σχεδιάστηκε για να εξάγεται και να αναλύεται αυτόνομα από εργαλεία που δεν ξέρουν τίποτα για PDF. Ακολουθεί ένα αντιπροσωπευτικό πακέτο:

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

Τρεις λεπτομέρειες μέσα σε εκείνο το μπλοκ καθορίζουν αν τα μεταδεδομένα θα επιβιώσουν στην επαφή με πραγματικά εργαλεία. Οι οδηγίες επεξεργασίας xpacket δεν είναι διακόσμηση: πλαισιώνουν το πακέτο ώστε ένας εξαγωγέας να το βρίσκει μέσα σε μια μεγαλύτερη ροή byte, και ένας συγγραφέας που παραλείπει το τελικό <?xpacket end="w"?> παράγει αρχείο που ανοίγει κανονικά αλλά σκοντάφτει στους αυστηρούς επικυρωτές. Έχουν σημασία και οι τύποι δεδομένων των ιδιοτήτων. Το dc:title είναι γλωσσική εναλλακτική τυλιγμένη σε rdf:Alt, ενώ το dc:creator είναι διατεταγμένη λίστα και παίρνει rdf:Seq· η εκπομπή οποιουδήποτε από τα δύο ως γυμνού κόμβου κειμένου είναι το πιο συχνό λάθος XMP, ανεκτό από τα περισσότερα προγράμματα προβολής μέχρι εκείνο που δεν το ανέχεται. Τα προθέματα χώρων ονομάτων είναι συμβατικά, αλλά τα URI στα οποία δεσμεύονται είναι κανονιστικά: ένας αναλυτής κλειδώνει πάνω στο URI, όχι στο πρόθεμα

Ο σκληρός κανόνας με δύο αποθήκες είναι ότι πρέπει να συμφωνούν. Αν το /Info λέει ότι συγγραφέας είναι ένα πρόσωπο και το dc:creator ονομάζει άλλο, έχετε παραδώσει έγγραφο που απαντά στην ίδια ερώτηση με δύο τρόπους, και ποια απάντηση κερδίζει εξαρτάται από το ποιο πεδίο διαβάζει το εργαλείο που το καταναλώνει. Μια βιβλιοθήκη συνήθως γράφει και τα δύο για λογαριασμό σας, αλλά μόλις επεξεργαστείτε το ένα στο χέρι ή συγχωνεύσετε αρχεία από διαφορετικές γεννήτριες, τα δύο αποκλίνουν. Αντιμετωπίστε το λεξικό Info ως συμβατότητα με το παρελθόν και το XMP ως πηγή αλήθειας, και παραγάγετε ξανά και τα δύο από ένα ενιαίο σύνολο τιμών αντί να τα μπαλώνετε ανεξάρτητα. Για το PDF/A αυτό γίνεται απαίτηση συμμόρφωσης: το ISO 19005 επιβάλλει XMP και απαγορεύει οποιαδήποτε ιδιότητα Info αντιφάσκει με το αντίστοιχό της στο XMP

Το δέντρο διάρθρωσης πίσω από τον πίνακα σελιδοδεικτών

Αυτό που ένα πρόγραμμα προβολής δείχνει ως πίνακα σελιδοδεικτών είναι, μέσα στο αρχείο, ένα διπλά συνδεδεμένο δέντρο λεξικών που ονομάζεται διάρθρωση του εγγράφου. Ο κατάλογος δείχνει σε ένα ριζικό λεξικό διάρθρωσης μέσω του /Outlines· η ρίζα δείχνει στο πρώτο και στο τελευταίο στοιχείο ανώτατου επιπέδου· και κάθε στοιχείο είναι δεμένο με τους γείτονές του και με τον γονέα του. Δεν υπάρχει πουθενά πίνακας με σελιδοδείκτες. Ολόκληρη η δομή ανασυγκροτείται ακολουθώντας αναφορές, και ακριβώς γι' αυτό ένας μόνο σπασμένος σύνδεσμος μπορεί να εξαφανίσει έναν ολόκληρο κλάδο από τον πίνακα χωρίς κανένα σφάλμα

Διάγραμμα PDF του δέντρου διάρθρωσης PDF που δείχνει τους συνδέσμους Parent, First, Last, Prev, Next και Count οι οποίοι ανασυγκροτούν τον πίνακα σελιδοδεικτών του προγράμματος προβολής
Ο πίνακας σελιδοδεικτών ξαναχτίζεται από ένα διπλά συνδεδεμένο δέντρο διάρθρωσης δεμένο με Parent, First, Last, Prev, Next και Count. Ένας ξεπερασμένος σύνδεσμος κρύβει ολόκληρο κλάδο χωρίς σφάλμα
8 0 obj                                    % η ρίζα της διάρθρωσης
<< /Type /Outlines /Count 4 /First 9 0 R /Last 9 0 R >>
endobj
9 0 obj                                    % ανώτατο επίπεδο: ένα κεφάλαιο
<< /Title (Chapter 1: Results)
   /Parent 8 0 R /Count 2
   /First 12 0 R /Last 15 0 R >>
endobj
12 0 obj                                   % πρώτο παιδί
<< /Title (Introduction)
   /Parent 9 0 R /Next 15 0 R
   /Dest [3 0 R /XYZ 72 720 0] >>
endobj
15 0 obj                                   % δεύτερο παιδί, τελευταίο αδελφάκι
<< /Title (Methodology)
   /Parent 9 0 R /Prev 12 0 R
   /Dest [3 0 R /Fit] >>
endobj

Διαβάστε τους συνδέσμους και οι αναλλοίωτες συνθήκες γίνονται προφανείς. Κάθε στοιχείο δείχνει πίσω στον /Parent του. Τα αδέλφια σχηματίζουν αλυσίδα μέσω των /Prev και /Next, με το πρώτο στοιχείο να παραλείπει το /Prev και το τελευταίο το /Next. Ένας γονέας ονομάζει το πρώτο και το τελευταίο παιδί του μέσω των /First και /Last, ενώ τα ενδιάμεσα παιδιά είναι προσβάσιμα μόνο διατρέχοντας την αλυσίδα των αδελφών. Κάντε ένα λάθος και η αποτυχία είναι σιωπηλή: ένα ξεπερασμένο /Next κόβει ένα κεφάλαιο, ένας γονέας του οποίου το /Last δεν τερματίζει την αλυσίδα αφήνει στοιχεία ορφανά, και το πρόγραμμα προβολής αποδίδει ό,τι μπορεί να φτάσει

Το πεδίο /Count κουβαλά μια πληροφορία κατάστασης που ξαφνιάζει τον κόσμο. Στη ρίζα και σε κάθε αναπτυγμένο στοιχείο κρατά το πλήθος των απογόνων που είναι αυτή τη στιγμή ορατοί· σε ένα συμπτυγμένο στοιχείο είναι αρνητικός αριθμός του οποίου το μέτρο δείχνει πόσοι απόγονοι θα εμφανίζονταν αν αναπτυσσόταν. Άρα το /Count δεν είναι σταθερό δομικό γεγονός για το δέντρο, είναι η αποθηκευμένη ανοιχτή ή κλειστή κατάσταση του πίνακα, και μια γεννήτρια που το γράφει καρφωτά ως θετικό σύνολο ξανανοίγει κάθε κλάδο που ο συγγραφέας ήθελε να μείνει κλειστός

Κάθε στοιχείο κερδίζει τη θέση του δείχνοντας κάπου. Το /Title είναι αυτό που δείχνει ο πίνακας· το /Dest είναι εκεί όπου προσγειώνεται ένα κλικ. Ένας προορισμός μπορεί να είναι ενσωματωμένος μέσα στο στοιχείο, όπως παραπάνω, ή ένα όνομα που επιλύεται μέσω του λεξικού ονομάτων του εγγράφου, που είναι η καλύτερη επιλογή όταν πολλοί σελιδοδείκτες και σύνδεσμοι στοχεύουν τα ίδια σημεία, επειδή διορθώνετε έναν στόχο που μετακινήθηκε σε ένα μόνο μέρος. Μια βιβλιοθήκη γενικά κρύβει αυτό το δέντρο πίσω από έναν χειριστή ρίζας διάρθρωσης και μεθόδους που προσθέτουν θυγατρικές καταχωρίσεις· στο HotPDF το έγγραφο εκθέτει ένα OutlineRoot τύπου THPDFDocOutlineObject και δένει για λογαριασμό σας τους συνδέσμους /Prev, /Next, /Parent και /Count καθώς προσαρτάτε στοιχεία. Αξίζει να το εκμεταλλευτείτε, επειδή η συντήρηση αυτών των αναλλοίωτων συνθηκών στο χέρι σε κάθε επεξεργασία είναι το σημείο όπου σπάνε οι διαρθρώσεις

Προορισμοί: η γραμματική του πού πηγαίνει ένα κλικ

Τόσο οι σελιδοδείκτες όσο και οι σχολιάσεις συνδέσμων δείχνουν σε προορισμούς, και ένας προορισμός είναι κάτι περισσότερο από αριθμός σελίδας. Είναι ένας πίνακας που ονομάζει ένα αντικείμενο σελίδας και έπειτα καθορίζει, μέσα από ένα ρήμα στη δεύτερη θέση, πώς πρέπει να το πλαισιώσει το πρόγραμμα προβολής. Ο πιο συνηθισμένος και ο πιο κακομεταχειρισμένος είναι ο /XYZ, της μορφής [page /XYZ left top zoom]. Οι τρεις τελεστέοι του είναι ανεξάρτητοι, και οποιοσδήποτε μπορεί να είναι null ώστε να σημαίνει «άφησέ το όπως το είχε ο αναγνώστης». Έτσι το [page /XYZ null null null] πηδά στη σελίδα χωρίς να πειράξει τη θέση κύλισης ή το ζουμ, συνήθως αυτό που θέλετε από έναν σύνδεσμο «μετάβασης σε σελίδα». Οι αριθμοί είναι στον προεπιλεγμένο χώρο χρήστη, μετρημένοι από την κάτω αριστερή γωνία με το y να αυξάνεται προς τα πάνω, το ίδιο σύστημα συντεταγμένων που χρησιμοποιεί το περιεχόμενο της σελίδας. Οι συγγραφείς που έρχονται από τη διάταξη οθόνης μετρούν αντανακλαστικά από πάνω και στέλνουν τον αναγνώστη στη λάθος άκρη της σελίδας

Η οικογένεια /Fit ανταλλάσσει την ακριβή τοποθέτηση με ανθεκτικότητα. Το [page /Fit] κλιμακώνει ολόκληρη τη σελίδα μέσα στο παράθυρο, το [page /FitH top] προσαρμόζει το πλάτος της σελίδας με δεδομένη πάνω ακμή, και το [page /FitR l b r t] μεγεθύνει ένα ορθογώνιο ώστε να γεμίσει την προβολή. Επειδή αυτά υπολογίζουν την κλίμακα από τη γεωμετρία της σελίδας και όχι από σταθερές συντεταγμένες, ένας προορισμός /Fit εξακολουθεί να κάνει το λογικό αφού αλλάξει μέγεθος η σελίδα, ενώ ένας προορισμός /XYZ με ψημένο μέσα ζουμ μπορεί να αφήσει τον αναγνώστη να κοιτάζει το περιθώριο. Για έναν πίνακα περιεχομένων, το /FitH με τη συντεταγμένη κορυφής της ενότητας γερνά καλύτερα από το /XYZ με ένα ζουμ στην τύχη

Σχολιάσεις: κάθε τι διαδραστικό που δεν είναι περιεχόμενο σελίδας

Μια σχολίαση είναι ένα αντικείμενο που επικαλύπτει τη σελίδα χωρίς να είναι μέρος της ροής περιεχομένου της. Σύνδεσμοι, αυτοκόλλητες σημειώσεις, επισημάνσεις, γραφικά στοιχεία φόρμας, εικονίδια συνημμένων αρχείων, σφραγίδες: όλα είναι σχολιάσεις, καταχωρημένες στον πίνακα /Annots της σελίδας στην οποία κάθονται. Η αφαίρεση μιας σχολίασης από αυτόν τον πίνακα την αφαιρεί από τη σελίδα, παρότι το υποκείμενο περιεχόμενο μένει ανέγγιχτο. Αυτό ακριβώς είναι το νόημα: οι σχολιάσεις είναι στρώμα επεξεργασίας, ξεχωριστό από τα σημάδια πάνω από τα οποία κάθονται

Κάθε σχολίαση μοιράζεται μια μικρή ραχοκοκαλιά. Το /Subtype ονομάζει το είδος, το /Rect δίνει το πλαίσιο οριοθέτησής της σε συντεταγμένες σελίδας, και το /Contents κρατά κείμενο που λειτουργεί και ως προσβάσιμη περιγραφή. Η σχολίαση συνδέσμου είναι η περίπτωση που αξίζει μελέτη, επειδή έρχεται σε δύο μορφές: γυμνός προορισμός και ενέργεια

12 0 obj                                    % σύνδεσμος προς προορισμό
<< /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                                    % σύνδεσμος που εκτελεί ενέργεια
<< /Type /Annot /Subtype /Link
   /Rect [50 50 200 100]
   /Border [0 0 0]
   /A << /Type /Action /S /URI /URI (https://www.example.com) >> >>
endobj

Το /Rect είναι μια ενεργή περιοχή· ένα κλικ μέσα της στέλνει τον αναγνώστη στον προορισμό, ξαναχρησιμοποιώντας την ίδια γραμματική με τη διάρθρωση. Το /Border [0 0 0] κάνει πραγματική δουλειά, καταστέλλοντας το άσχημο προεπιλεγμένο ορθογώνιο που σχεδιάζουν τα προγράμματα προβολής γύρω από τους συνδέσμους. Η δεύτερη μορφή ανταλλάσσει το γυμνό /Dest με μια ενέργεια /A, της οποίας ο υποτύπος /S επιλέγει τη συμπεριφορά: /GoTo μέσα σε αυτό το αρχείο, /GoToR για άλλο αρχείο, /URI για διεύθυνση ιστού, /Launch για την εκτέλεση εξωτερικού προγράμματος. Η τελευταία αξίζει καχυποψία. Ένα /Launch που ξεκινά εκτελέσιμο είναι η συμπεριφορά που κάνει τα PDF φορέα κακόβουλου λογισμικού, οπότε τα συμμορφούμενα προγράμματα προβολής το μπλοκάρουν ή ρωτούν ηχηρά και ο σύνδεσμος αποτυγχάνει για τους περισσότερους αναγνώστες. Πιάστε το /URI και το /GoTo και αφήστε το /Launch ήσυχο

Οι σχολιάσεις επισήμανσης, όπως οι υπογραμμίσεις και οι αυτοκόλλητες σημειώσεις, και οι σχολιάσεις σχημάτων όπως το /Square, προσθέτουν μια δυσκολία: η εμφάνισή τους στην οθόνη δεν συνάγεται από τον τύπο τους. Ένα πρόγραμμα προβολής αποδίδει τη δική του εκδοχή εκτός αν καρφώσετε την εμφάνιση με μια ροή εμφάνισης, την καταχώριση /AP, που αναφέρεται σε ένα XObject φόρμας το οποίο κρατά τους τελεστές σχεδίασης. Παραλείψτε την και η ίδια επισήμανση μπορεί να φαίνεται διαφορετική σε δύο προγράμματα ανάγνωσης, ή πριν και μετά από ένα πέρασμα σε επεξεργαστή. Για οτιδήποτε η ακριβής εμφάνισή του είναι μέρος του εγγράφου, δώστε το /AP. Τα συνημμένα αρχεία, παρεμπιπτόντως, ξαναχρησιμοποιούν τον ίδιο μηχανισμό: μια ροή ενσωματωμένου αρχείου και ένα λεξικό προδιαγραφής αρχείου, που εμφανίζονται είτε ως σχολίαση /FileAttachment είτε μέσα από το δέντρο ονομάτων /EmbeddedFiles κάτω από το /Names του καταλόγου

Πού σπάει αυτό το στρώμα, και πώς να το πιάσετε

Η επαναλαμβανόμενη αποτυχία σε όλα αυτά είναι η αναφορά που κρέμεται στο κενό. Οι σελιδοδείκτες παύουν να εμφανίζονται όταν ο κατάλογος δεν έχει καταχώριση /Outlines ή όταν μια αλυσίδα αδελφών σπάει στη μέση του δέντρου· τα μεταδεδομένα αγνοούνται όταν στη ροή XMP λείπει η σήμανση /Type /Metadata /Subtype /XML ή όταν το περιτύλιγμα xpacket είναι κακοσχηματισμένο. Σε κάθε περίπτωση το περιεχόμενο των σελίδων είναι μια χαρά, οπότε ένα πρόχειρο άνοιγμα φαίνεται σωστό και το ελάττωμα αναδύεται μόνο στον πίνακα που κανείς δεν έλεγξε

Δύο φθηνές συνήθειες πιάνουν τα περισσότερα. Ανοίξτε το τελικό αρχείο σε πραγματικό πρόγραμμα προβολής και περάστε με κλικ τον πίνακα σελιδοδεικτών και ένα δείγμα συνδέσμων, κάτι που δοκιμάζει το γράφημα των αναφορών όπως θα το δοκιμάσει ένας αναγνώστης. Έπειτα διαβάστε πίσω τα μεταδεδομένα με ξεχωριστό εργαλείο και επιβεβαιώστε ότι το λεξικό Info και το XMP συμφωνούν, η μία διαφωνία που καμία ποσότητα κλικ δεν αποκαλύπτει. Παραγάγετε αυτό το στρώμα μέσα από μια βιβλιοθήκη που αναλαμβάνει τη λογιστική των συνδέσμων και οι περισσότερες από αυτές τις παγίδες δεν ανοίγουν ποτέ. Το HotPDF Delphi Component για Delphi και C++Builder εκθέτει τις δομές διάρθρωσης, σχολιάσεων και μεταδεδομένων μέσα από API σε επίπεδο εγγράφου, ώστε εσείς να περιγράφετε την ιεραρχία των σελιδοδεικτών και τους συνδέσμους και να αφήνετε εκείνο να δένει τις αναφορές. Για το μοντέλο αντικειμένων στο οποίο προσαρτώνται αυτές οι δομές, η τεχνική επισκόπηση της δομής αρχείου PDF καλύπτει τον κατάλογο και τον πίνακα διασταυρούμενων αναφορών από τους οποίους εξαρτώνται