from __future__ import annotations from ocr_studio.config import ( LANGUAGE_AUTO, LANGUAGE_BOTH, LANGUAGE_EN, LANGUAGE_FA, LOCALE_EN, LOCALE_FA, MODE_COMPARE, MODE_DOCUMENT, MODE_FIELDS, MODE_MARKDOWN, MODE_PRECISE, MODE_TABLE, ) STRINGS: dict[str, dict[str, str]] = { LOCALE_EN: { "title": "Document OCR", "intro": ( "# Document OCR\n\n" "Extract Persian and English text from scans, photos, or PDFs. " "Download a searchable PDF, Word, Markdown, JSON, and Unicode text. " "Edit the result and rebuild the PDF without running the model again." ), "note.limits": "Images, HEIC, and PDF · up to {max_mb} MB · {max_pages} pages per job", "note.privacy": "Files stay in a temporary folder for this request and are discarded afterward.", "note.quality": "Sharp, well-lit, reasonably straight pages work best. Deskew and high-accuracy mode help difficult scans.", "image": "Camera or image", "files": "PDF or extra images", "language": "Document language", "mode": "Output mode", "deskew": "Straighten and enhance the scan", "accurate": "High accuracy (slower, tiled reading)", "api_key": "API key", "run": "Extract text", "rebuild": "Rebuild files from edited text", "status.wait": "Waiting for a document.", "text": "Extracted text (editable)", "preview": "Detected regions", "pdf": "Searchable PDF", "txt": "Text file", "md": "Markdown", "json": "JSON", "docx": "Word document", "zip": "All files (ZIP)", "history": "This session", "ui_language": "Interface", "examples": "Examples", "footer": ( "Engine: [PaddleOCR-VL-1.6](https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.6) · Apache-2.0 \n" "Author: [Alireza Aminzadeh](https://huggingface.co/alirezaaminzadeh)" ), "lang.auto": "Auto-detect", "lang.fa+en": "Persian + English", "lang.fa": "Persian", "lang.en": "English", "mode.document": "Document text", "mode.precise": "Precise overlay", "mode.table": "Tables", "mode.markdown": "Markdown", "mode.fields": "Form fields", "mode.compare": "Compare text + overlay", "locale.en": "English", "locale.fa": "فارسی", "hist.time": "Time", "hist.pages": "Pages", "hist.language": "Language", "hist.mode": "Mode", "hist.chars": "Characters", "hist.preview": "Preview", "warn.short": "Very little text was read. Try a sharper image or high-accuracy mode.", "warn.sparse": "The page looks sparse relative to its size. Check lighting and crop.", "warn.no_boxes": "No text regions were located. The PDF will use a simple text layer.", "warn.truncated_pages": "Only the first {count} pages were processed.", "warn.deskew": "The scan was straightened by {angle:.1f}°.", "warn.tokens": "The page is dense; some trailing text may be missing. Enable high accuracy or crop the page.", "err.no_input": "Upload an image, take a photo, or attach a PDF.", "err.no_text": "No readable text was found. Try a sharper, well-lit scan.", "err.api_key": "This server requires a valid API key.", "err.option": "Invalid option selected.", "err.rebuild": "Run extraction first, then edit the text and rebuild.", "err.failed": "Processing failed. Try a smaller file or a clearer page.", "err.too_many_pages": "This job exceeds {max_pages} pages. Split the file and try again.", "err.too_many_files": "Upload at most {max_items} files per job.", }, LOCALE_FA: { "title": "بازشناسی اسناد", "intro": ( "# بازشناسی اسناد\n\n" "متن فارسی و انگلیسی را از اسکن، عکس یا PDF استخراج کنید. " "خروجی شامل PDF قابل جستجو، ورد، مارک‌داون، JSON و متن یونیکد است. " "متن را ویرایش کنید و فایل‌ها را بدون اجرای دوبارهٔ مدل بسازید." ), "note.limits": "تصویر، HEIC و PDF · حداکثر {max_mb} مگابایت · {max_pages} صفحه در هر کار", "note.privacy": "فایل‌ها فقط در پوشهٔ موقت همین درخواست ذخیره می‌شوند و بعد از آن حذف می‌گردند.", "note.quality": "صفحهٔ صاف، واضح و با نور مناسب بهترین نتیجه را می‌دهد. صاف‌کردن و حالت دقت بالا برای اسکن‌های سخت مفید است.", "image": "دوربین یا تصویر", "files": "PDF یا تصاویر اضافه", "language": "زبان سند", "mode": "حالت خروجی", "deskew": "صاف‌کردن و بهبود اسکن", "accurate": "دقت بالا (کندتر، خواندن قطعه‌ای)", "api_key": "کلید API", "run": "استخراج متن", "rebuild": "بازسازی فایل‌ها از متن ویرایش‌شده", "status.wait": "در انتظار سند.", "text": "متن استخراج‌شده (قابل ویرایش)", "preview": "نواحی تشخیص‌داده‌شده", "pdf": "PDF قابل جستجو", "txt": "فایل متنی", "md": "مارک‌داون", "json": "JSON", "docx": "سند ورد", "zip": "همهٔ فایل‌ها (ZIP)", "history": "همین نشست", "ui_language": "رابط کاربری", "examples": "نمونه‌ها", "footer": ( "موتور: [PaddleOCR-VL-1.6](https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.6) · Apache-2.0 \n" "نویسنده: [Alireza Aminzadeh](https://huggingface.co/alirezaaminzadeh)" ), "lang.auto": "تشخیص خودکار", "lang.fa+en": "فارسی + انگلیسی", "lang.fa": "فارسی", "lang.en": "انگلیسی", "mode.document": "متن سند", "mode.precise": "لایهٔ دقیق", "mode.table": "جدول", "mode.markdown": "مارک‌داون", "mode.fields": "فیلدهای فرم", "mode.compare": "مقایسه متن و لایه", "locale.en": "English", "locale.fa": "فارسی", "hist.time": "زمان", "hist.pages": "صفحه", "hist.language": "زبان", "hist.mode": "حالت", "hist.chars": "نویسه", "hist.preview": "پیش‌نمایش", "warn.short": "متن خیلی کمی خوانده شد. تصویر واضح‌تر یا حالت دقت بالا را امتحان کنید.", "warn.sparse": "نسبت به اندازهٔ صفحه متن کمی استخراج شد. نور و کادر را بررسی کنید.", "warn.no_boxes": "ناحیهٔ متنی پیدا نشد. PDF با لایهٔ ساده ساخته می‌شود.", "warn.truncated_pages": "فقط {count} صفحهٔ اول پردازش شد.", "warn.deskew": "اسکن به اندازهٔ {angle:.1f} درجه صاف شد.", "warn.tokens": "صفحه فشرده است و ممکن است انتهای متن ناقص باشد. دقت بالا را روشن کنید یا صفحه را برش دهید.", "err.no_input": "یک تصویر آپلود کنید، عکس بگیرید، یا PDF پیوست کنید.", "err.no_text": "متن خوانایی پیدا نشد. اسکن واضح‌تر و با نور بهتر امتحان کنید.", "err.api_key": "این سرور به کلید API معتبر نیاز دارد.", "err.option": "گزینهٔ نامعتبر انتخاب شده است.", "err.rebuild": "ابتدا استخراج را اجرا کنید، سپس متن را ویرایش و بازسازی کنید.", "err.failed": "پردازش ناموفق بود. فایل کوچک‌تر یا صفحهٔ واضح‌تر امتحان کنید.", "err.too_many_pages": "این کار بیش از {max_pages} صفحه دارد. فایل را تقسیم کنید.", "err.too_many_files": "در هر کار حداکثر {max_items} فایل آپلود کنید.", }, } LANGUAGE_LABEL_KEYS = { LANGUAGE_AUTO: "lang.auto", LANGUAGE_BOTH: "lang.fa+en", LANGUAGE_FA: "lang.fa", LANGUAGE_EN: "lang.en", } MODE_LABEL_KEYS = { MODE_DOCUMENT: "mode.document", MODE_PRECISE: "mode.precise", MODE_TABLE: "mode.table", MODE_MARKDOWN: "mode.markdown", MODE_FIELDS: "mode.fields", MODE_COMPARE: "mode.compare", } def normalize_locale(value: str | None) -> str: if value == LOCALE_FA or value == "فارسی": return LOCALE_FA return LOCALE_EN def t(locale: str | None, key: str, **kwargs: object) -> str: bundle = STRINGS.get(normalize_locale(locale), STRINGS[LOCALE_EN]) text = bundle.get(key) or STRINGS[LOCALE_EN].get(key, key) if kwargs: return text.format(**kwargs) return text def language_choices(locale: str | None) -> list[tuple[str, str]]: return [(t(locale, LANGUAGE_LABEL_KEYS[key]), key) for key in LANGUAGE_LABEL_KEYS] def mode_choices(locale: str | None) -> list[tuple[str, str]]: return [(t(locale, MODE_LABEL_KEYS[key]), key) for key in MODE_LABEL_KEYS] def locale_choices(locale: str | None) -> list[tuple[str, str]]: return [(t(locale, "locale.en"), LOCALE_EN), (t(locale, "locale.fa"), LOCALE_FA)]