🧩Objekte: die Bausteine jeder PDF

Alles in einer PDF-Datei – Seiten, Schriften, Bilder, Metadaten – ist aus wenigen Grundtypen gebaut (ISO 32000-1, 7.3). Die Syntax stammt von PostScript, ist aber keine Programmiersprache: es gibt keine Variablen, Schleifen oder Prozeduren.

✅
Boolean
true   false

Die Schlüsselwörter true und false, z. B. /NeedAppearances true.

🔢
Zahl (Integer, Real)
123  -98  +17
34.5  -.002  4.

Ganzzahlen und Dezimalzahlen mit Punkt. Keine Exponentenschreibweise (1e3 ist ungültig) und kein Hex.

🔤
String (literal)
(Hallo \(Welt\))
(Zeile\nZwei)
(\101\102)

In runden Klammern; balancierte Klammern sind erlaubt, sonst \(. Escapes \n \r \t \b \f \\ und Oktal \ddd. Strings sind Bytefolgen, keine Unicode-Texte.

🔣
String (hexadezimal)
<48656C6C6F>
<901FA>

Zwei Hex-Ziffern je Byte, Leerraum wird ignoriert. Bei ungerader Anzahl gilt die fehlende letzte Ziffer als 0 (<901FA> = 90 1F A0).

🏷️
Name
/Type  /Page
/Lime#20Green

Beginnt mit /, eindeutiger Bezeichner (wie ein Symbol). Sonderzeichen als #xx (seit PDF 1.2). Namen sind Groß-/Kleinschreibungs-sensitiv.

📚
Array
[0 0 595 842]
[3 0 R (x) /N]

Geordnete Liste beliebiger Objekte in [ ], auch gemischt und verschachtelt.

📖
Dictionary
<< /Type /Font
   /BaseFont /Helvetica >>

Schlüssel-Wert-Paare in << >>; Schlüssel sind immer Namen. Ein Eintrag mit Wert null gilt als nicht vorhanden. /Type sagt, was das Dictionary darstellt.

🌊
Stream
<< /Length 41
   /Filter /FlateDecode >>
stream
…Bytes…
endstream

Dictionary + beliebig lange Bytefolge. /Length = Anzahl Bytes, /Filter = Kodierung (FlateDecode = zlib, DCTDecode = JPEG …). Streams sind immer indirekte Objekte.

∅
null
null

Das Null-Objekt. Eine Referenz auf ein nicht existierendes Objekt wird ebenfalls als null behandelt.

🔗
Indirektes Objekt + Referenz
5 0 obj
  (Inhalt)
endobj

… /Font 5 0 R …

n g obj … endobj gibt einem Objekt Nummer und Generation. 5 0 R verweist darauf – wie ein Zeiger. Die xref-Tabelle löst die Nummer in einen Byte-Offset auf.

🧪Tokenizer & Parser zum Ausprobieren

Tippe ein PDF-Objekt ein. Der Tokenizer zerlegt die Bytes nach den Regeln für Leerraum und Begrenzer, der Parser baut daraus einen Objektbaum – mit derselben Logik, die auch die Beispiel-PDF liest.
1 · Tokenizer (19 Tokens)
<<delim/Typename/Pagename/Parentname2number0numberRkeyword/MediaBoxname[delim0number0number595number842number]delim/Contentsname4number0numberRkeyword>>delim
2 · Parser (Objektbaum)
Dictionary4 Einträge
/TypeName/Page
/ParentReferenzObjekt 2, Generation 0
/MediaBoxArray4 Elemente
[0]Zahl0 (Integer)
[1]Zahl0 (Integer)
[2]Zahl595 (Integer)
[3]Zahl842 (Integer)
/ContentsReferenzObjekt 4, Generation 0

✂️Leerraum und Begrenzer

💡 Leerraum (Tabelle 1)
NUL (0x00), TAB (0x09), LF (0x0A), FF (0x0C), CR (0x0D), Leerzeichen (0x20). Mehrere gelten wie eines – außer innerhalb von Strings und Streams.
✅ Begrenzer (Tabelle 2)
( ) < > [ ] { } / % – sie beenden ein Token. Deshalb ist /Type/Page dasselbe wie /Type /Page.
⚠️ Kommentare
% bis Zeilenende. Ausnahmen mit Bedeutung: %PDF-n.m und %%EOF.