Compare every original page with its recognized text before editing,
+ sharing, or printing the transcription.
+
+ {"".join(cards)}
+
+
+
+"""
+ output.write_text(document, encoding="utf-8")
+
+
+def build_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(
+ description="Turn one or more handwriting photos into reviewable documents."
+ )
+ parser.add_argument("inputs", nargs="+", type=Path, help="Image files in reading order")
+ parser.add_argument("-o", "--output", type=Path, default=Path("output/handwriting"))
+ parser.add_argument("--title", default="Handwriting transcription")
+ parser.add_argument("--language", default="eng", help="Installed Tesseract language code")
+ parser.add_argument("--psm", type=int, default=6, choices=range(14))
+ parser.add_argument("--tesseract", help="Path to the Tesseract executable")
+ parser.add_argument("--debug-images", action="store_true")
+ parser.add_argument(
+ "--no-review-report",
+ action="store_true",
+ help="Skip the self-contained HTML source/transcription review report",
+ )
+ return parser
+
+
+def main(argv: list[str] | None = None) -> int:
+ args = build_parser().parse_args(argv)
+ try:
+ verify_tesseract(args.tesseract)
+ results = convert_images(
+ args.inputs,
+ language=args.language,
+ page_segmentation=args.psm,
+ debug_dir=args.output.parent / "debug" if args.debug_images else None,
+ )
+ write_text(results, args.output.with_suffix(".txt"))
+ write_pdf(results, args.output.with_suffix(".pdf"), args.title)
+ if not args.no_review_report:
+ write_review_report(results, args.output.with_suffix(".html"), args.title)
+ except (FileNotFoundError, RuntimeError, ValueError) as exc:
+ print(f"error: {exc}")
+ return 1
+
+ detected = sum(bool(item.text) for item in results)
+ print(f"Converted {len(results)} page(s); detected text on {detected}.")
+ print(f"Text: {args.output.with_suffix('.txt')}")
+ print(f"PDF: {args.output.with_suffix('.pdf')}")
+ if not args.no_review_report:
+ print(f"Review: {args.output.with_suffix('.html')}")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
From 40ab67cf4c97fd1dfa5870e8d5a9c9ae7e7d0696 Mon Sep 17 00:00:00 2001
From: SimpleCaci <92838396+SimpleCaci@users.noreply.github.com>
Date: Fri, 6 Nov 2026 19:56:46 -0800
Subject: [PATCH 2/2] docs: clarify OCR setup and contribution workflow
---
CONTRIBUTING.md | 16 ++++++++++++++++
README.md | 4 ++++
2 files changed, 20 insertions(+)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..924eb83
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,16 @@
+# Contributing to HandwritingConverter
+
+Use Python 3.11+ and the Tesseract installation described in the README. Install `requirements-dev.txt` in a virtual environment, then run:
+
+```bash
+ruff check main.py tests
+python -m pytest -q
+```
+
+The deterministic tests replace the OCR call while exercising image preparation, reports, and file output. Changes to recognition behavior should also include a local Tesseract run and identify the language data and page-segmentation mode used.
+
+Keep sample notes synthetic or yours to share. Do not attach private class notes or someone else's handwriting without permission. For an OCR bug, describe lighting, image orientation, Tesseract version, command options, and expected versus observed text. Confidence scores are not accuracy measurements.
+
+For a pull request, explain the change and validation. Include a report screenshot for presentation changes, and preserve the distinction between raw OCR and manually reviewed text. Discuss a new OCR backend or desktop interface in an issue before adding large dependencies.
+
+Contributions follow the existing MIT license. There is no guaranteed support or response time.
diff --git a/README.md b/README.md
index 54c1edd..822785e 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,10 @@
Turn photos of handwritten notes into searchable text and a printable PDF.
+[](https://github.com/SimpleCaci/HandwritingConverter/actions/workflows/validate.yml)
+
+[Install](#installation) · [Convert notes](#usage) · [Contribute](CONTRIBUTING.md)
+

I built this because writing by hand is often the fastest way for me to think, but paper notes are difficult to search, revise, and print with my portable printer. HandwritingConverter connects those two workflows without pretending that handwriting OCR is perfect.