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,18 @@
1
+ """Flash Office 转换器复用的调用方二进制流读取能力。"""
2
+
3
+ from typing import BinaryIO
4
+
5
+
6
+ def rewind_stream(file_stream: BinaryIO) -> bool:
7
+ """将可复位的二进制流移动到起点;不可复位时返回 False。"""
8
+ try:
9
+ file_stream.seek(0)
10
+ except (AttributeError, OSError, ValueError):
11
+ return False
12
+ return True
13
+
14
+
15
+ def read_stream_bytes_from_start(file_stream: BinaryIO) -> bytes:
16
+ """从流起点读取完整字节;不可复位的流则从当前位置读取剩余字节。"""
17
+ rewind_stream(file_stream)
18
+ return file_stream.read()
@@ -0,0 +1,3 @@
1
+ """Excel 97–2003 二进制解析实现。"""
2
+
3
+ __all__: list[str] = []
@@ -0,0 +1,132 @@
1
+ """解析 BIFF chart BRAI 中的简单单元格引用。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ import struct
7
+
8
+ from .records import BiffRecord
9
+
10
+ BRAI = 0x1051
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class ChartSourceSelection:
15
+ """一个 chart 引用到的唯一源工作表及行列集合。"""
16
+
17
+ sheet_index: int
18
+ rows: tuple[int, ...]
19
+ cols: tuple[int, ...]
20
+
21
+
22
+ def _extern_sheet_index(
23
+ extern_sheets: list[int | None],
24
+ extern_index: int,
25
+ ) -> int | None:
26
+ """把 ixti 解析为内部工作表索引。"""
27
+
28
+ if 0 <= extern_index < len(extern_sheets):
29
+ return extern_sheets[extern_index]
30
+ return None
31
+
32
+
33
+ def _reference_from_tokens(
34
+ tokens: bytes,
35
+ *,
36
+ current_sheet_index: int,
37
+ extern_sheets: list[int | None],
38
+ ) -> tuple[int, list[int], list[int]] | None:
39
+ """解析单一 PtgRef/PtgArea 及其 3D 变体和源工作表。"""
40
+
41
+ if not tokens:
42
+ return None
43
+ token = tokens[0] & 0x1F
44
+ if token == 0x04 and len(tokens) >= 5:
45
+ row, column_flags = struct.unpack_from("<HH", tokens, 1)
46
+ return current_sheet_index, [int(row)], [int(column_flags & 0x00FF)]
47
+ if token == 0x05 and len(tokens) >= 9:
48
+ row_first, row_last, col_first, col_last = struct.unpack_from("<4H", tokens, 1)
49
+ return (
50
+ current_sheet_index,
51
+ list(range(min(row_first, row_last), max(row_first, row_last) + 1)),
52
+ list(range((col_first & 0x00FF), (col_last & 0x00FF) + 1)),
53
+ )
54
+ if token == 0x1A and len(tokens) >= 7:
55
+ extern_index, row, column_flags = struct.unpack_from("<3H", tokens, 1)
56
+ sheet_index = _extern_sheet_index(extern_sheets, int(extern_index))
57
+ if sheet_index is None:
58
+ return None
59
+ return sheet_index, [int(row)], [int(column_flags & 0x00FF)]
60
+ if token == 0x1B and len(tokens) >= 11:
61
+ extern_index, row_first, row_last, col_first, col_last = struct.unpack_from("<5H", tokens, 1)
62
+ sheet_index = _extern_sheet_index(extern_sheets, int(extern_index))
63
+ if sheet_index is None:
64
+ return None
65
+ first_col = col_first & 0x00FF
66
+ last_col = col_last & 0x00FF
67
+ return (
68
+ sheet_index,
69
+ list(range(min(row_first, row_last), max(row_first, row_last) + 1)),
70
+ list(range(min(first_col, last_col), max(first_col, last_col) + 1)),
71
+ )
72
+ return None
73
+
74
+
75
+ def chart_source_selection(
76
+ records: list[BiffRecord],
77
+ *,
78
+ current_sheet_index: int,
79
+ extern_sheets: list[int | None],
80
+ ) -> ChartSourceSelection | None:
81
+ """合并 chart 名称、分类、数值与气泡引用并要求唯一源工作表。"""
82
+
83
+ rows: set[int] = set()
84
+ cols: set[int] = set()
85
+ sheet_indices: set[int] = set()
86
+ formulas_found = False
87
+ for record in records:
88
+ if record.record_type != BRAI or len(record.payload) < 8:
89
+ continue
90
+ formula_length = int(struct.unpack_from("<H", record.payload, 6)[0])
91
+ if formula_length <= 0:
92
+ continue
93
+ formulas_found = True
94
+ tokens = record.payload[8 : 8 + formula_length]
95
+ if len(tokens) != formula_length:
96
+ return None
97
+ reference = _reference_from_tokens(
98
+ tokens,
99
+ current_sheet_index=current_sheet_index,
100
+ extern_sheets=extern_sheets,
101
+ )
102
+ if reference is None:
103
+ return None
104
+ sheet_index, reference_rows, reference_cols = reference
105
+ sheet_indices.add(sheet_index)
106
+ rows.update(reference_rows)
107
+ cols.update(reference_cols)
108
+ if not formulas_found or not rows or not cols or len(sheet_indices) != 1:
109
+ return None
110
+ return ChartSourceSelection(
111
+ sheet_index=next(iter(sheet_indices)),
112
+ rows=tuple(sorted(rows)),
113
+ cols=tuple(sorted(cols)),
114
+ )
115
+
116
+
117
+ def chart_source_axes(
118
+ records: list[BiffRecord],
119
+ *,
120
+ current_sheet_index: int,
121
+ extern_sheets: list[int | None],
122
+ ) -> tuple[list[int], list[int]] | None:
123
+ """兼容 worksheet 内嵌 chart,仅接受引用当前工作表的数据。"""
124
+
125
+ selection = chart_source_selection(
126
+ records,
127
+ current_sheet_index=current_sheet_index,
128
+ extern_sheets=extern_sheets,
129
+ )
130
+ if selection is None or selection.sheet_index != current_sheet_index:
131
+ return None
132
+ return list(selection.rows), list(selection.cols)
@@ -0,0 +1,299 @@
1
+ """从 Excel.Chart 或 MSGraph.Chart OLE 对象恢复 HTML 数据表。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ import struct
7
+
8
+ from loguru import logger
9
+
10
+ from ..legacy.ole import BoundedOleReader
11
+ from ..legacy.binary import get_f64, get_u16
12
+ from ..errors import LegacyOfficeMalformedError, LegacyOfficeResourceLimitError
13
+ from ..limits import MAX_GRID_SLOTS
14
+ from .models import XlsCell, XlsRichText, XlsSheet, XlsWorkbook
15
+ from .number_format import builtin_number_format, format_number
16
+ from .parser import parse_xls_workbook
17
+ from .records import BOF, EOF, iter_records, record_at
18
+ from .strings import clean_text
19
+ from .xls_converter import render_xls_chart_html
20
+
21
+ GRAPH_VERSION = 0x0680
22
+ GRAPH_WORKBOOK_SUBSTREAM = 0x0005
23
+ GRAPH_CHART_SUBSTREAM = 0x8000
24
+ GRAPH_BLANK = 0x0001
25
+ GRAPH_NUMBER = 0x0003
26
+ GRAPH_LABEL = 0x0204
27
+ GRAPH_DATE1904 = 0x0022
28
+ GRAPH_FORMAT = 0x041E
29
+ GRAPH_BOF_DATASHEET = 0x1052
30
+ GRAPH_EXCLUDE_ROWS = 0x1053
31
+ GRAPH_EXCLUDE_COLUMNS = 0x1054
32
+ GRAPH_MAX_ROWS = 4_000
33
+ GRAPH_MAX_COLS = 256
34
+
35
+
36
+ @dataclass(frozen=True, slots=True)
37
+ class EmbeddedChartData:
38
+ """嵌入式 chart 已解析出的工作簿和唯一表格选择。"""
39
+
40
+ workbook: XlsWorkbook
41
+ sheet_name: str
42
+ rows: tuple[int, ...]
43
+ cols: tuple[int, ...]
44
+ source_kind: str
45
+
46
+
47
+ def _nonempty_selection(sheet: XlsSheet) -> tuple[tuple[int, ...], tuple[int, ...]] | None:
48
+ """返回工作表非空单元格覆盖的稳定行列集合。"""
49
+
50
+ if not sheet.cells:
51
+ return None
52
+ rows = tuple(sorted({row for row, _col in sheet.cells}))
53
+ cols = tuple(sorted({col for _row, col in sheet.cells}))
54
+ if len(rows) * len(cols) > MAX_GRID_SLOTS:
55
+ raise LegacyOfficeResourceLimitError(f"workbook extent exceeds max_grid_slots={MAX_GRID_SLOTS}")
56
+ return rows, cols
57
+
58
+
59
+ def _excel_chart_data(workbook_stream: bytes) -> EmbeddedChartData | None:
60
+ """解析 Excel.Chart 工作簿中的活动独立 chart sheet。"""
61
+
62
+ workbook = parse_xls_workbook(workbook_stream)
63
+ visible_charts = [chart for chart in workbook.chart_sheets if chart.visible]
64
+ selected = next(
65
+ (
66
+ chart
67
+ for chart in visible_charts
68
+ if workbook.active_sheet_index is not None and chart.order == workbook.active_sheet_index
69
+ ),
70
+ None,
71
+ )
72
+ if selected is None and len(visible_charts) == 1:
73
+ selected = visible_charts[0]
74
+ if selected is not None and selected.source_sheet_name:
75
+ if selected.source_rows and selected.source_cols:
76
+ return EmbeddedChartData(
77
+ workbook=workbook,
78
+ sheet_name=selected.source_sheet_name,
79
+ rows=selected.source_rows,
80
+ cols=selected.source_cols,
81
+ source_kind="excel",
82
+ )
83
+
84
+ visible_sheets = [sheet for sheet in workbook.sheets if sheet.visible and sheet.cells]
85
+ if len(visible_sheets) != 1:
86
+ return None
87
+ fallback = _nonempty_selection(visible_sheets[0])
88
+ if fallback is None:
89
+ return None
90
+ rows, cols = fallback
91
+ return EmbeddedChartData(
92
+ workbook=workbook,
93
+ sheet_name=visible_sheets[0].name,
94
+ rows=rows,
95
+ cols=cols,
96
+ source_kind="excel",
97
+ )
98
+
99
+
100
+ def _decode_short_unicode(payload: bytes, offset: int) -> str | None:
101
+ """读取 MS-OGRAPH ShortXLUnicodeString。"""
102
+
103
+ if offset < 0 or offset + 2 > len(payload):
104
+ return None
105
+ count = payload[offset]
106
+ flags = payload[offset + 1]
107
+ if flags & 0xFE:
108
+ return None
109
+ width = 2 if flags & 0x01 else 1
110
+ start = offset + 2
111
+ end = start + count * width
112
+ if end > len(payload):
113
+ return None
114
+ encoding = "utf-16le" if width == 2 else "cp1252"
115
+ try:
116
+ return clean_text(payload[start:end].decode(encoding, errors="strict"))
117
+ except UnicodeDecodeError:
118
+ return None
119
+
120
+
121
+ def _decode_unicode_min2(payload: bytes, offset: int) -> str | None:
122
+ """读取带 u16 长度的 MS-OGRAPH XLUnicodeStringMin2。"""
123
+
124
+ count = get_u16(payload, offset)
125
+ if count is None or offset + 3 > len(payload):
126
+ return None
127
+ flags = payload[offset + 2]
128
+ if flags & 0xFE:
129
+ return None
130
+ width = 2 if flags & 0x01 else 1
131
+ start = offset + 3
132
+ end = start + int(count) * width
133
+ if end > len(payload):
134
+ return None
135
+ encoding = "utf-16le" if width == 2 else "cp1252"
136
+ try:
137
+ return clean_text(payload[start:end].decode(encoding, errors="strict"))
138
+ except UnicodeDecodeError:
139
+ return None
140
+
141
+
142
+ def _graph_included_indices(
143
+ candidates: tuple[int, ...],
144
+ payload: bytes | None,
145
+ ) -> tuple[int, ...]:
146
+ """按 MS-OGRAPH 交替边界筛选 chart 实际包含的行或列。"""
147
+
148
+ if not payload:
149
+ return candidates
150
+ if len(payload) % 2:
151
+ return candidates
152
+ boundaries = [int(struct.unpack_from("<H", payload, offset)[0]) for offset in range(0, len(payload), 2)]
153
+ if len(boundaries) % 2:
154
+ return candidates
155
+ included = tuple(
156
+ value for value in candidates if any(start <= value < end for start, end in zip(boundaries[::2], boundaries[1::2]))
157
+ )
158
+ return included or candidates
159
+
160
+
161
+ def _graph_chart_data(workbook_stream: bytes) -> EmbeddedChartData | None:
162
+ """解析 MS-OGRAPH chart sheet 内嵌的 datasheet。"""
163
+
164
+ records = list(iter_records(workbook_stream))
165
+ bof_records = [record for record in records if record.record_type == BOF]
166
+ if len(bof_records) != 2:
167
+ return None
168
+ first, second = bof_records
169
+ if (
170
+ get_u16(first.payload, 0) != GRAPH_VERSION
171
+ or get_u16(first.payload, 2) != GRAPH_WORKBOOK_SUBSTREAM
172
+ or get_u16(second.payload, 0) != GRAPH_VERSION
173
+ or get_u16(second.payload, 2) != GRAPH_CHART_SUBSTREAM
174
+ ):
175
+ return None
176
+
177
+ date1904 = False
178
+ custom_formats: dict[int, str] = {}
179
+ in_chart = False
180
+ in_datasheet = False
181
+ cells: dict[tuple[int, int], XlsCell] = {}
182
+ excluded_rows: bytes | None = None
183
+ excluded_cols: bytes | None = None
184
+ for record in records:
185
+ if record is second:
186
+ in_chart = True
187
+ continue
188
+ if not in_chart:
189
+ if record.record_type == GRAPH_DATE1904:
190
+ date1904 = get_u16(record.payload, 0) == 1
191
+ elif record.record_type == GRAPH_FORMAT:
192
+ format_id = get_u16(record.payload, 0)
193
+ format_code = _decode_unicode_min2(record.payload, 2)
194
+ if format_id is not None and format_code:
195
+ custom_formats[int(format_id)] = format_code
196
+ continue
197
+ if record.record_type == EOF:
198
+ break
199
+ if record.record_type == GRAPH_BOF_DATASHEET:
200
+ in_datasheet = True
201
+ continue
202
+ if record.record_type == GRAPH_EXCLUDE_ROWS:
203
+ excluded_rows = record.payload
204
+ continue
205
+ if record.record_type == GRAPH_EXCLUDE_COLUMNS:
206
+ excluded_cols = record.payload
207
+ continue
208
+ if not in_datasheet or len(record.payload) < 7:
209
+ continue
210
+ row = get_u16(record.payload, 0)
211
+ col = get_u16(record.payload, 2)
212
+ format_id = get_u16(record.payload, 5)
213
+ if row is None or col is None or row >= GRAPH_MAX_ROWS or col >= GRAPH_MAX_COLS:
214
+ continue
215
+ text: str | None = None
216
+ if record.record_type == GRAPH_LABEL:
217
+ text = _decode_short_unicode(record.payload, 7)
218
+ elif record.record_type == GRAPH_NUMBER:
219
+ value = get_f64(record.payload, 7)
220
+ if value is not None:
221
+ format_code = custom_formats.get(int(format_id or 0)) or builtin_number_format(int(format_id or 0))
222
+ text = format_number(value, format_code, date1904=date1904)
223
+ elif record.record_type == GRAPH_BLANK:
224
+ text = ""
225
+ if text is None:
226
+ continue
227
+ cells[(int(row), int(col))] = XlsCell(
228
+ row=int(row),
229
+ col=int(col),
230
+ value=XlsRichText(text),
231
+ )
232
+
233
+ sheet = XlsSheet(name="Data", visible=True, order=0, cells=cells)
234
+ selection = _nonempty_selection(sheet)
235
+ if selection is None:
236
+ return None
237
+ rows, cols = selection
238
+ rows = _graph_included_indices(rows, excluded_rows)
239
+ cols = _graph_included_indices(cols, excluded_cols)
240
+ if not rows or not cols or len(rows) * len(cols) > MAX_GRID_SLOTS:
241
+ return None
242
+ return EmbeddedChartData(
243
+ workbook=XlsWorkbook(sheets=[sheet]),
244
+ sheet_name=sheet.name,
245
+ rows=rows,
246
+ cols=cols,
247
+ source_kind="graph",
248
+ )
249
+
250
+
251
+ def extract_embedded_chart_data(workbook_stream: bytes) -> EmbeddedChartData | None:
252
+ """按 BOF 版本选择 Excel BIFF 或 MS-OGRAPH chart 解析器。"""
253
+
254
+ first = record_at(workbook_stream, 0)
255
+ if first is None or first.record_type != BOF:
256
+ return None
257
+ version = get_u16(first.payload, 0)
258
+ try:
259
+ if version in {0x0500, 0x0600}:
260
+ return _excel_chart_data(workbook_stream)
261
+ if version == GRAPH_VERSION:
262
+ return _graph_chart_data(workbook_stream)
263
+ except LegacyOfficeResourceLimitError:
264
+ raise
265
+ except (LegacyOfficeMalformedError, ValueError, struct.error) as exc:
266
+ logger.warning("LEGACY_CHART_DATA_FALLBACK: {}", exc)
267
+ return None
268
+
269
+
270
+ def extract_embedded_chart_html(workbook_stream: bytes) -> str | None:
271
+ """从 Workbook/Book stream 恢复一个可渲染的 HTML 数据表。"""
272
+
273
+ chart = extract_embedded_chart_data(workbook_stream)
274
+ if chart is None:
275
+ return None
276
+ return render_xls_chart_html(
277
+ chart.workbook,
278
+ chart.sheet_name,
279
+ chart.rows,
280
+ chart.cols,
281
+ )
282
+
283
+
284
+ def extract_embedded_chart_html_from_storage(storage: bytes) -> str | None:
285
+ """从独立 OLE CFB 对象中读取 Workbook/Book 并恢复数据表。"""
286
+
287
+ try:
288
+ with BoundedOleReader(storage) as ole:
289
+ if ole.has_stream("Workbook"):
290
+ workbook_stream = ole.read_stream("Workbook")
291
+ elif ole.has_stream("Book"):
292
+ workbook_stream = ole.read_stream("Book")
293
+ else:
294
+ return None
295
+ except LegacyOfficeResourceLimitError:
296
+ raise
297
+ except ValueError:
298
+ return None
299
+ return extract_embedded_chart_html(workbook_stream)
@@ -0,0 +1,109 @@
1
+ """旧版 Excel 解析阶段使用的内部语义模型。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+
8
+ @dataclass(frozen=True, slots=True)
9
+ class XlsFontStyle:
10
+ """一个 BIFF FONT 记录中可表达的行内文字样式。"""
11
+
12
+ bold: bool = False
13
+ italic: bool = False
14
+ underline: bool = False
15
+ strike: bool = False
16
+ superscript: bool = False
17
+ subscript: bool = False
18
+
19
+
20
+ @dataclass(frozen=True, slots=True)
21
+ class XlsRichRun:
22
+ """以 Python 字符索引表示的富文本区间。"""
23
+
24
+ start: int
25
+ end: int
26
+ style: XlsFontStyle
27
+
28
+
29
+ @dataclass(frozen=True, slots=True)
30
+ class XlsRichText:
31
+ """单元格或 drawing 文本及其富文本区间。"""
32
+
33
+ text: str
34
+ runs: tuple[XlsRichRun, ...] = ()
35
+
36
+
37
+ @dataclass(slots=True)
38
+ class XlsCell:
39
+ """工作表中的一个可见语义单元格。"""
40
+
41
+ row: int
42
+ col: int
43
+ value: XlsRichText
44
+ hyperlink: str | None = None
45
+
46
+
47
+ @dataclass(frozen=True, slots=True)
48
+ class XlsImage:
49
+ """绑定到工作表 cell anchor 的已序列化图片。"""
50
+
51
+ row: int
52
+ col: int
53
+ image_base64: str
54
+
55
+
56
+ @dataclass(frozen=True, slots=True)
57
+ class XlsEquation:
58
+ """绑定到工作表 cell anchor 的原生或图片 comment 公式。"""
59
+
60
+ row: int
61
+ col: int
62
+ latex: str
63
+
64
+
65
+ @dataclass(frozen=True, slots=True)
66
+ class XlsChart:
67
+ """由嵌入 chart 引用恢复出的源数据坐标。"""
68
+
69
+ row: int
70
+ col: int
71
+ source_rows: tuple[int, ...]
72
+ source_cols: tuple[int, ...]
73
+ image_base64: str | None = None
74
+
75
+
76
+ @dataclass(slots=True)
77
+ class XlsSheet:
78
+ """一个 worksheet 的单元格、合并区域与 drawing 资源。"""
79
+
80
+ name: str
81
+ visible: bool
82
+ order: int = -1
83
+ cells: dict[tuple[int, int], XlsCell] = field(default_factory=dict)
84
+ merges: list[tuple[int, int, int, int]] = field(default_factory=list)
85
+ images: list[XlsImage] = field(default_factory=list)
86
+ equations: list[XlsEquation] = field(default_factory=list)
87
+ charts: list[XlsChart] = field(default_factory=list)
88
+ recovered: bool = False
89
+
90
+
91
+ @dataclass(frozen=True, slots=True)
92
+ class XlsChartSheet:
93
+ """一个独立 chart sheet 及其源工作表选择范围。"""
94
+
95
+ name: str
96
+ visible: bool
97
+ order: int
98
+ source_sheet_name: str | None
99
+ source_rows: tuple[int, ...] = ()
100
+ source_cols: tuple[int, ...] = ()
101
+
102
+
103
+ @dataclass(slots=True)
104
+ class XlsWorkbook:
105
+ """Excel 97–2003 工作簿的内部分页表示。"""
106
+
107
+ sheets: list[XlsSheet]
108
+ chart_sheets: list[XlsChartSheet] = field(default_factory=list)
109
+ active_sheet_index: int | None = None