BabelDOC 0.3.62__tar.gz → 0.3.64__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {babeldoc-0.3.62 → babeldoc-0.3.64}/PKG-INFO +16 -3
- {babeldoc-0.3.62 → babeldoc-0.3.64}/README.md +15 -2
- babeldoc-0.3.64/babeldoc/__init__.py +1 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/assets/embedding_assets_metadata.py +21 -21
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/const.py +1 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/backend/pdf_creater.py +5 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/detect_scanned_file.py +30 -6
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/il_translator.py +1 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/il_translator_llm_only.py +2 -2
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/fontmap.py +37 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/docvision/doclayout.py +1 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/docvision/rpc_doclayout.py +1 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/docvision/table_detection/rapidocr.py +1 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/high_level.py +43 -6
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/main.py +17 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/tools/generate_font_metadata.py +15 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/translation_config.py +16 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/CONTRIBUTOR_REWARD.md +8 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/pyproject.toml +2 -2
- {babeldoc-0.3.62 → babeldoc-0.3.64}/uv.lock +148 -64
- babeldoc-0.3.62/babeldoc/__init__.py +0 -1
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.cursorignore +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/PULL_REQUEST_TEMPLATE/pr_form.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/dependabot.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/labels.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/release-drafter.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/codeql.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/docs.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/labeler.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/lint.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/pr-lint.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/publish-to-pypi.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.github/workflows/test.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.gitignore +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/.pre-commit-config.yaml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/LICENSE +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/assets/assets.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/asynchronize/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/converter.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/backend/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/frontend/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/frontend/il_creater.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/il_version_1.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/il_version_1.rnc +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/il_version_1.rng +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/il_version_1.xsd +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/add_debug_information.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/automatic_term_extractor.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/layout_parser.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/paragraph_finder.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/remove_descent.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/styles_and_formulas.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/table_parser.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/midend/typesetting.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/translator/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/translator/cache.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/translator/translator.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/atomic_integer.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/layout_helper.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/mupdf_helper.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/paragraph_helper.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/priority_thread_pool_executor.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/style_helper.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/utils/zstd_helper.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/document_il/xml_converter.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/docvision/README.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/docvision/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/docvision/base_doclayout.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/format/office/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/glossary.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfinterp.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/LICENSE +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/__init__.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/_saslprep.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/arcfour.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/ascii85.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/casting.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/ccitt.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78ms-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/78ms-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/83pv-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/83pv-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/90ms-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/90ms-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/90msp-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/90msp-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/90pv-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/90pv-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Add-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Add-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Add-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Add-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/B5pc-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/B5pc-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/CNS-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/CNS-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/CNS1-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/CNS1-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/CNS2-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/CNS2-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/ETHK-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/ETHK-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/ETen-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/ETen-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/ETenms-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/ETenms-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Ext-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Ext-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Ext-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Ext-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GB-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GB-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GB-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GB-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBK-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBK-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBK2K-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBK2K-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBKp-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBKp-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBT-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBT-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBT-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBT-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBTpc-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBTpc-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBpc-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/GBpc-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKdla-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKdla-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKdlb-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKdlb-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKgccs-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKgccs-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKm314-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKm314-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKm471-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKm471-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKscs-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/HKscs-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Hankaku-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Hankaku-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Hiragana-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Hiragana-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSC-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSC-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSC-Johab-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSC-Johab-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSCms-UHC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSCms-UHC-HW-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSCms-UHC-HW-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSCms-UHC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSCpc-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/KSCpc-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Katakana-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Katakana-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/NWP-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/NWP-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/README.txt +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Roman-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/Roman-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniCNS-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniGB-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UCS2-HW-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UCS2-HW-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS2004-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS2004-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS2004-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS2004-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS2004-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJIS2004-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJISX0213-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJISX0213-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJISX02132004-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniJISX02132004-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/UniKS-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/WP-Symbol-H.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/WP-Symbol-V.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/to-unicode-Adobe-CNS1.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/to-unicode-Adobe-GB1.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/to-unicode-Adobe-Japan1.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmap/to-unicode-Adobe-Korea1.pickle.gz +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/cmapdb.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/converter.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/data_structures.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/encodingdb.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/fontmetrics.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/glyphlist.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/high_level.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/image.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/jbig2.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/latin_enc.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/layout.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/lzw.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfcolor.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfdevice.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfdocument.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfexceptions.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdffont.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfinterp.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfpage.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdfparser.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/pdftypes.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/psexceptions.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/psparser.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/py.typed +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/runlength.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/settings.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/pdfminer/utils.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/progress_monitor.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/result_merger.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/split_manager.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/tools/italic_assistance.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/babeldoc/tools/italic_recognize_tool.py +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/CODE_OF_CONDUCT.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/CONTRIBUTING.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/README.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/README.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/deploy.sh +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/example/demo_glossary.csv +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-banner.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-big-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-big-logo.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-contributor_reward_example.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-preview.gif +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-small-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/images/babeldoc-small-logo.png +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/index.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/intro-to-pdf-object.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/requirements.txt +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/docs/supported_languages.md +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/mkdocs.yml +0 -0
- {babeldoc-0.3.62 → babeldoc-0.3.64}/tests/test_translation_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: BabelDOC
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.64
|
|
4
4
|
Summary: Yet Another Document Translator
|
|
5
5
|
Project-URL: Homepage, https://github.com/funstory-ai/BabelDOC
|
|
6
6
|
Project-URL: Issues, https://github.com/funstory-ai/BabelDOC/issues
|
|
@@ -210,7 +210,8 @@ uv run babeldoc --files example.pdf --files example2.pdf --openai --openai-model
|
|
|
210
210
|
- `--show-char-box`: Show character bounding boxes (debug only, default: False)
|
|
211
211
|
- `--skip-scanned-detection`: Skip scanned document detection (default: False). When using split translation, only the first part performs detection if not skipped.
|
|
212
212
|
- `--ocr-workaround`: Use OCR workaround (default: False). Only suitable for documents with black text on white background. When enabled, white rectangular blocks will be added below the translation to cover the original text content, and all text will be forced to black color.
|
|
213
|
-
|
|
213
|
+
- `--auto-enable-ocr-workaround`: Enable automatic OCR workaround (default: False). If a document is detected as heavily scanned, this will attempt to enable OCR processing and skip further scan detection. See "Important Interaction Note" below for crucial details on how this interacts with `--ocr-workaround` and `--skip-scanned-detection`.
|
|
214
|
+
- `--primary-font-family`: Override primary font family for translated text. Choices: 'serif' for serif fonts, 'sans-serif' for sans-serif fonts, 'script' for script/italic fonts. If not specified, uses automatic font selection based on original text properties.
|
|
214
215
|
|
|
215
216
|
- `--rpc-doclayout`: RPC service host address for document layout analysis (default: None)
|
|
216
217
|
- `--working-dir`: Working directory for translation. If not set, use temp directory.
|
|
@@ -328,6 +329,7 @@ show_char_box = false # Show character bounding boxes (debug)
|
|
|
328
329
|
ocr_workaround = false # Use OCR workaround for scanned PDFs
|
|
329
330
|
rpc_doclayout = "" # RPC service host for document layout analysis
|
|
330
331
|
working_dir = "" # Working directory for translation
|
|
332
|
+
auto_enable_ocr_workaround = false # Enable automatic OCR workaround for scanned PDFs. See docs for interaction with ocr_workaround and skip_scanned_detection.
|
|
331
333
|
|
|
332
334
|
# Translation service
|
|
333
335
|
openai = true
|
|
@@ -477,4 +479,15 @@ Everyone interacting in YADT and its sub-projects' codebases, issue trackers, ch
|
|
|
477
479
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date" />
|
|
478
480
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date"/>
|
|
479
481
|
</picture>
|
|
480
|
-
</a>
|
|
482
|
+
</a>
|
|
483
|
+
|
|
484
|
+
> [!WARNING]
|
|
485
|
+
> **Important Interaction Note for `--auto-enable-ocr-workaround`:**
|
|
486
|
+
>
|
|
487
|
+
> When `--auto-enable-ocr-workaround` is set to `true` (either via command line or config file):
|
|
488
|
+
>
|
|
489
|
+
> 1. During the initial setup, the values for `ocr_workaround` and `skip_scanned_detection` will be forced to `false` by `TranslationConfig`, regardless of whether you also set `--ocr-workaround` or `--skip-scanned-detection` flags.
|
|
490
|
+
> 2. Then, during the scanned document detection phase (`DetectScannedFile` stage):
|
|
491
|
+
> * If the document is identified as heavily scanned (e.g., >80% scanned pages) AND `auto_enable_ocr_workaround` is `true` (i.e., `translation_config.auto_enable_ocr_workaround` is true), the system will then attempt to set both `ocr_workaround` to `true` and `skip_scanned_detection` to `true`.
|
|
492
|
+
>
|
|
493
|
+
> This means that `--auto-enable-ocr-workaround` effectively gives the system control to enable OCR processing for scanned documents, potentially overriding manual settings for `--ocr-workaround` and `--skip_scanned_detection` based on its detection results. If the document is *not* detected as heavily scanned, then the initial `false` values for `ocr_workaround` and `skip_scanned_detection` (forced by `--auto-enable-ocr-workaround` at the `TranslationConfig` initialization stage) will remain in effect unless changed by other logic.
|
|
@@ -159,7 +159,8 @@ uv run babeldoc --files example.pdf --files example2.pdf --openai --openai-model
|
|
|
159
159
|
- `--show-char-box`: Show character bounding boxes (debug only, default: False)
|
|
160
160
|
- `--skip-scanned-detection`: Skip scanned document detection (default: False). When using split translation, only the first part performs detection if not skipped.
|
|
161
161
|
- `--ocr-workaround`: Use OCR workaround (default: False). Only suitable for documents with black text on white background. When enabled, white rectangular blocks will be added below the translation to cover the original text content, and all text will be forced to black color.
|
|
162
|
-
|
|
162
|
+
- `--auto-enable-ocr-workaround`: Enable automatic OCR workaround (default: False). If a document is detected as heavily scanned, this will attempt to enable OCR processing and skip further scan detection. See "Important Interaction Note" below for crucial details on how this interacts with `--ocr-workaround` and `--skip-scanned-detection`.
|
|
163
|
+
- `--primary-font-family`: Override primary font family for translated text. Choices: 'serif' for serif fonts, 'sans-serif' for sans-serif fonts, 'script' for script/italic fonts. If not specified, uses automatic font selection based on original text properties.
|
|
163
164
|
|
|
164
165
|
- `--rpc-doclayout`: RPC service host address for document layout analysis (default: None)
|
|
165
166
|
- `--working-dir`: Working directory for translation. If not set, use temp directory.
|
|
@@ -277,6 +278,7 @@ show_char_box = false # Show character bounding boxes (debug)
|
|
|
277
278
|
ocr_workaround = false # Use OCR workaround for scanned PDFs
|
|
278
279
|
rpc_doclayout = "" # RPC service host for document layout analysis
|
|
279
280
|
working_dir = "" # Working directory for translation
|
|
281
|
+
auto_enable_ocr_workaround = false # Enable automatic OCR workaround for scanned PDFs. See docs for interaction with ocr_workaround and skip_scanned_detection.
|
|
280
282
|
|
|
281
283
|
# Translation service
|
|
282
284
|
openai = true
|
|
@@ -426,4 +428,15 @@ Everyone interacting in YADT and its sub-projects' codebases, issue trackers, ch
|
|
|
426
428
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date" />
|
|
427
429
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=funstory-ai/babeldoc&type=Date"/>
|
|
428
430
|
</picture>
|
|
429
|
-
</a>
|
|
431
|
+
</a>
|
|
432
|
+
|
|
433
|
+
> [!WARNING]
|
|
434
|
+
> **Important Interaction Note for `--auto-enable-ocr-workaround`:**
|
|
435
|
+
>
|
|
436
|
+
> When `--auto-enable-ocr-workaround` is set to `true` (either via command line or config file):
|
|
437
|
+
>
|
|
438
|
+
> 1. During the initial setup, the values for `ocr_workaround` and `skip_scanned_detection` will be forced to `false` by `TranslationConfig`, regardless of whether you also set `--ocr-workaround` or `--skip-scanned-detection` flags.
|
|
439
|
+
> 2. Then, during the scanned document detection phase (`DetectScannedFile` stage):
|
|
440
|
+
> * If the document is identified as heavily scanned (e.g., >80% scanned pages) AND `auto_enable_ocr_workaround` is `true` (i.e., `translation_config.auto_enable_ocr_workaround` is true), the system will then attempt to set both `ocr_workaround` to `true` and `skip_scanned_detection` to `true`.
|
|
441
|
+
>
|
|
442
|
+
> This means that `--auto-enable-ocr-workaround` effectively gives the system control to enable OCR processing for scanned documents, potentially overriding manual settings for `--ocr-workaround` and `--skip_scanned_detection` based on its detection results. If the document is *not* detected as heavily scanned, then the initial `false` values for `ocr_workaround` and `skip_scanned_detection` (forced by `--auto-enable-ocr-workaround` at the `TranslationConfig` initialization stage) will remain in effect unless changed by other logic.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.64"
|
|
@@ -49,7 +49,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
49
49
|
"font_name": "Go Noto Kurrent-Bold Bold",
|
|
50
50
|
"italic": 0,
|
|
51
51
|
"monospace": 0,
|
|
52
|
-
"serif":
|
|
52
|
+
"serif": 0,
|
|
53
53
|
"sha3_256": "000b37f592477945b27b7702dcad39f73e23e140e66ddff9847eb34f32389566",
|
|
54
54
|
"size": 15303772,
|
|
55
55
|
},
|
|
@@ -62,7 +62,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
62
62
|
"font_name": "Go Noto Kurrent-Regular Regular",
|
|
63
63
|
"italic": 0,
|
|
64
64
|
"monospace": 0,
|
|
65
|
-
"serif":
|
|
65
|
+
"serif": 0,
|
|
66
66
|
"sha3_256": "4324a60d507c691e6efc97420647f4d2c2d86d9de35009d1c769861b76074ae6",
|
|
67
67
|
"size": 15515760,
|
|
68
68
|
},
|
|
@@ -75,7 +75,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
75
75
|
"font_name": "Klee One Regular",
|
|
76
76
|
"italic": 0,
|
|
77
77
|
"monospace": 0,
|
|
78
|
-
"serif":
|
|
78
|
+
"serif": 0,
|
|
79
79
|
"sha3_256": "8585c29f89b322d937f83739f61ede5d84297873e1465cad9a120a208ac55ce0",
|
|
80
80
|
"size": 8724704,
|
|
81
81
|
},
|
|
@@ -88,7 +88,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
88
88
|
"font_name": "LXGW WenKai GB Regular",
|
|
89
89
|
"italic": 0,
|
|
90
90
|
"monospace": 0,
|
|
91
|
-
"serif":
|
|
91
|
+
"serif": 0,
|
|
92
92
|
"sha3_256": "b563a5e8d9db4cd15602a3a3700b01925e80a21f99fb88e1b763b1fb8685f8ee",
|
|
93
93
|
"size": 19558756,
|
|
94
94
|
},
|
|
@@ -101,7 +101,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
101
101
|
"font_name": "LXGW WenKai Mono TC Regular",
|
|
102
102
|
"italic": 0,
|
|
103
103
|
"monospace": 1,
|
|
104
|
-
"serif":
|
|
104
|
+
"serif": 0,
|
|
105
105
|
"sha3_256": "596b278d11418d374a1cfa3a50cbfb82b31db82d3650cfacae8f94311b27fdc5",
|
|
106
106
|
"size": 13115416,
|
|
107
107
|
},
|
|
@@ -114,7 +114,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
114
114
|
"font_name": "LXGW WenKai TC Regular",
|
|
115
115
|
"italic": 0,
|
|
116
116
|
"monospace": 0,
|
|
117
|
-
"serif":
|
|
117
|
+
"serif": 0,
|
|
118
118
|
"sha3_256": "66ccd0ffe8e56cd585dabde8d1292c3f551b390d8ed85f81d7a844825f9c2379",
|
|
119
119
|
"size": 13100328,
|
|
120
120
|
},
|
|
@@ -127,7 +127,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
127
127
|
"font_name": "MaruBuri Regular",
|
|
128
128
|
"italic": 0,
|
|
129
129
|
"monospace": 0,
|
|
130
|
-
"serif":
|
|
130
|
+
"serif": 0,
|
|
131
131
|
"sha3_256": "abb672dde7b89e06914ce27c59159b7a2933f26207bfcc47981c67c11c41e6d1",
|
|
132
132
|
"size": 3268988,
|
|
133
133
|
},
|
|
@@ -140,7 +140,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
140
140
|
"font_name": "Noto Sans Bold",
|
|
141
141
|
"italic": 0,
|
|
142
142
|
"monospace": 0,
|
|
143
|
-
"serif":
|
|
143
|
+
"serif": 0,
|
|
144
144
|
"sha3_256": "ecd38d472c1cad07d8a5dffd2b5a0f72edcd40fff2b4e68d770da8f2ef343a82",
|
|
145
145
|
"size": 630964,
|
|
146
146
|
},
|
|
@@ -153,7 +153,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
153
153
|
"font_name": "Noto Sans Bold Italic",
|
|
154
154
|
"italic": 1,
|
|
155
155
|
"monospace": 0,
|
|
156
|
-
"serif":
|
|
156
|
+
"serif": 0,
|
|
157
157
|
"sha3_256": "0b6c690a4a6b7d605b2ecbde00c7ac1a23e60feb17fa30d8b972d61ec3ff732b",
|
|
158
158
|
"size": 644340,
|
|
159
159
|
},
|
|
@@ -166,7 +166,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
166
166
|
"font_name": "Noto Sans Italic",
|
|
167
167
|
"italic": 1,
|
|
168
168
|
"monospace": 0,
|
|
169
|
-
"serif":
|
|
169
|
+
"serif": 0,
|
|
170
170
|
"sha3_256": "830652f61724c017e5a29a96225b484a2ccbd25f69a1b3f47e5f466a2dbed1ad",
|
|
171
171
|
"size": 642344,
|
|
172
172
|
},
|
|
@@ -179,7 +179,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
179
179
|
"font_name": "Noto Sans Regular",
|
|
180
180
|
"italic": 0,
|
|
181
181
|
"monospace": 0,
|
|
182
|
-
"serif":
|
|
182
|
+
"serif": 0,
|
|
183
183
|
"sha3_256": "7dfe2bbf97dc04c852d1223b220b63430e6ad03b0dbb28ebe6328a20a2d45eb8",
|
|
184
184
|
"size": 629024,
|
|
185
185
|
},
|
|
@@ -244,7 +244,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
244
244
|
"font_name": "Source Han Sans CN Bold",
|
|
245
245
|
"italic": 0,
|
|
246
246
|
"monospace": 0,
|
|
247
|
-
"serif":
|
|
247
|
+
"serif": 0,
|
|
248
248
|
"sha3_256": "82314c11016a04ef03e7afd00abe0ccc8df54b922dee79abf6424f3002a31825",
|
|
249
249
|
"size": 10174460,
|
|
250
250
|
},
|
|
@@ -257,7 +257,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
257
257
|
"font_name": "Source Han Sans CN Regular",
|
|
258
258
|
"italic": 0,
|
|
259
259
|
"monospace": 0,
|
|
260
|
-
"serif":
|
|
260
|
+
"serif": 0,
|
|
261
261
|
"sha3_256": "b45a80cf3650bfc62aa014e58243c6325e182c4b0c5819e41a583c699cce9a8f",
|
|
262
262
|
"size": 10397552,
|
|
263
263
|
},
|
|
@@ -270,7 +270,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
270
270
|
"font_name": "Source Han Sans HK Bold",
|
|
271
271
|
"italic": 0,
|
|
272
272
|
"monospace": 0,
|
|
273
|
-
"serif":
|
|
273
|
+
"serif": 0,
|
|
274
274
|
"sha3_256": "3eecd57457ba9a0fbad6c794f40e7ae704c4f825091aef2ac18902ffdde50608",
|
|
275
275
|
"size": 6856692,
|
|
276
276
|
},
|
|
@@ -283,7 +283,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
283
283
|
"font_name": "Source Han Sans HK Regular",
|
|
284
284
|
"italic": 0,
|
|
285
285
|
"monospace": 0,
|
|
286
|
-
"serif":
|
|
286
|
+
"serif": 0,
|
|
287
287
|
"sha3_256": "5fe4141f9164c03616323400b2936ee4c8265314492e2b822c3a6fbfb63ffe08",
|
|
288
288
|
"size": 6999792,
|
|
289
289
|
},
|
|
@@ -296,7 +296,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
296
296
|
"font_name": "Source Han Sans JP Bold",
|
|
297
297
|
"italic": 0,
|
|
298
298
|
"monospace": 0,
|
|
299
|
-
"serif":
|
|
299
|
+
"serif": 0,
|
|
300
300
|
"sha3_256": "fb05bd84d62e8064117ee357ab6a4481e1cde931e8e984c0553c8c4b09dc3938",
|
|
301
301
|
"size": 5603068,
|
|
302
302
|
},
|
|
@@ -309,7 +309,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
309
309
|
"font_name": "Source Han Sans JP Regular",
|
|
310
310
|
"italic": 0,
|
|
311
311
|
"monospace": 0,
|
|
312
|
-
"serif":
|
|
312
|
+
"serif": 0,
|
|
313
313
|
"sha3_256": "722cfbdcc0fd83fe07a3d1b10e9e64343c924a351d02cfe8dbb6ec4c6bc38230",
|
|
314
314
|
"size": 5723960,
|
|
315
315
|
},
|
|
@@ -322,7 +322,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
322
322
|
"font_name": "Source Han Sans KR Bold",
|
|
323
323
|
"italic": 0,
|
|
324
324
|
"monospace": 0,
|
|
325
|
-
"serif":
|
|
325
|
+
"serif": 0,
|
|
326
326
|
"sha3_256": "02959eb2c1eea0786a736aeb50b6e61f2ab873cd69c659389b7511f80f734838",
|
|
327
327
|
"size": 5858892,
|
|
328
328
|
},
|
|
@@ -335,7 +335,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
335
335
|
"font_name": "Source Han Sans KR Regular",
|
|
336
336
|
"italic": 0,
|
|
337
337
|
"monospace": 0,
|
|
338
|
-
"serif":
|
|
338
|
+
"serif": 0,
|
|
339
339
|
"sha3_256": "aba70109eff718e8f796f0185f8dca38026c1661b43c195883c84577e501adf2",
|
|
340
340
|
"size": 5961704,
|
|
341
341
|
},
|
|
@@ -348,7 +348,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
348
348
|
"font_name": "Source Han Sans TW Bold",
|
|
349
349
|
"italic": 0,
|
|
350
350
|
"monospace": 0,
|
|
351
|
-
"serif":
|
|
351
|
+
"serif": 0,
|
|
352
352
|
"sha3_256": "4a92730e644a1348e87bba7c77e9b462f257f381bd6abbeac5860d8f8306aee6",
|
|
353
353
|
"size": 6883224,
|
|
354
354
|
},
|
|
@@ -361,7 +361,7 @@ EMBEDDING_FONT_METADATA = {
|
|
|
361
361
|
"font_name": "Source Han Sans TW Regular",
|
|
362
362
|
"italic": 0,
|
|
363
363
|
"monospace": 0,
|
|
364
|
-
"serif":
|
|
364
|
+
"serif": 0,
|
|
365
365
|
"sha3_256": "6129b68ff4b0814624cac7edca61fbacf8f4d79db6f4c3cfc46b1c48ea2f81ac",
|
|
366
366
|
"size": 7024812,
|
|
367
367
|
},
|
|
@@ -99,6 +99,7 @@ def parse_truetype_data(data):
|
|
|
99
99
|
TOUNICODE_HEAD = """\
|
|
100
100
|
/CIDInit /ProcSet findresource begin
|
|
101
101
|
12 dict begin
|
|
102
|
+
begincmap
|
|
102
103
|
/CIDSystemInfo <</Registry(Adobe)/Ordering(UCS)/Supplement 0>> def
|
|
103
104
|
/CMapName /Adobe-Identity-UCS def
|
|
104
105
|
/CMapType 2 def
|
|
@@ -124,7 +125,10 @@ def make_tounicode(cmap, used):
|
|
|
124
125
|
if code < 0x10000:
|
|
125
126
|
line.append(f"<{glyph:04x}><{code:04x}>")
|
|
126
127
|
else:
|
|
127
|
-
|
|
128
|
+
code -= 0x10000
|
|
129
|
+
high = 0xD800 + (code >> 10)
|
|
130
|
+
low = 0xDC00 + (code & 0b1111111111)
|
|
131
|
+
line.append(f"<{glyph:04x}><{high:04x}{low:04x}>")
|
|
128
132
|
line.append("endbfchar")
|
|
129
133
|
line.append(TOUNICODE_TAIL)
|
|
130
134
|
return "\n".join(line)
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
import cv2
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pymupdf
|
|
6
|
+
import regex
|
|
6
7
|
from skimage.metrics import structural_similarity
|
|
7
8
|
|
|
8
9
|
from babeldoc.document_il import il_version_1
|
|
@@ -63,6 +64,20 @@ class DetectScannedFile:
|
|
|
63
64
|
),
|
|
64
65
|
)
|
|
65
66
|
|
|
67
|
+
def fast_check(self, doc: pymupdf.Document) -> bool:
|
|
68
|
+
if doc:
|
|
69
|
+
hit_list = [0] * len(doc)
|
|
70
|
+
for page in doc:
|
|
71
|
+
contents_list = page.get_contents()
|
|
72
|
+
for index in contents_list:
|
|
73
|
+
contents = doc.xref_stream(index)
|
|
74
|
+
if regex.search(rb"/Artifact(\s*\<\<|\s+BDC)", contents):
|
|
75
|
+
hit_list[page.number] += 1
|
|
76
|
+
if regex.search(rb"\s3\s+Tr\s", contents):
|
|
77
|
+
hit_list[page.number] += 1
|
|
78
|
+
return bool(sum(hit_list) > len(doc) * 0.8)
|
|
79
|
+
return False
|
|
80
|
+
|
|
66
81
|
def process(self, docs: il_version_1.Document):
|
|
67
82
|
"""Generate layouts for all pages that need to be translated."""
|
|
68
83
|
# Get pages that need to be translated
|
|
@@ -96,11 +111,20 @@ class DetectScannedFile:
|
|
|
96
111
|
progress.advance(1)
|
|
97
112
|
|
|
98
113
|
if scanned > threshold:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
114
|
+
if self.translation_config.auto_enable_ocr_workaround:
|
|
115
|
+
logger.warning(
|
|
116
|
+
f"Detected {scanned} scanned pages, which is more than 80% of the total pages. "
|
|
117
|
+
"Turning on OCR workaround.",
|
|
118
|
+
)
|
|
119
|
+
self.translation_config.shared_context_cross_split_part.auto_enabled_ocr_workaround = True
|
|
120
|
+
self.translation_config.ocr_workaround = True
|
|
121
|
+
self.translation_config.skip_scanned_detection = True
|
|
122
|
+
else:
|
|
123
|
+
logger.warning(
|
|
124
|
+
f"Detected {scanned} scanned pages, which is more than 80% of the total pages. "
|
|
125
|
+
"Please check the input PDF file.",
|
|
126
|
+
)
|
|
127
|
+
raise ScannedPDFError("Scanned PDF detected.")
|
|
104
128
|
|
|
105
129
|
@staticmethod
|
|
106
130
|
def detect_page_is_scanned(page: il_version_1.Page, pdf: pymupdf.Document) -> bool:
|
|
@@ -130,4 +154,4 @@ class DetectScannedFile:
|
|
|
130
154
|
)[:, :, ::-1]
|
|
131
155
|
before_page_image = cv2.cvtColor(before_page_image, cv2.COLOR_RGB2GRAY)
|
|
132
156
|
after_page_image = cv2.cvtColor(after_page_image, cv2.COLOR_RGB2GRAY)
|
|
133
|
-
return structural_similarity(before_page_image, after_page_image) > 0.
|
|
157
|
+
return structural_similarity(before_page_image, after_page_image) > 0.97
|
|
@@ -867,7 +867,7 @@ class ILTranslator:
|
|
|
867
867
|
"3. If there is no need to translate (such as proper nouns, codes, etc.), then return the original text."
|
|
868
868
|
)
|
|
869
869
|
llm_input.append(
|
|
870
|
-
"4. Only output the translation result without explanations and annotations."
|
|
870
|
+
f"4. Only output the translation result in {self.translation_config.lang_out} without explanations and annotations."
|
|
871
871
|
)
|
|
872
872
|
llm_input.append(f"5. Translate text into {self.translation_config.lang_out}.")
|
|
873
873
|
prompt_template = f"""
|
|
@@ -284,7 +284,7 @@ class ILTranslatorLLMOnly:
|
|
|
284
284
|
llm_prompt_parts.append(self.translation_config.custom_system_prompt)
|
|
285
285
|
else:
|
|
286
286
|
llm_prompt_parts.append(
|
|
287
|
-
f"You are a professional and reliable machine translation engine responsible for translating the input text into {self.translation_config.lang_out}
|
|
287
|
+
f"You are a professional and reliable machine translation engine responsible for translating the input text into {self.translation_config.lang_out}.\n"
|
|
288
288
|
"When translating, strictly follow the instructions below to ensure translation quality and preserve all formatting, tags, and placeholders:\n"
|
|
289
289
|
)
|
|
290
290
|
|
|
@@ -378,7 +378,7 @@ class ILTranslatorLLMOnly:
|
|
|
378
378
|
'1. You will receive a JSON object with entries containing "id" and "input" fields.'
|
|
379
379
|
)
|
|
380
380
|
llm_prompt_parts.append(
|
|
381
|
-
'2. Your task is to translate the value of "input" into
|
|
381
|
+
f'2. Your task is to translate the value of "input" into {self.translation_config.lang_out}, while applying the rules above.'
|
|
382
382
|
)
|
|
383
383
|
llm_prompt_parts.append(
|
|
384
384
|
'3. Return a new JSON object with the same "id" and the translated "output" field.'
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import enum
|
|
1
2
|
import functools
|
|
2
3
|
import logging
|
|
3
4
|
import re
|
|
@@ -12,11 +13,39 @@ from babeldoc.translation_config import TranslationConfig
|
|
|
12
13
|
logger = logging.getLogger(__name__)
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
class PrimaryFontFamily(enum.IntEnum):
|
|
17
|
+
SERIF = 1
|
|
18
|
+
SANS_SERIF = 2
|
|
19
|
+
SCRIPT = 3
|
|
20
|
+
NONE = 4
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def from_str(cls, value: str):
|
|
24
|
+
if value == "serif":
|
|
25
|
+
return cls.SERIF
|
|
26
|
+
elif value == "sans-serif":
|
|
27
|
+
return cls.SANS_SERIF
|
|
28
|
+
elif value == "script":
|
|
29
|
+
return cls.SCRIPT
|
|
30
|
+
else:
|
|
31
|
+
return cls.NONE
|
|
32
|
+
|
|
33
|
+
|
|
15
34
|
class FontMapper:
|
|
16
35
|
stage_name = "Add Fonts"
|
|
17
36
|
|
|
18
37
|
def __init__(self, translation_config: TranslationConfig):
|
|
19
38
|
self.translation_config = translation_config
|
|
39
|
+
assert translation_config.primary_font_family in [
|
|
40
|
+
None,
|
|
41
|
+
"serif",
|
|
42
|
+
"sans-serif",
|
|
43
|
+
"script",
|
|
44
|
+
]
|
|
45
|
+
self.primary_font_family = PrimaryFontFamily.from_str(
|
|
46
|
+
translation_config.primary_font_family,
|
|
47
|
+
)
|
|
48
|
+
|
|
20
49
|
font_family = assets.get_font_family(translation_config.lang_out)
|
|
21
50
|
self.font_file_names = []
|
|
22
51
|
for k in (
|
|
@@ -141,6 +170,14 @@ class FontMapper:
|
|
|
141
170
|
)
|
|
142
171
|
return None
|
|
143
172
|
|
|
173
|
+
if self.primary_font_family == PrimaryFontFamily.SERIF:
|
|
174
|
+
serif = True
|
|
175
|
+
elif self.primary_font_family == PrimaryFontFamily.SANS_SERIF:
|
|
176
|
+
serif = False
|
|
177
|
+
elif self.primary_font_family == PrimaryFontFamily.SCRIPT:
|
|
178
|
+
serif = False
|
|
179
|
+
italic = True
|
|
180
|
+
|
|
144
181
|
script_font_map_result = self.map_in_type(
|
|
145
182
|
bold, italic, monospaced, serif, char_unicode, "script"
|
|
146
183
|
)
|
|
@@ -217,7 +217,7 @@ class OnnxModel(DocLayoutModel):
|
|
|
217
217
|
with self.lock:
|
|
218
218
|
# pix = mupdf_doc[page.page_number].get_pixmap(dpi=72)
|
|
219
219
|
pix = get_no_rotation_img(mupdf_doc[page.page_number])
|
|
220
|
-
image = np.
|
|
220
|
+
image = np.frombuffer(pix.samples, np.uint8).reshape(
|
|
221
221
|
pix.height,
|
|
222
222
|
pix.width,
|
|
223
223
|
3,
|
|
@@ -259,7 +259,7 @@ class RpcDocLayoutModel(DocLayoutModel):
|
|
|
259
259
|
with self.lock:
|
|
260
260
|
# pix = mupdf_doc[page.page_number].get_pixmap(dpi=72)
|
|
261
261
|
pix = get_no_rotation_img(mupdf_doc[page.page_number])
|
|
262
|
-
image = np.
|
|
262
|
+
image = np.frombuffer(pix.samples, np.uint8).reshape(
|
|
263
263
|
pix.height,
|
|
264
264
|
pix.width,
|
|
265
265
|
3,
|
|
@@ -239,7 +239,7 @@ class RapidOCRModel:
|
|
|
239
239
|
with self.lock:
|
|
240
240
|
# pix = mupdf_doc[page.page_number].get_pixmap(dpi=72)
|
|
241
241
|
pix = get_no_rotation_img(mupdf_doc[page.page_number])
|
|
242
|
-
image = np.
|
|
242
|
+
image = np.frombuffer(pix.samples, np.uint8).reshape(
|
|
243
243
|
pix.height,
|
|
244
244
|
pix.width,
|
|
245
245
|
3,
|
|
@@ -4,6 +4,7 @@ import hashlib
|
|
|
4
4
|
import io
|
|
5
5
|
import logging
|
|
6
6
|
import pathlib
|
|
7
|
+
import re
|
|
7
8
|
import shutil
|
|
8
9
|
import threading
|
|
9
10
|
import time
|
|
@@ -21,6 +22,8 @@ from babeldoc.assets.assets import warmup
|
|
|
21
22
|
from babeldoc.const import CACHE_FOLDER
|
|
22
23
|
from babeldoc.converter import TranslateConverter
|
|
23
24
|
from babeldoc.document_il import il_version_1
|
|
25
|
+
from babeldoc.document_il.babeldoc_exception.BabelDOCException import ExtractTextError
|
|
26
|
+
from babeldoc.document_il.babeldoc_exception.BabelDOCException import ScannedPDFError
|
|
24
27
|
from babeldoc.document_il.backend.pdf_creater import SAVE_PDF_STAGE_NAME
|
|
25
28
|
from babeldoc.document_il.backend.pdf_creater import SUBSET_FONT_STAGE_NAME
|
|
26
29
|
from babeldoc.document_il.backend.pdf_creater import PDFCreater
|
|
@@ -185,7 +188,7 @@ def start_parse_il(
|
|
|
185
188
|
# but in order to facilitate the migration of pdf2zh,
|
|
186
189
|
# the relevant code is temporarily retained.
|
|
187
190
|
# pix = doc_zh[page.pageno].get_pixmap()
|
|
188
|
-
# image = np.
|
|
191
|
+
# image = np.frombuffer(pix.samples, np.uint8).reshape(
|
|
189
192
|
# pix.height, pix.width, 3
|
|
190
193
|
# )[:, :, ::-1]
|
|
191
194
|
# page_layout = model.predict(
|
|
@@ -590,11 +593,7 @@ def do_translate(
|
|
|
590
593
|
result.original_pdf_path = translation_config.input_file
|
|
591
594
|
result.peak_memory_usage = peak_memory_usage
|
|
592
595
|
|
|
593
|
-
|
|
594
|
-
# Although the issue of Windows Edge
|
|
595
|
-
# not being able to copy translated text can be fixed,
|
|
596
|
-
# the macOS preview is broken
|
|
597
|
-
# fix_cmap(result, translation_config)
|
|
596
|
+
fix_cmap(result, translation_config)
|
|
598
597
|
try:
|
|
599
598
|
migrate_toc(translation_config, result)
|
|
600
599
|
except Exception as e:
|
|
@@ -684,12 +683,30 @@ def fix_media_box(doc: Document) -> None:
|
|
|
684
683
|
return mediabox_data
|
|
685
684
|
|
|
686
685
|
|
|
686
|
+
def check_cid_char(il: il_version_1.Document):
|
|
687
|
+
chars = []
|
|
688
|
+
for page in il.page:
|
|
689
|
+
chars.extend(page.pdf_character)
|
|
690
|
+
|
|
691
|
+
cid_count = 0
|
|
692
|
+
for char in chars:
|
|
693
|
+
if re.match(r"^\(cid:\d+\)$", char.char_unicode):
|
|
694
|
+
cid_count += 1
|
|
695
|
+
|
|
696
|
+
return cid_count > len(chars) * 0.8
|
|
697
|
+
|
|
698
|
+
|
|
687
699
|
def _do_translate_single(
|
|
688
700
|
pm: ProgressMonitor,
|
|
689
701
|
translation_config: TranslationConfig,
|
|
690
702
|
) -> TranslateResult:
|
|
691
703
|
"""Original translation logic for a single document or part"""
|
|
692
704
|
translation_config.progress_monitor = pm
|
|
705
|
+
|
|
706
|
+
if translation_config.shared_context_cross_split_part.auto_enabled_ocr_workaround:
|
|
707
|
+
translation_config.ocr_workaround = True
|
|
708
|
+
translation_config.skip_scanned_detection = True
|
|
709
|
+
|
|
693
710
|
original_pdf_path = translation_config.input_file
|
|
694
711
|
if translation_config.debug:
|
|
695
712
|
doc_input = Document(original_pdf_path)
|
|
@@ -725,6 +742,23 @@ def _do_translate_single(
|
|
|
725
742
|
|
|
726
743
|
resfont = None
|
|
727
744
|
doc_pdf2zh.save(temp_pdf_path)
|
|
745
|
+
|
|
746
|
+
if not translation_config.skip_scanned_detection and DetectScannedFile(
|
|
747
|
+
translation_config
|
|
748
|
+
).fast_check(doc_pdf2zh):
|
|
749
|
+
if translation_config.auto_enable_ocr_workaround:
|
|
750
|
+
logger.warning(
|
|
751
|
+
"Fast scanned check hit, Turning on OCR workaround.",
|
|
752
|
+
)
|
|
753
|
+
translation_config.shared_context_cross_split_part.auto_enabled_ocr_workaround = True
|
|
754
|
+
translation_config.ocr_workaround = True
|
|
755
|
+
translation_config.skip_scanned_detection = True
|
|
756
|
+
else:
|
|
757
|
+
logger.warning(
|
|
758
|
+
"Fast scanned check hit, Please check the input PDF file.",
|
|
759
|
+
)
|
|
760
|
+
raise ScannedPDFError("Scanned PDF detected.")
|
|
761
|
+
|
|
728
762
|
il_creater = ILCreater(translation_config)
|
|
729
763
|
il_creater.mupdf = doc_pdf2zh
|
|
730
764
|
xml_converter = XMLConverter()
|
|
@@ -747,6 +781,9 @@ def _do_translate_single(
|
|
|
747
781
|
translation_config.get_working_file_path("create_il.debug.json"),
|
|
748
782
|
)
|
|
749
783
|
|
|
784
|
+
if check_cid_char(docs):
|
|
785
|
+
raise ExtractTextError("The document contains too many CID chars.")
|
|
786
|
+
|
|
750
787
|
# Rest of the original translation logic...
|
|
751
788
|
# [Previous implementation of do_translate continues here]
|
|
752
789
|
|
|
@@ -21,7 +21,7 @@ from babeldoc.translation_config import TranslationConfig
|
|
|
21
21
|
from babeldoc.translation_config import WatermarkOutputMode
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
|
-
__version__ = "0.3.
|
|
24
|
+
__version__ = "0.3.64"
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def create_parser():
|
|
@@ -248,6 +248,19 @@ def create_parser():
|
|
|
248
248
|
default=True,
|
|
249
249
|
help="Disable automatic term extraction. (Config file: set auto_extract_glossary = false)",
|
|
250
250
|
)
|
|
251
|
+
translation_group.add_argument(
|
|
252
|
+
"--auto-enable-ocr-workaround",
|
|
253
|
+
action="store_true",
|
|
254
|
+
default=False,
|
|
255
|
+
help="Enable automatic OCR workaround. If a document is detected as heavily scanned, this will attempt to enable OCR processing and skip further scan detection. Note: This option interacts with `--ocr-workaround` and `--skip-scanned-detection`. See documentation for details. (default: False)",
|
|
256
|
+
)
|
|
257
|
+
translation_group.add_argument(
|
|
258
|
+
"--primary-font-family",
|
|
259
|
+
type=str,
|
|
260
|
+
choices=["serif", "sans-serif", "script"],
|
|
261
|
+
default=None,
|
|
262
|
+
help="Override primary font family for translated text. Choices: 'serif' for serif fonts, 'sans-serif' for sans-serif fonts, 'script' for script/italic fonts. If not specified, uses automatic font selection based on original text properties.",
|
|
263
|
+
)
|
|
251
264
|
# service option argument group
|
|
252
265
|
service_group = translation_group.add_mutually_exclusive_group()
|
|
253
266
|
service_group.add_argument(
|
|
@@ -468,6 +481,8 @@ async def main():
|
|
|
468
481
|
glossaries=loaded_glossaries,
|
|
469
482
|
pool_max_workers=args.pool_max_workers,
|
|
470
483
|
auto_extract_glossary=args.auto_extract_glossary,
|
|
484
|
+
auto_enable_ocr_workaround=args.auto_enable_ocr_workaround,
|
|
485
|
+
primary_font_family=args.primary_font_family,
|
|
471
486
|
)
|
|
472
487
|
|
|
473
488
|
# Create progress handler
|
|
@@ -602,6 +617,7 @@ def cli():
|
|
|
602
617
|
or v.name.startswith("httpx")
|
|
603
618
|
or "http11" in v.name
|
|
604
619
|
or "openai" in v.name
|
|
620
|
+
or "pdfminer" in v.name
|
|
605
621
|
):
|
|
606
622
|
v.disabled = True
|
|
607
623
|
v.propagate = False
|