Metadata-Version: 2.4
Name: larzpdf
Version: 0.1.0
Summary: Money-native PDF documents in pure Python: invoices, receipts, and flowing documents with exact decimal totals. No reportlab. Zero dependencies.
Author: larz-scripter
License: MIT
Project-URL: Homepage, https://github.com/larz-scripter/larzpdf
Project-URL: Repository, https://github.com/larz-scripter/larzpdf
Project-URL: Documentation, https://github.com/larz-scripter/larzpdf#readme
Project-URL: Issues, https://github.com/larz-scripter/larzpdf/issues
Keywords: pdf,invoice,receipt,pdf-generation,reportlab-alternative,documents,billing,money,zero-dependency,pure-python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Printing
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# larzpdf

**Money-native PDF documents in pure Python. Zero dependencies.**

A from-scratch PDF writer with one thing it's genuinely great at: **financial
documents**. Generating an invoice or a receipt — line items, exact decimal
totals, tax, clean right-aligned money columns — should be a few lines, not a
graphics project. No `reportlab`, no font files, no C extensions.

```python
from larzpdf import Invoice

inv = Invoice("INV-1001", date="2026-07-27",
              seller={"name": "Acme Co", "email": "billing@acme.com"},
              buyer={"name": "Ada Lovelace"}, currency="$")
inv.item("Consulting", qty=10, price="150.00")
inv.item("Hosting", qty=1, price="29.99")
inv.tax(0.0825)
inv.save("invoice.pdf")
```

## What makes it different

Most pure-Python PDF libraries are general drawing tools, and general drawing
tools make invoices *tedious*. larzpdf inverts that: the invoice/receipt is the
first-class feature.

- **Money done right.** Totals use **exact `Decimal` math** (no float cents
  drifting), formatting groups thousands and rounds HALF_UP, and money columns
  are right-aligned in a monospaced font so they line up perfectly.
- **Accepts real money objects.** Pass plain numbers, strings, or
  [larzmoney](https://github.com/larz-scripter/larzmoney) `Money` objects — it
  formats and totals them correctly either way.
- **Zero dependencies.** A complete, spec-valid PDF writer in a few hundred lines
  — correct cross-reference table and byte offsets, standard built-in fonts (no
  embedding). It opens in any reader.

Underneath there's a general `Document` (headings, wrapped text, tables, rules,
auto page breaks) and a low-level `PDF` canvas, but the money documents are the
point.

## Install

```bash
pip install larzpdf
```

## Invoices & receipts

```python
from larzpdf import Invoice, Receipt

inv = Invoice("INV-42", date="2026-07-27",
              seller={"name": "Acme", "address": "1 St", "email": "b@acme.com"},
              buyer={"name": "Ada", "email": "ada@ex.com"},
              currency="$", notes="Payment due in 30 days.")
inv.item("Design work", qty=8, price="120.00")
inv.item("Revisions", qty=2, price="90.00")
inv.tax(0.08, label="VAT")

inv.subtotal()     # Decimal('1140.00')  — exact
inv.tax_amount()   # Decimal('91.20')
inv.total()        # Decimal('1231.20')
inv.save("invoice.pdf")

receipt = Receipt("R-100", buyer={"name": "Bo"}, currency="$", paid=True)
receipt.item("Coffee", 2, "3.50")
receipt.save("receipt.pdf")
```

## General documents

```python
from larzpdf import Document

doc = Document()
doc.heading("Monthly Report")
doc.text("A paragraph that wraps automatically and paginates as needed. " * 10)
doc.hr()
doc.table(
    [["Widgets", "1200", ("money", "9999.50")],
     ["Gadgets", "340",  ("money", "1210.00")]],
    headers=["Product", "Units", "Revenue"],
    widths=[0.5, 0.25, 0.25],
    align=["l", "r", "r"],
)
doc.save("report.pdf")
```

A cell written as `("money", value)` is formatted and right-aligned in a
monospaced column automatically.

## Low-level canvas

```python
from larzpdf import PDF

p = PDF()
p.text(72, 720, "Hello", font="Helvetica-Bold", size=18)
p.line(72, 710, 540, 710)
p.rect(72, 600, 200, 80, fill=(0.95, 0.95, 0.95), stroke=(0, 0, 0))
p.add_page()
p.save("out.pdf")
```

## Scope

larzpdf targets clean, text-and-table business documents (invoices, receipts,
statements, reports) with the standard PDF fonts. It doesn't embed custom fonts
or draw images — if you need rich graphics, that's a different tool. For getting
correct, good-looking money documents out the door with zero dependencies, it's
exactly enough.

## Tests

```bash
python -m unittest discover -s tests -v   # 20 tests incl. a PDF xref validator
```

## The Larz stack

Pure-Python, zero-dependency building blocks: **[larz](https://github.com/larz-scripter/larz)** · **[larzchain](https://github.com/larz-scripter/larzchain)** · **[larzmoney](https://github.com/larz-scripter/larzmoney)** · **[larzcrypt](https://github.com/larz-scripter/larzcrypt)** · **[larzdb](https://github.com/larz-scripter/larzdb)** · **[larzagent](https://github.com/larz-scripter/larzagent)** · **[larzchart](https://github.com/larz-scripter/larzchart)** · **[larzmark](https://github.com/larz-scripter/larzmark)** · **[larztask](https://github.com/larz-scripter/larztask)** · **[larzvault](https://github.com/larz-scripter/larzvault)** · **[larzvm](https://github.com/larz-scripter/larzvm)** · **[larzcache](https://github.com/larz-scripter/larzcache)** · **[larzvalidate](https://github.com/larz-scripter/larzvalidate)** · **[larzid](https://github.com/larz-scripter/larzid)** · **[larzrpc](https://github.com/larz-scripter/larzrpc)** · **[larzstate](https://github.com/larz-scripter/larzstate)** · **[larzhttp](https://github.com/larz-scripter/larzhttp)** · **[larzconf](https://github.com/larz-scripter/larzconf)** · **[larzcron](https://github.com/larz-scripter/larzcron)** · **[larzlimit](https://github.com/larz-scripter/larzlimit)** · **[larzlog](https://github.com/larz-scripter/larzlog)** · **[larzcli](https://github.com/larz-scripter/larzcli)** · **[larzretry](https://github.com/larz-scripter/larzretry)** · **[larztime](https://github.com/larz-scripter/larztime)** · **larzpdf**

## License

MIT © larz-scripter
