Python API Reference

This reference documents the dynamic Python API exposed by pdftl. All operations return an pdftl.core.types.OpResult object.

Note

These functions are generated dynamically at runtime via pdftl.api.

pdftl.api.add_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Add one or more top-level bookmarks to a PDF outline.

pdftl.api.add_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Applies all parsed add_images rules to a PDF in-place.

This function coordinates the rule parser and the ImageStamper engine to apply overlays/underlays to the input PDF.

pdftl.api.add_text(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies all parsed add_text rules to a PDF in-place.

This function coordinates the parser and the TextDrawer to apply text overlays to the input PDF.

pdftl.api.attach_files(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Attach files to a PDF document, according to the specified options

pdftl.api.background(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.barcode(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Main entry point for the barcode operation.

pdftl.api.booklet(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Imposes pages into a booklet sequence.

pdftl.api.burst(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Split one or more PDFs into multiple files, single-page files by default.

Args:

opened_pdfs (list): A list of opened PDF files to burst

operation_args (list): User-supplied arguments

output_pattern (str): A C-style format string for the output

filenames, e.g., “page_%03d.pdf”.

Return: the first input pdf (for pipeline chainability)

Note: Uses the hook side-effect to actually burst

pdftl.api.cat(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Concatenates pages from input PDFs into a new PDF, then rebuilds all links and named destinations, including transforming link target coordinates.

pdftl.api.chop(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Chops specified pages of a PDF into multiple smaller pages.

BUG FIXME: currently does strange things with page rotation (pages out of order?)

pdftl.api.clip(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Crop or clip pages in a PDF using specs like ‘1-3(10pt,5%)’.

pdftl.api.create(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Create a new PDF from scratch with blank pages.

pdftl.api.crop(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Crop or clip pages in a PDF using specs like ‘1-3(10pt,5%)’.

pdftl.api.delete(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Deletes pages from input PDF, and otherwise leaves the PDF structure essentially unchanged.

pdftl.api.delete_actions(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete actions from a PDF, optionally filtered by selector specs.

pdftl.api.delete_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete annotations from a PDF, optionally filtered by selector specs. Without selectors, deletes all annotations from all pages.

pdftl.api.delete_attachments(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Deletes attachments matching criteria from the document NameTree and scrubs corresponding page annotations.

pdftl.api.delete_blank(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete pages that are blank or visually uniform.

Each spec is evaluated independently. A page is deleted if any spec marks it as blank. Deletion happens in reverse page order so indices remain valid throughout.

pdftl.api.delete_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Delete bookmarks from a PDF outline, optionally filtered by page spec.

pdftl.api.delete_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Overwrites images matching criteria with 1x1 transparent stubs. Defaults to global search if no page range is provided.

pdftl.api.deskew(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for deskew: Parses arguments, detects text skew, and rotates pages.

pdftl.api.diff_text(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Performs a highly granular, spatially-aware text comparison between two PDFs. Outputs a JSON array of structural changes, including precise bounding box coordinates for where the changes occurred on the page.

Options

  • `granularity=<level>`: Controls how the diff engine groups text before comparing. Options:

    char, word, line, paragraph. Using word prevents sub-word shredding on typos. (Default: word)

  • `ignore_whitespace=<bool>`: If true, drops changes where the only difference is invisible

    space (e.g., reflow line-breaks). (Default: true)

  • `ignore_soft_hyphens=<bool>`: If true, strips ufffe soft hyphens before comparing. Useful

    for ignoring hyphenation differences caused by text reflowing across margins. (Default: false)

  • `include_bboxes=<bool>`: If true, includes spatial bounding box coordinates for every

    change. Turn this off for a cleaner, text-only JSON output. (Default: true)

  • `margin_top=<float>`, `margin_bottom=<float>`, `margin_left=<float>`,

    `margin_right=<float>`: Filters out changes that fall entirely within these margins (in points). Excellent for removing noisy page headers, footers, or marginalia. (Default: 0)

pdftl.api.dump_actions(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps all actions from a PDF in JSON format, optionally filtered.

pdftl.api.dump_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps all annotations from a PDF in JSON format, with compact arrays. Optionally filtered by selector specs using the same syntax as modify_annots.

pdftl.api.dump_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extracts the document’s Table of Contents (bookmarks) into a highly readable and editable YAML format (or JSON).

This faithful extraction preserves both the hierarchical structure and the complex properties of your bookmarks. The resulting file can be easily edited in any text editor and applied back to the same (or a different) PDF using the update_bookmarks operation.

Supported Bookmark Properties Each bookmark node is represented as a dictionary (key-value mapping). The extractor natively supports and outputs the following properties:

  • `title`: The display text of the bookmark.

  • `page`: The 1-indexed target page number.

  • `children`: A nested list of sub-bookmarks to maintain outline hierarchy.

  • `color`: An RGB array for the bookmark text color (e.g., [1.0, 0.0, 0.0] for red).

  • `bold` / `italic`: Boolean flags for text styling (true or false).

  • `uri`: An external web link (used if the bookmark points to a URL rather than a page).

  • `dest`: A string reference to a Named Destination embedded inside the PDF.

  • `view`: The precise zoom/viewport array (e.g., [“XYZ”, 0, 700, 2.5], [“FitH”, 500]).

Skipping Destination Resolution By default, named destinations are automatically resolved into exact page and view parameters to make the data more immediately useful. If you want to skip this step and only output the original dest names without deriving their page targets, pass the no_resolve flag.

This may be useful if you want to edit the output from dump_bookmarks and pass it to the update_bookmarks operation. See the update_bookmarks help for rules on dest versus page and view precedence.

Format Example .. code-block:: yaml

  • title: Chapter 1 page: 1 bold: true children:

    • title: Sub-section A page: 2 view: [“FitH”, 800]

    • title: Important Chart page: 3 color: [1.0, 0.0, 0.0]

  • title: External Resources uri: [https://example.com](https://example.com)

Dependency note

YAML extraction requires the pyyaml library. If it is not installed, you can install it via pip install pdftl[yaml-bookmarks], or simply use the json flag to extract using Python’s standard JSON library instead.

pdftl.api.dump_colorspaces(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Report color spaces used throughout a PDF document.

pdftl.api.dump_data(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Imitate pdftk’s dump_data output, writing to a file or stdout.

pdftl.api.dump_data_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps annotation data from a PDF in pdftk style

pdftl.api.dump_data_fields(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extracts form field data from the PDF using a Hybrid Tree Walk.

pdftl.api.dump_data_fields_utf8(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extracts form field data from the PDF using a Hybrid Tree Walk.

pdftl.api.dump_data_utf8(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Imitate pdftk’s dump_data output, writing to a file or stdout.

pdftl.api.dump_dests(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Traverses the /Dests name tree of a PDF using pikepdf.NameTree. This provides a robust, iterable interface to the destinations.

pdftl.api.dump_encryption(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dumps comprehensive encryption and permission data from a PDF.

pdftl.api.dump_files(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

List files attached to the PDF. Returns a list of dicts with all available attachment metadata.

pdftl.api.dump_fonts(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dump detailed font metadata records from a PDF file.

pdftl.api.dump_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dump embedded image metadata of a PDF file.

pdftl.api.dump_layers(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extract OCG (Layer) data and write as JSON.

pdftl.api.dump_signatures(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Validate PDF signatures and returns a list of validation results.

pdftl.api.dump_streams(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Dump page content streams in the form that replace operates on them.

pdftl.api.dump_tables(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Extract tables from a PDF file.

pdftl.api.dump_tags(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Inspect the PDF structure tree in one of three modes: reading_order (default), tree, or issues.

pdftl.api.dump_text(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Dump text content of a PDF file.

pdftl.api.embed_fonts(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Locate equivalents for unembedded fonts and inject their binary streams back into the PDF structures.

pdftl.api.export_fonts(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Export fonts with unified sidecar mappings and metrics.

pdftl.api.export_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Export embedded images to a directory with a JSON manifest.

pdftl.api.fill_form(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Fill in a form, treating the first argument as a filename for data.

pdftl.api.filter(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Return the given PDF.

pdftl.api.generate_fdf(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Output FDF data for the given PDF

pdftl.api.grep(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

The grep operation searches the text content of a PDF for a specified regular expression or literal string. It outputs a structured JSON array detailing matches, page locations, context snippets, and precise coordinate bounding boxes.

Arguments:
  • <pattern>: The regular expression or text string to search for.

  • [pages…]: Optional page ranges (e.g., 1-5, 9-end) to restrict the search. If omitted, the entire document is searched.

Search Options:
  • regex=<b>: If true, treats the pattern as a Python-compatible regular expression. If false, matches the pattern as a plain literal string. (Default: true)

  • ignore_case=<b> or i=<b>: If true, performs a case-insensitive search. (Default: false)

  • multiline=<b> or m=<b>: If true, ^ and $ match the start and end of lines. (Default: true)

  • dotall=<b> or s=<b>: If true, the . special character matches any character, including newlines. (Default: false)

  • max_count=<N>: Stop searching and parsing after locating <N> total matches.

Context Options:
  • context=<N>: Number of surrounding lines of text to include before and after each match. (Default: 0)

  • before_context=<N>: Number of surrounding lines to include strictly before the match.

  • after_context=<N>: Number of surrounding lines to include strictly after the match.

Typographic Filtering:

You can restrict matches to text that meets specific visual criteria. * min_size=<F>, max_size=<F>: Only match text within a given point-size range. * font_match=<S>: Only match if the font name contains this substring (e.g., “Bold”). * require_bold=<b>: Only match if the text is explicitly bold. * require_italic=<b>: Only match if the text is explicitly italicized. * fonts=<b>: Always extract and output font metadata for matches. Automatically enabled

if any typographic filters are used. (Default: false)

Output Format:

The results are written as a JSON object containing global metadata, a match metrics summary block (count), and a list of hits. Each hit contains: * page, line: 1-indexed page and line numbers where the match begins. * text: The exact string matching the main query. * bboxes: Coordinate bounding boxes [x0, y0, x1, y1] grouped per line. * context_match: The full string of the line(s) containing the match. * match_start_idx, match_end_idx: 0-indexed character offsets marking where the

match resides within context_match.

  • context_before, context_after: Arrays of surrounding context lines (if requested).

  • captures: If the regex utilizes capture groups (e.g., Invoice:s*(d+)), this array automatically populates with the group number, exact text, and precise bboxes for every distinct captured sub-pattern.

pdftl.api.highlight(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies all parsed highlight rules to a PDF in-place.

pdftl.api.import_fonts(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

The import_fonts operation reads a JSON manifest (generated by export_fonts) and overwrites the corresponding internal PDF font structures with the edited assets from a directory.

It automatically handles:
  • Binary Font stream injection if MD5 hashes differ (safe skip on unmodified files).

  • Character metrics updates based on the ‘width_sync_mode’ parameter.

  • Re-compilation of sidecar ToUnicode JSON maps back to compliant PostScript CMaps.

  • /FontDescriptor property edits from the sidecar’s descriptor block.

  • /CIDToGIDMap restoration, from either “Identity” or an explicit .cid2gid.json sidecar.

  • Type 3 glyph procedure reconstruction (including inline images) from a .charprocs file.

If both .json and .ps files exist for a given font’s /ToUnicode map, an error is raised to prevent ambiguity. The user must delete or rename one of them first.

encoding_cmap edits are limited: the only supported change is switching a Type0 font’s /Encoding between /Identity-H and /Identity-V. Any other value written into encoding_cmap is rejected with a warning, and /Encoding is left untouched — there is no general mechanism here for re-encoding into an arbitrary CMap.

Width Sync Modes

Each font’s unified JSON sidecar (font_{obj_id}_{gen_id}_{name}.json) has a top-level width_sync_mode field, defaulting to auto on export. This controls how import_fonts reconciles the PDF’s /Widths (or /W for CID fonts) with any edits:

  • auto (default): Reads the true metrics out of the edited font binary (if its MD5 changed since export) and writes those into the PDF. If the binary is unchanged or unreadable, falls back to manual behavior using any width.pdf values present in the sidecar mappings.

  • manual: Writes the width.pdf values from the sidecar mappings directly into the PDF, ignoring the font binary.

  • patch_font_metrics: Dynamically patches the font binary’s horizontal metrics table in-memory to match the sidecar’s width.pdf values, and writes the patched stream directly into the PDF (leaving workspace files untouched).

  • squash_font_vectors: Dynamically rescales the font binary’s glyph outlines in-memory to visually fit the sidecar’s width.pdf values, and writes the squashed stream directly into the PDF (leaving workspace files untouched).

  • preserve: Leaves the PDF’s existing /Widths untouched entirely.

patch_font_metrics and squash_font_vectors require the embedded font file to be present in the directory; without it, no width sync occurs for that font.

For both of these modes, the in-memory binary edit is only ever best-effort: if it can’t be applied (an unresolvable CID-to-GID mapping, no character codes in the font actually matched, or a malformed/unreadable font program), import_fonts still writes the sidecar’s width.pdf values into /Widths or /W directly, so a requested width edit is never silently dropped even when the font program itself couldn’t be patched.

Format-Specific Limitations

When employing squash_font_vectors, be advised that this mode relies on direct, affine coordinate scaling which is only structurally supported for TrueType outline representations (glyf tables). For OpenType-CFF (CFF/CFF2) and classic Adobe Type 1 fonts which do not possess a standard TrueType glyf table, the operation degrades silently to patch_font_metrics mode—meaning the font binary’s internal character metrics will be updated correctly in-memory to prevent layout mismatches, but the visual glyph outline vectors will remain unscaled.

pdftl.api.import_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Import edited images from a directory and overwrite internal PDF streams.

pdftl.api.import_streams(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Import and apply streams into the PDF.

pdftl.api.inject(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Injects code at the start and/or end of page content streams.

pdftl.api.insert(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Insert blank pages into the PDF.

pdftl.api.modify_annots(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Modifies properties of existing annotations in a PDF.

pdftl.api.modify_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Applies parallelized bitmap image pipeline transformations to target pages.

Raises InvalidArgumentError on unknown image modifiers.

pdftl.api.modify_layers(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The modify_layers operation allows you to alter Optional Content Groups (layers) in a PDF. You can permanently merge/strip them, or change their default visibility and behavior.

The command reads a sequence of action-target pairs. If no target is provided after an action, it defaults to affecting “all” layers.

Available Actions

Structural (Permanent): * merge: The visual content of the layer is permanently baked into the

page. The layer is removed from the PDF’s layer menu.

  • strip: The visual content of the layer is completely deleted from the document, and the layer is removed from the PDF’s layer menu.

State & Behavior (Non-destructive): * show / hide: Sets the default visibility when the document is opened. * lock / unlock: Prevents/allows the user from toggling the layer in viewers. * print / noprint: Overrides behavior to force layer visibility ON or OFF when printing. * screen / noscreen:

Overrides behavior to force layer visibility ON or OFF on digital displays.

Utility: * keep: Used primarily to exclude a specific layer when targeting “all” others.

Note on State vs. Usage: Layer visibility on screen (`show`/`hide`) is independent of its visibility when printing. Modifying a usage state (like `noprint`) without changing its base state will leave its on-screen visibility unchanged.

Target Specifications

  • name=<string>: Sloppy match. Applies the action to all layers with this name.

  • id=<integer>: Strict match. Applies the action to the exact underlying PDF object.

  • all: Explicitly targets all layers.

  • <string>: If no key= prefix is provided, it defaults to a name= match.

pdftl.api.montage(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Imposes pages onto new canvas pages based on a grid or layout strategy.

pdftl.api.move(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for move: Parses string arguments into a spec, then runs logic.

pdftl.api.multibackground(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.multistamp(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.mutate_content(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The mutate_content operation allows you to run custom Python logic against the raw instruction streams of a PDF. You can specify your own Python script, and the function from that script to run. The default function search for if no function is specified is mutate.

The Context Dictionary Your function receives a context dictionary with the following keys:

  • pdf: The current pikepdf.Pdf object.

  • page_num: The current page number (1-indexed) or None for XObjects.

  • is_xobject: Boolean, True if mutating a Form XObject.

  • object: the pikepdf.Object (either a page or an XObject) containing the content stream.

  • args: A list of extra arguments passed via CLI after the script name.

Passing Arguments You can pass custom parameters to your script: pdftl in.pdf mutate_content script.py 1.5 2.0 output out.pdf In this case, context[‘args’] would be [‘1.5’, ‘2.0’].

pdftl.api.normalize(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Normalize page content streams.

pdftl.api.optimize_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Optimize images in the given PDF.

pdftl.api.place(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies geometric transformations (direct similarities) to the content of selected pages.

`<spec>` syntax:

[<pages>](<operation>…)

Operations:
  • shift=dx, dy Moves content by the specified x and y distances. Supports units (pt, in, cm, mm) and percentages relative to page size. Example: shift=1in, 50%

  • scale=factor[:anchor] Scales content by a multiplier (e.g., 0.5 for half size). Optional anchor determines the fixed point (default: center).

  • spin=angle[:anchor] Rotates content by degrees clockwise. Optional anchor determines the pivot point (default: center).

More than one operation can be given. They should be separated by semicolons, ‘;’. Operations are applied in the order they appear, from left to right.

Anchors:

Anchors define the center of scaling or rotation. * Named: center (default), top-left, top, top-right,

left, right, bottom-left, bottom, bottom-right.

  • Coordinate: x,y (e.g., 0,0 for bottom-left corner).

pdftl.api.recolor_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Finds and grayscales color images on targeted pages using parallel tasks.

pdftl.api.recolor_vectors(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Orchestrator entry point registered into pdftl’s core layout pipeline.

pdftl.api.render(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The render operation converts PDF pages into raster images or a single PDF. It respects page rotation, cropping, and current pipeline modifications.

You can specify a page range using standard page specifications (e.g., 1-5, even). If no pages are specified, all pages are rendered.

The dpi=<val> argument sets the raster image resolution, in dots per inch (default: 150). It must be a positive number.

The png_compression=<level> argument sets the PNG compression, for PNG output. It must be an integer between 1 and 9, where 9 is the highest compression level, and the slowest. The default level is 9.

The default <template> is page_%d.png. The parameter %d is replaced with the output page counter value, starting at 1. Standard formatting directives like %03d are supported.

Single PDF Output: If the output template ends with .pdf and contains no % directive (e.g., output out.pdf), all rendered pages will be combined into a single PDF file. Note: This keeps all page images in memory until saved.

Image Output: If rendering to images, the output format is guessed from the <template> extension (e.g., .png, .jpg). If no extension is given, PNG is used.

pdftl.api.replace(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Replace in page content streams.

pdftl.api.resample_images(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Resample images exceeding the dpi threshold using a ThreadPoolExecutor.

pdftl.api.rotate(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Applies rotations and/or scaling to specified pages of a PDF.

pdftl.api.server(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Bootstrap and start the stateless HTTP daemon server.

pdftl.api.set(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Orchestrates setting various document-level metadata and preferences.

pdftl.api.shuffle(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Shuffles (interleaves) pages from multiple PDFs, applying transformations like rotation and scaling.

pdftl.api.simplify_vectors(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) 'OpResult'

Entry point registered with the pdftl operation registry.

pdftl.api.stamp(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply overlay or underlay with optional OCG layering and page-range filtering.

pdftl.api.stamp_fields(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Entry point for the stamp_fields operation.

pdftl.api.style_text(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Apply text styles in page content streams.

pdftl.api.tag(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Auto-tag a PDF using OpenDataLoader and return the tagged pikepdf.Pdf document.

pdftl.api.unpack_files(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Unpacks attachments from a single PDF file. Returns a generator yielding (filename, bytes).

pdftl.api.unpause(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The unpause operation removes intermediate animation frames from PDF slide decks, such as those produced by LaTeX Beamer with pause or uncover directives.

The algorithm renders each page at low resolution and checks whether all ink pixels from the previous page are still present on the current page. If they are, the previous page is considered an intermediate animation frame and is discarded. Only pages where ink disappears or moves are kept, plus the final page.

The dpi=<val> argument controls render resolution for comparison (default: 72). Higher values are slower but more accurate for fine detail.

The ink=<val> argument is the pixel darkness threshold (0-255) below which a pixel is considered ink (default: auto). In auto mode, Otsu’s method is used per page.

The survival=<val> argument is the minimum fraction (0.0-1.0) of ink pixels from the previous page that must survive on the current page for it to be considered a continuation (default: 0.98). Genuine Beamer transitions produce survival=1.00; new slides typically produce <0.20.

pdftl.api.update_bookmarks(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

Replaces the document’s Table of Contents (bookmarks) entirely using a specified YAML or JSON file, or YAML data on stdin if bookmarks_file is set to “-“.

This operation consumes the structured format generated by the dump_bookmarks command. It applies validation to prevent broken PDFs: it validates page boundaries, catches typos in property names, and ensures the hierarchical tree structure is sound.

Important Rules & Behaviors * Full Replacement: This command does not merge or append bookmarks. It completely

overwrites the existing Table of Contents with the contents of your file.

  • Page Indexing: Target page numbers must be 1-indexed (e.g., page: 1 points to the very first physical page of the document).

  • Boundary Checking: If a bookmark points to a page number that exceeds the total number of pages in the PDF, the operation will fail safely to prevent document corruption.

  • Strict Validation: Unrecognized properties (such as a typoed pagee instead of page) will trigger an error rather than being silently ignored. This ensures your routing logic always behaves as expected.

  • Precedence: dump_bookmarks output may contain a dest field alongside resolved page and view fields. This means that the bookmark uses a named destination, and for convenience, the dump includes the resolved page number and view parameters. For update_bookmarks, the dest field, if present, always takes precedence. If both are present, a warning is issued on first encounter. * To update page and view, delete the dest field. * To avoid the warning and keep the dest field only, delete page and view.

    Alternatively, use the no_resolve keyword when using dump_bookmarks to avoid this issue.

Clearing Bookmarks If you want to completely remove the Table of Contents from a PDF, you can provide a file containing just an empty list. * YAML file content: [] * JSON file content: { “bookmarks”: [] }

Dependency note Loading YAML files requires the pyyaml library. If it is not installed, you can install it via pip install pdftl[yaml-bookmarks], or simply use .json files natively.

pdftl.api.update_info(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for update_info: parses string arguments into a spec, then runs logic.

Expects op_args to have valid operation arguments (see pdftl help update_info).

xml_strings controls whether to XML-decode string fields in the input.

pdftl.api.update_info_utf8(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

CLI Adapter for update_info: parses string arguments into a spec, then runs logic.

Expects op_args to have valid operation arguments (see pdftl help update_info).

xml_strings controls whether to XML-decode string fields in the input.

pdftl.api.zoom(*, inputs: list[str] = None, opened_pdfs: list[pikepdf._core.Pdf] = None, operation_args: list[str] = None, password: str = None, output: str = None, run_cli_hook: bool = False, full_result: bool = False, aliases: dict[str, Any] = None, options: dict[str, Any] = None) pdftl.core.core_types.OpResult

The zoom operation rescales entire pages (including the MediaBox) to fit a specified target dimension. Unlike place, which only moves content within existing boundaries, zoom physically transforms the page size.

This is an in-place operation: unspecified pages are left unchanged.

Syntax:

zoom “<pages>(<target>[,<options>])”

Target Formats:
  • Relative/Percentage: (50%) or (200%). Resizes the page relative to its current dimensions.

  • Single Value/Paper: (A4) or (100mm). Scales the page uniformly so that it fits inside a bounding box of that size (aspect ratio preserved).

  • Explicit Box: (100mm,200mm). Scales the page uniformly to fit inside the specified width and height.

  • Axis Specific: (width=A4) or (height=11in). Scales the page proportionally based only on the specified dimension.

Options:
  • shrink: Only scale pages down. If the page is already smaller than the target, it remains unchanged.

  • grow: Only scale pages up. If the page is already larger than the target, it remains unchanged.

Note: Scaling is always uniform. If a target rectangle is provided, the operation uses the limiting dimension to ensure the entire page fits inside the “envelope”.