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,175 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from pathlib import Path
5
+ from typing import Final
6
+
7
+
8
+ # ── file types ─────────────────────────────────────────────────────
9
+
10
+ # Legacy Office binary formats and RTF are natively parsed by model.flash.office converters.
11
+ # Unsupported document/e-book/archive-like formats:
12
+ # "key",
13
+ # "mobi",
14
+ # "numbers",
15
+ # "pages",
16
+ # Unsupported mail formats:
17
+ # "eml",
18
+ # "mbox",
19
+ # Other doc formats:
20
+ # "djvu/djv"
21
+ # "epdf",
22
+ # "xps",
23
+ # "ps",
24
+ # "eps/epsi/epi"
25
+ # "ept/ept2/ept3"
26
+
27
+ PDF_EXTENSIONS: frozenset[str] = frozenset({"pdf"})
28
+
29
+ IMAGE_EXTENSIONS: frozenset[str] = frozenset({"png", "jpg", "jpeg", "webp", "gif", "bmp", "tiff", "jp2"})
30
+
31
+ ODF_EXTENSIONS: frozenset[str] = frozenset({"odt", "ods", "odp"})
32
+
33
+ EPUB_EXTENSIONS: frozenset[str] = frozenset({"epub"})
34
+
35
+ OFD_EXTENSIONS: frozenset[str] = frozenset({"ofd"})
36
+
37
+ OFFICE_EXTENSIONS: frozenset[str] = frozenset({"doc", "docx", "ppt", "pptx", "xls", "xlsx", "rtf"}) | ODF_EXTENSIONS
38
+
39
+ HTML_EXTENSIONS: frozenset[str] = frozenset({"html", "htm", "shtml"})
40
+
41
+ CSV_EXTENSIONS: frozenset[str] = frozenset({"csv", "tsv"})
42
+
43
+ TEXT_EXTENSIONS: frozenset[str] = frozenset(
44
+ {"txt", "text", "ftxt", "md", "markdown", "mdx", "rst", "tex", "latex", "adoc", "asciidoc"}
45
+ )
46
+
47
+ TIERED_PARSE_EXTENSIONS: frozenset[str] = PDF_EXTENSIONS | IMAGE_EXTENSIONS
48
+
49
+ PAGE_RANGE_PARSE_EXTENSIONS: frozenset[str] = PDF_EXTENSIONS
50
+
51
+ FLASH_ONLY_PARSE_EXTENSIONS: frozenset[str] = (
52
+ OFFICE_EXTENSIONS | HTML_EXTENSIONS | CSV_EXTENSIONS | EPUB_EXTENSIONS | OFD_EXTENSIONS
53
+ )
54
+
55
+ PARSEABLE_EXTENSIONS: frozenset[str] = TIERED_PARSE_EXTENSIONS | FLASH_ONLY_PARSE_EXTENSIONS
56
+
57
+ # Acceptable for doclib ingest
58
+ INGESTIBLE_EXTENSIONS: frozenset[str] = PARSEABLE_EXTENSIONS | TEXT_EXTENSIONS
59
+
60
+ # Used for doclib scan and watch
61
+ DISCOVERABLE_EXTENSIONS: frozenset[str] = INGESTIBLE_EXTENSIONS - IMAGE_EXTENSIONS
62
+
63
+ FILE_TYPE_BY_EXTENSION: dict[str, str] = {
64
+ **dict.fromkeys(PDF_EXTENSIONS, "pdf"),
65
+ **dict.fromkeys(IMAGE_EXTENSIONS, "image"),
66
+ **{ext: ext for ext in OFFICE_EXTENSIONS},
67
+ **dict.fromkeys(HTML_EXTENSIONS, "html"),
68
+ **dict.fromkeys(CSV_EXTENSIONS, "csv"),
69
+ **dict.fromkeys(EPUB_EXTENSIONS, "epub"),
70
+ **dict.fromkeys(OFD_EXTENSIONS, "ofd"),
71
+ "txt": "text",
72
+ "text": "text",
73
+ "ftxt": "text",
74
+ "md": "markdown",
75
+ "markdown": "markdown",
76
+ "mdx": "markdown",
77
+ "rst": "rst",
78
+ "tex": "tex",
79
+ "latex": "tex",
80
+ "adoc": "asciidoc",
81
+ "asciidoc": "asciidoc",
82
+ }
83
+
84
+ TEXT_FILE_TYPES: frozenset[str] = frozenset(FILE_TYPE_BY_EXTENSION[ext] for ext in TEXT_EXTENSIONS)
85
+
86
+ MIME_TYPE_BY_EXTENSION: dict[str, str] = {
87
+ "pdf": "application/pdf",
88
+ "doc": "application/msword",
89
+ "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
90
+ "ppt": "application/vnd.ms-powerpoint",
91
+ "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
92
+ "xls": "application/vnd.ms-excel",
93
+ "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
94
+ "rtf": "application/rtf",
95
+ "odt": "application/vnd.oasis.opendocument.text",
96
+ "ods": "application/vnd.oasis.opendocument.spreadsheet",
97
+ "odp": "application/vnd.oasis.opendocument.presentation",
98
+ "csv": "text/csv",
99
+ "tsv": "text/tab-separated-values",
100
+ "epub": "application/epub+zip",
101
+ # OFD 尚无 IANA 注册 subtype;使用生态中通行的项目级 MIME 映射。
102
+ "ofd": "application/ofd",
103
+ "html": "text/html",
104
+ "htm": "text/html",
105
+ "shtml": "text/html",
106
+ "png": "image/png",
107
+ "jpg": "image/jpeg",
108
+ "jpeg": "image/jpeg",
109
+ "jp2": "image/jp2",
110
+ "webp": "image/webp",
111
+ "gif": "image/gif",
112
+ "bmp": "image/bmp",
113
+ "tiff": "image/tiff",
114
+ "txt": "text/plain",
115
+ "text": "text/plain",
116
+ "ftxt": "text/plain",
117
+ "md": "text/markdown",
118
+ "markdown": "text/markdown",
119
+ "mdx": "text/markdown",
120
+ "rst": "text/x-rst",
121
+ "tex": "text/x-tex",
122
+ "latex": "application/x-latex",
123
+ "adoc": "text/plain",
124
+ "asciidoc": "text/plain",
125
+ }
126
+
127
+ _RTF_HEADER_RE: Final = re.compile(
128
+ rb"\A(?:\xef\xbb\xbf)?[ \t\r\n]{0,64}\{\\rtf(?=[0-9])",
129
+ re.IGNORECASE,
130
+ )
131
+
132
+
133
+ def rtf_header_offset(file_bytes: bytes) -> int | None:
134
+ """返回 RTF 根组左花括号偏移;不接受带任意前缀的伪装文本。"""
135
+ match = _RTF_HEADER_RE.match(file_bytes)
136
+ if match is None:
137
+ return None
138
+ return file_bytes.find(b"{", 0, match.end())
139
+
140
+
141
+ def normalize_parse_extension(path_or_ext: str | Path) -> str:
142
+ text = str(path_or_ext)
143
+ if text.startswith("."):
144
+ return text.lower().lstrip(".")
145
+ suffix = Path(text).suffix
146
+ if suffix:
147
+ return suffix.lower().lstrip(".")
148
+ return text.lower().lstrip(".")
149
+
150
+
151
+ def file_type_for_extension(path_or_ext: str | Path) -> str:
152
+ ext = normalize_parse_extension(path_or_ext)
153
+ return FILE_TYPE_BY_EXTENSION.get(ext, ext or "unknown")
154
+
155
+
156
+ def mime_type_for_extension(path_or_ext: str | Path, *, default: str = "application/octet-stream") -> str:
157
+ return MIME_TYPE_BY_EXTENSION.get(normalize_parse_extension(path_or_ext), default)
158
+
159
+
160
+ def is_tiered_parse_extension(path_or_ext: str | Path) -> bool:
161
+ return normalize_parse_extension(path_or_ext) in TIERED_PARSE_EXTENSIONS
162
+
163
+
164
+ def is_page_range_parse_extension(path_or_ext: str | Path) -> bool:
165
+ """仅允许 PDF 输入使用局部页范围解析。"""
166
+ return normalize_parse_extension(path_or_ext) in PAGE_RANGE_PARSE_EXTENSIONS
167
+
168
+
169
+ def is_flash_only_parse_extension(path_or_ext: str | Path) -> bool:
170
+ return normalize_parse_extension(path_or_ext) in FLASH_ONLY_PARSE_EXTENSIONS
171
+
172
+
173
+ def is_office_temp_lock_file(path: str | Path) -> bool:
174
+ file_path = Path(path)
175
+ return file_path.name.startswith("~$") and file_path.suffix.lower().lstrip(".") in OFFICE_EXTENSIONS
@@ -0,0 +1,167 @@
1
+ """所有入口共享的页码范围语法、求值和格式化;默认选页策略由调用方决定。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from collections.abc import Iterable
7
+
8
+ from loguru import logger
9
+
10
+ from ..errors import InvalidRequestError
11
+
12
+ PAGE_RANGE_DESCRIPTION = (
13
+ "PDF page selection: 1-based inclusive ranges, e.g. '1-5,8,r3-r1'; "
14
+ "'r1' is the last page and 'all' selects every page. Blank means unspecified. "
15
+ "Selections are sorted and deduplicated; out-of-bounds pages are omitted. "
16
+ "Reversed ranges, '~' and negative page numbers are invalid."
17
+ )
18
+ _SEGMENT_PATTERN = re.compile(r"(r?[1-9][0-9]*)(?:\s*-\s*(r?[1-9][0-9]*))?")
19
+
20
+
21
+ def get_end_page_id(end_page_id: int | None, pdf_page_num: int) -> int:
22
+ """归一化旧 CLI 的 0-based 结束页,越界时钳制到最后一页。"""
23
+ normalized_end_page_id = end_page_id if end_page_id is not None and end_page_id >= 0 else pdf_page_num - 1
24
+ if normalized_end_page_id > pdf_page_num - 1:
25
+ logger.debug("end_page_id is out of range, use images length")
26
+ normalized_end_page_id = pdf_page_num - 1
27
+ return normalized_end_page_id
28
+
29
+
30
+ def _invalid_range(raw: str | None, reason: str) -> InvalidRequestError:
31
+ """统一生成可跨 Python、CLI 和 HTTP 传递的页码错误。"""
32
+ return InvalidRequestError("page_range_invalid", f"Invalid page range {raw!r}: {reason}", "page_range")
33
+
34
+
35
+ def _parse_endpoint(token: str) -> int:
36
+ """以负整数在内部标记倒数端点,外部输入只接受 rN。"""
37
+ return -int(token[1:]) if token.startswith("r") else int(token)
38
+
39
+
40
+ def _parse_segments(raw: str | None) -> list[tuple[int, int]] | None:
41
+ """解析完整表达式;None 表示全部,倒数端点留待获得总页数后求值。"""
42
+ value = (raw or "").strip()
43
+ if not value or value == "all":
44
+ return None
45
+ segments: list[tuple[int, int]] = []
46
+ for part in value.split(","):
47
+ match = _SEGMENT_PATTERN.fullmatch(part.strip())
48
+ if match is None:
49
+ raise _invalid_range(raw, "expected a page, an inclusive range, or 'all'")
50
+ try:
51
+ start = _parse_endpoint(match[1])
52
+ end = _parse_endpoint(match[2]) if match[2] else start
53
+ except ValueError as exc:
54
+ raise _invalid_range(raw, "page number is too large") from exc
55
+ if (start > 0) == (end > 0) and start > end:
56
+ raise _invalid_range(raw, "reversed ranges are not supported")
57
+ segments.append((start, end))
58
+ return segments
59
+
60
+
61
+ def _merge_intervals(intervals: Iterable[tuple[int, int]]) -> list[tuple[int, int]]:
62
+ """合并已求值区间,无需逐页展开即可排序、去重和连接相邻区间。"""
63
+ merged: list[tuple[int, int]] = []
64
+ for start, end in sorted(intervals):
65
+ if merged and start <= merged[-1][1] + 1:
66
+ merged[-1] = (merged[-1][0], max(end, merged[-1][1]))
67
+ else:
68
+ merged.append((start, end))
69
+ return merged
70
+
71
+
72
+ def _format_endpoint(value: int) -> str:
73
+ """把内部端点转换为正整数或 rN 文本。"""
74
+ return str(value) if value > 0 else f"r{-value}"
75
+
76
+
77
+ def _format_intervals(intervals: Iterable[tuple[int, int]]) -> str:
78
+ """生成无空白的范围文本,单页只输出一个端点。"""
79
+ return ",".join(
80
+ _format_endpoint(start) if start == end else f"{_format_endpoint(start)}-{_format_endpoint(end)}"
81
+ for start, end in intervals
82
+ )
83
+
84
+
85
+ def normalize_page_range_input(raw: str | None) -> str:
86
+ """校验未绑定文档的输入,清理空白并保留 all/rN;空值统一为未指定。"""
87
+ segments = _parse_segments(raw)
88
+ if segments is None:
89
+ return "all" if (raw or "").strip() else ""
90
+ if all(start > 0 and end > 0 for start, end in segments):
91
+ segments = _merge_intervals(segments)
92
+ return _format_intervals(segments)
93
+
94
+
95
+ def _resolved_intervals(raw: str | None, page_count: int) -> list[tuple[int, int]]:
96
+ """按文档总页数求值并裁剪,先验证所有区间再合并有效交集。"""
97
+ segments = _parse_segments(raw)
98
+ if page_count <= 0:
99
+ raise _invalid_range(raw, "document has no available pages")
100
+ if segments is None:
101
+ return [(1, page_count)]
102
+ intervals: list[tuple[int, int]] = []
103
+ for start, end in segments:
104
+ start = start if start > 0 else page_count + start + 1
105
+ end = end if end > 0 else page_count + end + 1
106
+ if start > end:
107
+ raise _invalid_range(raw, "reversed ranges are not supported")
108
+ lo, hi = max(1, start), min(page_count, end)
109
+ if lo <= hi:
110
+ intervals.append((lo, hi))
111
+ if not intervals:
112
+ raise _invalid_range(raw, "selection does not contain any available pages")
113
+ return _merge_intervals(intervals)
114
+
115
+
116
+ def parse_page_range(raw: str, page_count: int) -> list[int]:
117
+ """把 1-based 表达式转换为去重升序的 0-based 页索引,空值选择全部。"""
118
+ return [page_idx for start, end in _resolved_intervals(raw, page_count) for page_idx in range(start - 1, end)]
119
+
120
+
121
+ def expand_page_range(raw: str | None, page_count: int) -> str:
122
+ """将含 all/rN 的表达式展开为实际文档的正整数规范范围。"""
123
+ return _format_intervals(_resolved_intervals(raw, page_count))
124
+
125
+
126
+ def _absolute_intervals(raw: str) -> list[tuple[int, int]]:
127
+ """读取已求值范围,兼容历史半角 ~;空文本为空集合,禁止 all/rN。"""
128
+ if not raw.strip():
129
+ return []
130
+ # 只在结果读取边界兼容旧分隔符,新请求及全角波浪号仍由严格语法拒绝。
131
+ segments = _parse_segments(raw.replace("~", "-"))
132
+ if segments is None or any(start < 0 or end < 0 for start, end in segments):
133
+ raise _invalid_range(raw, "page count is required to resolve all/rN")
134
+ return _merge_intervals(segments)
135
+
136
+
137
+ def normalize_result_page_range(raw: str) -> str:
138
+ """将已求值的新旧结果范围规范化为连字符格式,不修改持久化记录或文件名。"""
139
+ return _format_intervals(_absolute_intervals(raw))
140
+
141
+
142
+ def parse_page_range_set(raw: str) -> set[int]:
143
+ """把已求值的范围转换为 1-based 页码集合,供缓存覆盖与内容过滤使用。"""
144
+ return {page_no for start, end in _absolute_intervals(raw) for page_no in range(start, end + 1)}
145
+
146
+
147
+ def count_pages_in_range(raw: str) -> int:
148
+ """统计已求值范围的唯一页数,不为统计分配逐页集合。"""
149
+ return sum(end - start + 1 for start, end in _absolute_intervals(raw))
150
+
151
+
152
+ def format_page_range(page_numbers: Iterable[int]) -> str:
153
+ """将 1-based 页码集合格式化为去重升序的连续范围;空集合输出空字符串。"""
154
+ return _format_intervals(_merge_intervals((page_no, page_no) for page_no in page_numbers))
155
+
156
+
157
+ __all__ = [
158
+ "PAGE_RANGE_DESCRIPTION",
159
+ "count_pages_in_range",
160
+ "expand_page_range",
161
+ "format_page_range",
162
+ "get_end_page_id",
163
+ "normalize_page_range_input",
164
+ "normalize_result_page_range",
165
+ "parse_page_range",
166
+ "parse_page_range_set",
167
+ ]
@@ -0,0 +1,19 @@
1
+ """PDF 文档访问、显式分类及共享文本契约。"""
2
+
3
+ from .document import PDFDocument, PDFPage, PDFPageTextGeometry, get_lines_from_chars
4
+ from .text import Bbox, Char, Line, Span
5
+ from .pdfium import PdfiumFontError, PdfiumRuntimeInfo, initialize_pdfium_runtime
6
+
7
+ __all__ = [
8
+ "PDFDocument",
9
+ "PDFPage",
10
+ "PDFPageTextGeometry",
11
+ "get_lines_from_chars",
12
+ "Bbox",
13
+ "Char",
14
+ "Line",
15
+ "Span",
16
+ "initialize_pdfium_runtime",
17
+ "PdfiumRuntimeInfo",
18
+ "PdfiumFontError",
19
+ ]