Skip to content

Latest commit

 

History

52 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pdfc

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

Install

pip

pip install localpdf

The distribution is called localpdf because PyPI already has a project too close to pdfc; the command it installs is still pdfc. Add [ocr] if you want OCR: pip install localpdf[ocr].

Homebrew

brew install 6meowscles/tap/pdfc

macOS or Linux. The formula builds a virtualenv of its own, and pulls in cairo and pango because weasyprint loads them at import time.

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.

pdfc is not on the AUR; the PKGBUILD lives here, so it is built from the checkout rather than fetched by an AUR helper.

Fedora

There is no COPR repository yet, so build the RPM from the spec in this repository:

sudo dnf install rpm-build rpmdevtools python3-devel pyproject-rpm-macros
rpmdev-setuptree
spectool -g -R packaging/copr/pdfc.spec
rpmbuild -ba packaging/copr/pdfc.spec
sudo dnf install ~/rpmbuild/RPMS/noarch/pdfc-*.noarch.rpm

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.

OCR is the one dependency no install method pulls in for you, because it drags the whole tesseract stack behind it. Add it deliberately:

pip install localpdf[ocr]

or install your distribution's own ocrmypdf package.

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).

About

A local PDF converter CLI: images, text, markdown, HTML and office formats in and out of PDF, plus merge/split/rotate/compress and OCR. Nothing leaves your machine.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages