pycpdf is a Python extension to enable read-only access to the contents of PDF files. It is similar to PyPDF/PyPDF2 except that it is read-only, is much quicker, and has some of the bugs fixed.
The main class is pycpdf.PDF
, which is given the PDF data as a byte-string
and, optionally, a decryption password. This object has the following
properties:
pages
: a list ofPage
objectsversion
: the PDF file format version as a string (e.g."1.6"
)info
: the Document Information Dictionary, orNone
linearized
: the Linearization Parameter Dictionary, orNone
catalog
: the Document Catalog dictionarytrailer
: the trailer dictionary
Page
objects are similar to dictionaries, but they have the following two
extra properties:
text
: the textual contents of the pagecontents
: a list of the PDF operators that comprise the page contents
StreamObject
objects are also similar to dictionaries, but have the
following two extra properties:
data
: the binary data contained within the streamcontents
: the binary data parsed as a list of PDF operators
The module also contains unicode_translations
, which is a dictionary
suitable for passing to str.translate
to simplify Unicode strings
somewhat:
- replace various spaces (00A0, 2000-200A, 3000) with an ASCII space
- remove soft hyphens (00AD) and zero width space (200B)
- replace various hyphens (2010-2014, 2212) with an ASCII hyphen
- replace various sexed quotation marks (2018, 2019, 201C, 201D) with the equivalent unsexed ASCII quotation marks
- replace the horizontal ellipsis character (2026) with '...'
- replace various latin ligatures (ae, dz, ff, fi, fl, ffi, ffl, st) with their equivalent ASCII character strings
pdf = pycpdf.PDF(open('file.pdf', 'rb').read())
if pdf.info and pdf.info.get('Title'):
print('Title:', pdf.info['Title'])
for pageno, page in enumerate(pdf.pages):
print('Page', pageno + 1)
print(page.text.translate(pycpdf.unicode_translations))
All strings are always Unicode. Note that, unlike in PyPDF, name objects do
not start with a forward slash /
- i.e. you should reference obj['Type']
not obj['/Type']
. This is because the PDF Reference unequivocally states
that the slash is not part of the name.
The page.text
property lists the textual contents of the page in the order
that the relevant operators occur. It may sometimes be out of order, and
there may be unexpected spacing.
If container objects (arrays and dictionaries) contain indirect objects then these objects will not be extracted from the PDF file until they are referenced for the first time. This is to enable opening large PDF files efficiently. Altering the contents of container objects is not actively prevented but should never be done and will lead to undefined behaviour.
The intention of the extension is to allow fast low-level access to all the internal structures of PDF files. Higher-level interfaces could be added in Python to allow, for example, better text extraction or access to images.
Some encryption and image encoding methods are not currently supported.
- Bug fixes to do with in-line images
- Bug-fixed StreamObject.contents
- When decoding text, if ToUnicode fails, fall back to Encoding
- Extended documentation slightly.
- Added Travis auto-deployment to PyPI.
- Added
pycpdf.__version__
- Initial release.