BabelDOC 0.3.61__tar.gz → 0.3.63__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.61 → babeldoc-0.3.63}/PKG-INFO +16 -3
- {babeldoc-0.3.61 → babeldoc-0.3.63}/README.md +15 -2
- babeldoc-0.3.63/babeldoc/__init__.py +1 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/assets/embedding_assets_metadata.py +21 -21
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/const.py +1 -1
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/detect_scanned_file.py +30 -6
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/fontmap.py +37 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/high_level.py +92 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/main.py +17 -1
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/tools/generate_font_metadata.py +15 -1
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/translation_config.py +16 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/pyproject.toml +2 -2
- {babeldoc-0.3.61 → babeldoc-0.3.63}/uv.lock +1 -1
- babeldoc-0.3.61/babeldoc/__init__.py +0 -1
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.cursorignore +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/PULL_REQUEST_TEMPLATE/pr_form.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/dependabot.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/labels.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/release-drafter.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/codeql.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/docs.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/labeler.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/lint.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/pr-lint.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/publish-to-pypi.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.github/workflows/test.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.gitignore +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/.pre-commit-config.yaml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/LICENSE +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/assets/assets.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/asynchronize/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/converter.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/babeldoc_exception/BabelDOCException.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/backend/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/backend/pdf_creater.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/frontend/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/frontend/il_creater.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/il_version_1.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/il_version_1.rnc +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/il_version_1.rng +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/il_version_1.xsd +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/add_debug_information.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/automatic_term_extractor.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/il_translator.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/il_translator_llm_only.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/layout_parser.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/paragraph_finder.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/remove_descent.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/styles_and_formulas.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/table_parser.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/midend/typesetting.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/translator/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/translator/cache.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/translator/translator.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/atomic_integer.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/layout_helper.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/mupdf_helper.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/paragraph_helper.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/priority_thread_pool_executor.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/style_helper.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/utils/zstd_helper.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/document_il/xml_converter.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/docvision/README.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/docvision/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/docvision/base_doclayout.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/docvision/doclayout.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/docvision/rpc_doclayout.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/docvision/table_detection/rapidocr.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/format/office/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/glossary.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfinterp.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/LICENSE +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/__init__.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/_saslprep.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/arcfour.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/ascii85.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/casting.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/ccitt.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78ms-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/78ms-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/83pv-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/83pv-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/90ms-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/90ms-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/90msp-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/90msp-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/90pv-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/90pv-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Add-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Add-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Add-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Add-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/B5pc-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/B5pc-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/CNS-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/CNS-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/CNS1-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/CNS1-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/CNS2-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/CNS2-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/ETHK-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/ETHK-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/ETen-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/ETen-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/ETenms-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/ETenms-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Ext-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Ext-RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Ext-RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Ext-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GB-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GB-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GB-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GB-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBK-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBK-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBK2K-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBK2K-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBKp-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBKp-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBT-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBT-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBT-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBT-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBTpc-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBTpc-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBpc-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/GBpc-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKdla-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKdla-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKdlb-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKdlb-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKgccs-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKgccs-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKm314-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKm314-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKm471-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKm471-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKscs-B5-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/HKscs-B5-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Hankaku-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Hankaku-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Hiragana-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Hiragana-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSC-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSC-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSC-Johab-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSC-Johab-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSCms-UHC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSCms-UHC-HW-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSCms-UHC-HW-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSCms-UHC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSCpc-EUC-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/KSCpc-EUC-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Katakana-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Katakana-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/NWP-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/NWP-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/README.txt +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/RKSJ-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/RKSJ-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Roman-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/Roman-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniCNS-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniGB-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UCS2-HW-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UCS2-HW-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS2004-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS2004-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS2004-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS2004-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS2004-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJIS2004-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJISX0213-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJISX0213-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJISX02132004-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniJISX02132004-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UCS2-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UCS2-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UTF16-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UTF16-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UTF32-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UTF32-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UTF8-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/UniKS-UTF8-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/WP-Symbol-H.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/WP-Symbol-V.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/to-unicode-Adobe-CNS1.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/to-unicode-Adobe-GB1.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/to-unicode-Adobe-Japan1.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmap/to-unicode-Adobe-Korea1.pickle.gz +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/cmapdb.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/converter.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/data_structures.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/encodingdb.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/fontmetrics.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/glyphlist.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/high_level.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/image.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/jbig2.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/latin_enc.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/layout.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/lzw.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfcolor.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfdevice.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfdocument.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfexceptions.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdffont.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfinterp.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfpage.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdfparser.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/pdftypes.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/psexceptions.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/psparser.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/py.typed +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/runlength.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/settings.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/pdfminer/utils.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/progress_monitor.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/result_merger.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/split_manager.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/tools/italic_assistance.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/babeldoc/tools/italic_recognize_tool.py +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/CODE_OF_CONDUCT.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/CONTRIBUTING.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/CONTRIBUTOR_REWARD.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/README.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/README.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/deploy.sh +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/example/demo_glossary.csv +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-banner.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-big-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-big-logo.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-contributor_reward_example.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-preview.gif +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-small-logo-with-transparent-background.svg +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/images/babeldoc-small-logo.png +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/index.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/intro-to-pdf-object.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/requirements.txt +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/docs/supported_languages.md +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/mkdocs.yml +0 -0
- {babeldoc-0.3.61 → babeldoc-0.3.63}/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.63
|
|
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.63"
|
|
@@ -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
|
},
|
|
@@ -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
|
|
@@ -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
|
)
|
|
@@ -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
|
|
@@ -595,6 +598,12 @@ def do_translate(
|
|
|
595
598
|
# not being able to copy translated text can be fixed,
|
|
596
599
|
# the macOS preview is broken
|
|
597
600
|
# fix_cmap(result, translation_config)
|
|
601
|
+
try:
|
|
602
|
+
migrate_toc(translation_config, result)
|
|
603
|
+
except Exception as e:
|
|
604
|
+
logger.error(
|
|
605
|
+
f"Failed to migrate TOC from {translation_config.input_file}: {e}"
|
|
606
|
+
)
|
|
598
607
|
pm.translate_done(result)
|
|
599
608
|
return result
|
|
600
609
|
|
|
@@ -612,6 +621,51 @@ def do_translate(
|
|
|
612
621
|
translation_config.cleanup_temp_files()
|
|
613
622
|
|
|
614
623
|
|
|
624
|
+
def migrate_toc(
|
|
625
|
+
translation_config: TranslationConfig, translate_result: TranslateResult
|
|
626
|
+
):
|
|
627
|
+
old_doc = Document(translation_config.input_file)
|
|
628
|
+
if not old_doc:
|
|
629
|
+
return
|
|
630
|
+
|
|
631
|
+
try:
|
|
632
|
+
fix_filter(old_doc)
|
|
633
|
+
fix_null_xref(old_doc)
|
|
634
|
+
except Exception:
|
|
635
|
+
logger.exception("auto fix failed, please check the pdf file")
|
|
636
|
+
|
|
637
|
+
toc_data = old_doc.get_toc()
|
|
638
|
+
|
|
639
|
+
if not toc_data:
|
|
640
|
+
logger.info("No TOC found in the original PDF, skipping migration.")
|
|
641
|
+
return
|
|
642
|
+
|
|
643
|
+
files = {
|
|
644
|
+
translate_result.dual_pdf_path,
|
|
645
|
+
# translate_result.mono_pdf_path,
|
|
646
|
+
translate_result.no_watermark_dual_pdf_path,
|
|
647
|
+
# translate_result.no_watermark_mono_pdf_path
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
for f in files:
|
|
651
|
+
mig_toc_temp_input = translation_config.get_working_file_path(
|
|
652
|
+
"mig_toc_temp.pdf"
|
|
653
|
+
)
|
|
654
|
+
shutil.copy(f, mig_toc_temp_input)
|
|
655
|
+
new_doc = Document(mig_toc_temp_input.as_posix())
|
|
656
|
+
if not new_doc:
|
|
657
|
+
continue
|
|
658
|
+
|
|
659
|
+
new_doc.set_toc(toc_data)
|
|
660
|
+
PDFCreater.save_pdf_with_timeout(
|
|
661
|
+
new_doc,
|
|
662
|
+
f.as_posix(),
|
|
663
|
+
translation_config=translation_config,
|
|
664
|
+
clean=not translation_config.skip_clean,
|
|
665
|
+
tag="mig_toc",
|
|
666
|
+
)
|
|
667
|
+
|
|
668
|
+
|
|
615
669
|
def fix_media_box(doc: Document) -> None:
|
|
616
670
|
mediabox_data = {}
|
|
617
671
|
for x in range(1, doc.xref_length()):
|
|
@@ -633,12 +687,30 @@ def fix_media_box(doc: Document) -> None:
|
|
|
633
687
|
return mediabox_data
|
|
634
688
|
|
|
635
689
|
|
|
690
|
+
def check_cid_char(il: il_version_1.Document):
|
|
691
|
+
chars = []
|
|
692
|
+
for page in il.page:
|
|
693
|
+
chars.extend(page.pdf_character)
|
|
694
|
+
|
|
695
|
+
cid_count = 0
|
|
696
|
+
for char in chars:
|
|
697
|
+
if re.match(r"^\(cid:\d+\)$", char.char_unicode):
|
|
698
|
+
cid_count += 1
|
|
699
|
+
|
|
700
|
+
return cid_count > len(chars) * 0.8
|
|
701
|
+
|
|
702
|
+
|
|
636
703
|
def _do_translate_single(
|
|
637
704
|
pm: ProgressMonitor,
|
|
638
705
|
translation_config: TranslationConfig,
|
|
639
706
|
) -> TranslateResult:
|
|
640
707
|
"""Original translation logic for a single document or part"""
|
|
641
708
|
translation_config.progress_monitor = pm
|
|
709
|
+
|
|
710
|
+
if translation_config.shared_context_cross_split_part.auto_enabled_ocr_workaround:
|
|
711
|
+
translation_config.ocr_workaround = True
|
|
712
|
+
translation_config.skip_scanned_detection = True
|
|
713
|
+
|
|
642
714
|
original_pdf_path = translation_config.input_file
|
|
643
715
|
if translation_config.debug:
|
|
644
716
|
doc_input = Document(original_pdf_path)
|
|
@@ -674,6 +746,23 @@ def _do_translate_single(
|
|
|
674
746
|
|
|
675
747
|
resfont = None
|
|
676
748
|
doc_pdf2zh.save(temp_pdf_path)
|
|
749
|
+
|
|
750
|
+
if not translation_config.skip_scanned_detection and DetectScannedFile(
|
|
751
|
+
translation_config
|
|
752
|
+
).fast_check(doc_pdf2zh):
|
|
753
|
+
if translation_config.auto_enable_ocr_workaround:
|
|
754
|
+
logger.warning(
|
|
755
|
+
"Fast scanned check hit, Turning on OCR workaround.",
|
|
756
|
+
)
|
|
757
|
+
translation_config.shared_context_cross_split_part.auto_enabled_ocr_workaround = True
|
|
758
|
+
translation_config.ocr_workaround = True
|
|
759
|
+
translation_config.skip_scanned_detection = True
|
|
760
|
+
else:
|
|
761
|
+
logger.warning(
|
|
762
|
+
"Fast scanned check hit, Please check the input PDF file.",
|
|
763
|
+
)
|
|
764
|
+
raise ScannedPDFError("Scanned PDF detected.")
|
|
765
|
+
|
|
677
766
|
il_creater = ILCreater(translation_config)
|
|
678
767
|
il_creater.mupdf = doc_pdf2zh
|
|
679
768
|
xml_converter = XMLConverter()
|
|
@@ -696,6 +785,9 @@ def _do_translate_single(
|
|
|
696
785
|
translation_config.get_working_file_path("create_il.debug.json"),
|
|
697
786
|
)
|
|
698
787
|
|
|
788
|
+
if check_cid_char(docs):
|
|
789
|
+
raise ExtractTextError("The document contains too many CID chars.")
|
|
790
|
+
|
|
699
791
|
# Rest of the original translation logic...
|
|
700
792
|
# [Previous implementation of do_translate continues here]
|
|
701
793
|
|
|
@@ -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.63"
|
|
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
|
|
@@ -6,6 +6,7 @@ import argparse
|
|
|
6
6
|
import hashlib
|
|
7
7
|
import io
|
|
8
8
|
import logging
|
|
9
|
+
import re
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
11
12
|
import babeldoc.high_level
|
|
@@ -17,6 +18,13 @@ from rich.logging import RichHandler
|
|
|
17
18
|
|
|
18
19
|
logger = logging.getLogger(__name__)
|
|
19
20
|
|
|
21
|
+
serif_keywords = [
|
|
22
|
+
"serif",
|
|
23
|
+
]
|
|
24
|
+
sans_serif_keywords = ["sans", "GoNotoKurrent"]
|
|
25
|
+
serif_regex = "|".join(serif_keywords)
|
|
26
|
+
sans_serif_regex = "|".join(sans_serif_keywords)
|
|
27
|
+
|
|
20
28
|
|
|
21
29
|
def get_font_metadata(font_path) -> PdfFont:
|
|
22
30
|
doc = pymupdf.open()
|
|
@@ -74,6 +82,12 @@ def main():
|
|
|
74
82
|
break
|
|
75
83
|
hash_.update(chunk)
|
|
76
84
|
extracted_metadata = get_font_metadata(font_path)
|
|
85
|
+
|
|
86
|
+
if re.search(serif_regex, extracted_metadata.name, re.IGNORECASE):
|
|
87
|
+
serif = 1
|
|
88
|
+
else:
|
|
89
|
+
serif = 0
|
|
90
|
+
|
|
77
91
|
metadata = {
|
|
78
92
|
"file_name": font_path.name,
|
|
79
93
|
"font_name": extracted_metadata.name,
|
|
@@ -81,7 +95,7 @@ def main():
|
|
|
81
95
|
"bold": extracted_metadata.bold,
|
|
82
96
|
"italic": extracted_metadata.italic,
|
|
83
97
|
"monospace": extracted_metadata.monospace,
|
|
84
|
-
"serif":
|
|
98
|
+
"serif": serif,
|
|
85
99
|
"ascent": extracted_metadata.ascent,
|
|
86
100
|
"descent": extracted_metadata.descent,
|
|
87
101
|
"sha3_256": hash_.hexdigest(),
|
|
@@ -31,6 +31,7 @@ class SharedContextCrossSplitPart:
|
|
|
31
31
|
self.user_glossaries: list[Glossary] = []
|
|
32
32
|
self.auto_extracted_glossary: Glossary | None = None
|
|
33
33
|
self.raw_extracted_terms: list[tuple[str, str]] = []
|
|
34
|
+
self.auto_enabled_ocr_workaround = False
|
|
34
35
|
|
|
35
36
|
def initialize_glossaries(self, initial_glossaries: list[Glossary] | None):
|
|
36
37
|
with self._lock:
|
|
@@ -150,6 +151,8 @@ class TranslationConfig:
|
|
|
150
151
|
glossaries: list[Glossary] | None = None,
|
|
151
152
|
pool_max_workers: int | None = None,
|
|
152
153
|
auto_extract_glossary: bool = True,
|
|
154
|
+
auto_enable_ocr_workaround: bool = False,
|
|
155
|
+
primary_font_family: str | None = None,
|
|
153
156
|
):
|
|
154
157
|
self.translator = translator
|
|
155
158
|
initial_user_glossaries = list(glossaries) if glossaries else []
|
|
@@ -251,6 +254,19 @@ class TranslationConfig:
|
|
|
251
254
|
self.custom_system_prompt = custom_system_prompt
|
|
252
255
|
self.add_formula_placehold_hint = add_formula_placehold_hint
|
|
253
256
|
self.auto_extract_glossary = auto_extract_glossary
|
|
257
|
+
self.auto_enable_ocr_workaround = auto_enable_ocr_workaround
|
|
258
|
+
|
|
259
|
+
if auto_enable_ocr_workaround:
|
|
260
|
+
self.ocr_workaround = False
|
|
261
|
+
self.skip_scanned_detection = False
|
|
262
|
+
|
|
263
|
+
assert primary_font_family in [
|
|
264
|
+
None,
|
|
265
|
+
"serif",
|
|
266
|
+
"sans-serif",
|
|
267
|
+
"script",
|
|
268
|
+
]
|
|
269
|
+
self.primary_font_family = primary_font_family
|
|
254
270
|
|
|
255
271
|
def parse_pages(self, pages_str: str | None) -> list[tuple[int, int]] | None:
|
|
256
272
|
"""解析页码字符串,返回页码范围列表
|