Skip to main content

pdfc

A local PDF converter. Everything runs on this machine; nothing is uploaded.

Install

Arch Linux

git clone https://github.com/6meowscles/pdfc
cd pdfc/packaging/aur && makepkg -si

That builds a real package from the latest release and installs it with pacman, so pdfc lands in /usr/bin and its dependencies come from the official repositories. makepkg runs the test suite as part of the build.

Anywhere else

./install.sh

That creates .venv/, installs the package, and links ~/.local/bin/pdfc. If a dependency has no wheel for your Python, rerun with an older one: PYTHON=python3.12 ./install.sh.

Note that this install stays tied to the checkout: deleting or rebuilding .venv/ breaks the linked command. The Arch package has no such link.

Use

pdfc scan.pdf out/page.png --dpi 300   # render pages to images
pdfc notes.md notes.pdf                # markdown to PDF, via HTML
pdfc report.docx report.pdf            # needs libreoffice
pdfc scan.pdf notes.txt                # extract text

pdfc merge a.pdf b.pdf -o all.pdf
pdfc split big.pdf --pages 1-5,9 -o out/
pdfc split big.pdf --each -o pages/
pdfc rotate scan.pdf --angle 90 -o fixed.pdf
pdfc compress big.pdf --quality ebook -o small.pdf
pdfc ocr scan.pdf -o searchable.pdf

pdfc routes lists every conversion and whether its dependencies are installed.

--dry-run, -f/--force, --progress, -q and -v belong to each command rather than to pdfc itself, so they follow the positional arguments:

pdfc notes.md notes.pdf --dry-run     # prints the route and the output paths
pdfc split big.pdf --each -o pages/ -f

Optional dependencies

Feature Needs
Office formats (docx, odt, pptx, xlsx) libreoffice
OCR tesseract, ocrmypdf
Compression, and the OCR text layer ghostscript
Any PDF output pango and cairo, for weasyprint

You do not need to look these up. When a conversion needs something that is missing, pdfc names it and prints the command for your system — pacman, apt, dnf, zypper or brew, chosen from /etc/os-release:

$ pdfc report.docx report.pdf
error: converting docx → pdf needs libreoffice
       install it with: sudo apt install libreoffice

pdfc routes lists every conversion up front and marks which are blocked.

The pip install pulls ocrmypdf in automatically; a distro package leaves it optional.

Progress output

Each step prints its verb while it runs and again, past tense, when it finishes:

rendering  pdf → png  ████████░░░░  8/12  0:03
rendered   pdf → png  12 files → out/  4.2 MB  5.1s

Progress goes to stderr, so piping stdout stays clean. --progress bar|plain|none overrides the default, which is a bar on a terminal and plain lines everywhere else.

Design

docs/design.md covers the architecture: the converter registry, the two-hop routing rule, format detection, output-path templating, and the error/exit-code contract.

Tests

.venv/bin/pytest

License

GNU AGPL-3.0-or-later — see LICENSE.

This is not a preference so much as an inheritance: pdfc is built on PyMuPDF, which is dual-licensed AGPL-3.0 or commercial, and PyMuPDF does the real work here — rendering, text extraction, and the page operations. A work built on it and distributed has to carry the same terms, so a permissive license would be promising something these dependencies do not allow.

The external tools pdfc shells out to — ghostscript, libreoffice, tesseract — run as separate processes and do not affect this. The rest of the Python stack is permissive: click and markdown (BSD), pillow (MIT-CMU), rich (MIT), ocrmypdf (MPL-2.0).

Metadata

Release files for localpdf 0.2.1

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

Source distribution (sdist)

Source distribution for localpdf 0.2.1
File Size Uploaded
localpdf-0.2.1.tar.gz 48.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for localpdf 0.2.1
File Interpreter ABI Platform
localpdf-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 86.0 kB

Release files / localpdf-0.2.1.tar.gz

Download URL localpdf-0.2.1.tar.gz
Size 48.9 kB
Tags Source
SHA-256 checksum
How to use checksums
2193714945e4741cc97dc0754717dc3e72bb8dde5f37e6a2490169479b97115b
BLAKE2b-256 checksum
How to use checksums
659c4166677ef447386a68a683b031f00b881606c5c898059de5a55d4acd2757
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / localpdf-0.2.1-py3-none-any.whl

Download URL localpdf-0.2.1-py3-none-any.whl
Size 37.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6518be4b881d4e52eee0d47c0a3638d98cf91b4ef046a35cc4c1ac5d6f8171c1
BLAKE2b-256 checksum
How to use checksums
39f045eaf9eac4c5100d03fdfc082600ac4508731f9a05e0d93313e980abf4d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

0.2.2

2 release files

This release

0.2.1 This release

2 release files

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