rusty-pdfgrep 0.1.0

Grep through PDF files — a Rust port of Hans-Peter Deifel's `pdfgrep(1)` with lopdf-backed text extraction, regex + fancy-regex pluggable engines, --password retry for encrypted PDFs, GNU-grep-compatible color output, recursive walking with fnmatch include/exclude, and a typed library API.
Documentation
# rusty-pdfgrep — Design Notes

Authoritative spec/plan: [`specs/00008-pdfgrep-port/`](../../rusty/specs/00008-pdfgrep-port/) in the umbrella repo.

## Upstream Dependency Status

E003 (reusable `port-ci.yml` workflow) is not yet shipped in the umbrella repo at v0.1.0 time. Inline workflows (`ci.yml`, `release.yml`) are duplicated from `rusty-pv` (post-fix versions including the `taiki-e/install-action@v2` audit replacement, `rustup target add --toolchain 1.85` cross-target fix, and correct `rusty-pdfgrep` bin name) as a pragmatic-path solution. When E003 v1.0.0 lands, these files are replaced by thin callers pinned to that tag.

## Library Foundation Choices

- **`lopdf` 0.36** — page-level `extract_text(&[page_num])` API matches pdfgrep's "page = grep's line" semantic; encryption hooks ready; 1.7M/mo downloads; pure-Rust (no shared library shipping).
- **`regex` 1 + `fancy-regex` 0.13** — pure-Rust; no libpcre2 FFI. `regex::escape` for `-F`; `fancy-regex` for `-P` lookaround/backreferences. PCRE2-vs-fancy-regex edge cases documented in compat statement.
- **`anstyle` + `termcolor`** — handles legacy Windows console fallback for the `--color` write path.
- **`walkdir` + `globset`** — matches upstream pdfgrep fnmatch semantics exactly (no gitignore awareness, which would silently diverge).

## SemVer Bump Policy

- **MAJOR**: change Strict-mode byte-exact output format; change `PdfGrepError` variant payload; change `Match` semantics; change default match-line format.
- **MINOR**: add a new `PdfGrepError` variant via `#[non_exhaustive]`; add a new `Match` field via `#[non_exhaustive]`; add a new public method on `PdfGrepBuilder`; add a new CLI flag; expose `--features pdfium` opt-in for richer extraction; raise `lopdf` minor pin.
- **PATCH**: bug fixes; performance improvements; doc-only changes.

## Build / Feature Matrix

| Feature combination | Binary | Library deps |
|---|---|---|
| `default = ["cli"]` | `rusty-pdfgrep` | lopdf, regex, fancy-regex, thiserror + clap, clap_complete, anyhow, termcolor, anstyle, walkdir, globset |
| `default-features = false` | none | lopdf, regex, fancy-regex, thiserror |

Verified by `tests/library_api.rs::default_features_off_dep_tree`.

## Panic Boundary

`lopdf` v0.36 has known panic paths on malformed CID font dictionaries. Per AD-012, the per-page extraction is wrapped in `std::panic::catch_unwind`: a panic on page N emits a stderr warning and the iterator advances to page N+1. Exit code stays 0/1 by match presence; only file-OPEN failures escalate to exit 2.