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,444 @@
1
+ """PDF 表格与注释输出物化;保留原有认领顺序与判定规则。"""
2
+
3
+ from __future__ import annotations
4
+ from typing import Any
5
+ from loguru import logger
6
+ from ....document.pdf.text.contracts import Char
7
+ from .table_recovery import (
8
+ NativeTableInput,
9
+ NativeTableRectangle,
10
+ NativeTableRule,
11
+ coerce_native_table_rectangles,
12
+ coerce_native_table_rules,
13
+ recover_native_pdf_table,
14
+ )
15
+ from .table_text_styles import render_native_table_html_with_scripts
16
+ from ....foundation.text import merge_text_line_contents
17
+ from .spatial_text import project_pdf_table_text
18
+ from ....schema import BBox
19
+ from ....foundation.language import detect_lang
20
+ from .models import _LineItem, _PageSource, _TableAnnotation, _TableCandidate
21
+ from .geometry import (
22
+ _bbox_axis_overlap_ratio,
23
+ _bbox_center_x,
24
+ _bbox_center_y,
25
+ _bbox_overlap_in_smaller,
26
+ _bbox_union,
27
+ _bbox_union_many,
28
+ _point_in_bbox,
29
+ _rotate_bbox_to_upright,
30
+ )
31
+ from .line_layout import _font_signatures_share_family, _line_effective_height, _line_tight_output_bbox
32
+ from .line_merging import _same_baseline_geometry
33
+ from .native_text import _normalize_native_run_text
34
+
35
+
36
+ def _recover_native_table_html(
37
+ source: _PageSource,
38
+ table_bbox: BBox,
39
+ angle: int,
40
+ chars: tuple[Char, ...] | None = None,
41
+ drawing_lines: tuple[NativeTableRule, ...] | None = None,
42
+ rectangles: tuple[NativeTableRectangle, ...] | None = None,
43
+ tight_bboxes: dict[int, BBox] | None = None,
44
+ origins: dict[int, tuple[float, float]] | None = None,
45
+ ) -> str:
46
+ """使用共享原生字符与绘图原语恢复高置信表格 HTML。"""
47
+
48
+ table_input = NativeTableInput(
49
+ table_bbox=table_bbox,
50
+ page_size=source.page_size,
51
+ angle=angle,
52
+ chars=chars if chars is not None else tuple(source.chars),
53
+ drawing_lines=(drawing_lines if drawing_lines is not None else coerce_native_table_rules(source.drawing_lines)),
54
+ rectangles=(rectangles if rectangles is not None else coerce_native_table_rectangles(source.path_infos)),
55
+ )
56
+ result = recover_native_pdf_table(table_input)
57
+ if result is None:
58
+ return ""
59
+ return render_native_table_html_with_scripts(
60
+ result,
61
+ table_input,
62
+ tight_bboxes or {},
63
+ origins or {},
64
+ )
65
+
66
+
67
+ def _materialize_table_blocks(
68
+ source: _PageSource,
69
+ candidates: list[_TableCandidate],
70
+ *,
71
+ tight_bboxes: dict[int, BBox] | None = None,
72
+ origins: dict[int, tuple[float, float]] | None = None,
73
+ ) -> tuple[list[dict[str, Any]], list[dict[str, Any]], set[int]]:
74
+ """原子物化表体及其独立注释,仅认领整组成功输出的文本行。"""
75
+
76
+ table_blocks: list[dict[str, Any]] = []
77
+ annotation_blocks: list[dict[str, Any]] = []
78
+ accepted_candidate_bboxes: list[BBox] = []
79
+ claimed: set[int] = set()
80
+ native_chars = tuple(source.chars)
81
+ native_rules = coerce_native_table_rules(source.drawing_lines)
82
+ native_rectangles = coerce_native_table_rectangles(source.path_infos)
83
+ for candidate in sorted(candidates, key=lambda item: item.score, reverse=True):
84
+ # 候选去重仍使用包含注释的完整框,不能因输出表体收缩而放行重复表格。
85
+ if any(_bbox_overlap_in_smaller(candidate.bbox, bbox) >= 0.5 for bbox in accepted_candidate_bboxes):
86
+ continue
87
+ output_angle = candidate.angle
88
+ candidate_annotation_blocks, externalized_line_indices, failed_annotations = _materialize_table_annotations(
89
+ source, candidate
90
+ )
91
+ projection_line_indices = _candidate_projection_line_indices(source, candidate)
92
+ for annotation in candidate.annotations:
93
+ projection_line_indices.update(annotation.line_indices)
94
+ projection_line_indices.difference_update(externalized_line_indices)
95
+ body_bbox = _table_body_materialization_bbox(
96
+ candidate,
97
+ failed_annotations,
98
+ )
99
+ content = ""
100
+ try:
101
+ content = _recover_native_table_html(
102
+ source,
103
+ body_bbox,
104
+ candidate.angle,
105
+ native_chars,
106
+ native_rules,
107
+ native_rectangles,
108
+ tight_bboxes,
109
+ origins,
110
+ )
111
+ except Exception as exc:
112
+ logger.warning(
113
+ f"Flash native table recovery failed and fell back to projection: bbox={candidate.bbox}, error={exc}"
114
+ )
115
+ if content:
116
+ logger.debug(f"Flash native table recovery accepted: bbox={body_bbox}, angle={candidate.angle}")
117
+ try:
118
+ if not content:
119
+ # 使用完整原始字符流保留 PDF 物理换行;行索引仅负责表体与注释的所有权认领。
120
+ content = project_pdf_table_text(
121
+ source.chars,
122
+ body_bbox,
123
+ angle=candidate.angle,
124
+ )
125
+ except Exception as exc:
126
+ # 表体投影异常时同时撤销预构造注释,保持整组不输出、不认领。
127
+ logger.warning(f"Flash table projection failed and rolled back: bbox={candidate.bbox}, error={exc}")
128
+ continue
129
+ if not content or not content.strip():
130
+ continue
131
+ table_blocks.append(
132
+ {
133
+ "type": "table",
134
+ "bbox": body_bbox,
135
+ "angle": output_angle,
136
+ "content": content,
137
+ }
138
+ )
139
+ annotation_blocks.extend(candidate_annotation_blocks)
140
+ accepted_candidate_bboxes.append(candidate.bbox)
141
+ # 表体和成功外置的注释行在同一事务中各认领一次。
142
+ claimed.update(projection_line_indices | externalized_line_indices)
143
+ table_blocks.sort(key=lambda block: (block["bbox"][1], block["bbox"][0]))
144
+ annotation_blocks.sort(key=lambda block: (block["bbox"][1], block["bbox"][0]))
145
+ return table_blocks, annotation_blocks, claimed
146
+
147
+
148
+ def _materialize_table_annotations(
149
+ source: _PageSource,
150
+ candidate: _TableCandidate,
151
+ ) -> tuple[list[dict[str, Any]], set[int], list[_TableAnnotation]]:
152
+ """构造候选注释块,并返回成功外置行与需回退到表体的注释记录。"""
153
+
154
+ blocks: list[dict[str, Any]] = []
155
+ externalized_line_indices: set[int] = set()
156
+ failed_annotations: list[_TableAnnotation] = []
157
+ annotations = sorted(
158
+ candidate.annotations,
159
+ key=lambda annotation: (
160
+ _rotate_bbox_to_upright(
161
+ annotation.bbox,
162
+ source.page_size,
163
+ candidate.angle,
164
+ )[1],
165
+ _rotate_bbox_to_upright(
166
+ annotation.bbox,
167
+ source.page_size,
168
+ candidate.angle,
169
+ )[0],
170
+ annotation.kind,
171
+ ),
172
+ )
173
+ for annotation in annotations:
174
+ annotation_blocks = _build_table_annotation_blocks(
175
+ source,
176
+ candidate,
177
+ annotation,
178
+ )
179
+ if not annotation_blocks:
180
+ failed_annotations.append(annotation)
181
+ continue
182
+ blocks.extend(annotation_blocks)
183
+ externalized_line_indices.update(annotation.line_indices)
184
+ return blocks, externalized_line_indices, failed_annotations
185
+
186
+
187
+ def _split_table_annotation_visual_groups(
188
+ line_geometry: list[tuple[_LineItem, BBox]],
189
+ ) -> list[list[tuple[_LineItem, BBox]]]:
190
+ """用短尾后的字体或字号重启拆分独立表格注释段。"""
191
+
192
+ if len(line_geometry) < 2:
193
+ return [line_geometry] if line_geometry else []
194
+ maximum_width = max(bbox[2] - bbox[0] for _line, bbox in line_geometry)
195
+ group_left = min(bbox[0] for _line, bbox in line_geometry)
196
+ groups = [[line_geometry[0]]]
197
+ for previous, current in zip(line_geometry, line_geometry[1:]):
198
+ previous_line, previous_bbox = previous
199
+ current_line, current_bbox = current
200
+ previous_width = previous_bbox[2] - previous_bbox[0]
201
+ current_width = current_bbox[2] - current_bbox[0]
202
+ pair_height = max(
203
+ _line_effective_height(*previous),
204
+ _line_effective_height(*current),
205
+ )
206
+ font_switch = (
207
+ previous_line.font_signature is not None
208
+ and current_line.font_signature is not None
209
+ and previous_line.font_coverage >= 0.6
210
+ and current_line.font_coverage >= 0.75
211
+ and not _font_signatures_share_family(
212
+ previous_line.font_signature,
213
+ current_line.font_signature,
214
+ )
215
+ )
216
+ scale_ratio = max(
217
+ previous_line.em_height or _line_effective_height(*previous),
218
+ current_line.em_height or _line_effective_height(*current),
219
+ ) / max(
220
+ 0.1,
221
+ min(
222
+ previous_line.em_height or _line_effective_height(*previous),
223
+ current_line.em_height or _line_effective_height(*current),
224
+ ),
225
+ )
226
+ vertical_gap = current_bbox[1] - (previous_bbox[1] + _line_effective_height(*previous))
227
+ should_split = (
228
+ previous_width <= 0.45 * maximum_width
229
+ and current_width >= 0.75 * maximum_width
230
+ and current_bbox[0] - group_left <= 3.0 * pair_height
231
+ and -0.25 * pair_height <= vertical_gap <= 0.75 * pair_height
232
+ and (font_switch or scale_ratio >= 1.25)
233
+ )
234
+ if should_split:
235
+ groups.append([current])
236
+ else:
237
+ groups[-1].append(current)
238
+ return groups
239
+
240
+
241
+ def _build_table_annotation_blocks(
242
+ source: _PageSource,
243
+ candidate: _TableCandidate,
244
+ annotation: _TableAnnotation,
245
+ ) -> list[dict[str, Any]]:
246
+ """按视觉重启切分原生行,并生成保留排版元数据的独立注释块。"""
247
+
248
+ line_geometry = [
249
+ (
250
+ line,
251
+ _rotate_bbox_to_upright(
252
+ line.bbox,
253
+ source.page_size,
254
+ candidate.angle,
255
+ ),
256
+ )
257
+ for line in source.lines
258
+ if line.source_index in annotation.line_indices
259
+ ]
260
+ # 原生来源顺序可抵抗旋转文字同一基线上的字形顶边抖动。
261
+ line_geometry.sort(key=lambda item: item[0].source_index)
262
+ blocks = []
263
+ for group in _split_table_annotation_visual_groups(line_geometry):
264
+ content = _merge_table_annotation_content(
265
+ [line.text for line, _local_bbox in group],
266
+ )
267
+ if not content:
268
+ continue
269
+ local_output_line_bboxes = []
270
+ output_bbox_repaired = False
271
+ for line, local_bbox in group:
272
+ tight_candidate = _line_tight_output_bbox(
273
+ line,
274
+ source.page_size,
275
+ )
276
+ if tight_candidate is None:
277
+ local_output_line_bboxes.append(local_bbox)
278
+ else:
279
+ local_output_line_bboxes.append(
280
+ _rotate_bbox_to_upright(
281
+ tight_candidate,
282
+ source.page_size,
283
+ candidate.angle,
284
+ )
285
+ )
286
+ output_bbox_repaired = True
287
+ blocks.append(
288
+ {
289
+ "type": annotation.kind,
290
+ "bbox": _bbox_union_many(
291
+ [
292
+ annotation.line_bboxes.get(
293
+ line.source_index,
294
+ line.bbox,
295
+ )
296
+ for line, _local_bbox in group
297
+ ]
298
+ ),
299
+ "angle": candidate.angle,
300
+ "content": content,
301
+ "_local_line_bboxes": [bbox for _line, bbox in group],
302
+ "_local_output_line_bboxes": local_output_line_bboxes,
303
+ "_output_bbox_repaired": output_bbox_repaired,
304
+ "_line_heights": [_line_effective_height(line, bbox) for line, bbox in group],
305
+ "_font_signatures": {
306
+ line.font_signature
307
+ for line, _bbox in group
308
+ if line.font_signature is not None and line.font_coverage >= 0.5
309
+ },
310
+ # 已由表格检测器给出完整边界,禁止通用表注规则继续向下扩张。
311
+ "_table_annotation_complete": True,
312
+ }
313
+ )
314
+ return blocks
315
+
316
+
317
+ def _merge_table_annotation_content(line_texts: list[str]) -> str:
318
+ """按正文一致的语言与行末断词规则折叠表格注释原生行。"""
319
+
320
+ normalized_lines = [normalized for text in line_texts if (normalized := _normalize_native_run_text(str(text or "")))]
321
+ if not normalized_lines:
322
+ return ""
323
+ try:
324
+ block_language = detect_lang("".join(normalized_lines))
325
+ except Exception:
326
+ block_language = ""
327
+ return merge_text_line_contents(
328
+ normalized_lines,
329
+ block_language=block_language,
330
+ )
331
+
332
+
333
+ def _table_body_materialization_bbox(
334
+ candidate: _TableCandidate,
335
+ failed_annotations: list[_TableAnnotation],
336
+ ) -> BBox:
337
+ """返回排除有效注释后的表体框,并把无效注释边界保守并回表体。"""
338
+
339
+ if not candidate.annotations or len(failed_annotations) == len(candidate.annotations):
340
+ return candidate.bbox
341
+ body_bbox = candidate.core_bbox or candidate.bbox
342
+ for annotation in failed_annotations:
343
+ body_bbox = _bbox_union(body_bbox, annotation.bbox)
344
+ return body_bbox
345
+
346
+
347
+ def _candidate_projection_line_indices(
348
+ source: _PageSource,
349
+ candidate: _TableCandidate,
350
+ ) -> set[int]:
351
+ """合并核心成员、同基线续段及非零角度表格的表头文本。"""
352
+
353
+ line_indices = set(candidate.line_indices)
354
+ if candidate.core_bbox is not None:
355
+ for line in source.lines:
356
+ if _point_in_bbox(
357
+ (_bbox_center_x(line.bbox), _bbox_center_y(line.bbox)),
358
+ candidate.core_bbox,
359
+ ):
360
+ line_indices.add(line.source_index)
361
+ if candidate.angle == 0:
362
+ _expand_candidate_same_baseline_members(source, candidate, line_indices)
363
+ return line_indices
364
+ if candidate.core_bbox is None:
365
+ return line_indices
366
+
367
+ candidate_local_bbox = _rotate_bbox_to_upright(
368
+ candidate.bbox,
369
+ source.page_size,
370
+ candidate.angle,
371
+ )
372
+ core_local_bbox = _rotate_bbox_to_upright(
373
+ candidate.core_bbox,
374
+ source.page_size,
375
+ candidate.angle,
376
+ )
377
+ for line in source.lines:
378
+ if line.angle != candidate.angle:
379
+ continue
380
+ page_center = (_bbox_center_x(line.bbox), _bbox_center_y(line.bbox))
381
+ if not _point_in_bbox(page_center, candidate.bbox):
382
+ continue
383
+ local_bbox = _rotate_bbox_to_upright(
384
+ line.bbox,
385
+ source.page_size,
386
+ candidate.angle,
387
+ )
388
+ local_center_y = _bbox_center_y(local_bbox)
389
+ if not candidate_local_bbox[1] <= local_center_y <= candidate_local_bbox[3]:
390
+ continue
391
+ if _bbox_axis_overlap_ratio(local_bbox, core_local_bbox, axis="x") < 0.05:
392
+ continue
393
+ line_indices.add(line.source_index)
394
+ return line_indices
395
+
396
+
397
+ def _expand_candidate_same_baseline_members(
398
+ source: _PageSource,
399
+ candidate: _TableCandidate,
400
+ line_indices: set[int],
401
+ ) -> None:
402
+ """迭代吸收完整候选框内与已认领成员同基线相邻的 angle=0 续段。"""
403
+
404
+ local_bboxes = {
405
+ line.source_index: _rotate_bbox_to_upright(
406
+ line.bbox,
407
+ source.page_size,
408
+ candidate.angle,
409
+ )
410
+ for line in source.lines
411
+ if line.angle == candidate.angle
412
+ }
413
+ changed = True
414
+ while changed:
415
+ changed = False
416
+ selected_lines = [line for line in source.lines if line.angle == candidate.angle and line.source_index in line_indices]
417
+ for line in source.lines:
418
+ if line.angle != candidate.angle or line.source_index in line_indices:
419
+ continue
420
+ if not _point_in_bbox(
421
+ (_bbox_center_x(line.bbox), _bbox_center_y(line.bbox)),
422
+ candidate.bbox,
423
+ ):
424
+ continue
425
+ line_bbox = local_bboxes[line.source_index]
426
+ line_height = _line_effective_height(line, line_bbox)
427
+ for selected in selected_lines:
428
+ if (
429
+ line.font_signature is not None
430
+ and selected.font_signature is not None
431
+ and line.font_signature != selected.font_signature
432
+ ):
433
+ continue
434
+ selected_bbox = local_bboxes[selected.source_index]
435
+ if not _same_baseline_geometry(
436
+ line_bbox,
437
+ line_height,
438
+ selected_bbox,
439
+ _line_effective_height(selected, selected_bbox),
440
+ ):
441
+ continue
442
+ line_indices.add(line.source_index)
443
+ changed = True
444
+ break
@@ -0,0 +1,15 @@
1
+ """面向已有 table bbox 的 Native PDF 表格结构恢复公共内部入口。"""
2
+
3
+ from .contracts import NativeTableCell, NativeTableInput, NativeTableRectangle, NativeTableResult, NativeTableRule
4
+ from .engine import coerce_native_table_rectangles, coerce_native_table_rules, recover_native_pdf_table
5
+
6
+ __all__ = [
7
+ "NativeTableCell",
8
+ "NativeTableInput",
9
+ "NativeTableRectangle",
10
+ "NativeTableResult",
11
+ "NativeTableRule",
12
+ "coerce_native_table_rectangles",
13
+ "coerce_native_table_rules",
14
+ "recover_native_pdf_table",
15
+ ]