Docs / Help
Contributing
The full guide lives at CONTRIBUTING.md in the repository root; this page mirrors the essentials.
Tests and linting run in CI on every push and pull request
Run
pytest after installing the test extra; CI also uploads coverage to Codecov. A few of the newer or trickier modules still have no coverage, see Adding tests below.
Development setup
bash
git clone https://github.com/Hyacinthe-primus/scanlayer.git
cd scanlayer
python -m venv .venv
source .venv/bin/activate # .venv\Scripts\activate on Windows
pip install -r requirements.txt # from the repo root, next to scanlayer/
pip install -e .
You will also need Tesseract OCR (and poppler, for PDF-input work), see Installation.
Project layout
text
scanlayer/
├── __init__.py # public API: convert, convert_batch, convert_merge, configure
├── main.py # the top-level convert()/convert_batch()/convert_merge()
├── config.py # all tunables, Tesseract/poppler discovery
├── cli/ # argparse CLI: parser.py, run.py, dry_run.py
├── preprocessing/enhance.py # EXIF/OSD/deskew, illumination, denoise, CLAHE, sharpen
├── ocr/engine.py # PSM candidate racing, Tesseract invocation
├── ocr/export.py # txt/json/tsv/hocr exporters
├── layout/columns.py # multi-column reading-order reconstruction
├── pdf/builder.py # searchable PDF construction (single + multi-page)
├── pdf/fonts.py # automatic font selection
└── utils/ # validators, exceptions, logging, debug-image overlay
Making a change
- Open an issue first for anything non-trivial (new flags, a changed default, anything touching the exception hierarchy). Small, obviously-correct fixes can go straight to a PR.
- Keep the CLI and library in sync: every capability should be
reachable both ways, with matching parameter names (
--lang↔lang=). - Respect the two-tier exception hierarchy: a failed precondition is a
ValidationErrorsubclass; an operational failure mid-stage is aPipelineErrorsubclass. Map any new exception to a CLI exit code. See Library API → Exceptions. - Never let OCR-only processing touch the visual background:
backgroundandocr_imagestay separate throughoutpreprocessing/enhance.py. - Update the docs in the same PR: new CLI flag → CLI Reference; new library parameter → Library API; new default → Configuration; new capability → Feature Catalog.
Adding tests
A tests/ directory already exists, covering config.py,
ocr/export.py, layout/columns.py, pdf/fonts.py,
pdf/builder.py, and an end-to-end convert() test (skipped
automatically without a real Tesseract install). Run it with pytest after
installing requirements.txt (which includes pytest). Coverage gaps worth closing next, in priority order:
utils/validators.py: pure functions, no Tesseract required, and not yet exercised directly (only indirectly, through the integration test).preprocessing/enhance.py: EXIF/OSD/deskew, illumination, denoise; needs fixture images with known rotation/lighting defects.ocr/engine.py: the PSM-candidate racing logic, with a real or mocked Tesseract invocation.- More end-to-end cases: a genuine multi-column sample, a rotated sample, a blank-page sample, asserting on word-count/confidence ranges rather than exact OCR text.
Submitting
- One logical change per PR.
- Describe what you tested it against (image type, OS, Tesseract version); CI runs the suite on push, but a manual check of your actual scenario is still welcome.
- Reference the issue you opened, if applicable.
By contributing, you agree your contribution is licensed under this project's MIT License.