Changelog
This changelog format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
Added
Guess shell for
--completionif it is not specifiedadd
{count}as an alias for{n}inadd_textandadd_bookmarksunpauseoperationdump_colorspacesoperationdelete_attachmentsoperation
Changed
Performance improvements in link/outline remapping
dump_filesoutput now includes attachment ‘location’
[0.19.0] - 2026-06-01
Fixed
Fix crash on outline items without a /Title
Added
Filter annotations in
dump_annotsanddelete_annotsadd
EACH…JOB, documented underpdftl help pipelinedelete_bookmarksoperationadd_bookmarksoperationadd
{n}template toadd_text(andadd_bookmarks)
Changed
Improve error message when too many files are opened
[0.18.1] - 2026-05-29
Changed
When
--debugis passed,optimize_imagesnow outputs ocrmypdf debug messagesImprove error message for invalid page specs
Fixed
dump_annots: fix crash caused by named destinations which are not valid python dictionary keysUpdated API type stubs
Improve broken pipe handling: suppress tracebacks when piping to a pager
Improve test robustness (fixes #25)
[0.18.0] - 2026-05-05
Added
zoomoperationfastoutput option
Changed
pipx-specific installation instructions for missing dependencies
help output uses executable name correctly
update_bookmarkscan now read bookmark data from stdinadd_textsupports markdown-style hyperlinkssethandles common metadata, in both Info and XMPstamp,multistamp,background,multibackgroundaccept page specshelp: link to readthedocs page
Fixed
modify_layersnow hooks up print/view events (/AS dictionary)dump_layersreports /AS dictionary hookup as ‘active’ state
[0.17.0] - 2026-05-02
Added
modify_layersoperationdump_imagesoperationhighlightoperationstamp,background,multistamp,multibackground: option to add content in a new layerpage ranges accept
portraitandlandscapequalifiers
Changed
plain
renderarguments are now page specs, and we can output a multi-page render PDF
[0.16.0] - 2026-04-26
Added
delete_blankoperationdelete_imagesoperation
[0.15.0] - 2026-04-19
Added
setoperationimprove handling of unknown command line flags
suggest possible bug reporting on errors
CONTRIBUTING.md added
Fixed
work around a pyHanko bug affecting
dump_signatures
[0.14.0] - 2026-04-17
Added
dump_encryptionoperationdump_bookmarksoperationupdate_bookmarksoperation
Changed
montage: removedfitparameter
Fixed
pdftkcompatibility: default to all permissions deniedmontageandbookletbug handling pages with negative rotation fixedplaceandadd_textrotation bugs fixed and visual tests addedcroprotation bugs fixed and visual tests added
[0.13.0] - 2026-04-15
Added
page ranges accept
step<n>to step through a range in regular intervalsburstaccepts page specs or bookmark levels for chunk split points, and chunk size limits
Fixed
Completions updated
dump_textnow works in a pipeline, instead of crashingmontageandbookletnow handle page rotation betterpdftkcompatibility:burstnow outputs doc_data.txtdump_dataomits empty fields
Changed
Minor shell completion performance improvements
[0.12.1] - 2026-04-06
Fixed
Improved memory management
Fixed
chop,place, andbookletoperations to correctly calculate physical boundaries on pages with non-zero origins or non-standard/Rotateflags
Changed
Paper spec parser now falls back to landscape when missing an underscore (e.g.,
a4ltoa4_l).Pipeline execution now fails with an error if stage arguments cannot be parsed, rather than warning and proceeding.
Improved error messages for corrupted or invalid PDF files.
[0.12.0] - 2026-04-04
Added
clipoperation: enclose page content in a clipping rectangleAbsolute rectangle specifications for
cropandclipmontageoperation: impose multiple pages onto a grid layout, useful for contact sheets and N-up handouts. Supports configurable grid size, canvas, margins, gutters, and aspect ratio control (fit=contain|fill).bookletoperation: reorder and impose pages for duplex booklet printing. Automatically pads to a multiple of 4, supports signature-based chunking (sig=N), custom canvas size, and right-to-left binding (rtl=true).
[0.11.2] - 2026-03-22
Added
--versionnow displays core dependencies (pikepdf, libqpdf, python) and optional dependencies, along with a docs URL
Fixed
cropwith an invalid spec now prints a clean error message instead of a traceback--versionno longer crashes if pikepdf is not installed
[0.11.1] - 2026-02-09
Fixed
Bug fix:
rendershould no longer save a PDF to the pattern file
[0.11.0] - 2026-02-08
Added
Inline pipeline substitution using new
JOBandDONEkeywords, documented underpdftl help pipeline
Changed
Bump pikepdf required version to 10.3.0 to enable better pdftk compatibility
Compatibility:
Default to encrypt_aes128 encryption, the strongest which is pdftk compatible
pdftl now passes the vendored pdftk-java test suite
Shell completion improvements and optimization
Respect XDG environment variables for cache and plugin directory on non-Windows
Performance improvements, particularly in
catanddump_dataAPI now accepts
io.BytesIOas PDF inputs (as well aspathlib.Path, etc)
Fixed
Resolved issue with outlines (contents) when using
catwith named destinations
[0.10.0] - 2026-01-28
Added
Shell completion for bash, zsh and powershell
[0.9.2] - 2026-01-26
Changed
Performance improvements for
cat,shuffle, androtateoperations, especially regarding hyperlink handling.Invalid page arguments (e.g., requesting page 10 of a 5-page PDF) now return descriptive error messages instead of crashing.
Fixed
delete: Now properly removes page resources, resulting in smaller output files.generate_fdf: Fixed an issue where generation could fail or produce invalid output when handlingNonevalues or specific binary string formats.The option parser (used in
add_text, etc.) now correctly handles unbalanced quotes by raising a descriptive error, preventing data corruption.
Security
Replaced regex parsing with a state machine to prevent application hangs (ReDoS) when processing malformed quoted strings.
Now using
defusedxmlto avoidxml.etree.ElementTreevulnerabilities.Ensure passwords are redacted from all logging calls.
[0.9.1] - 2026-01-21
Fixed
README.md,NOTICE.mdandCHANGELOG.mdupdated/corrected
[0.9.0] - 2026-01-21
Added
mutate_contentoperation: mutate page content streams using a user-supplied Python scriptupdate_info: Support settingPdfID0to “RESET” to force valid ID regeneration on save.replacement_fontoption: change the font used for user text in forms
Changed
--versionincludes optional dependency versionsDocumentation updated for
dump_data,dump_annots, anddump_data_fieldsto better explain output formats and pdftk compatibility.
Fixed
Compatibility:
generate_fdffixed andreplacement_fontimplemented. Now passes the pdftk-java tests using bleeding edgepikepdf.startup performance improvements: lazy loading, and working around heavy Rich formatting for default help text
Pipeline: Read-only operations (like
dump_text) now implicitly pass the input PDF to the next stage, fixing chained commands (e.g.,dump_text --- cat).Handling of features with missing dependencies should be more consistent.
[0.8.0] - 2026-01-17
Added
Official support for Python 3.14
More comprehensive
vendor_tests/pdftk-javatest suite, frompdftk-java. This test suite only is licensed under the GPL 2, see NOTICE.md.no_encrypt_metadataoption: do not encrypt metadata. Only supported by AES encryption methods.COMPATIBILITY.md: compatibility notesdump_data_fieldsnow extracts tooltips (FieldNameAlt) and default values (FieldValueDefault).API: inputs now support pathlib.Path objects directly.
Changed
Encryption method now defaults to
encrypt_aes128ifuser_pworowner_pware passed, instead of not encrypting. This is more similar topdftk.attach_filesis now an operation, not an output option (pdftk compatibility)exit codes better aligned with pdftk’s exit codes
CLI: stricter argument parsing now raises
DuplicateArgumentErrorif keywords are repeated.
Fixed
catshould now properly handle forms.fill_formcompatibility fixesdump_data_fields_utf8: fixed crash/output issues.set_info: added validation for page label indices and better error handling for rotation/mediabox.
[0.7.0] - 2026-01-11
Added
automated
pdftkcompatibility testing using third party php test suite.drop_xfaoutput option to drop XFA form data (pdftk compatibility)renderoperation: rasterize pagesmove,update_info,update_info_utf8now accept instructions from a JSON “at-file” using@filename.jsonin place of CLI argumentsdump_datagives JSON output via thejsonkeywordextensibility: add custom operations by putting Python files in
~/.config/pdftl/operations(*nix) or%APPDATA%\pdftl\config(windows)
Fixed
bug in
add_pages.pywhen a page has an integer key-valuemore comprehensive handling of the five PDF page boxes for
dump_dataandupdate_infodrop_infoanddrop_xmpoutput options should now work as claimedflattenreimplemented for robustness
[0.6.0] - 2026-01-04
Added
moveoperation: move pages within a PDF fileplaceoperation: shift, scale and/or spin content within the page
Changed
Now handles compound page specifications like
1,3-4,7-end
Fixed
Improved API documentation generation
Removed
spinoperation. Seeplacefor this functionality.
[0.5.0] - 2026-01-03
Added
add_textfeatures:source metadata variables (
source_filename,source_page, etc)Bates stamping variable features, e.g.
DEF-{page+120:06d}produces DEF-000121, DEF-000122, …
insertoperation: insert blank pages
[0.4.1] - 2026-01-02
Fixed
Broken link in README.md
[0.4.0] - 2026-01-01
Added
API with fluent and functional interfaces
docs/api_tutorial.mdand auto-generated API docs
Changed
Renamed operation:
list_filesis nowdump_files
Fixed
Fixed bug preventing parsing of the page specification “right”
[0.3.1] - 2025-12-20
Fixed
README.mdcorrected, and “platform” badge added
[0.3.0] - 2025-12-20
Added
Get
helpby tag withpdftl help tag:<tagname>dump_signatures: view and validate PDF signaturesPDF signature output options:
sign_cert <file>Path to certificate PEMsign_field <name>Signature field name (default: Signature1)sign_key <file>Path to private key PEMsign_pass_env <var>Environment variable with sign_cert passphrasesign_pass_promptPrompt for sign_cert passphrase
dump_layers: dump PDF optional content groups (OCGs), a.k.a. “layers”
Fixed
performance improvements for
cat
[0.2.1] - 2025-12-17
Added
crop: addedfitandfit-groupartwork
extended NOTICE.md: acknowledge
pikepdf/qpdfandpypdfium2Windows testing
Fixed
performance improvements (lazy-loaded imports)
help tweaks: add sources for non-operations; more help topic aliases
[0.2.0] - 2025-12-13
Added
readthedocs integration and docs generation
Fixed
Improved help text
[0.1.1] - 2025-12-12
Added
codecov integration
PyPI publish integration
[0.1.0] - 2025-12-11
Added
Initial public release of
pdftl.Operations:
add_textAdd user-specified text strings to PDF pagesbackgroundUse a 1-page PDF as the background for each pageburstSplit a single PDF into individual page filescatConcatenate pages from input PDFs into a new PDFchopChop pages into multiple smaller piecescropCrop pagesdeleteDelete pages from an input PDFdelete_annotsDelete annotation infodump_annotsDump annotation infodump_dataMetadata, page and bookmark info (XML-escaped)dump_data_annotsDump annotation info in pdftk styledump_data_fieldsPrint PDF form field data with XML-style escapingdump_data_fields_utf8Print PDF form field data in UTF-8dump_data_utf8Metadata, page and bookmark info (in UTF-8)dump_destsPrint PDF named destinations data to the consoledump_textPrint PDF text data to the console or a filefill_formFill a PDF formfilterDo nothing. (The default if<operation>omitted.)generate_fdfGenerate an FDF file containing PDF form datainjectInject code at start or end of page content streamslist_filesList file attachmentsmodify_annotsModify properties of existing annotationsmultibackgroundUse multiple pages as backgroundsmultistampStamp multiple pages onto an input PDFnormalizeReformat page content streamsoptimize_imagesOptimize imagesreplaceRegex replacement on page content streamsrotateRotate pages in a PDFshuffleInterleave pages from multiple input PDFsspinSpin page content in a PDFstampStamp a 1-page PDF onto each page of an input PDFunpack_filesUnpack file attachmentsupdate_infoUpdate PDF metadataupdate_info_utf8Update PDF metadata from dump_data_utf8 instructions
Output options:
allow <perm>...Specify permissions for encrypted filesattach_files <file>… Attach files to the output PDFcompress(default) Compress output file streamsdrop_infoDiscard document-level info metadatadrop_xmpDiscard document-level XMP metadataencrypt_128bitUse 128 bit encryption (obsolete, maybe insecure)encrypt_40bitUse 40 bit encryption (obsolete, highly insecure)encrypt_aes128Use 128 bit AES encryption (maybe obsolete)encrypt_aes256Use 256 bit AES encryptionflattenFlatten all annotationskeep_final_idCopy final input PDF’s ID metadata to outputkeep_first_idCopy first input PDF’s ID metadata to outputlinearizeLinearize output file(s)need_appearancesSet a form rendering flag in the output PDFoutput <file>The output file path, or a template for ‘burst’owner_pw <pw>Set owner password and encrypt outputuncompressDisables compression of output file streamsuser_pw <pw>Set user password and encrypt outputverboseTurn on verbose output