pdfrw Documentation

repository·master·Indexed 23 days ago

https://github.com/pmaupin/pdfrw

A high-performance, pure Python library for reading, writing, and manipulating PDF files. pdfrw focuses on vector fidelity for tasks such as merging, subsetting, rotating, and watermarking without rasterization. It features a usage model based on PdfArray and PdfDict, supports Form XObjects for embedding content, and integrates with ReportLab for generating PDF output. Note that it does not natively support encryption or most compression filters; pdftk is recommended as a workaround for these files.

Tokens
3.1K
Snippets
3
Records
21
Agent score
82%

What's inside pdfrw

  1. Introduction to pdfrw

    master

    Overview

    pdfrw is a pure Python library and utility designed for reading and writing PDF files. It is optimized for speed and is capable of faithfully reproducing vector formats without rasterization.

    Key Capabilities

    • PDF Operations: Subsetting, merging, rotating, and modifying metadata.
    • Vector Fidelity: Reproduces vector images without converting them to rasters (used by rst2pdf).
    • Integration: Can be used standalone or in conjunction with reportlab to reuse existing PDF content in new documents.
    • Compatibility: Version 0.4 is tested on Python 2.6, 2.7, 3.3, 3.4, 3.5, and 3.6.
    • License: Permissively licensed.
  2. Available example programs in pdfrw

    master

    The pdfrw repository includes several example scripts demonstrating common PDF manipulation tasks. These examples can be used as templates for building your own PDF processing tools.

    Core PDF Manipulation Examples

    • 4up.py: Prints pages four-up.
    • alter.py: Performs slight modifications to a PDF.
    • booklet.py: Converts a PDF into a booklet format.
    • cat.py: Concatenates multiple PDFs and adds metadata.
    • poster.py: Resizes a PDF to create a poster.
    • print_two.py: Prints two cut-down copies on a single sheet of paper (double-sided). Note: Requires uncompressed PDF.
    • rotate.py: Rotates selected ranges of pages within a document.
    • subset.py: Retrieves a subset of pages from a document.
    • watermark.py: Adds a watermark to a PDF.

    ReportLab Integration Examples

    These examples demonstrate how to use pdfrw in conjunction with the reportlab library for generating or modifying PDF output.

    • rl1/4up.py: Four-up printing using reportlab for output.
    • rl1/booklet.py: Booklet conversion using reportlab for output.
    • rl1/platypus_pdf_template.py: Uses a PDF page as a watermark background with reportlab.
    • rl1/subset.py: Page subsetting using reportlab for output.
    • rl2/copy.py: Demonstrates parsing a graphics stream and using reportlab for output. (Warning: This is a complex example and may not be suitable for production without significant modification).
  3. How pdfrw handles PDF indirect objects and circular references

    master

    PDF files use 'indirect objects' to allow multiple references to the same data and to handle circular references.

    • Reading: pdfrw automatically handles these. When it encounters an indirect object, the resulting Python object will have an indirect attribute set to True.
    • Writing: To prevent infinite loops when writing custom data structures, you must break circular references by ensuring at least one object in every cycle has an indirect attribute that evaluates to True.
  4. High-level PDF manipulation capabilities

    master

    While pdfrw is primarily a container library, it provides high-level support for:

    • PDF Pages: Finding and extracting pages for new documents.
    • Form XObjects: Converting pages or rectangles into Form XObjects, supporting scaling, rotation, and positioning.
    • ReportLab Integration: Recursively creating reportlab objects from internal pdfrw formats, allowing you to reuse existing PDF content when building new documents with reportlab.
  5. Understand the pdfrw usage model: PdfArray and PdfDict

    master

    The pdfrw usage model treats most objects as strings during writing, with two primary exceptions:

    1. PdfArray: A subclass of list. It supports an indirect attribute to be written as an indirect PDF object and uses lazy resolution to resolve references to other indirect objects only when needed.
    2. PdfDict: A subclass of dict. It supports an indirect attribute and lazy resolution.
      • Attribute Access: Since PDF names (like /CamelCase) are used as keys, you can access dictionary elements using object attribute access (e.g., dict.Key) or standard dictionary index lookup (e.g., dict['/Key']).
      • Streams: PdfDict can have an associated stream. Assigning a value to the .stream attribute automatically sets the PDF /Length attribute for that dictionary.
  6. Understand PDF object types in pdfrw

    master

    pdfrw represents PDF elements using specific Python classes. Most classes include an indirect attribute; if set to True, the object is written as an indirect object in the resulting PDF, allowing it to be referenced by multiple containers or support circular references.

    Key object types include:

    • PdfObject: A subclass of str used as a catch-all for elements not explicitly represented by other classes.
    • PdfName: A singleton used to convert strings into PDF names by prepending a slash (e.g., PdfName('Rotate') becomes '/Rotate'). Note: Only PdfName objects (of class BasePdfName) can be used as keys in PdfDict objects.
    • PdfString: A subclass of str for encoded strings, providing encode and decode methods.
    • PdfArray: A subclass of list for PDF arrays. It supports the indirect attribute and transparently handles unresolved indirect objects.
    • PdfDict: A subclass of dict for PDF dictionaries. It supports attribute access (e.g., mydict.Foo), returns None for missing keys, and manages stream/length attributes.
  7. Use pdfrw to convert PDF pages to Form XObjects

    master
    The pdfrw library can be used to read PDF files and convert individual pages into PDF Form XObjects. This allows you to treat existing PDF pages as reusable graphical objects that can be embedded into new PDF documents. In the provided examples, pdfrw is used for the extraction and object conversion, while reportlab is used to write the final output PDF.
  8. Use Form XObjects to embed PDF content

    master
    A core concept of pdfrw is the use of Form XObjects. This abstraction allows you to easily embed specific pieces or pages of one PDF into another PDF. This is the recommended way to perform low-level manipulation or reuse content, rather than attempting to parse graphics streams directly.
  9. Example scripts for PDF manipulation with pdfrw and reportlab

    master

    The following scripts demonstrate different ways to manipulate PDF pages by converting them to XObjects and re-rendering them using reportlab:

    • subset.py: Prints a specific subset of pages from a source PDF.
    • 4up.py: Prints pages in a 4-up layout (four pages per sheet).
    • booklet.py: Creates a booklet layout from the provided pages.
  10. Setup the pdfrw test environment

    master

    To run the library tests, you must provide the required static PDF assets which are not included in the main package.

    1. Clone the full repository from GitHub.
    2. Navigate to the tests directory.
    3. Clone the static_pdfs repository into a subdirectory named static_pdfs within the tests folder.
    4. Run tests using pytest, unittest, or nose.

    Example using pytest:

    $ pip install pytest reportlab
    $ pwd
    <...>/pdfrw/tests
    $ git clone https://github.com/pmaupin/static_pdfs
    $ ln -s ../pdfrw
    $ pytest

    To run a specific test case:

    $ pytest test_roundtrip.py -k "test_compress_9f98322c243fe67726d56ccfa8e0885b.pdf"
  11. Known limitations and missing features in pdfrw

    master

    The following features are currently not supported by pdfrw:

    • Most compression/decompression filters.
    • Encryption.

    Workaround: You can use the pdftk command-line tool to convert PDFs to remove encryption and compression before processing them with pdfrw.

  12. Troubleshoot PDF parsing issues

    master

    If pdfrw examples or your own implementations fail to work with a specific PDF, the file may be compressed or encrypted.

    Solution: Try using pdftk to uncompress and/or unencrypt the PDF before processing it with pdfrw.