Relocate convert_to_scanned.sh from tests/fixtures/scanned/ to tools/ with comprehensive documentation header. Delete incomplete regenerate.sh stub from tests/fixtures/grep-corpus/. Create tools/README.md cataloging all 18 generators with usage examples. Changes: - Move: tests/fixtures/scanned/convert_to_scanned.sh → tools/convert_pdf_to_scanned.sh - Delete: tests/fixtures/grep-corpus/regenerate.sh (incomplete stub) - Create: tools/README.md (comprehensive generator catalog) - Enhance: convert_pdf_to_scanned.sh with detailed documentation Closes bf-2yhak |
||
|---|---|---|
| .. | ||
| build-objstm-fixture | ||
| build-xref-fixture | ||
| debug-fingerprint | ||
| debug-fingerprint-diff | ||
| convert_pdf_to_scanned.sh | ||
| count_docs.py | ||
| count_docs.sh | ||
| count_public_api.py | ||
| extract-release-notes.sh | ||
| generate_encoding_fixtures.py | ||
| generate_encrypted_pdf_fixtures.py | ||
| generate_encrypted_pdf_fixtures.rs | ||
| generate_invoice_fixture.rs | ||
| generate_invoice_pdf_fixtures.py | ||
| generate_stress_pdf.py | ||
| README.md | ||
pdftract Tools & Generators
This directory contains utility scripts and generators for creating PDF test fixtures, debugging, and development workflow automation.
PDF Fixture Generators
Python Generators
generate_encoding_fixtures.py
Purpose: Generate Unicode recovery test fixtures for Phase 2.2–2.5
Fixtures Generated:
no-mapping.pdf- Font with no ToUnicode and no standard encoding (worst case)agl-only.pdf- Font with only AGL glyph names (Level 2 recovery)fingerprint-match.pdf- Font embedded for fingerprint matching (Level 3)shape-match.pdf- Font for shape-based recognition (Level 4)
Usage:
python tools/generate_encoding_fixtures.py
Requirements: Python 3, standard library only
generate_encrypted_pdf_fixtures.py
Purpose: Generate encrypted PDF test fixtures for password handling
Fixtures Generated:
EC-04.pdf- RC4-40 encrypted PDF (V=1, R=2)EC-05.pdf- AES-128 encrypted PDF (V=4, R=4)EC-06.pdf- AES-256 encrypted PDF (V=5, R=6)EC-empty-password.pdf- PDF with empty password
Usage:
python tools/generate_encrypted_pdf_fixtures.py
Requirements: Python 3, pikepdf
generate_stress_pdf.py
Purpose: Generate synthetic stress-test PDFs for memory ceiling testing
Fixtures Generated:
- Large-page-count PDFs for memory target validation
- 100-page vector PDF for buffered mode testing (target: < 512 MB)
- 10,000-page stress test for streaming mode validation (target: < 256 MB)
Usage:
python tools/generate_stress_pdf.py --pages 100 -o tests/fixtures/perf/100-page-vector.pdf
python tools/generate_stress_pdf.py --pages 10000 -o tests/fixtures/perf/10k-page.pdf
Requirements: Python 3, reportlab
generate_invoice_pdf_fixtures.py
Purpose: Generate invoice OCR test fixtures with proper DPI metadata
Fixtures Generated:
- Scanned PDF with correct 300 DPI settings
- Single invoice page with ground truth text for OCR testing
Usage:
python tools/generate_invoice_pdf_fixtures.py
Requirements: Python 3, PIL (Pillow)
count_docs.py
Purpose: Count rustdoc coverage for pdftract-core
Usage:
python tools/count_docs.py
Requirements: Python 3, standard library only
Rust Generators
generate_invoice_fixture.rs
Purpose: Generate invoice fixture as a native Rust binary
Usage:
cargo run --bin generate_invoice_fixture
generate_encrypted_pdf_fixtures.rs
Purpose: Generate encrypted PDF fixtures as a native Rust binary
Usage:
cargo run --bin generate_encrypted_pdf_fixtures
Shell Scripts
convert_pdf_to_scanned.sh
Purpose: Convert text-embedded PDFs to scanned image-based PDFs at 300 DPI
Fixtures Generated:
invoice/invoice-300dpi.pdf(and backup invoice-300dpi-text-embedded.pdf)letter/letter-300dpi.pdf(and backup letter-300dpi-text-embedded.pdf)form/form-300dpi.pdf(and backup form-300dpi-text-embedded.pdf)
Usage:
./tools/convert_pdf_to_scanned.sh
Requirements:
pdftoppm(poppler-utils)- ImageMagick (via nix-shell or direct installation)
Process:
- Backs up original text-embedded versions with
-text-embedded.pdfsuffix - Converts PDF to PPM images at specified DPI using
pdftoppm - Converts PPM images back to PDF using ImageMagick
- Cleans up temporary files
count_docs.sh
Purpose: Wrapper script for documentation counting
Usage:
./tools/count_docs.sh
extract-release-notes.sh
Purpose: Extract release notes from git commits
Usage:
./tools/extract-release-notes.sh
Debugging Tools
debug-fingerprint/
Purpose: Debug tool for PDF fingerprint computation
Usage:
cargo run --bin debug-fingerprint -- <pdf-path>
Output: Displays PDF fingerprint and computation time
debug-fingerprint-diff/
Purpose: Compare fingerprints between two PDFs
Usage:
cargo run --bin debug-fingerprint-diff -- <pdf1> <pdf2>
Specialized Fixture Builders
build-objstm-fixture/
Purpose: Generate object stream fixtures for testing
Usage:
cd tools/build-objstm-fixture
cargo run --bin build-objstm-fixture
Fixtures Generated:
- Minimal PDFs with specific object stream structures
- Various compressed object configurations
build-xref-fixture/
Purpose: Generate xref testing fixtures
Usage:
cd tools/build-xref-fixture
cargo run --bin build-xref-fixture
Fixture Types:
- Well-formed PDF with traditional xref table
- Well-formed PDF with xref stream (PDF 1.5)
- Hybrid file with traditional xref +
/XRefStm - PDF with 3 incremental revisions (
/Prevchain) - Linearized PDF (50 pages)
- File truncated at the start of xref
- File with
startxrefoffset off by one - File with corrupt xref entry
- File with circular
/Prevreference
Development Workflow
Quick Documentation Coverage Check
python tools/count_docs.py
Generate All Encoding Fixtures
python tools/generate_encoding_fixtures.py
Generate All Encrypted PDF Fixtures
python tools/generate_encrypted_pdf_fixtures.py
Generate Stress Test PDFs
python tools/generate_stress_pdf.py --pages 100 -o tests/fixtures/perf/100-page.pdf
python tools/generate_stress_pdf.py --pages 10000 -o tests/fixtures/perf/10k-page.pdf
Debug Fingerprint Issues
cargo run --bin debug-fingerprint -- tests/fixtures/your-file.pdf
Contributing
When adding new generators:
- Use descriptive names with
generate_prefix - Add a docstring/comment block explaining:
- What fixtures it generates
- How to run it (command line, dependencies)
- Any special requirements (input data, API keys, etc.)
- Update this README with the new tool
- Follow existing patterns (Python for encoding/OCR, Rust for security/crypto)