Abjad_0.2 / abjad_convert.py
Alsamir's picture
Add Hunyuan-style repository documentation and tooling
2885e32 verified
Raw History Blame Contribute Delete
2.66 kB
#!/usr/bin/env python3
"""One-command Arabic scanned document conversion to editable RTL Word."""
import argparse, json, subprocess, tempfile
from pathlib import Path
ROOT = Path(__file__).resolve().parent
BUNDLED_PYTHON = Path("/Users/abdulrahmanalshehry/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3")
def main():
ap = argparse.ArgumentParser(description="Convert Arabic images, scanned PDFs, or scanned Word files to RTL DOCX")
ap.add_argument("input", type=Path); ap.add_argument("output", type=Path)
ap.add_argument("--dpi", type=int, default=150); ap.add_argument("--resume", action="store_true"); ap.add_argument("--layout", action="store_true", help="Use Abjad vision layout mode for tables and structured pages"); ap.add_argument("--trained", action="store_true", help="Use the trained MLX LoRA adapter instead of fast macOS Vision")
args = ap.parse_args()
with tempfile.TemporaryDirectory(prefix="abjad-convert-") as td:
temp = Path(td); text = temp / "ocr.txt"
venv_python = ROOT / ".venv" / "bin" / "python"
word_python = str(BUNDLED_PYTHON) if BUNDLED_PYTHON.exists() else "python3"
python = str(venv_python) if args.trained and venv_python.exists() else word_python
if args.layout and args.trained:
ap.error("--layout and --trained are mutually exclusive")
if args.layout:
subprocess.run([python, str(ROOT / "extract_to_word.py"), str(args.input), "-o", str(args.output), "--model", "Abjad_0.1", "--dpi", str(args.dpi)], check=True)
print(json.dumps({"word_output": str(args.output), "mode": "layout"}, ensure_ascii=False)); return
engine = "macOS Vision Arabic OCR"
pipeline = ROOT / "vision_pipeline.py"
if args.trained:
pipeline = ROOT / "mlx_ocr_pipeline.py"
engine = "Abjad MLX LoRA Arabic OCR"
command = [python, str(pipeline), str(args.input), "-o", str(text), "--dpi", str(args.dpi)]
if args.trained:
command.extend(["--adapter", str(ROOT / "adapters")])
if args.resume: command.append("--resume")
subprocess.run(command, check=True)
subprocess.run([word_python, str(ROOT / "text_to_word.py"), str(text), str(args.output)], check=True)
report = json.loads((text.with_suffix(".progress.json")).read_text(encoding="utf-8"))
report["word_output"] = str(args.output)
args.output.with_suffix(".quality.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(report, ensure_ascii=False, indent=2))
if __name__ == "__main__": main()