Skip to main content

Quick start · Features · CLI · API · Architecture · Limitations

SmartPDFCompare is a lightweight Python library for comparing the extractable text in two PDF versions. It gives applications structured word and page changes, then uses the same coordinates to write readable highlighted PDFs and an optional side-by-side review report.

Features

  • Structured comparison — added, removed, replaced, added-page, removed-page, and moved-page records with JSON serialization.
  • Unicode-aware text extraction — PyMuPDF word coordinates, NFKC normalization, case folding, ligatures, NBSPs, and dash/minus variants.
  • Practical page alignment — content matching for inserted/moved pages, bounded sequential look-ahead, and index-by-index comparison.
  • Visual review — native PDF highlights or boxes in safe output copies; optional side-by-side report pages.
  • Small CLI — terminal summary, JSON result, highlighted output, report, alignment policy, and style controls.

Install

python -m pip install --upgrade smart-pdf-compare

The package tracks the current major PyMuPDF release. Create a virtual environment first for a predictable setup:

python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
python -m pip install --upgrade smart-pdf-compare

Quick start

from smart_pdf_compare import compare_pdfs, highlight_differences

result = compare_pdfs("original.pdf", "revised.pdf")

print(result.is_identical)
print(result.summary)
for change in result.differences:
    print(f"{change.change_type}: {change.old_text!r} -> {change.new_text!r}")

outputs = highlight_differences(
    "original.pdf",
    "revised.pdf",
    output_dir="diff-output",
    result=result,
    include_report=True,
)
print(outputs)

Work with JSON

import json

with open("comparison.json", "w", encoding="utf-8") as file:
    json.dump(result.to_dict(), file, indent=2)

result.truncated is True when max_differences limits returned detail entries. Aggregate counts in result.summary always cover the full comparison.

Highlighted output

Original
Removed or replaced text receives red markup.
Revised
Added or replaced text receives green markup.
original_highlighted.pdf revised_highlighted.pdf

Use real PDF annotations by default, or boxes where highlights are not desired:

from smart_pdf_compare import highlight_differences

highlight_differences(
    "original.pdf", "revised.pdf", "diff-output",
    style="box",          # "highlight" is the default
    include_report=True,   # creates difference_report.pdf
)

Source PDFs are never overwritten. The side-by-side report contains only pages with differences, displays page labels, and leaves a clearly labeled blank side for an inserted or removed page.

Alignment choices

from smart_pdf_compare import ComparisonOptions, compare_pdfs

result = compare_pdfs(
    "original.pdf", "revised.pdf",
    options=ComparisonOptions(
        alignment="content",       # default
        similarity_threshold=0.60,
        lookahead=5,
        max_differences=1_000,
    ),
)
Strategy Best for Trade-off
content Documents with inserted, deleted, or moved pages Greedy matching; not globally optimal for highly repetitive pages.
sequential Mostly ordered revisions Resynchronizes only inside lookahead.
index Stable page-for-page documents An insertion can make later pages appear modified.

Normalization is deliberately conservative: it uses NFKC, case folding, ligature compatibility, non-breaking-space cleanup, and dash/minus unification. Punctuation remains significant by default, so decimal values, negative numbers, negation, and contractions do not silently disappear.

Command line

smart-pdf-compare original.pdf revised.pdf \
  --alignment content \
  --output-dir diff-output \
  --style highlight \
  --report \
  --json diff-output/comparison.json
Exit code Meaning
0 Textually identical under the chosen policy.
1 Changes were found.
2 Input, extraction, or configuration error.

Visual comparison

Text diffs and visual diffs answer different questions. The text API compares extracted words; the visual API renders pages through PyMuPDF and detects changes to layout, graphics, lines, and images as pixels. It requires no OpenCV, NumPy, or Pillow dependency.

from smart_pdf_compare import VisualComparisonOptions, compare_visual_pdfs

result = compare_visual_pdfs(
    "original.pdf",
    "revised.pdf",
    options=VisualComparisonOptions(dpi=144, pixel_threshold=8, output_mode="diff_image"),
    output_dir="visual-output",
)
print(result.pages[0].difference_ratio)

Choose output_mode="side_by_side" for paired rendered images or "none" for metrics only. Visual pages are intentionally paired by index; page-count differences become explicit unmatched-page records. For several PDFs, compare_visual_documents(paths, reference=0, ...) compares each non-reference input against the designated reference.

smart-pdf-compare original.pdf revised.pdf --visual-only \
  --visual-mode diff_image --visual-output-dir visual-output --json visual-output/result.json

Optional desktop viewer

On a desktop Python installation with Tk support, launch a two-pane viewer that reuses the same comparison results, change navigation, and save-highlighting workflow:

smart-pdf-compare-viewer original.pdf revised.pdf

The viewer is separate from core imports and creates no window until invoked. It intentionally focuses on PDF comparison; clipboard and Microsoft Word conversion were excluded because they are platform-dependent utilities outside the core library.

Limitations

SmartPDFCompare compares the PDF text layer, not rendered pixels. It does not perform OCR, visual-diff analysis, or image comparison. If either document has no extractable text, it raises MissingTextLayerError instead of falsely claiming that two scanned PDFs are identical. Complex tables and multi-column PDFs can also expose an unreliable reading order from the source PDF.

PyMuPDF is available under AGPL or commercial terms. Confirm that its license is appropriate for your use case.

Development

python -m pip install -e ".[dev]"
python -m pytest
python -m build
python -m twine check dist/*

Read the contribution guide, public API, architecture notes, and changelog. Before publishing, verify availability of smart-pdf-compare on PyPI, upload to TestPyPI, install the artifact in a clean environment, and use PyPI Trusted Publishing for the production release.

License

SmartPDFCompare’s own source code is licensed under the MIT License. Its PyMuPDF dependency has separate licensing, described above.


Built for clear, reviewable PDF changes.

Metadata

Release files for smart-pdf-compare 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for smart-pdf-compare 0.2.0
File Size Uploaded Provenance Actions
smart_pdf_compare-0.2.0.tar.gz 25.4 kB Without provenance Details for smart_pdf_compare-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for smart-pdf-compare 0.2.0
File Interpreter ABI Platform Actions
smart_pdf_compare-0.2.0-py3-none-any.whl Python 3 none any Details for smart_pdf_compare-0.2.0-py3-none-any.whl

Total release size: 51.2 kB

Release files / smart_pdf_compare-0.2.0.tar.gz

Download URL smart_pdf_compare-0.2.0.tar.gz
Size 25.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2789bec4e354b048f3fb09f6d66eb50de9c4df5a1d1bb5fa567d44241b5a6148
BLAKE2b-256 checksum
How to use checksums
7edccdad9ebc96a264004690ed47b276612041a04cce235f312eaea4faf6669c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / smart_pdf_compare-0.2.0-py3-none-any.whl

Download URL smart_pdf_compare-0.2.0-py3-none-any.whl
Size 25.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f6525953ae3f430a5a4196124abaac8eb2b7ab81a6dcb19a70fa01a74d6d9fd8
BLAKE2b-256 checksum
How to use checksums
a7c7dca6a488c99d0ee417d90fb1cd7358538b7c3e3682feddb779334299c622
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for smart-pdf-compare 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page