A Python PDF parsing library and tool built on top to browse the internal structure of a PDF file
Introduction
The project is focused on chapter 7 (“Syntax”) of the Portable Document Format (PDF) Specification.
PDFSyntax is lightweight (no dependencies) and written from scratch in pure Python.
- CLI: It started as a command-line interface to inspect the internal structure of a PDF file: the PDF source is pretty-printed and augmented with hyperlinks in a static HTML file.
- API: Now the internal functions are being exposed as a tooklit for PDF read/write operations.
It is mostly made of simple functions working on built-in types and named tuples. Shallow copying of the Doc object structure performed by pure functions offers some kind of – experimental – immutability.
PDFSyntax favors non-destructive edits allowed by the PDF Specification: by default incremental updates are added at the end of the original file.
Project status
WORK IN PROGRESS! This is ALPHA quality software.
CLI
Features
The generated HTML looks like the raw PDF file with the following additions:
- Pretty-print dictionary object
- Extract an object contained in an object stream and insert it in the flow like a regular object
- Decompress stream and display a small part of it
- Turn indirect object reference into hyperlink
- Turn offset reference (for example a /Prev entry) into hyperlink
- Put some color on key names (for example /Type)
- Display offset of an object
Screenshot
Usage
Generate the HTML file and open it in your browser:
Usage
Most functions are pure and are exposed both as basic functions and as instance methods of a Doc object: in the function signatures found in the following sections, a doc
first argument can read as self
.
For example both samples are equivalent:
File information
structure
and metadata
are functions showing general information about the document.
trailer
and catalog
give access to the starting point of the object tree.
1j
is a complex number (!) representing indirect reference 1 0 R
. Why? Because the approach is to map PDF object types to Python basic built-in types as much as possible, and it is a concise way to show both the object number (as the imaginary part) and the generation number (as the real part). Moreover the generation is very often equal to zero, so the real part is not shown.You may think of the
j
as a “jump” to another object :)
get_object
gives direct access to indirect objects.
PDFSyntax tracks document incremental updates made possible by appending new or updated objects at the end of an original PDF file (and the matching XREF section). The Revisions
entry of the structure
function result, if greater than 1, indicates that incremental updates have been appended. By default, a newly opened document by PDFSyntax is ready to write modifications in the next revision. The rewind
functi