BabelDOC 0.4.12__tar.gz → 0.4.13__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.
Files changed (302) hide show
  1. {babeldoc-0.4.12 → babeldoc-0.4.13}/.gitignore +6 -1
  2. {babeldoc-0.4.12 → babeldoc-0.4.13}/PKG-INFO +3 -1
  3. babeldoc-0.4.13/babeldoc/__init__.py +1 -0
  4. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/assets/embedding_assets_metadata.py +2 -1
  5. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/const.py +1 -1
  6. babeldoc-0.4.13/babeldoc/docvision/rpc_doclayout3.py +329 -0
  7. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/il_version_1.py +6 -0
  8. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/il_version_1.rnc +1 -0
  9. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/il_version_1.rng +6 -1
  10. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/il_version_1.xsd +2 -1
  11. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/typesetting.py +514 -222
  12. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/layout_helper.py +51 -17
  13. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/mupdf_helper.py +2 -2
  14. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/high_level.py +1 -1
  15. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/main.py +40 -1
  16. {babeldoc-0.4.12 → babeldoc-0.4.13}/pyproject.toml +5 -2
  17. babeldoc-0.4.12/babeldoc/__init__.py +0 -1
  18. babeldoc-0.4.12/uv.lock +0 -3284
  19. {babeldoc-0.4.12 → babeldoc-0.4.13}/.cursorignore +0 -0
  20. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
  21. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
  22. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/PULL_REQUEST_TEMPLATE/pr_form.yml +0 -0
  23. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  24. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/dependabot.yml +0 -0
  25. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/labels.yml +0 -0
  26. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/release-drafter.yml +0 -0
  27. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/codeql.yml +0 -0
  28. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/docs.yml +0 -0
  29. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/labeler.yml +0 -0
  30. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/lint.yml +0 -0
  31. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/pr-lint.yml +0 -0
  32. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/publish-to-pypi.yml +0 -0
  33. {babeldoc-0.4.12 → babeldoc-0.4.13}/.github/workflows/test.yml +0 -0
  34. {babeldoc-0.4.12 → babeldoc-0.4.13}/.pre-commit-config.yaml +0 -0
  35. {babeldoc-0.4.12 → babeldoc-0.4.13}/LICENSE +0 -0
  36. {babeldoc-0.4.12 → babeldoc-0.4.13}/README.md +0 -0
  37. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/assets/assets.py +0 -0
  38. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/asynchronize/__init__.py +0 -0
  39. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/babeldoc_exception/BabelDOCException.py +0 -0
  40. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/babeldoc_exception/__init__.py +0 -0
  41. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/README.md +0 -0
  42. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/__init__.py +0 -0
  43. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/base_doclayout.py +0 -0
  44. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/doclayout.py +0 -0
  45. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/rpc_doclayout.py +0 -0
  46. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/rpc_doclayout2.py +0 -0
  47. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/docvision/table_detection/rapidocr.py +0 -0
  48. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/__init__.py +0 -0
  49. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/__init__.py +0 -0
  50. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/converter.py +0 -0
  51. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/__init__.py +0 -0
  52. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/backend/__init__.py +0 -0
  53. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/backend/pdf_creater.py +0 -0
  54. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/frontend/__init__.py +0 -0
  55. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/frontend/il_creater.py +0 -0
  56. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/__init__.py +0 -0
  57. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/add_debug_information.py +0 -0
  58. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/automatic_term_extractor.py +0 -0
  59. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/detect_scanned_file.py +0 -0
  60. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/il_translator.py +0 -0
  61. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/il_translator_llm_only.py +0 -0
  62. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/layout_parser.py +0 -0
  63. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/paragraph_finder.py +0 -0
  64. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/remove_descent.py +0 -0
  65. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/styles_and_formulas.py +0 -0
  66. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/midend/table_parser.py +0 -0
  67. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/__init__.py +0 -0
  68. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/fontmap.py +0 -0
  69. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/formular_helper.py +0 -0
  70. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/paragraph_helper.py +0 -0
  71. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/style_helper.py +0 -0
  72. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/utils/zstd_helper.py +0 -0
  73. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/document_il/xml_converter.py +0 -0
  74. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/pdfinterp.py +0 -0
  75. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/result_merger.py +0 -0
  76. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/split_manager.py +0 -0
  77. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/format/pdf/translation_config.py +0 -0
  78. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/glossary.py +0 -0
  79. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/LICENSE +0 -0
  80. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/__init__.py +0 -0
  81. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/_saslprep.py +0 -0
  82. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/arcfour.py +0 -0
  83. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/ascii85.py +0 -0
  84. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/casting.py +0 -0
  85. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/ccitt.py +0 -0
  86. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78-EUC-H.pickle.gz +0 -0
  87. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78-EUC-V.pickle.gz +0 -0
  88. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78-H.pickle.gz +0 -0
  89. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78-RKSJ-H.pickle.gz +0 -0
  90. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78-RKSJ-V.pickle.gz +0 -0
  91. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78-V.pickle.gz +0 -0
  92. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78ms-RKSJ-H.pickle.gz +0 -0
  93. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/78ms-RKSJ-V.pickle.gz +0 -0
  94. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/83pv-RKSJ-H.pickle.gz +0 -0
  95. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/83pv-RKSJ-V.pickle.gz +0 -0
  96. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/90ms-RKSJ-H.pickle.gz +0 -0
  97. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/90ms-RKSJ-V.pickle.gz +0 -0
  98. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/90msp-RKSJ-H.pickle.gz +0 -0
  99. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/90msp-RKSJ-V.pickle.gz +0 -0
  100. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/90pv-RKSJ-H.pickle.gz +0 -0
  101. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/90pv-RKSJ-V.pickle.gz +0 -0
  102. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Add-H.pickle.gz +0 -0
  103. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Add-RKSJ-H.pickle.gz +0 -0
  104. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Add-RKSJ-V.pickle.gz +0 -0
  105. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Add-V.pickle.gz +0 -0
  106. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/B5-H.pickle.gz +0 -0
  107. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/B5-V.pickle.gz +0 -0
  108. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/B5pc-H.pickle.gz +0 -0
  109. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/B5pc-V.pickle.gz +0 -0
  110. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/CNS-EUC-H.pickle.gz +0 -0
  111. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/CNS-EUC-V.pickle.gz +0 -0
  112. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/CNS1-H.pickle.gz +0 -0
  113. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/CNS1-V.pickle.gz +0 -0
  114. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/CNS2-H.pickle.gz +0 -0
  115. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/CNS2-V.pickle.gz +0 -0
  116. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/ETHK-B5-H.pickle.gz +0 -0
  117. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/ETHK-B5-V.pickle.gz +0 -0
  118. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/ETen-B5-H.pickle.gz +0 -0
  119. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/ETen-B5-V.pickle.gz +0 -0
  120. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/ETenms-B5-H.pickle.gz +0 -0
  121. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/ETenms-B5-V.pickle.gz +0 -0
  122. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/EUC-H.pickle.gz +0 -0
  123. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/EUC-V.pickle.gz +0 -0
  124. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Ext-H.pickle.gz +0 -0
  125. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Ext-RKSJ-H.pickle.gz +0 -0
  126. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Ext-RKSJ-V.pickle.gz +0 -0
  127. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Ext-V.pickle.gz +0 -0
  128. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GB-EUC-H.pickle.gz +0 -0
  129. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GB-EUC-V.pickle.gz +0 -0
  130. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GB-H.pickle.gz +0 -0
  131. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GB-V.pickle.gz +0 -0
  132. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBK-EUC-H.pickle.gz +0 -0
  133. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBK-EUC-V.pickle.gz +0 -0
  134. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBK2K-H.pickle.gz +0 -0
  135. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBK2K-V.pickle.gz +0 -0
  136. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBKp-EUC-H.pickle.gz +0 -0
  137. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBKp-EUC-V.pickle.gz +0 -0
  138. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBT-EUC-H.pickle.gz +0 -0
  139. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBT-EUC-V.pickle.gz +0 -0
  140. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBT-H.pickle.gz +0 -0
  141. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBT-V.pickle.gz +0 -0
  142. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBTpc-EUC-H.pickle.gz +0 -0
  143. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBTpc-EUC-V.pickle.gz +0 -0
  144. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBpc-EUC-H.pickle.gz +0 -0
  145. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/GBpc-EUC-V.pickle.gz +0 -0
  146. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/H.pickle.gz +0 -0
  147. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKdla-B5-H.pickle.gz +0 -0
  148. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKdla-B5-V.pickle.gz +0 -0
  149. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKdlb-B5-H.pickle.gz +0 -0
  150. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKdlb-B5-V.pickle.gz +0 -0
  151. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKgccs-B5-H.pickle.gz +0 -0
  152. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKgccs-B5-V.pickle.gz +0 -0
  153. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKm314-B5-H.pickle.gz +0 -0
  154. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKm314-B5-V.pickle.gz +0 -0
  155. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKm471-B5-H.pickle.gz +0 -0
  156. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKm471-B5-V.pickle.gz +0 -0
  157. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKscs-B5-H.pickle.gz +0 -0
  158. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/HKscs-B5-V.pickle.gz +0 -0
  159. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Hankaku-H.pickle.gz +0 -0
  160. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Hankaku-V.pickle.gz +0 -0
  161. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Hiragana-H.pickle.gz +0 -0
  162. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Hiragana-V.pickle.gz +0 -0
  163. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSC-EUC-H.pickle.gz +0 -0
  164. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSC-EUC-V.pickle.gz +0 -0
  165. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSC-H.pickle.gz +0 -0
  166. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSC-Johab-H.pickle.gz +0 -0
  167. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSC-Johab-V.pickle.gz +0 -0
  168. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSC-V.pickle.gz +0 -0
  169. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSCms-UHC-H.pickle.gz +0 -0
  170. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSCms-UHC-HW-H.pickle.gz +0 -0
  171. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSCms-UHC-HW-V.pickle.gz +0 -0
  172. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSCms-UHC-V.pickle.gz +0 -0
  173. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSCpc-EUC-H.pickle.gz +0 -0
  174. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/KSCpc-EUC-V.pickle.gz +0 -0
  175. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Katakana-H.pickle.gz +0 -0
  176. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Katakana-V.pickle.gz +0 -0
  177. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/NWP-H.pickle.gz +0 -0
  178. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/NWP-V.pickle.gz +0 -0
  179. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/README.txt +0 -0
  180. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/RKSJ-H.pickle.gz +0 -0
  181. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/RKSJ-V.pickle.gz +0 -0
  182. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Roman-H.pickle.gz +0 -0
  183. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/Roman-V.pickle.gz +0 -0
  184. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UCS2-H.pickle.gz +0 -0
  185. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UCS2-V.pickle.gz +0 -0
  186. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UTF16-H.pickle.gz +0 -0
  187. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UTF16-V.pickle.gz +0 -0
  188. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UTF32-H.pickle.gz +0 -0
  189. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UTF32-V.pickle.gz +0 -0
  190. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UTF8-H.pickle.gz +0 -0
  191. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniCNS-UTF8-V.pickle.gz +0 -0
  192. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UCS2-H.pickle.gz +0 -0
  193. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UCS2-V.pickle.gz +0 -0
  194. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UTF16-H.pickle.gz +0 -0
  195. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UTF16-V.pickle.gz +0 -0
  196. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UTF32-H.pickle.gz +0 -0
  197. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UTF32-V.pickle.gz +0 -0
  198. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UTF8-H.pickle.gz +0 -0
  199. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniGB-UTF8-V.pickle.gz +0 -0
  200. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UCS2-H.pickle.gz +0 -0
  201. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UCS2-HW-H.pickle.gz +0 -0
  202. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UCS2-HW-V.pickle.gz +0 -0
  203. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UCS2-V.pickle.gz +0 -0
  204. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UTF16-H.pickle.gz +0 -0
  205. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UTF16-V.pickle.gz +0 -0
  206. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UTF32-H.pickle.gz +0 -0
  207. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UTF32-V.pickle.gz +0 -0
  208. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UTF8-H.pickle.gz +0 -0
  209. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS-UTF8-V.pickle.gz +0 -0
  210. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS2004-UTF16-H.pickle.gz +0 -0
  211. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS2004-UTF16-V.pickle.gz +0 -0
  212. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS2004-UTF32-H.pickle.gz +0 -0
  213. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS2004-UTF32-V.pickle.gz +0 -0
  214. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS2004-UTF8-H.pickle.gz +0 -0
  215. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJIS2004-UTF8-V.pickle.gz +0 -0
  216. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJISX0213-UTF32-H.pickle.gz +0 -0
  217. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJISX0213-UTF32-V.pickle.gz +0 -0
  218. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJISX02132004-UTF32-H.pickle.gz +0 -0
  219. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniJISX02132004-UTF32-V.pickle.gz +0 -0
  220. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UCS2-H.pickle.gz +0 -0
  221. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UCS2-V.pickle.gz +0 -0
  222. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UTF16-H.pickle.gz +0 -0
  223. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UTF16-V.pickle.gz +0 -0
  224. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UTF32-H.pickle.gz +0 -0
  225. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UTF32-V.pickle.gz +0 -0
  226. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UTF8-H.pickle.gz +0 -0
  227. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/UniKS-UTF8-V.pickle.gz +0 -0
  228. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/V.pickle.gz +0 -0
  229. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/WP-Symbol-H.pickle.gz +0 -0
  230. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/WP-Symbol-V.pickle.gz +0 -0
  231. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/to-unicode-Adobe-CNS1.pickle.gz +0 -0
  232. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/to-unicode-Adobe-GB1.pickle.gz +0 -0
  233. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/to-unicode-Adobe-Japan1.pickle.gz +0 -0
  234. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmap/to-unicode-Adobe-Korea1.pickle.gz +0 -0
  235. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/cmapdb.py +0 -0
  236. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/converter.py +0 -0
  237. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/data_structures.py +0 -0
  238. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/encodingdb.py +0 -0
  239. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/fontmetrics.py +0 -0
  240. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/glyphlist.py +0 -0
  241. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/high_level.py +0 -0
  242. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/image.py +0 -0
  243. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/jbig2.py +0 -0
  244. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/latin_enc.py +0 -0
  245. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/layout.py +0 -0
  246. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/lzw.py +0 -0
  247. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfcolor.py +0 -0
  248. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfdevice.py +0 -0
  249. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfdocument.py +0 -0
  250. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfexceptions.py +0 -0
  251. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdffont.py +0 -0
  252. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfinterp.py +0 -0
  253. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfpage.py +0 -0
  254. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdfparser.py +0 -0
  255. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/pdftypes.py +0 -0
  256. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/psexceptions.py +0 -0
  257. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/psparser.py +0 -0
  258. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/py.typed +0 -0
  259. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/runlength.py +0 -0
  260. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/settings.py +0 -0
  261. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/pdfminer/utils.py +0 -0
  262. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/progress_monitor.py +0 -0
  263. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/tools/generate_font_metadata.py +0 -0
  264. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/tools/italic_assistance.py +0 -0
  265. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/tools/italic_recognize_tool.py +0 -0
  266. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/translator/__init__.py +0 -0
  267. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/translator/cache.py +0 -0
  268. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/translator/translator.py +0 -0
  269. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/utils/__init__.py +0 -0
  270. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/utils/atomic_integer.py +0 -0
  271. {babeldoc-0.4.12 → babeldoc-0.4.13}/babeldoc/utils/priority_thread_pool_executor.py +0 -0
  272. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/CODE_OF_CONDUCT.md +0 -0
  273. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/CONTRIBUTING.md +0 -0
  274. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/CONTRIBUTOR_REWARD.md +0 -0
  275. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/AsyncTranslate/AsyncTranslate.md +0 -0
  276. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/ILTranslator/ILTranslator.md +0 -0
  277. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/PDFCreation/PDFCreation.md +0 -0
  278. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/PDFParsing/PDFParsing.md +0 -0
  279. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/ParagraphFinding/ParagraphFinding.md +0 -0
  280. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/README.md +0 -0
  281. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/StylesAndFormulas/StylesAndFormulas.md +0 -0
  282. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/ImplementationDetails/Typesetting/Typesetting.md +0 -0
  283. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/README.md +0 -0
  284. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/deploy.sh +0 -0
  285. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/example/demo_glossary.csv +0 -0
  286. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-banner.png +0 -0
  287. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.png +0 -0
  288. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-big-logo-darkmode-with-transparent-background.svg +0 -0
  289. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-big-logo-with-transparent-background.png +0 -0
  290. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-big-logo-with-transparent-background.svg +0 -0
  291. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-big-logo.png +0 -0
  292. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-contributor_reward_example.png +0 -0
  293. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-preview.gif +0 -0
  294. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-small-logo-with-transparent-background.png +0 -0
  295. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-small-logo-with-transparent-background.svg +0 -0
  296. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/images/babeldoc-small-logo.png +0 -0
  297. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/index.md +0 -0
  298. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/intro-to-pdf-object.md +0 -0
  299. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/requirements.txt +0 -0
  300. {babeldoc-0.4.12 → babeldoc-0.4.13}/docs/supported_languages.md +0 -0
  301. {babeldoc-0.4.12 → babeldoc-0.4.13}/mkdocs.yml +0 -0
  302. {babeldoc-0.4.12 → babeldoc-0.4.13}/tests/test_translation_config.py +0 -0
@@ -34,4 +34,9 @@ examples/
34
34
  /.cursor
35
35
  /xnotes
36
36
  /docs/workflow-rules.md
37
- babeldoc/format/txt
37
+ babeldoc/format/txt
38
+ /profile.svg
39
+
40
+
41
+ # uv
42
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: BabelDOC
3
- Version: 0.4.12
3
+ Version: 0.4.13
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
@@ -38,10 +38,12 @@ Requires-Dist: rapidocr-onnxruntime>=1.4.4
38
38
  Requires-Dist: rich>=13.9.4
39
39
  Requires-Dist: rtree>=1.4.0
40
40
  Requires-Dist: scikit-image>=0.25.2
41
+ Requires-Dist: scipy>=1.15.3
41
42
  Requires-Dist: tenacity>=9.0.0
42
43
  Requires-Dist: tiktoken>=0.9.0
43
44
  Requires-Dist: toml>=0.10.2
44
45
  Requires-Dist: tqdm>=4.67.1
46
+ Requires-Dist: uharfbuzz>=0.50.2
45
47
  Requires-Dist: xsdata[cli,lxml,soap]>=24.12
46
48
  Provides-Extra: cuda
47
49
  Requires-Dist: onnxruntime-gpu>=1.16.1; extra == 'cuda'
@@ -0,0 +1 @@
1
+ __version__ = "0.4.13"
@@ -608,6 +608,7 @@ ALL_FONT_FAMILY = {
608
608
  "KR": KR_FONT_FAMILY,
609
609
  "JP": JP_FONT_FAMILY,
610
610
  "EN": EN_FONT_FAMILY,
611
+ "JA": JP_FONT_FAMILY,
611
612
  }
612
613
 
613
614
 
@@ -633,7 +634,7 @@ def get_font_family(lang_code: str):
633
634
  lang_code = lang_code.upper()
634
635
  if "KR" in lang_code:
635
636
  font_family = KR_FONT_FAMILY
636
- elif "JP" in lang_code:
637
+ elif "JP" in lang_code or "JA" in lang_code:
637
638
  font_family = JP_FONT_FAMILY
638
639
  elif "HK" in lang_code:
639
640
  font_family = HK_FONT_FAMILY
@@ -3,7 +3,7 @@ import shutil
3
3
  import subprocess
4
4
  from pathlib import Path
5
5
 
6
- __version__ = "0.4.12"
6
+ __version__ = "0.4.13"
7
7
 
8
8
  CACHE_FOLDER = Path.home() / ".cache" / "babeldoc"
9
9
 
@@ -0,0 +1,329 @@
1
+ import json
2
+ import logging
3
+ import threading
4
+ from concurrent.futures import ThreadPoolExecutor
5
+ from pathlib import Path
6
+
7
+ import cv2
8
+ import httpx
9
+ import numpy as np
10
+ import pymupdf
11
+ from tenacity import retry
12
+ from tenacity import retry_if_exception_type
13
+ from tenacity import stop_after_attempt
14
+ from tenacity import wait_exponential
15
+
16
+ import babeldoc
17
+ from babeldoc.docvision.base_doclayout import DocLayoutModel
18
+ from babeldoc.docvision.base_doclayout import YoloBox
19
+ from babeldoc.docvision.base_doclayout import YoloResult
20
+ from babeldoc.format.pdf.document_il.utils.mupdf_helper import get_no_rotation_img
21
+
22
+ logger = logging.getLogger(__name__)
23
+ DPI = 150
24
+
25
+
26
+ def encode_image(image) -> bytes:
27
+ """Read and encode image to bytes
28
+
29
+ Args:
30
+ image: Can be either a file path (str) or numpy array
31
+ """
32
+ if isinstance(image, str):
33
+ if not Path(image).exists():
34
+ raise FileNotFoundError(f"Image file not found: {image}")
35
+ img = cv2.imread(image)
36
+ if img is None:
37
+ raise ValueError(f"Failed to read image: {image}")
38
+ else:
39
+ img = image
40
+
41
+ # logger.debug(f"Image shape: {img.shape}")
42
+ encoded = cv2.imencode(".jpg", img)[1].tobytes()
43
+ # logger.debug(f"Encoded image size: {len(encoded)} bytes")
44
+ return encoded
45
+
46
+
47
+ @retry(
48
+ stop=stop_after_attempt(3), # 最多重试 3 次
49
+ wait=wait_exponential(
50
+ multiplier=1, min=1, max=10
51
+ ), # 指数退避策略,初始 1 秒,最大 10 秒
52
+ retry=retry_if_exception_type((httpx.HTTPError, Exception)), # 针对哪些异常重试
53
+ before_sleep=lambda retry_state: logger.warning(
54
+ f"Request failed, retrying in {getattr(retry_state.next_action, 'sleep', 'unknown')} seconds... "
55
+ f"(Attempt {retry_state.attempt_number}/3)"
56
+ ),
57
+ )
58
+ def predict_layout(
59
+ image,
60
+ host: str = "http://localhost:8000",
61
+ _imgsz: int = 1024,
62
+ ):
63
+ """
64
+ Predict document layout using the MOSEC service
65
+
66
+ Args:
67
+ image: Can be either a file path (str) or numpy array
68
+ host: Service host URL
69
+ imgsz: Image size for model input
70
+
71
+ Returns:
72
+ List of predictions containing bounding boxes and classes
73
+ """
74
+ # Prepare request data
75
+
76
+ image_data = encode_image(image)
77
+
78
+ # Pack data using msgpack
79
+ # packed_data = msgpack.packb(data, use_bin_type=True)
80
+ # logger.debug(f"Packed data size: {len(packed_data)} bytes")
81
+
82
+ # Send request
83
+ # logger.debug(f"Sending request to {host}/inference")
84
+ response = httpx.post(
85
+ f"{host}/analyze?min_sim=0.7&early_stop=0.99&timeout=240",
86
+ files={"file": ("image.jpg", image_data, "image/jpeg")},
87
+ headers={
88
+ "Accept": "application/json",
89
+ },
90
+ timeout=300,
91
+ follow_redirects=True,
92
+ )
93
+
94
+ # logger.debug(f"Response status: {response.status_code}")
95
+ # logger.debug(f"Response headers: {response.headers}")
96
+ idx = 0
97
+ id_lookup = {}
98
+ if response.status_code == 200:
99
+ try:
100
+ result = json.loads(response.text)
101
+ useful_result = []
102
+ if isinstance(result, dict):
103
+ names = {}
104
+ for box in result["boxes"]:
105
+ if box["ocr_match_score"] < 0.7:
106
+ continue
107
+
108
+ box["xyxy"] = box["coords"]
109
+ box["conf"] = box["ocr_match_score"]
110
+ if box["label"] not in names:
111
+ idx += 1
112
+ names[idx] = box["label"]
113
+ box["cls_id"] = idx
114
+ id_lookup[box["label"]] = idx
115
+ else:
116
+ box["cls_id"] = id_lookup[box["label"]]
117
+ names[box["cls_id"]] = box["label"]
118
+ box["cls"] = box["cls_id"]
119
+ useful_result.append(box)
120
+ if "names" not in result:
121
+ result["names"] = names
122
+ result["boxes"] = useful_result
123
+ result = [result]
124
+ return result
125
+ except Exception as e:
126
+ logger.exception(f"Failed to unpack response: {e!s}")
127
+ raise
128
+ else:
129
+ logger.error(f"Request failed with status {response.status_code}")
130
+ logger.error(f"Response content: {response.content}")
131
+ raise Exception(
132
+ f"Request failed with status {response.status_code}: {response.text}",
133
+ )
134
+
135
+
136
+ class ResultContainer:
137
+ def __init__(self):
138
+ self.result = YoloResult(boxes_data=np.array([]), names=[])
139
+
140
+
141
+ class RpcDocLayoutModel(DocLayoutModel):
142
+ """DocLayoutModel implementation that uses RPC service."""
143
+
144
+ def __init__(self, host: str = "http://localhost:8000"):
145
+ """Initialize RPC model with host address."""
146
+ self.host = host
147
+ self._stride = 32 # Default stride value
148
+ self._names = ["text", "title", "list", "table", "figure"]
149
+ self.lock = threading.Lock()
150
+
151
+ @property
152
+ def stride(self) -> int:
153
+ """Stride of the model input."""
154
+ return self._stride
155
+
156
+ def resize_and_pad_image(self, image, new_shape):
157
+ """
158
+ Resize and pad the image to the specified size,
159
+ ensuring dimensions are multiples of stride.
160
+
161
+ Parameters:
162
+ - image: Input image
163
+ - new_shape: Target size (integer or (height, width) tuple)
164
+ - stride: Padding alignment stride, default 32
165
+
166
+ Returns:
167
+ - Processed image
168
+ """
169
+ if isinstance(new_shape, int):
170
+ new_shape = (new_shape, new_shape)
171
+
172
+ h, w = image.shape[:2]
173
+ new_h, new_w = new_shape
174
+
175
+ # Calculate scaling ratio
176
+ r = min(new_h / h, new_w / w)
177
+ resized_h, resized_w = int(round(h * r)), int(round(w * r))
178
+
179
+ # Resize image
180
+ image = cv2.resize(
181
+ image, (resized_w, resized_h), interpolation=cv2.INTER_LINEAR
182
+ )
183
+
184
+ # Calculate padding size
185
+ pad_h = new_h - resized_h
186
+ pad_w = new_w - resized_w
187
+ top, bottom = pad_h // 2, pad_h - pad_h // 2
188
+ left, right = pad_w // 2, pad_w - pad_w // 2
189
+
190
+ # Add padding
191
+ image = cv2.copyMakeBorder(
192
+ image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114)
193
+ )
194
+
195
+ return image
196
+
197
+ def scale_boxes(self, img1_shape, boxes, img0_shape):
198
+ """
199
+ Rescales bounding boxes (in the format of xyxy by default) from the shape of the image they were originally
200
+ specified in (img1_shape) to the shape of a different image (img0_shape).
201
+
202
+ Args:
203
+ img1_shape (tuple): The shape of the image that the bounding boxes are for,
204
+ in the format of (height, width).
205
+ boxes (torch.Tensor): the bounding boxes of the objects in the image, in the format of (x1, y1, x2, y2)
206
+ img0_shape (tuple): the shape of the target image, in the format of (height, width).
207
+
208
+ Returns:
209
+ boxes (torch.Tensor): The scaled bounding boxes, in the format of (x1, y1, x2, y2)
210
+ """
211
+
212
+ # Calculate scaling ratio
213
+ gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])
214
+
215
+ # Calculate padding size
216
+ pad_x = round((img1_shape[1] - img0_shape[1] * gain) / 2 - 0.1)
217
+ pad_y = round((img1_shape[0] - img0_shape[0] * gain) / 2 - 0.1)
218
+
219
+ # Remove padding and scale boxes
220
+ boxes = (boxes - [pad_x, pad_y, pad_x, pad_y]) / gain
221
+ return boxes
222
+
223
+ def predict_image(
224
+ self,
225
+ image,
226
+ host: str | None = None,
227
+ result_container: ResultContainer | None = None,
228
+ imgsz: int = 1024,
229
+ ) -> ResultContainer:
230
+ """Predict the layout of document pages using RPC service."""
231
+ if result_container is None:
232
+ result_container = ResultContainer()
233
+ target_imgsz = (800, 800)
234
+ orig_h, orig_w = image.shape[:2]
235
+ target_imgsz = (orig_h, orig_w)
236
+ if image.shape[0] != target_imgsz[0] or image.shape[1] != target_imgsz[1]:
237
+ image = self.resize_and_pad_image(image, new_shape=target_imgsz)
238
+ preds = predict_layout(image, host=self.host, imgsz=800)
239
+ orig_h, orig_w = orig_h / DPI * 72, orig_w / DPI * 72
240
+ if len(preds) > 0:
241
+ for pred in preds:
242
+ boxes = [
243
+ YoloBox(
244
+ None,
245
+ self.scale_boxes(
246
+ target_imgsz, np.array(x["xyxy"]), (orig_h, orig_w)
247
+ ),
248
+ np.array(x["conf"]),
249
+ x["cls"],
250
+ )
251
+ for x in pred["boxes"]
252
+ ]
253
+ result_container.result = YoloResult(
254
+ boxes=boxes,
255
+ names={int(k): v for k, v in pred["names"].items()},
256
+ )
257
+ return result_container.result
258
+
259
+ def predict(self, image, imgsz=1024, **kwargs) -> list[YoloResult]:
260
+ """Predict the layout of document pages using RPC service."""
261
+ # Handle single image input
262
+ if isinstance(image, np.ndarray) and len(image.shape) == 3:
263
+ image = [image]
264
+
265
+ result_containers = [ResultContainer() for _ in image]
266
+ predict_thread = ThreadPoolExecutor(max_workers=len(image))
267
+ for img, result_container in zip(image, result_containers, strict=True):
268
+ predict_thread.submit(
269
+ self.predict_image, img, self.host, result_container, 800
270
+ )
271
+ predict_thread.shutdown(wait=True)
272
+ result = [result_container.result for result_container in result_containers]
273
+ return result
274
+
275
+ def predict_page(
276
+ self, page, mupdf_doc: pymupdf.Document, translate_config, save_debug_image
277
+ ):
278
+ translate_config.raise_if_cancelled()
279
+ with self.lock:
280
+ # pix = mupdf_doc[page.page_number].get_pixmap(dpi=72)
281
+ pix = get_no_rotation_img(mupdf_doc[page.page_number], dpi=DPI)
282
+ image = np.frombuffer(pix.samples, np.uint8).reshape(
283
+ pix.height,
284
+ pix.width,
285
+ 3,
286
+ )[:, :, ::-1]
287
+ predict_result = self.predict_image(image, self.host, None, 800)
288
+ save_debug_image(image, predict_result, page.page_number + 1)
289
+ return page, predict_result
290
+
291
+ def handle_document(
292
+ self,
293
+ pages: list[babeldoc.format.pdf.document_il.il_version_1.Page],
294
+ mupdf_doc: pymupdf.Document,
295
+ translate_config,
296
+ save_debug_image,
297
+ ):
298
+ with ThreadPoolExecutor(max_workers=4) as executor:
299
+ yield from executor.map(
300
+ self.predict_page,
301
+ pages,
302
+ (mupdf_doc for _ in range(len(pages))),
303
+ (translate_config for _ in range(len(pages))),
304
+ (save_debug_image for _ in range(len(pages))),
305
+ )
306
+
307
+ @staticmethod
308
+ def from_host(host: str) -> "RpcDocLayoutModel":
309
+ """Create RpcDocLayoutModel from host address."""
310
+ return RpcDocLayoutModel(host=host)
311
+
312
+
313
+ if __name__ == "__main__":
314
+ logging.basicConfig(level=logging.DEBUG)
315
+ # Test the service
316
+ try:
317
+ # Use a default test image if example/1.png doesn't exist
318
+ image_path = "example/1.png"
319
+ if not Path(image_path).exists():
320
+ print(f"Warning: {image_path} not found.")
321
+ print("Please provide the path to a test image:")
322
+ image_path = input("> ")
323
+
324
+ logger.info(f"Processing image: {image_path}")
325
+ result = predict_layout(image_path)
326
+ print("Prediction results:")
327
+ print(result)
328
+ except Exception as e:
329
+ print(f"Error: {e!s}")
@@ -763,6 +763,12 @@ class PdfParagraph:
763
763
  "type": "Attribute",
764
764
  },
765
765
  )
766
+ optimal_scale: float | None = field(
767
+ default=None,
768
+ metadata={
769
+ "type": "Attribute",
770
+ },
771
+ )
766
772
  vertical: bool | None = field(
767
773
  default=None,
768
774
  metadata={
@@ -112,6 +112,7 @@ PDFParagraph =
112
112
  attribute xobjId { xsd:int }?,
113
113
  attribute unicode { xsd:string },
114
114
  attribute scale { xsd:float }?,
115
+ attribute optimal_scale { xsd:float }?,
115
116
  attribute vertical { xsd:boolean }?,
116
117
  attribute FirstLineIndent { xsd:boolean }?,
117
118
  attribute debug_id { xsd:string }?,
@@ -196,7 +196,7 @@
196
196
  </optional>
197
197
  <optional>
198
198
  <attribute name="formula_layout_id">
199
- <data type="boolean"/>
199
+ <data type="int"/>
200
200
  </attribute>
201
201
  </optional>
202
202
  <ref name="PDFStyle"/>
@@ -324,6 +324,11 @@
324
324
  <data type="float"/>
325
325
  </attribute>
326
326
  </optional>
327
+ <optional>
328
+ <attribute name="optimal_scale">
329
+ <data type="float"/>
330
+ </attribute>
331
+ </optional>
327
332
  <optional>
328
333
  <attribute name="vertical">
329
334
  <data type="boolean"/>
@@ -103,7 +103,7 @@
103
103
  <xs:attribute name="advance" type="xs:float"/>
104
104
  <xs:attribute name="xobjId" type="xs:int"/>
105
105
  <xs:attribute name="debug_info" type="xs:boolean"/>
106
- <xs:attribute name="formula_layout_id" type="xs:boolean"/>
106
+ <xs:attribute name="formula_layout_id" type="xs:int"/>
107
107
  </xs:complexType>
108
108
  </xs:element>
109
109
  <xs:element name="visual_bbox">
@@ -185,6 +185,7 @@
185
185
  <xs:attribute name="xobjId" type="xs:int"/>
186
186
  <xs:attribute name="unicode" use="required" type="xs:string"/>
187
187
  <xs:attribute name="scale" type="xs:float"/>
188
+ <xs:attribute name="optimal_scale" type="xs:float"/>
188
189
  <xs:attribute name="vertical" type="xs:boolean"/>
189
190
  <xs:attribute name="FirstLineIndent" type="xs:boolean"/>
190
191
  <xs:attribute name="debug_id" type="xs:string"/>