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,393 @@
1
+ """PPTX 形状层级及页面几何,复用当前转换器的单文档状态。"""
2
+
3
+ from typing import Optional
4
+ from loguru import logger
5
+ from pptx.enum.shapes import MSO_SHAPE_TYPE
6
+ from .....schema import BlockType
7
+
8
+ from .context import (
9
+ MIN_PICTURE_DIMENSION_RATIO,
10
+ MIN_PICTURE_AREA_RATIO,
11
+ BACKGROUND_PICTURE_TEXT_COVERAGE_RATIO,
12
+ DRAWINGML_NS,
13
+ OMML_NS,
14
+ _SlideTransform,
15
+ _FlattenedShape,
16
+ )
17
+
18
+
19
+ class _PptxShapes:
20
+ """集中维护形状层级及页面几何,不改变文档生命周期和公开入口。"""
21
+
22
+ @staticmethod
23
+ def _shape_type_cache_key(
24
+ shape,
25
+ ) -> Optional[tuple[Optional[str], Optional[int], Optional[str]]]:
26
+ """按原有形状层级及页面几何规则执行 _shape_type_cache_key,保持输入顺序与降级行为。"""
27
+ part = getattr(shape, "part", None)
28
+ partname = getattr(part, "partname", None)
29
+ element = getattr(shape, "element", None)
30
+ element_tag = getattr(element, "tag", None)
31
+ try:
32
+ shape_id = shape.shape_id
33
+ except Exception:
34
+ shape_id = None
35
+
36
+ if partname is None and shape_id is None and element_tag is None:
37
+ return None
38
+
39
+ return (partname, shape_id, element_tag)
40
+
41
+ def _safe_shape_type(self, shape) -> Optional[MSO_SHAPE_TYPE]:
42
+ """按原有形状层级及页面几何规则执行 _safe_shape_type,保持输入顺序与降级行为。"""
43
+ shape_key = self._shape_type_cache_key(shape)
44
+ if shape_key is not None and shape_key in self._shape_type_cache:
45
+ return self._shape_type_cache[shape_key]
46
+
47
+ try:
48
+ shape_type = shape.shape_type
49
+ except NotImplementedError as exc:
50
+ shape_name = getattr(shape, "name", None)
51
+ shape_element = getattr(shape, "element", None)
52
+ shape_element_tag = getattr(shape_element, "tag", None)
53
+ has_text_frame = getattr(shape, "has_text_frame", None)
54
+ logger.warning(
55
+ "Skipping shape_type-specific handling for unrecognized PPTX shape: "
56
+ f"class={type(shape).__name__}, "
57
+ f"name={shape_name!r}, "
58
+ f"element_tag={shape_element_tag!r}, "
59
+ f"has_text_frame={has_text_frame!r}, "
60
+ f"error={exc}"
61
+ )
62
+ shape_type = None
63
+
64
+ if shape_key is not None:
65
+ self._shape_type_cache[shape_key] = shape_type
66
+ return shape_type
67
+
68
+ def _flatten_slide_shapes(
69
+ self,
70
+ shapes,
71
+ slide_transform: Optional[_SlideTransform] = None,
72
+ ) -> list[_FlattenedShape]:
73
+ """按原有形状层级及页面几何规则执行 _flatten_slide_shapes,保持输入顺序与降级行为。"""
74
+ if slide_transform is None:
75
+ slide_transform = _SlideTransform()
76
+
77
+ linear_shapes: list[_FlattenedShape] = []
78
+ for shape in shapes:
79
+ shape_type = self._safe_shape_type(shape)
80
+ if shape_type == MSO_SHAPE_TYPE.GROUP:
81
+ group_transform = self._group_shape_transform(shape)
82
+ linear_shapes.extend(
83
+ self._flatten_slide_shapes(
84
+ shape.shapes,
85
+ slide_transform.compose(group_transform),
86
+ )
87
+ )
88
+ else:
89
+ linear_shapes.append(
90
+ _FlattenedShape(
91
+ shape=shape,
92
+ bbox=slide_transform.apply_bbox(self._shape_bbox(shape)),
93
+ )
94
+ )
95
+ return linear_shapes
96
+
97
+ def _collect_shape_blocks(
98
+ self,
99
+ shape_entry: _FlattenedShape,
100
+ linear_shapes: list[_FlattenedShape],
101
+ shape_index: int,
102
+ slide_width: int,
103
+ slide_height: int,
104
+ ) -> list:
105
+ """按原有形状层级及页面几何规则执行 _collect_shape_blocks,保持输入顺序与降级行为。"""
106
+ shape = shape_entry.shape
107
+ shape_blocks = []
108
+ previous_page = self.cur_page
109
+ previous_list_block_stack = self.list_block_stack
110
+ self.cur_page = shape_blocks
111
+ self.list_block_stack = []
112
+
113
+ try:
114
+ shape_type = self._safe_shape_type(shape)
115
+ if shape_type in {
116
+ MSO_SHAPE_TYPE.EMBEDDED_OLE_OBJECT,
117
+ MSO_SHAPE_TYPE.LINKED_OLE_OBJECT,
118
+ }:
119
+ if self._is_equation_ole_shape(shape):
120
+ omml_equations = self._pptx_ole_shape_omml(shape)
121
+ if omml_equations:
122
+ self.cur_page.extend(
123
+ {
124
+ "type": BlockType.EQUATION,
125
+ "content": latex,
126
+ }
127
+ for latex in omml_equations
128
+ )
129
+ return shape_blocks
130
+ latex = self._decode_pptx_ole_equation(shape)
131
+ if latex:
132
+ self.cur_page.append(
133
+ {
134
+ "type": BlockType.EQUATION,
135
+ "content": latex,
136
+ }
137
+ )
138
+ else:
139
+ self._handle_pictures(shape)
140
+ return shape_blocks
141
+
142
+ if shape.has_table:
143
+ self._handle_tables(shape)
144
+
145
+ if getattr(shape, "has_chart", False):
146
+ self._handle_chart(shape)
147
+
148
+ if shape_type == MSO_SHAPE_TYPE.PICTURE:
149
+ image_latex = self._decode_pptx_shape_image_equation(shape)
150
+ if image_latex:
151
+ self.cur_page.append(
152
+ {
153
+ "type": BlockType.EQUATION,
154
+ "content": image_latex,
155
+ }
156
+ )
157
+ return shape_blocks
158
+ later_shapes = linear_shapes[shape_index + 1 :]
159
+ if not self._should_skip_picture(
160
+ shape_entry,
161
+ later_shapes,
162
+ slide_width,
163
+ slide_height,
164
+ ):
165
+ self._handle_pictures(shape)
166
+
167
+ if not getattr(shape, "has_text_frame", False):
168
+ return shape_blocks
169
+
170
+ self._handle_text_elements(shape)
171
+ return shape_blocks
172
+ finally:
173
+ self.cur_page = previous_page
174
+ self.list_block_stack = previous_list_block_stack
175
+
176
+ @staticmethod
177
+ def _shape_bbox(shape) -> Optional[tuple[float, float, float, float]]:
178
+ """按原有形状层级及页面几何规则执行 _shape_bbox,保持输入顺序与降级行为。"""
179
+ try:
180
+ left = float(shape.left)
181
+ top = float(shape.top)
182
+ width = float(shape.width)
183
+ height = float(shape.height)
184
+ except Exception:
185
+ return None
186
+
187
+ if width <= 0 or height <= 0:
188
+ return None
189
+
190
+ return (left, top, left + width, top + height)
191
+
192
+ @staticmethod
193
+ def _group_shape_transform(shape) -> _SlideTransform:
194
+ """按原有形状层级及页面几何规则执行 _group_shape_transform,保持输入顺序与降级行为。"""
195
+ group_properties = getattr(shape._element, "grpSpPr", None)
196
+ xfrm = getattr(group_properties, "xfrm", None) if group_properties is not None else None
197
+ if xfrm is None:
198
+ return _SlideTransform()
199
+
200
+ child_offset = getattr(xfrm, "chOff", None)
201
+ child_extent = getattr(xfrm, "chExt", None)
202
+ if child_offset is None or child_extent is None:
203
+ return _SlideTransform()
204
+
205
+ try:
206
+ offset_x = float(xfrm.x)
207
+ offset_y = float(xfrm.y)
208
+ extent_x = float(xfrm.cx)
209
+ extent_y = float(xfrm.cy)
210
+ child_offset_x = float(child_offset.x)
211
+ child_offset_y = float(child_offset.y)
212
+ child_extent_x = float(child_extent.cx)
213
+ child_extent_y = float(child_extent.cy)
214
+ except Exception:
215
+ return _SlideTransform()
216
+
217
+ if extent_x <= 0 or extent_y <= 0 or child_extent_x <= 0 or child_extent_y <= 0:
218
+ return _SlideTransform()
219
+
220
+ scale_x = extent_x / child_extent_x
221
+ scale_y = extent_y / child_extent_y
222
+ return _SlideTransform(
223
+ scale_x=scale_x,
224
+ scale_y=scale_y,
225
+ translate_x=offset_x - child_offset_x * scale_x,
226
+ translate_y=offset_y - child_offset_y * scale_y,
227
+ )
228
+
229
+ @staticmethod
230
+ def _bbox_area(bbox: tuple[float, float, float, float]) -> float:
231
+ """按原有形状层级及页面几何规则执行 _bbox_area,保持输入顺序与降级行为。"""
232
+ return max(0.0, bbox[2] - bbox[0]) * max(0.0, bbox[3] - bbox[1])
233
+
234
+ @staticmethod
235
+ def _bbox_intersection(
236
+ bbox1: tuple[float, float, float, float],
237
+ bbox2: tuple[float, float, float, float],
238
+ ) -> Optional[tuple[float, float, float, float]]:
239
+ """按原有形状层级及页面几何规则执行 _bbox_intersection,保持输入顺序与降级行为。"""
240
+ x0 = max(bbox1[0], bbox2[0])
241
+ y0 = max(bbox1[1], bbox2[1])
242
+ x1 = min(bbox1[2], bbox2[2])
243
+ y1 = min(bbox1[3], bbox2[3])
244
+
245
+ if x1 <= x0 or y1 <= y0:
246
+ return None
247
+
248
+ return (x0, y0, x1, y1)
249
+
250
+ @classmethod
251
+ def _rectangles_union_area(cls, bboxes: list[tuple[float, float, float, float]]) -> float:
252
+ """按原有形状层级及页面几何规则执行 _rectangles_union_area,保持输入顺序与降级行为。"""
253
+ if not bboxes:
254
+ return 0.0
255
+
256
+ xs = sorted({bbox[0] for bbox in bboxes} | {bbox[2] for bbox in bboxes})
257
+ total_area = 0.0
258
+
259
+ for idx in range(len(xs) - 1):
260
+ x_left = xs[idx]
261
+ x_right = xs[idx + 1]
262
+ if x_right <= x_left:
263
+ continue
264
+
265
+ y_intervals = []
266
+ for bbox in bboxes:
267
+ if bbox[0] < x_right and bbox[2] > x_left:
268
+ y_intervals.append((bbox[1], bbox[3]))
269
+
270
+ if not y_intervals:
271
+ continue
272
+
273
+ y_intervals.sort()
274
+ merged_height = 0.0
275
+ current_y0, current_y1 = y_intervals[0]
276
+
277
+ for y0, y1 in y_intervals[1:]:
278
+ if y0 <= current_y1:
279
+ current_y1 = max(current_y1, y1)
280
+ continue
281
+
282
+ merged_height += max(0.0, current_y1 - current_y0)
283
+ current_y0, current_y1 = y0, y1
284
+
285
+ merged_height += max(0.0, current_y1 - current_y0)
286
+ total_area += (x_right - x_left) * merged_height
287
+
288
+ return total_area
289
+
290
+ @staticmethod
291
+ def _shape_has_raw_text(shape) -> bool:
292
+ """通过shape底层XML判断是否有文本,避免数学公式触发python-pptx文本转换。"""
293
+ if not getattr(shape, "has_text_frame", False):
294
+ return False
295
+
296
+ shape_xml = getattr(shape, "_element", None)
297
+ if shape_xml is None:
298
+ return False
299
+
300
+ text_tags = {
301
+ f"{{{DRAWINGML_NS}}}t",
302
+ f"{{{OMML_NS}}}t",
303
+ }
304
+ for text_node in shape_xml.iter():
305
+ if getattr(text_node, "tag", None) not in text_tags:
306
+ continue
307
+ if text_node.text and text_node.text.strip():
308
+ return True
309
+
310
+ return False
311
+
312
+ @staticmethod
313
+ def _is_nonempty_text_shape(shape) -> bool:
314
+ """按原有形状层级及页面几何规则执行 _is_nonempty_text_shape,保持输入顺序与降级行为。"""
315
+ return _PptxShapes._shape_has_raw_text(shape)
316
+
317
+ def _is_small_picture(
318
+ self,
319
+ picture_bbox: Optional[tuple[float, float, float, float]],
320
+ slide_width: int,
321
+ slide_height: int,
322
+ ) -> bool:
323
+ """按原有形状层级及页面几何规则执行 _is_small_picture,保持输入顺序与降级行为。"""
324
+ if picture_bbox is None:
325
+ return False
326
+
327
+ picture_width = picture_bbox[2] - picture_bbox[0]
328
+ picture_height = picture_bbox[3] - picture_bbox[1]
329
+
330
+ if picture_width <= 0 or picture_height <= 0:
331
+ return False
332
+
333
+ slide_area = float(slide_width) * float(slide_height)
334
+ if slide_area <= 0:
335
+ return False
336
+
337
+ if picture_width < MIN_PICTURE_DIMENSION_RATIO * float(slide_width):
338
+ return True
339
+ if picture_height < MIN_PICTURE_DIMENSION_RATIO * float(slide_height):
340
+ return True
341
+
342
+ picture_area_ratio = (picture_width * picture_height) / slide_area
343
+ return picture_area_ratio < MIN_PICTURE_AREA_RATIO
344
+
345
+ def _is_background_picture(
346
+ self,
347
+ picture_entry: _FlattenedShape,
348
+ later_shapes: list[_FlattenedShape],
349
+ ) -> bool:
350
+ """按原有形状层级及页面几何规则执行 _is_background_picture,保持输入顺序与降级行为。"""
351
+ picture_bbox = picture_entry.bbox
352
+ if picture_bbox is None:
353
+ return False
354
+
355
+ picture_area = self._bbox_area(picture_bbox)
356
+ if picture_area <= 0:
357
+ return False
358
+
359
+ overlap_bboxes = []
360
+ for later_shape in later_shapes:
361
+ if not self._is_nonempty_text_shape(later_shape.shape):
362
+ continue
363
+
364
+ later_bbox = later_shape.bbox
365
+ if later_bbox is None:
366
+ continue
367
+
368
+ overlap_bbox = self._bbox_intersection(picture_bbox, later_bbox)
369
+ if overlap_bbox is not None:
370
+ overlap_bboxes.append(overlap_bbox)
371
+
372
+ if not overlap_bboxes:
373
+ return False
374
+
375
+ covered_area = self._rectangles_union_area(overlap_bboxes)
376
+ return covered_area / picture_area >= BACKGROUND_PICTURE_TEXT_COVERAGE_RATIO
377
+
378
+ def _should_skip_picture(
379
+ self,
380
+ picture_entry: _FlattenedShape,
381
+ later_shapes: list[_FlattenedShape],
382
+ slide_width: int,
383
+ slide_height: int,
384
+ ) -> bool:
385
+ """按原有形状层级及页面几何规则执行 _should_skip_picture,保持输入顺序与降级行为。"""
386
+ return self._is_small_picture(
387
+ picture_entry.bbox,
388
+ slide_width,
389
+ slide_height,
390
+ ) or self._is_background_picture(
391
+ picture_entry,
392
+ later_shapes,
393
+ )