Metadata-Version: 2.4
Name: pdf2shrink
Version: 0.3.2
Summary: Compress PDFs and convert DOCX to minimal PDFs
Author: Rafa
License-Expression: MIT
Project-URL: Homepage, https://github.com/RafaCMur/pdf2shrink-python
Project-URL: Repository, https://github.com/RafaCMur/pdf2shrink-python
Project-URL: Issues, https://github.com/RafaCMur/pdf2shrink-python/issues
Keywords: pdf,compression,document,cli
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# pdf2shrink

Compress PDFs and convert DOCX to minimal PDFs on Linux, macOS, and Windows.

Strip images, extract text, or rebuild documents with maximum compression. Perfect for resumes, documents, and text-heavy PDFs.

## Features

- **4 compression modes**: Standard, Flat, Flat compact, Flat ultracompact
- **DOCX support**: Convert Word documents to minimal PDFs (direct text extraction for flat modes)
- **Interactive mode**: Choose compression mode with brief descriptions
- **Non-interactive mode**: Use `--yes` for scripts and cron jobs
- **Up to 89% compression**: Tested on real documents
- **Fast**: 0.25s - 1.3s per document
- **Cross-platform**: Linux, macOS, Windows (with external tools configured)
- **Zero Python dependencies**: Uses system tools (Ghostscript, LibreOffice)
- **Safe**: LibreOffice profile isolation prevents corruption when LO is running
- **Robust**: Subprocess timeouts (300s), stderr capture on failure, atomic output replacement
- **Windows-ready**: Auto-detects `gswin64c`/`gswin32c`, `soffice.exe`

## What's new in 0.3.1

- Atomic output replacement after successful compression
- Hard-link input protection
- Correct Windows LibreOffice profile URLs
- DOCX dependency checks match the selected mode and converter fallback

## What's new in 0.3.0

- LibreOffice profile isolation (prevents corruption when LO is running)
- Windows binary detection (`gswin64c`/`gswin32c`, `soffice.exe`)
- `soffice` fallback chain (libreoffice → soffice → pandoc)
- DOCX flat modes: direct text extraction (1 hop, faster)
- Subprocess timeouts (300s, no hangs)
- Output-exists warning before overwrite
- `--quiet` / `-q` flag to suppress dependency list
- `--install` flag for auto-install on Debian/Ubuntu
- Dynamic banner per mode (shows "DOCX to Flat PDF" etc.)
- Better error reporting (stderr shown on failure)

## Installation

### Install via pip

```bash
pip install pdf2shrink
```

### Install from source

```bash
git clone https://github.com/RafaCMur/pdf2shrink-python.git
cd pdf2shrink-python
pip install .
```

### Install external dependencies

**Linux (Ubuntu/Debian):**
```bash
sudo apt install ghostscript poppler-utils libreoffice python3
```

**Linux (Arch):**
```bash
sudo pacman -S ghostscript poppler libreoffice python
```

**macOS:**
```bash
brew install ghostscript poppler
brew install --cask libreoffice
```

**Windows:**
- Install Ghostscript from https://ghostscript.com/releases/gsdnld.html
- Install poppler from https://github.com/oschwartz10612/poppler-windows/releases
- Install LibreOffice from https://www.libreoffice.org/download/
- Add the `bin` folders for Ghostscript and Poppler to `PATH` if their installers do not do it.
- Or use WSL (recommended): `wsl --install`

## Usage

### Interactive mode

```bash
pdf2shrink document.pdf
```

You'll be prompted to choose a compression mode:

```
Select compression mode:
  [1] Standard          - Strip images, fast web view, max compression (default)
  [2] Flat              - Text-only, rebuild plain PDF (no colors, no layout)
  [3] Flat compact      - Collapse line wraps, fewer pages (good for resumes)
  [4] Flat ultracompact - 5pt font, 2 columns, maximum density
```

### Non-interactive mode

```bash
# Standard mode (default)
pdf2shrink --yes document.pdf

# Specific modes
pdf2shrink --mode flat document.pdf
pdf2shrink --mode flat-compact document.pdf
pdf2shrink --mode flat-ultracompact document.pdf
```

### Custom output path

```bash
pdf2shrink -o output.pdf input.pdf
```

### Convert DOCX to PDF

```bash
pdf2shrink resume.docx
pdf2shrink --mode flat-compact resume.docx
```

## Compression modes explained

### Standard (default)

- Strips images, keeps text
- Preserves original layout
- Fast web view (linearized)
- **Compression: 36-45%**
- **Time: ~0.25s**
- **Use when**: You want moderate compression while keeping layout

### Flat

- Extracts text only
- Rebuilds plain black-on-white PDF
- No colors, no images, no original layout
- **Compression: 62-83%**
- **Time: ~1.1s**
- **Use when**: You need text-only documents

### Flat compact

- Like Flat, but collapses line wraps
- Line breaks become ` ↵ ` markers
- Page breaks become `§` separators
- **Compression: 80-89%**
- **Time: ~0.7s**
- **Use when**: Resumes, CVs, text-heavy documents

### Flat ultracompact

- 5pt font, 2 columns
- Line-height 1.0, tight margins
- Maximum density
- **Compression: 80-89%**
- **Time: ~0.7s**
- **Use when**: You need maximum compression (documents shrink to 1-2 pages)

## Real-world test results

### Resume PDF (300K)

| Mode | Output | Compression | Time |
|------|--------|-------------|------|
| Standard | 192K | 36% | 0.25s |
| Flat | 50K | 83% | 1.33s |
| Flat compact | 33K | 89% | 0.73s |
| Flat ultracompact | 33K | 89% | 0.66s |

### Profile PDF (268K)

| Mode | Output | Compression | Time |
|------|--------|-------------|------|
| Standard | 147K | 45% | 0.25s |
| Flat | 102K | 62% | 1.07s |
| Flat compact | 54K | 80% | 0.75s |
| Flat ultracompact | 50K | 81% | 0.71s |

## How it works

1. **DOCX input**: Converts to PDF via LibreOffice/soffice/Pandoc (flat modes extract text directly)
2. **Ghostscript**: Strips images (-dFILTERIMAGE), converts to grayscale, linearizes, downsamples, compresses
3. **Flat modes**: Extracts text with `pdftotext` (PDF) or LibreOffice (DOCX), rebuilds with LibreOffice

All subprocess calls have 300s timeouts. LibreOffice runs with isolated user profiles to prevent corruption.

## Environment variables

- `TMPDIR`: Override temp directory (default: system temp directory)

## Requirements

- **Python 3.8+**
- **Ghostscript** (`gs` on Linux/macOS, `gswin64c`/`gswin32c` on Windows): PDF compression
- **poppler-utils** (`pdftotext`, `pdftoppm`): Text extraction
- **LibreOffice** (`libreoffice` or `soffice`): PDF rebuilding (flat modes), DOCX conversion

## Troubleshooting

### "Command not found" errors

Install missing dependencies:

```bash
# Ubuntu/Debian
sudo apt install ghostscript poppler-utils libreoffice python3

# Or use --install flag
pdf2shrink --install
```

### Output file same as input

The script prevents overwriting input files. Use a different output path:

```bash
pdf2shrink -o output.pdf input.pdf
```

### Flat modes produce empty PDF

The input PDF must have a text layer. For scanned documents, use OCR first:

```bash
# Add text layer with OCR
ocrmypdf input.pdf output.pdf

# Then compress
pdf2shrink --mode flat output.pdf
```

## License

MIT © 2026
