Repository navigation
Development
git clone https://github.com/0x1d1e/ocr-foundry.git
cd ocr-foundry
uv sync --extra dev # installs dev deps (pytest, ruff, ty) - pure Python
uv sync --extra dev --extra rust # also builds the Rust extension via maturinuv sync --extra dev installs development tools without requiring a Rust toolchain.
Adding --extra rust resolves khocr-gen-core from rust/ as an editable path dependency,
building and installing the native acceleration extension.
uv run ruff check . # lint
uv run ruff format . # format
uv run pytest # tests (addopts + coverage config from pyproject.toml)
uv run ty check # type check (CI fails on diagnostics)Run a single test file or test:
uv run pytest tests/test_rendering.py
uv run pytest tests/test_line_height.py -k sampleWith coverage, as CI does:
uv run pytest --cov=khocr_gen --cov-report=term-missingRuff is configured in pyproject.toml:
| Setting | Value |
|---|---|
target-version |
py312 |
line-length |
100 |
| Enabled rules |
E, W, F, I, B, C4, UP, SIM, TCH, RUF
|
| Ignored |
E501 (line too long — handled by the formatter), B008
|
| isort first-party | khocr_gen |
| Format | double quotes, space indent, magic trailing comma preserved |
Because E501 is ignored, the formatter decides line breaks, not the linter. Run
uv run ruff format . before committing.
Tests live in tests/ and are grouped by subsystem:
tests/
├── test_augmentation.py test_combine.py test_config.py
├── test_config_loader.py test_corpus.py test_data_generator.py
├── test_errors.py test_fonts.py test_generate.py
├── test_line_height.py test_lmdb_pack.py test_normalizer.py
├── test_online_aug.py test_parallel.py test_rendering.py
├── test_text_decoration.py test_text_effects.py
pytest is configured with testpaths = ["tests"] and pythonpath = ["src"], so tests import the
working tree without an install. Coverage uses branch coverage over src/khocr_gen and omits
_rust_accel.py.
When you add behaviour, add a test in the matching file. When you fix a bug, add the regression test that would have caught it.
ty runs against src with extra-paths = ["typings"]. Its CI step fails on
diagnostics. Workflow checks become enforced merge requirements only through
repository/organization rulesets or branch protection; verify those settings separately.
.github/workflows/ci.yml runs on pushes to main and on pull requests targeting main.
- Install system packages (
libraqm-dev,libfribidi-dev,libfreetype6-dev,fonts-noto-core,fonts-noto-cjk) - Set up font directories and compatibility symlinks
- Install Rust toolchain (when
rust-accel: true) - Install
uv 0.13.7(cache keyed frompyproject.toml) uv sync --extra dev [--extra rust] --python <version>- Assert native acceleration is active (
rust-accel: true) or pure-Python fallback is active (rust-accel: false) -
uv run ruff check .— gate -
uv run ty check— gate (0 diagnostics required, nocontinue-on-error) -
uv run pytest --cov=khocr_gen --cov-report=term-missing— gate - CLI rendering smoke test (
ocr-foundry layout) for words, tables, transforms, vertical CJK, and mixed fallback — gate
fail-fast: false, so all matrix combinations report even if one fails.
-
cargo fmt --check— gate (strictly enforced, nocontinue-on-error) -
cargo clippy --all-targets -- -D warnings— gate (strictly enforced, nocontinue-on-error) -
cargo build --release— gate
All formatting and clippy diagnostics have been completely eliminated.
Local dependency resolution may create uv.lock, but the repository does not track
it. Record the exact dependency resolution separately when preparing a reproducible
release environment.
Publishing is automated by .github/workflows/publish.yml:
- Triggered by any tag push or manually via
workflow_dispatch. - Builds
sdistand wheel withuv build, then runsuv publish. - The publish step is skipped when
PYPI_TOKENis missing. A green run can mean no upload. - There is no dependency on the CI workflow, tag/version validation, or GitHub Release creation.
For pending v0.2.0, follow the
release runbook.
Repository transfer and rename are complete. Require all checks on the
exact release commit before any tag push. Package version 0.2.0 is already set;
the matching tag will be v0.2.0. Date the pending changelog only when release
readiness is established. Tagging, uploading, publishing a GitHub Release and
publishing wiki pages are separate external actions requiring authorization.
Verify the actual files and version on PyPI,
not only the Actions conclusion. No publishing action has been executed in preparation.
The changelog follows Keep a Changelog and the project follows Semantic Versioning.
See Rust Acceleration, in particular the
warning about cd rust && uv run … creating a stray rust/.venv, and about uv sync overwriting a
hand-built extension.
README.md is the repository landing page. README.pypi.md, selected by pyproject.toml, is the
package description shown on PyPI. docs/ contains in-repository references; this wiki is the
separately published user guide. Keep pages aligned when both describe the same behavior or option.
Update the landing pages when the quick start or project overview changes. For behavior, setup, or configuration changes, update the references and wiki pages that cover them.
- Architecture — module map and pipeline
- Rust Acceleration — native extension workflow
- Troubleshooting — when the dev loop misbehaves
OCR Foundry — synthetic OCR training data with Khmer/English and opt-in multilingual rendering · MIT · Repository · Issues · PyPI · Changelog
Using OCR Foundry
Data controls
- Corpus and Normalization
- Fonts
- Variable Line Height
- Text Decorations and Effects
- Augmentation
- Output and Storage
- Page Layout
Internals
Help