docvortex 0.2.1__py3-none-any.whl

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 (364) hide show
  1. docvortex/__init__.py +21 -0
  2. docvortex/analyzers/__init__.py +3 -0
  3. docvortex/analyzers/native/__init__.py +37 -0
  4. docvortex/analyzers/native/_shared/__init__.py +3 -0
  5. docvortex/analyzers/native/_shared/hyperlink.py +16 -0
  6. docvortex/analyzers/native/_shared/image.py +8 -0
  7. docvortex/analyzers/native/_shared/markup/__init__.py +47 -0
  8. docvortex/analyzers/native/_shared/markup/anchors.py +30 -0
  9. docvortex/analyzers/native/_shared/markup/formula.py +37 -0
  10. docvortex/analyzers/native/_shared/markup/projector.py +57 -0
  11. docvortex/analyzers/native/_shared/markup/styles.py +19 -0
  12. docvortex/analyzers/native/_shared/mathml.py +17 -0
  13. docvortex/analyzers/native/_shared/names.py +7 -0
  14. docvortex/analyzers/native/_shared/xycut.py +414 -0
  15. docvortex/analyzers/native/contracts.py +44 -0
  16. docvortex/analyzers/native/csv.py +351 -0
  17. docvortex/analyzers/native/epub/__init__.py +18 -0
  18. docvortex/analyzers/native/epub/constants.py +45 -0
  19. docvortex/analyzers/native/epub/converter.py +80 -0
  20. docvortex/analyzers/native/epub/errors.py +20 -0
  21. docvortex/analyzers/native/epub/metadata.py +31 -0
  22. docvortex/analyzers/native/epub/package.py +649 -0
  23. docvortex/analyzers/native/epub/xhtml.py +306 -0
  24. docvortex/analyzers/native/html/__init__.py +6 -0
  25. docvortex/analyzers/native/html/anchors.py +271 -0
  26. docvortex/analyzers/native/html/constants.py +25 -0
  27. docvortex/analyzers/native/html/contracts.py +7 -0
  28. docvortex/analyzers/native/html/converter.py +117 -0
  29. docvortex/analyzers/native/html/document.py +389 -0
  30. docvortex/analyzers/native/html/errors.py +12 -0
  31. docvortex/analyzers/native/html/resources.py +365 -0
  32. docvortex/analyzers/native/html/selector.py +421 -0
  33. docvortex/analyzers/native/models.py +209 -0
  34. docvortex/analyzers/native/ofd/__init__.py +14 -0
  35. docvortex/analyzers/native/ofd/constants.py +59 -0
  36. docvortex/analyzers/native/ofd/converter.py +31 -0
  37. docvortex/analyzers/native/ofd/errors.py +16 -0
  38. docvortex/analyzers/native/ofd/geometry.py +215 -0
  39. docvortex/analyzers/native/ofd/images.py +124 -0
  40. docvortex/analyzers/native/ofd/metadata.py +53 -0
  41. docvortex/analyzers/native/ofd/models.py +170 -0
  42. docvortex/analyzers/native/ofd/package.py +346 -0
  43. docvortex/analyzers/native/ofd/path.py +201 -0
  44. docvortex/analyzers/native/ofd/reading_order.py +293 -0
  45. docvortex/analyzers/native/ofd/resources.py +122 -0
  46. docvortex/analyzers/native/ofd/scene.py +347 -0
  47. docvortex/analyzers/native/ofd/table.py +240 -0
  48. docvortex/analyzers/native/ofd/text.py +521 -0
  49. docvortex/analyzers/native/office/__init__.py +3 -0
  50. docvortex/analyzers/native/office/doc/__init__.py +3 -0
  51. docvortex/analyzers/native/office/doc/bookmarks.py +81 -0
  52. docvortex/analyzers/native/office/doc/doc_converter.py +573 -0
  53. docvortex/analyzers/native/office/doc/fib.py +261 -0
  54. docvortex/analyzers/native/office/doc/fields.py +101 -0
  55. docvortex/analyzers/native/office/doc/formatting.py +171 -0
  56. docvortex/analyzers/native/office/doc/images.py +162 -0
  57. docvortex/analyzers/native/office/doc/lists.py +356 -0
  58. docvortex/analyzers/native/office/doc/models.py +164 -0
  59. docvortex/analyzers/native/office/doc/parser.py +851 -0
  60. docvortex/analyzers/native/office/doc/pieces.py +256 -0
  61. docvortex/analyzers/native/office/doc/records.py +40 -0
  62. docvortex/analyzers/native/office/doc/sprm.py +269 -0
  63. docvortex/analyzers/native/office/doc/styles.py +215 -0
  64. docvortex/analyzers/native/office/docx/__init__.py +3 -0
  65. docvortex/analyzers/native/office/docx/context.py +71 -0
  66. docvortex/analyzers/native/office/docx/docx_converter.py +614 -0
  67. docvortex/analyzers/native/office/docx/equationxml.py +119 -0
  68. docvortex/analyzers/native/office/docx/fields.py +816 -0
  69. docvortex/analyzers/native/office/docx/formatting_types.py +23 -0
  70. docvortex/analyzers/native/office/docx/main.py +50 -0
  71. docvortex/analyzers/native/office/docx/numbering.py +491 -0
  72. docvortex/analyzers/native/office/docx/office_xml.py +57 -0
  73. docvortex/analyzers/native/office/docx/package_normalizer.py +248 -0
  74. docvortex/analyzers/native/office/docx/resources.py +526 -0
  75. docvortex/analyzers/native/office/docx/styles.py +693 -0
  76. docvortex/analyzers/native/office/docx/tables.py +515 -0
  77. docvortex/analyzers/native/office/equation/__init__.py +3 -0
  78. docvortex/analyzers/native/office/equation/image.py +470 -0
  79. docvortex/analyzers/native/office/equation/latex_dict.py +324 -0
  80. docvortex/analyzers/native/office/equation/mtef.py +885 -0
  81. docvortex/analyzers/native/office/equation/mtef_v5.py +941 -0
  82. docvortex/analyzers/native/office/equation/omml.py +561 -0
  83. docvortex/analyzers/native/office/equation/ooxml.py +62 -0
  84. docvortex/analyzers/native/office/errors.py +33 -0
  85. docvortex/analyzers/native/office/image.py +307 -0
  86. docvortex/analyzers/native/office/legacy/__init__.py +3 -0
  87. docvortex/analyzers/native/office/legacy/binary.py +43 -0
  88. docvortex/analyzers/native/office/legacy/officeart.py +362 -0
  89. docvortex/analyzers/native/office/legacy/ole.py +110 -0
  90. docvortex/analyzers/native/office/limits.py +12 -0
  91. docvortex/analyzers/native/office/odf/__init__.py +3 -0
  92. docvortex/analyzers/native/office/odf/chart.py +76 -0
  93. docvortex/analyzers/native/office/odf/constants.py +70 -0
  94. docvortex/analyzers/native/office/odf/converters.py +403 -0
  95. docvortex/analyzers/native/office/odf/errors.py +18 -0
  96. docvortex/analyzers/native/office/odf/metadata.py +91 -0
  97. docvortex/analyzers/native/office/odf/models.py +176 -0
  98. docvortex/analyzers/native/office/odf/package.py +270 -0
  99. docvortex/analyzers/native/office/odf/styles.py +329 -0
  100. docvortex/analyzers/native/office/odf/table.py +469 -0
  101. docvortex/analyzers/native/office/odf/text.py +1002 -0
  102. docvortex/analyzers/native/office/ooxml_chart.py +1016 -0
  103. docvortex/analyzers/native/office/opc.py +38 -0
  104. docvortex/analyzers/native/office/ppt/__init__.py +3 -0
  105. docvortex/analyzers/native/office/ppt/models.py +118 -0
  106. docvortex/analyzers/native/office/ppt/parser.py +1895 -0
  107. docvortex/analyzers/native/office/ppt/ppt_converter.py +292 -0
  108. docvortex/analyzers/native/office/ppt/records.py +131 -0
  109. docvortex/analyzers/native/office/ppt/style_text.py +247 -0
  110. docvortex/analyzers/native/office/pptx/__init__.py +3 -0
  111. docvortex/analyzers/native/office/pptx/context.py +113 -0
  112. docvortex/analyzers/native/office/pptx/lists.py +558 -0
  113. docvortex/analyzers/native/office/pptx/main.py +20 -0
  114. docvortex/analyzers/native/office/pptx/package_normalizer.py +321 -0
  115. docvortex/analyzers/native/office/pptx/pptx_converter.py +323 -0
  116. docvortex/analyzers/native/office/pptx/resources.py +329 -0
  117. docvortex/analyzers/native/office/pptx/shapes.py +393 -0
  118. docvortex/analyzers/native/office/pptx/text_styles.py +625 -0
  119. docvortex/analyzers/native/office/pptx/titles.py +178 -0
  120. docvortex/analyzers/native/office/rich_text.py +420 -0
  121. docvortex/analyzers/native/office/rtf/__init__.py +3 -0
  122. docvortex/analyzers/native/office/rtf/converter.py +708 -0
  123. docvortex/analyzers/native/office/rtf/lexer.py +213 -0
  124. docvortex/analyzers/native/office/rtf/math.py +339 -0
  125. docvortex/analyzers/native/office/rtf/models.py +185 -0
  126. docvortex/analyzers/native/office/rtf/parser.py +1553 -0
  127. docvortex/analyzers/native/office/spreadsheet/__init__.py +3 -0
  128. docvortex/analyzers/native/office/spreadsheet/html.py +81 -0
  129. docvortex/analyzers/native/office/spreadsheet/models.py +79 -0
  130. docvortex/analyzers/native/office/spreadsheet/projector.py +928 -0
  131. docvortex/analyzers/native/office/streams.py +18 -0
  132. docvortex/analyzers/native/office/xls/__init__.py +3 -0
  133. docvortex/analyzers/native/office/xls/chart.py +132 -0
  134. docvortex/analyzers/native/office/xls/embedded_chart.py +299 -0
  135. docvortex/analyzers/native/office/xls/models.py +109 -0
  136. docvortex/analyzers/native/office/xls/number_format.py +521 -0
  137. docvortex/analyzers/native/office/xls/parser.py +1145 -0
  138. docvortex/analyzers/native/office/xls/records.py +201 -0
  139. docvortex/analyzers/native/office/xls/strings.py +205 -0
  140. docvortex/analyzers/native/office/xls/xls_converter.py +354 -0
  141. docvortex/analyzers/native/office/xlsx/__init__.py +3 -0
  142. docvortex/analyzers/native/office/xlsx/main.py +20 -0
  143. docvortex/analyzers/native/office/xlsx/ooxml_ole.py +522 -0
  144. docvortex/analyzers/native/office/xlsx/package_normalizer.py +310 -0
  145. docvortex/analyzers/native/office/xlsx/xlsx_converter.py +716 -0
  146. docvortex/analyzers/native/pdf/__init__.py +3 -0
  147. docvortex/analyzers/native/pdf/auxiliary_text.py +1671 -0
  148. docvortex/analyzers/native/pdf/char_geometry.py +1662 -0
  149. docvortex/analyzers/native/pdf/code_blocks.py +535 -0
  150. docvortex/analyzers/native/pdf/formulas.py +1985 -0
  151. docvortex/analyzers/native/pdf/geometry.py +281 -0
  152. docvortex/analyzers/native/pdf/graphics.py +1501 -0
  153. docvortex/analyzers/native/pdf/index_blocks.py +268 -0
  154. docvortex/analyzers/native/pdf/inline/__init__.py +3 -0
  155. docvortex/analyzers/native/pdf/inline/common.py +112 -0
  156. docvortex/analyzers/native/pdf/inline/detection.py +590 -0
  157. docvortex/analyzers/native/pdf/inline/matching.py +1185 -0
  158. docvortex/analyzers/native/pdf/inline/materialize.py +457 -0
  159. docvortex/analyzers/native/pdf/inline/scripts.py +975 -0
  160. docvortex/analyzers/native/pdf/inline/types.py +385 -0
  161. docvortex/analyzers/native/pdf/line_layout.py +1106 -0
  162. docvortex/analyzers/native/pdf/line_merging.py +1223 -0
  163. docvortex/analyzers/native/pdf/models.py +246 -0
  164. docvortex/analyzers/native/pdf/native_text.py +1004 -0
  165. docvortex/analyzers/native/pdf/pipeline.py +1390 -0
  166. docvortex/analyzers/native/pdf/script_geometry.py +636 -0
  167. docvortex/analyzers/native/pdf/shared.py +30 -0
  168. docvortex/analyzers/native/pdf/spatial_text.py +383 -0
  169. docvortex/analyzers/native/pdf/table_annotations.py +446 -0
  170. docvortex/analyzers/native/pdf/table_constants.py +48 -0
  171. docvortex/analyzers/native/pdf/table_detection.py +227 -0
  172. docvortex/analyzers/native/pdf/table_filled_grid.py +218 -0
  173. docvortex/analyzers/native/pdf/table_geometry.py +40 -0
  174. docvortex/analyzers/native/pdf/table_materialization.py +444 -0
  175. docvortex/analyzers/native/pdf/table_recovery/__init__.py +15 -0
  176. docvortex/analyzers/native/pdf/table_recovery/candidate.py +356 -0
  177. docvortex/analyzers/native/pdf/table_recovery/contracts.py +154 -0
  178. docvortex/analyzers/native/pdf/table_recovery/engine.py +609 -0
  179. docvortex/analyzers/native/pdf/table_recovery/geometry.py +164 -0
  180. docvortex/analyzers/native/pdf/table_recovery/sparse_common.py +85 -0
  181. docvortex/analyzers/native/pdf/table_recovery/sparse_hybrid.py +804 -0
  182. docvortex/analyzers/native/pdf/table_recovery/sparse_multiline.py +1122 -0
  183. docvortex/analyzers/native/pdf/table_recovery/text.py +414 -0
  184. docvortex/analyzers/native/pdf/table_recovery/text_grid.py +618 -0
  185. docvortex/analyzers/native/pdf/table_recovery/vector.py +1931 -0
  186. docvortex/analyzers/native/pdf/table_rows.py +34 -0
  187. docvortex/analyzers/native/pdf/table_rules.py +1129 -0
  188. docvortex/analyzers/native/pdf/table_text_styles.py +283 -0
  189. docvortex/analyzers/native/pdf/tables.py +147 -0
  190. docvortex/analyzers/native/pdf/text_assembly/__init__.py +3 -0
  191. docvortex/analyzers/native/pdf/text_assembly/annotations.py +581 -0
  192. docvortex/analyzers/native/pdf/text_assembly/assembly.py +292 -0
  193. docvortex/analyzers/native/pdf/text_assembly/common.py +477 -0
  194. docvortex/analyzers/native/pdf/text_assembly/footnotes.py +394 -0
  195. docvortex/analyzers/native/pdf/text_assembly/merging.py +1274 -0
  196. docvortex/analyzers/native/pdf/text_assembly/rows.py +692 -0
  197. docvortex/analyzers/native/pdf/text_blocks.py +82 -0
  198. docvortex/analyzers/native/pdf/text_styles.py +55 -0
  199. docvortex/analyzers/native/pdf/title_analysis/__init__.py +3 -0
  200. docvortex/analyzers/native/pdf/title_analysis/body_profile.py +215 -0
  201. docvortex/analyzers/native/pdf/title_analysis/common.py +117 -0
  202. docvortex/analyzers/native/pdf/title_analysis/document_profile.py +164 -0
  203. docvortex/analyzers/native/pdf/title_analysis/lane_titles.py +758 -0
  204. docvortex/analyzers/native/pdf/title_analysis/page_titles.py +1024 -0
  205. docvortex/analyzers/native/pdf/title_analysis/prototype.py +194 -0
  206. docvortex/analyzers/native/pdf/title_analysis/structural.py +1081 -0
  207. docvortex/analyzers/native/pdf/titles.py +75 -0
  208. docvortex/analyzers/native/pdf/typography.py +19 -0
  209. docvortex/analyzers/native/pdf/visual_annotations.py +1262 -0
  210. docvortex/api.py +180 -0
  211. docvortex/assets/__init__.py +5 -0
  212. docvortex/assets/store.py +51 -0
  213. docvortex/cli.py +54 -0
  214. docvortex/codecs/__init__.py +3 -0
  215. docvortex/codecs/html/__init__.py +22 -0
  216. docvortex/codecs/html/contracts.py +236 -0
  217. docvortex/codecs/html/materializer.py +331 -0
  218. docvortex/codecs/html/parser.py +763 -0
  219. docvortex/codecs/html/resources.py +34 -0
  220. docvortex/codecs/json.py +17 -0
  221. docvortex/content/__init__.py +5 -0
  222. docvortex/content/inline.py +248 -0
  223. docvortex/content/markup/__init__.py +44 -0
  224. docvortex/content/markup/anchors.py +188 -0
  225. docvortex/content/markup/formula.py +280 -0
  226. docvortex/content/markup/projector.py +1237 -0
  227. docvortex/content/markup/styles.py +327 -0
  228. docvortex/content/mathml.py +167 -0
  229. docvortex/content/normalization.py +188 -0
  230. docvortex/content/spans.py +183 -0
  231. docvortex/content/table/__init__.py +18 -0
  232. docvortex/content/table/blocks.py +152 -0
  233. docvortex/content/table/content.py +425 -0
  234. docvortex/content/table/document.py +104 -0
  235. docvortex/content/table/html.py +399 -0
  236. docvortex/content/table/models.py +76 -0
  237. docvortex/content/table/rules.py +42 -0
  238. docvortex/content/table/structure.py +221 -0
  239. docvortex/content/tree.py +5 -0
  240. docvortex/document/__init__.py +3 -0
  241. docvortex/document/contracts.py +22 -0
  242. docvortex/document/detection.py +389 -0
  243. docvortex/document/filetypes.py +175 -0
  244. docvortex/document/page_range.py +167 -0
  245. docvortex/document/pdf/__init__.py +19 -0
  246. docvortex/document/pdf/classify.py +1138 -0
  247. docvortex/document/pdf/constants.py +132 -0
  248. docvortex/document/pdf/diagnostics.py +350 -0
  249. docvortex/document/pdf/document.py +582 -0
  250. docvortex/document/pdf/font_runtime.py +335 -0
  251. docvortex/document/pdf/geometry.py +31 -0
  252. docvortex/document/pdf/images.py +654 -0
  253. docvortex/document/pdf/native_annotations.py +367 -0
  254. docvortex/document/pdf/native_contracts.py +169 -0
  255. docvortex/document/pdf/native_coordinates.py +216 -0
  256. docvortex/document/pdf/native_lifecycle.py +16 -0
  257. docvortex/document/pdf/native_objects.py +902 -0
  258. docvortex/document/pdf/native_text_geometry.py +315 -0
  259. docvortex/document/pdf/pdfium.py +325 -0
  260. docvortex/document/pdf/raster.py +46 -0
  261. docvortex/document/pdf/text/__init__.py +62 -0
  262. docvortex/document/pdf/text/contracts.py +211 -0
  263. docvortex/document/pdf/text/extract.py +165 -0
  264. docvortex/document/pdf/text/geometry.py +16 -0
  265. docvortex/document/pdf/text/groups.py +162 -0
  266. docvortex/document/pdf/visual_geometry.py +201 -0
  267. docvortex/document/pdf/visuals.py +343 -0
  268. docvortex/document/source.py +92 -0
  269. docvortex/errors.py +21 -0
  270. docvortex/export/__init__.py +3 -0
  271. docvortex/export/bundle.py +98 -0
  272. docvortex/export/files.py +66 -0
  273. docvortex/export/middle.py +208 -0
  274. docvortex/foundation/__init__.py +3 -0
  275. docvortex/foundation/geometry.py +125 -0
  276. docvortex/foundation/hyperlink.py +65 -0
  277. docvortex/foundation/image.py +48 -0
  278. docvortex/foundation/image_encoding.py +30 -0
  279. docvortex/foundation/image_payload.py +280 -0
  280. docvortex/foundation/language.py +92 -0
  281. docvortex/foundation/platform.py +38 -0
  282. docvortex/foundation/text.py +153 -0
  283. docvortex/foundation/type_identity.py +20 -0
  284. docvortex/foundation/xml_names.py +20 -0
  285. docvortex/options.py +30 -0
  286. docvortex/postprocess/__init__.py +3 -0
  287. docvortex/postprocess/content.py +53 -0
  288. docvortex/postprocess/document.py +19 -0
  289. docvortex/postprocess/lists.py +236 -0
  290. docvortex/postprocess/page_blocks.py +214 -0
  291. docvortex/postprocess/pages.py +95 -0
  292. docvortex/postprocess/paragraphs.py +580 -0
  293. docvortex/postprocess/visual.py +715 -0
  294. docvortex/render/__init__.py +48 -0
  295. docvortex/render/_internal/__init__.py +3 -0
  296. docvortex/render/_internal/common/__init__.py +3 -0
  297. docvortex/render/_internal/common/context.py +43 -0
  298. docvortex/render/_internal/common/html_table.py +178 -0
  299. docvortex/render/_internal/common/index.py +33 -0
  300. docvortex/render/_internal/common/list_items.py +158 -0
  301. docvortex/render/_internal/common/planner.py +140 -0
  302. docvortex/render/_internal/docx/__init__.py +3 -0
  303. docvortex/render/_internal/docx/assets.py +202 -0
  304. docvortex/render/_internal/docx/inline.py +434 -0
  305. docvortex/render/_internal/docx/math.py +220 -0
  306. docvortex/render/_internal/docx/renderer.py +905 -0
  307. docvortex/render/_internal/docx/styles.py +195 -0
  308. docvortex/render/_internal/docx/table.py +442 -0
  309. docvortex/render/_internal/epub/__init__.py +5 -0
  310. docvortex/render/_internal/epub/assets.py +173 -0
  311. docvortex/render/_internal/epub/package.py +249 -0
  312. docvortex/render/_internal/epub/renderer.py +1156 -0
  313. docvortex/render/_internal/html/__init__.py +3 -0
  314. docvortex/render/_internal/html/inline.py +346 -0
  315. docvortex/render/_internal/html/renderer.py +1041 -0
  316. docvortex/render/_internal/html/sanitizer.py +478 -0
  317. docvortex/render/_internal/html/table.py +121 -0
  318. docvortex/render/_internal/latex/__init__.py +1 -0
  319. docvortex/render/_internal/latex/assets.py +85 -0
  320. docvortex/render/_internal/latex/inline.py +145 -0
  321. docvortex/render/_internal/latex/renderer.py +506 -0
  322. docvortex/render/_internal/latex/table.py +347 -0
  323. docvortex/render/_internal/markdown/__init__.py +3 -0
  324. docvortex/render/_internal/markdown/assets.py +78 -0
  325. docvortex/render/_internal/markdown/blocks.py +635 -0
  326. docvortex/render/_internal/markdown/escaping.py +51 -0
  327. docvortex/render/_internal/markdown/inline.py +260 -0
  328. docvortex/render/_internal/markdown/renderer.py +93 -0
  329. docvortex/render/_internal/markdown/table.py +281 -0
  330. docvortex/render/_internal/pdf/__init__.py +3 -0
  331. docvortex/render/_internal/pdf/assets.py +197 -0
  332. docvortex/render/_internal/pdf/formula.py +417 -0
  333. docvortex/render/_internal/pdf/inline.py +343 -0
  334. docvortex/render/_internal/pdf/renderer.py +734 -0
  335. docvortex/render/_internal/pdf/styles.py +206 -0
  336. docvortex/render/_internal/pdf/table.py +272 -0
  337. docvortex/render/_internal/structured_content/__init__.py +3 -0
  338. docvortex/render/_internal/structured_content/renderer.py +193 -0
  339. docvortex/render/api.py +199 -0
  340. docvortex/render/contracts.py +205 -0
  341. docvortex/render/docx.py +38 -0
  342. docvortex/render/epub.py +35 -0
  343. docvortex/render/fragments.py +70 -0
  344. docvortex/render/html.py +29 -0
  345. docvortex/render/latex.py +24 -0
  346. docvortex/render/markdown.py +50 -0
  347. docvortex/render/pdf.py +25 -0
  348. docvortex/render/structured_content.py +23 -0
  349. docvortex/resources/epub/docvortex.css +91 -0
  350. docvortex/resources/fasttext-langdetect/lid.176.ftz +0 -0
  351. docvortex/resources/fonts/DroidSansFallbackFull.ttf +0 -0
  352. docvortex/resources/fonts/NOTICE +190 -0
  353. docvortex/resources/fonts/manifest.json +9 -0
  354. docvortex/resources/html/docvortex.css +601 -0
  355. docvortex/resources/html/docvortex.min.css +1 -0
  356. docvortex/result.py +91 -0
  357. docvortex/schema.py +1141 -0
  358. docvortex/version.py +3 -0
  359. docvortex-0.2.1.dist-info/METADATA +193 -0
  360. docvortex-0.2.1.dist-info/RECORD +364 -0
  361. docvortex-0.2.1.dist-info/WHEEL +5 -0
  362. docvortex-0.2.1.dist-info/entry_points.txt +2 -0
  363. docvortex-0.2.1.dist-info/licenses/LICENSE.md +21 -0
  364. docvortex-0.2.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,132 @@
1
+ """PDF 分析各领域阶段共享的阈值、类型集合与映射。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ...schema import RAW_ALGORITHM, RAW_CAPTION, RAW_FOOTNOTE, RAW_FORMULA_NUMBER, RAW_PHONETIC, BlockType
6
+
7
+ LAYOUT_BASE_BATCH_SIZE = 1
8
+ MFR_BASE_BATCH_SIZE = 16
9
+ OCR_DET_BASE_BATCH_SIZE = 8
10
+ LAYOUT_TITLE_SPLIT_OVERLAP_THRESHOLD = 0.8
11
+ IMAGE_BLOCK_CONTAINMENT_THRESHOLD = 0.8
12
+ IMAGE_BLOCK_LAYOUT_COVERAGE_THRESHOLD = 0.9
13
+ IMAGE_BLOCK_LAYOUT_MIN_VISUAL_COUNT = 2
14
+ BATCH_RATIO = 2
15
+ TABLE_TEXT_LINE_OVERLAP_THRESHOLD = 0.5
16
+ TABLE_TEXT_ORIENTATION_MIN_VALID_LINES = 3
17
+ TABLE_TEXT_ORIENTATION_MIN_DOMINANCE_RATIO = 0.6
18
+ TABLE_TEXT_ORIENTATION_ANGLES = frozenset({0, 90, 180, 270})
19
+ _VLM_UNCLASSIFIED_TITLE_TYPE = "title"
20
+
21
+ TITLE_BLOCK_TYPES = {
22
+ _VLM_UNCLASSIFIED_TITLE_TYPE,
23
+ BlockType.DOC_TITLE,
24
+ BlockType.PARAGRAPH_TITLE,
25
+ }
26
+ CODE_CONTENT_BLOCK_TYPES = {BlockType.CODE, RAW_ALGORITHM}
27
+ LINE_METADATA_BLOCK_TYPES = {
28
+ BlockType.TEXT,
29
+ BlockType.REF_TEXT,
30
+ BlockType.DOC_TITLE,
31
+ BlockType.PARAGRAPH_TITLE,
32
+ RAW_CAPTION,
33
+ RAW_FOOTNOTE,
34
+ }
35
+ NATURAL_LANGUAGE_CONTENT_BLOCK_TYPES = {
36
+ BlockType.TEXT,
37
+ BlockType.DOC_TITLE,
38
+ BlockType.PARAGRAPH_TITLE,
39
+ BlockType.ASIDE_TEXT,
40
+ BlockType.HEADER,
41
+ BlockType.FOOTER,
42
+ BlockType.PAGE_NUMBER,
43
+ BlockType.PAGE_FOOTNOTE,
44
+ BlockType.REF_TEXT,
45
+ BlockType.LIST,
46
+ BlockType.INDEX,
47
+ RAW_CAPTION,
48
+ RAW_FOOTNOTE,
49
+ }
50
+ VLM_VISUAL_ANNOTATION_TYPE_MAP = {
51
+ BlockType.TABLE_CAPTION: RAW_CAPTION,
52
+ BlockType.IMAGE_CAPTION: RAW_CAPTION,
53
+ BlockType.CODE_CAPTION: RAW_CAPTION,
54
+ BlockType.TABLE_FOOTNOTE: RAW_FOOTNOTE,
55
+ BlockType.IMAGE_FOOTNOTE: RAW_FOOTNOTE,
56
+ }
57
+ VLM_MODEL_LIST_FIELDS = frozenset({"type", "bbox", "content", "angle", "score", "sub_type", "cell_merge"})
58
+ MODEL_JSON_VISUAL_BLOCK_TYPES = {
59
+ BlockType.IMAGE,
60
+ BlockType.CHART,
61
+ BlockType.TABLE,
62
+ BlockType.EQUATION,
63
+ }
64
+ LOCAL_LAYOUT_IMAGE_BLOCK_BODY_TYPES = {BlockType.IMAGE, BlockType.CHART}
65
+ LOCAL_LAYOUT_IMAGE_BLOCK_AREA_TYPES = {
66
+ *LOCAL_LAYOUT_IMAGE_BLOCK_BODY_TYPES,
67
+ BlockType.IMAGE_CAPTION,
68
+ RAW_CAPTION,
69
+ BlockType.IMAGE_FOOTNOTE,
70
+ RAW_FOOTNOTE,
71
+ }
72
+ VLM_LAYOUT_LABEL_MAP = {
73
+ "abstract": BlockType.TEXT,
74
+ "algorithm": BlockType.CODE,
75
+ "aside_text": BlockType.ASIDE_TEXT,
76
+ "chart": BlockType.CHART,
77
+ "content": BlockType.INDEX,
78
+ "display_formula": BlockType.EQUATION,
79
+ "doc_title": BlockType.DOC_TITLE,
80
+ "figure_title": RAW_CAPTION,
81
+ "footer": BlockType.FOOTER,
82
+ "footer_image": BlockType.FOOTER,
83
+ "footnote": BlockType.PAGE_FOOTNOTE,
84
+ "formula_number": RAW_FORMULA_NUMBER,
85
+ "header": BlockType.HEADER,
86
+ "header_image": BlockType.HEADER,
87
+ "image": BlockType.IMAGE,
88
+ "number": BlockType.PAGE_NUMBER,
89
+ "paragraph_title": BlockType.PARAGRAPH_TITLE,
90
+ "reference_content": BlockType.REF_TEXT,
91
+ "seal": BlockType.IMAGE,
92
+ "table": BlockType.TABLE,
93
+ "text": BlockType.TEXT,
94
+ "vertical_text": BlockType.TEXT,
95
+ "vision_footnote": RAW_FOOTNOTE,
96
+ }
97
+ PIPELINE_DET_TYPE = {
98
+ BlockType.TEXT,
99
+ BlockType.CODE,
100
+ BlockType.ASIDE_TEXT,
101
+ BlockType.INDEX,
102
+ BlockType.DOC_TITLE,
103
+ RAW_CAPTION,
104
+ BlockType.FOOTER,
105
+ BlockType.PAGE_FOOTNOTE,
106
+ BlockType.HEADER,
107
+ BlockType.PAGE_NUMBER,
108
+ BlockType.PARAGRAPH_TITLE,
109
+ BlockType.REF_TEXT,
110
+ RAW_FOOTNOTE,
111
+ }
112
+ NOT_EXTRACT_TYPES = {
113
+ BlockType.TEXT,
114
+ _VLM_UNCLASSIFIED_TITLE_TYPE,
115
+ BlockType.DOC_TITLE,
116
+ BlockType.PARAGRAPH_TITLE,
117
+ BlockType.HEADER,
118
+ BlockType.FOOTER,
119
+ BlockType.PAGE_NUMBER,
120
+ BlockType.PAGE_FOOTNOTE,
121
+ BlockType.REF_TEXT,
122
+ BlockType.TABLE_CAPTION,
123
+ BlockType.IMAGE_CAPTION,
124
+ RAW_CAPTION,
125
+ BlockType.TABLE_FOOTNOTE,
126
+ BlockType.IMAGE_FOOTNOTE,
127
+ RAW_FOOTNOTE,
128
+ BlockType.CODE_CAPTION,
129
+ RAW_PHONETIC,
130
+ }
131
+ VLM_TXT_DET_TYPE = NOT_EXTRACT_TYPES
132
+ VLM_OCR_DET_TYPE = set(LINE_METADATA_BLOCK_TYPES)
@@ -0,0 +1,350 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from io import BytesIO
5
+ from typing import Any
6
+
7
+ from loguru import logger
8
+ from pypdf import PageObject, PdfReader, PdfWriter
9
+ from reportlab.pdfgen import canvas
10
+
11
+ from ...schema import BBox, RAW_PHONETIC, Block, BlockType, PageInfo
12
+
13
+ # 文本类 block 共用 text bbox 样式,避免新增文本形态时遗漏多个绘制入口。
14
+ TEXT_LIKE_BLOCK_TYPES_FOR_BBOX = {
15
+ BlockType.TEXT,
16
+ BlockType.REF_TEXT,
17
+ RAW_PHONETIC,
18
+ }
19
+
20
+ # layout.pdf 中这些 block 直接使用自身 bbox,复合 block 则使用子 block bbox。
21
+ DIRECT_LAYOUT_BBOX_BLOCK_TYPES = TEXT_LIKE_BLOCK_TYPES_FOR_BBOX | {
22
+ BlockType.DOC_TITLE,
23
+ BlockType.PARAGRAPH_TITLE,
24
+ BlockType.EQUATION,
25
+ BlockType.LIST,
26
+ BlockType.INDEX,
27
+ }
28
+
29
+
30
+ def _get_layout_source_blocks(page: PageInfo) -> list[Block]:
31
+ """获取 layout.pdf 的页内原始布局块,避免段落合并后跨页子项串页绘制。"""
32
+ return page.preproc_blocks
33
+
34
+
35
+ def cal_canvas_rect(page: Any, bbox: BBox) -> list[float]:
36
+ """
37
+ Calculate the rectangle coordinates on the canvas based on the original PDF page and bounding box.
38
+
39
+ Args:
40
+ page: A PyPDF2 Page object representing a single page in the PDF.
41
+ bbox: [x0, y0, x1, y1] representing the bounding box coordinates.
42
+
43
+ Returns:
44
+ rect: [x0, y0, width, height] representing the rectangle coordinates on the canvas.
45
+ """
46
+ page_width, page_height = float(page.cropbox[2]), float(page.cropbox[3])
47
+
48
+ actual_width = page_width # The width of the final PDF display
49
+ actual_height = page_height # The height of the final PDF display
50
+
51
+ rotation_obj = page.get("/Rotate", 0)
52
+ try:
53
+ rotation = int(rotation_obj) % 360 # cast rotation to int to handle IndirectObject
54
+ except (ValueError, TypeError) as e:
55
+ logger.warning(f"Invalid /Rotate value {rotation_obj!r} on page; defaulting to 0. Error: {e}")
56
+ rotation = 0
57
+
58
+ if rotation in [90, 270]:
59
+ # PDF is rotated 90 degrees or 270 degrees, and the width and height need to be swapped
60
+ actual_width, actual_height = actual_height, actual_width
61
+
62
+ x0, y0, x1, y1 = bbox
63
+ rect_w = abs(x1 - x0)
64
+ rect_h = abs(y1 - y0)
65
+
66
+ if rotation == 270:
67
+ rect_w, rect_h = rect_h, rect_w
68
+ x0 = actual_height - y1
69
+ y0 = actual_width - x1
70
+ elif rotation == 180:
71
+ x0 = page_width - x1
72
+ # y0 stays the same
73
+ elif rotation == 90:
74
+ rect_w, rect_h = rect_h, rect_w
75
+ x0, y0 = y0, x0
76
+ else:
77
+ # rotation == 0
78
+ y0 = page_height - y1
79
+
80
+ rect = [x0, y0, rect_w, rect_h]
81
+ return rect
82
+
83
+
84
+ def draw_bbox_without_number(
85
+ i: int,
86
+ bbox_list: list[list[BBox]],
87
+ page: Any,
88
+ c: Any,
89
+ rgb_config: list[int],
90
+ fill_config: bool,
91
+ ) -> Any:
92
+ new_rgb = [float(color) / 255 for color in rgb_config]
93
+ page_data = bbox_list[i]
94
+
95
+ for bbox in page_data:
96
+ rect = cal_canvas_rect(page, bbox) # Define the rectangle
97
+
98
+ if fill_config: # filled rectangle
99
+ c.setFillColorRGB(new_rgb[0], new_rgb[1], new_rgb[2], 0.3)
100
+ c.rect(rect[0], rect[1], rect[2], rect[3], stroke=0, fill=1)
101
+ else: # bounding box
102
+ c.setStrokeColorRGB(new_rgb[0], new_rgb[1], new_rgb[2])
103
+ c.rect(rect[0], rect[1], rect[2], rect[3], stroke=1, fill=0)
104
+ return c
105
+
106
+
107
+ def draw_bbox_with_number(
108
+ i: int,
109
+ bbox_list: list[list[BBox]],
110
+ page: Any,
111
+ c: Any,
112
+ rgb_config: list[int],
113
+ fill_config: bool,
114
+ draw_bbox: bool = True,
115
+ ) -> Any:
116
+ new_rgb = [float(color) / 255 for color in rgb_config]
117
+ page_data = bbox_list[i]
118
+ # 强制转换为 float
119
+ # page_width, page_height = float(page.cropbox[2]), float(page.cropbox[3])
120
+
121
+ for j, bbox in enumerate(page_data):
122
+ # 确保bbox的每个元素都是float
123
+ rect = cal_canvas_rect(page, bbox) # Define the rectangle
124
+
125
+ if draw_bbox:
126
+ if fill_config:
127
+ c.setFillColorRGB(*new_rgb, 0.3)
128
+ c.rect(rect[0], rect[1], rect[2], rect[3], stroke=0, fill=1)
129
+ else:
130
+ c.setStrokeColorRGB(*new_rgb)
131
+ c.rect(rect[0], rect[1], rect[2], rect[3], stroke=1, fill=0)
132
+ c.setFillColorRGB(*new_rgb, 1.0)
133
+ c.setFontSize(size=10)
134
+
135
+ c.saveState()
136
+ rotation_obj = page.get("/Rotate", 0)
137
+ try:
138
+ rotation = int(rotation_obj) % 360 # cast rotation to int to handle IndirectObject
139
+ except (ValueError, TypeError):
140
+ logger.warning(f"Invalid /Rotate value: {rotation_obj!r}, defaulting to 0")
141
+ rotation = 0
142
+
143
+ if rotation == 0:
144
+ c.translate(rect[0] + rect[2] + 2, rect[1] + rect[3] - 10)
145
+ elif rotation == 90:
146
+ c.translate(rect[0] + 10, rect[1] + rect[3] + 2)
147
+ elif rotation == 180:
148
+ c.translate(rect[0] - 2, rect[1] + 10)
149
+ elif rotation == 270:
150
+ c.translate(rect[0] + rect[2] - 10, rect[1] - 2)
151
+
152
+ c.rotate(rotation)
153
+ c.drawString(0, 0, str(j + 1))
154
+ c.restoreState()
155
+
156
+ return c
157
+
158
+
159
+ def draw_layout_bbox(
160
+ pages: list[PageInfo],
161
+ pdf_bytes: bytes,
162
+ out_path: str,
163
+ filename: str,
164
+ ) -> None:
165
+ dropped_bbox_list = []
166
+ tables_body_list, tables_caption_list, tables_footnote_list = [], [], []
167
+ imgs_body_list, imgs_caption_list, imgs_footnote_list = [], [], []
168
+ codes_body_list, codes_caption_list, codes_footnote_list = [], [], []
169
+ titles_list = []
170
+ texts_list = []
171
+ equations_list = []
172
+ lists_list = []
173
+ list_items_list = []
174
+ indexs_list = []
175
+
176
+ for page in pages:
177
+ page_dropped_list = []
178
+ tables_body, tables_caption, tables_footnote = [], [], []
179
+ imgs_body, imgs_caption, imgs_footnote = [], [], []
180
+ codes_body, codes_caption, codes_footnote = [], [], []
181
+ titles = []
182
+ texts = []
183
+ equations = []
184
+ lists = []
185
+ list_items = []
186
+ indices = []
187
+
188
+ for dropped_bbox in page.discarded_blocks:
189
+ page_dropped_list.append(dropped_bbox.bbox)
190
+ dropped_bbox_list.append(page_dropped_list)
191
+ for block in _get_layout_source_blocks(page):
192
+ bbox = block.bbox
193
+ if block.type == BlockType.TABLE:
194
+ for nested_block in block.blocks:
195
+ bbox = nested_block.bbox
196
+ if nested_block.type == BlockType.TABLE_BODY:
197
+ tables_body.append(bbox)
198
+ elif nested_block.type == BlockType.TABLE_CAPTION:
199
+ tables_caption.append(bbox)
200
+ elif nested_block.type == BlockType.TABLE_FOOTNOTE:
201
+ if nested_block._cross_page:
202
+ continue
203
+ tables_footnote.append(bbox)
204
+ elif block.type == BlockType.IMAGE:
205
+ for nested_block in block.blocks:
206
+ bbox = nested_block.bbox
207
+ if nested_block.type == BlockType.IMAGE_BODY:
208
+ imgs_body.append(bbox)
209
+ elif nested_block.type == BlockType.IMAGE_CAPTION:
210
+ imgs_caption.append(bbox)
211
+ elif nested_block.type == BlockType.IMAGE_FOOTNOTE:
212
+ imgs_footnote.append(bbox)
213
+ elif block.type == BlockType.CODE:
214
+ for nested_block in block.blocks:
215
+ if nested_block.type == BlockType.CODE_BODY:
216
+ bbox = nested_block.bbox
217
+ codes_body.append(bbox)
218
+ elif nested_block.type == BlockType.CODE_CAPTION:
219
+ bbox = nested_block.bbox
220
+ codes_caption.append(bbox)
221
+ elif nested_block.type == BlockType.CODE_FOOTNOTE:
222
+ bbox = nested_block.bbox
223
+ codes_footnote.append(bbox)
224
+ elif block.type == BlockType.CHART:
225
+ for nested_block in block.blocks:
226
+ if nested_block.type == BlockType.CHART_BODY:
227
+ bbox = nested_block.bbox
228
+ imgs_body.append(bbox)
229
+ elif nested_block.type == BlockType.CHART_CAPTION:
230
+ bbox = nested_block.bbox
231
+ imgs_caption.append(bbox)
232
+ elif nested_block.type == BlockType.CHART_FOOTNOTE:
233
+ bbox = nested_block.bbox
234
+ imgs_footnote.append(bbox)
235
+ elif block.type in {BlockType.DOC_TITLE, BlockType.PARAGRAPH_TITLE}:
236
+ titles.append(bbox)
237
+ elif block.type in TEXT_LIKE_BLOCK_TYPES_FOR_BBOX:
238
+ texts.append(bbox)
239
+ elif block.type == BlockType.EQUATION:
240
+ equations.append(bbox)
241
+ elif block.type == BlockType.LIST:
242
+ lists.append(bbox)
243
+ if block.blocks:
244
+ for sub_block in block.blocks:
245
+ list_items.append(sub_block.bbox)
246
+ elif block.type == BlockType.INDEX:
247
+ indices.append(bbox)
248
+
249
+ tables_body_list.append(tables_body)
250
+ tables_caption_list.append(tables_caption)
251
+ tables_footnote_list.append(tables_footnote)
252
+ imgs_body_list.append(imgs_body)
253
+ imgs_caption_list.append(imgs_caption)
254
+ imgs_footnote_list.append(imgs_footnote)
255
+ titles_list.append(titles)
256
+ texts_list.append(texts)
257
+ equations_list.append(equations)
258
+ lists_list.append(lists)
259
+ list_items_list.append(list_items)
260
+ indexs_list.append(indices)
261
+ codes_body_list.append(codes_body)
262
+ codes_caption_list.append(codes_caption)
263
+ codes_footnote_list.append(codes_footnote)
264
+
265
+ layout_bbox_list = []
266
+
267
+ for page in pages:
268
+ page_block_list = []
269
+ for block in _get_layout_source_blocks(page):
270
+ if block.type in DIRECT_LAYOUT_BBOX_BLOCK_TYPES:
271
+ bbox = block.bbox
272
+ page_block_list.append(bbox)
273
+ elif block.type in [BlockType.IMAGE, BlockType.CHART, BlockType.CODE, BlockType.TABLE]:
274
+ for sub_block in block.blocks:
275
+ if sub_block._cross_page:
276
+ continue
277
+ bbox = sub_block.bbox
278
+ page_block_list.append(bbox)
279
+
280
+ layout_bbox_list.append(page_block_list)
281
+
282
+ pdf_bytes_io = BytesIO(pdf_bytes)
283
+ pdf_docs = PdfReader(pdf_bytes_io)
284
+ output_pdf = PdfWriter()
285
+
286
+ for i, page in enumerate(pdf_docs.pages):
287
+ # 获取原始页面尺寸
288
+ page_width, page_height = float(page.cropbox[2]), float(page.cropbox[3])
289
+ custom_page_size = (page_width, page_height)
290
+
291
+ packet = BytesIO()
292
+ # 使用原始PDF的尺寸创建canvas
293
+ c = canvas.Canvas(packet, pagesize=custom_page_size)
294
+
295
+ c = draw_bbox_without_number(i, codes_body_list, page, c, [102, 0, 204], True)
296
+ c = draw_bbox_without_number(i, codes_caption_list, page, c, [204, 153, 255], True)
297
+ c = draw_bbox_without_number(i, codes_footnote_list, page, c, [229, 204, 255], True)
298
+ c = draw_bbox_without_number(i, dropped_bbox_list, page, c, [158, 158, 158], True)
299
+ c = draw_bbox_without_number(i, tables_body_list, page, c, [204, 204, 0], True)
300
+ c = draw_bbox_without_number(i, tables_caption_list, page, c, [255, 255, 102], True)
301
+ c = draw_bbox_without_number(i, tables_footnote_list, page, c, [229, 255, 204], True)
302
+ c = draw_bbox_without_number(i, imgs_body_list, page, c, [153, 255, 51], True)
303
+ c = draw_bbox_without_number(i, imgs_caption_list, page, c, [102, 178, 255], True)
304
+ c = draw_bbox_without_number(i, imgs_footnote_list, page, c, [255, 178, 102], True)
305
+ c = draw_bbox_without_number(i, titles_list, page, c, [102, 102, 255], True)
306
+ c = draw_bbox_without_number(i, texts_list, page, c, [153, 0, 76], True)
307
+ c = draw_bbox_without_number(i, equations_list, page, c, [0, 255, 0], True)
308
+ c = draw_bbox_without_number(i, lists_list, page, c, [40, 169, 92], True)
309
+ c = draw_bbox_without_number(i, list_items_list, page, c, [40, 169, 92], False)
310
+ c = draw_bbox_without_number(i, indexs_list, page, c, [40, 169, 92], True)
311
+ c = draw_bbox_with_number(i, layout_bbox_list, page, c, [255, 0, 0], False, draw_bbox=False)
312
+
313
+ c.save()
314
+ packet.seek(0)
315
+ overlay_pdf = PdfReader(packet)
316
+
317
+ # 添加检查确保overlay_pdf.pages不为空
318
+ if len(overlay_pdf.pages) > 0:
319
+ new_page = PageObject(pdf=None)
320
+ new_page.update(page)
321
+ page = new_page
322
+ page.merge_page(overlay_pdf.pages[0])
323
+ else:
324
+ # 记录日志并继续处理下一个页面
325
+ # logger.warning(f"layout.pdf: 第{i + 1}页未能生成有效的overlay PDF")
326
+ pass
327
+
328
+ output_pdf.add_page(page)
329
+
330
+ # 保存结果
331
+ with open(f"{out_path}/{filename}", "wb") as f:
332
+ output_pdf.write(f)
333
+
334
+
335
+ if __name__ == "__main__":
336
+ # 读取PDF文件
337
+ pdf_path = "examples/demo1.pdf"
338
+ with open(pdf_path, "rb") as f:
339
+ pdf_bytes = f.read()
340
+
341
+ # 从json文件读取pdf_info
342
+
343
+ json_path = "examples/demo1_1746005777.0863056_middle.json"
344
+ with open(json_path, "r", encoding="utf-8") as f:
345
+ pdf_ann = json.load(f)
346
+ pdf_info = pdf_ann["pdf_info"]
347
+ from .document import PDFDocument
348
+
349
+ doc = PDFDocument(pdf_bytes)
350
+ doc.draw_layout_bbox(pdf_info, "examples/output_with_layout.pdf")