docvortex 0.4.7__tar.gz → 0.4.8__tar.gz

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 (675) hide show
  1. {docvortex-0.4.7/src/docvortex.egg-info → docvortex-0.4.8}/PKG-INFO +1 -1
  2. docvortex-0.4.8/docs/flash-spatial-layout-followup-2026-09-16.md +48 -0
  3. docvortex-0.4.8/docs/flash-spatial-layout-round3-2026-09-16.md +76 -0
  4. docvortex-0.4.8/docs/flash-title-coverage-2026-09-16.md +25 -0
  5. docvortex-0.4.8/src/docvortex/analyzers/native/pdf/annotation_bands.py +161 -0
  6. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/formulas.py +164 -2
  7. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/line_layout.py +2 -1
  8. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/line_merging.py +48 -5
  9. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/models.py +3 -0
  10. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/pipeline.py +16 -0
  11. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_materialization.py +40 -0
  12. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/continuity.py +168 -4
  13. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/merging.py +36 -40
  14. docvortex-0.4.8/src/docvortex/analyzers/native/pdf/title_analysis/compact_titles.py +93 -0
  15. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/lane_titles.py +8 -1
  16. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/page_titles.py +23 -2
  17. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/structural.py +52 -2
  18. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/visual_annotations.py +17 -0
  19. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/pages.py +1 -1
  20. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/paragraphs.py +5 -0
  21. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/version.py +1 -1
  22. {docvortex-0.4.7 → docvortex-0.4.8/src/docvortex.egg-info}/PKG-INFO +1 -1
  23. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex.egg-info/SOURCES.txt +14 -0
  24. docvortex-0.4.8/tests/fixtures/flash_round3_annotations.json +4033 -0
  25. docvortex-0.4.8/tests/fixtures/flash_round3_followup_review_decisions.json +378 -0
  26. docvortex-0.4.8/tests/fixtures/flash_round3_review_decisions.json +703 -0
  27. docvortex-0.4.8/tests/fixtures/flash_title_coverage_review_decisions.json +97 -0
  28. docvortex-0.4.8/tests/test_release_ci_gate.py +205 -0
  29. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_flash_pdf_test_utils.py +3 -0
  30. docvortex-0.4.8/tests/unittest/pdfs/flash_layout/journal_dual_caption.pdf +0 -0
  31. docvortex-0.4.8/tests/unittest/pdfs/flash_layout/quantum_appendix_layout.pdf +0 -0
  32. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_manual_annotations.py +19 -0
  33. docvortex-0.4.8/tests/unittest/test_flash_round3_annotations.py +261 -0
  34. docvortex-0.4.8/tests/unittest/test_flash_spatial_evidence.py +317 -0
  35. {docvortex-0.4.7 → docvortex-0.4.8}/LICENSE.md +0 -0
  36. {docvortex-0.4.7 → docvortex-0.4.8}/MANIFEST.in +0 -0
  37. {docvortex-0.4.7 → docvortex-0.4.8}/README.md +0 -0
  38. {docvortex-0.4.7 → docvortex-0.4.8}/demo/README.md +0 -0
  39. {docvortex-0.4.7 → docvortex-0.4.8}/demo/demo.py +0 -0
  40. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/README.md +0 -0
  41. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/docx_01.doc +0 -0
  42. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/docx_01.docx +0 -0
  43. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/pptx_01.ppt +0 -0
  44. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/pptx_01.pptx +0 -0
  45. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/rtf_01.rtf +0 -0
  46. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/xlsx_01.xls +0 -0
  47. {docvortex-0.4.7 → docvortex-0.4.8}/demo/office_docs/xlsx_01.xlsx +0 -0
  48. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/2407.00079v4_origi-10.pdf +0 -0
  49. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/IEBM_A_2667169_O-5.pdf +0 -0
  50. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/caibao1.pdf +0 -0
  51. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/demo1.pdf +0 -0
  52. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/demo2.pdf +0 -0
  53. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/demo3.pdf +0 -0
  54. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/demo4.pdf +0 -0
  55. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/demo6.pdf +0 -0
  56. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/mixed_elements_pages_03_06.pdf +0 -0
  57. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/mixed_elements_pages_07_10.pdf +0 -0
  58. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/mixed_elements_pages_11_15.pdf +0 -0
  59. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/mixed_elements_pages_39_40.pdf +0 -0
  60. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs/small_ocr.pdf +0 -0
  61. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/207.pdf" +0 -0
  62. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/2072.pdf" +0 -0
  63. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/2073.pdf" +0 -0
  64. {docvortex-0.4.7 → docvortex-0.4.8}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/2074.pdf" +0 -0
  65. {docvortex-0.4.7 → docvortex-0.4.8}/docs/HTML_PROTOCOL.md +0 -0
  66. {docvortex-0.4.7 → docvortex-0.4.8}/docs/JSON_PROTOCOL.md +0 -0
  67. {docvortex-0.4.7 → docvortex-0.4.8}/docs/METADATA.md +0 -0
  68. {docvortex-0.4.7 → docvortex-0.4.8}/docs/PDF_FONTS.md +0 -0
  69. {docvortex-0.4.7 → docvortex-0.4.8}/docs/RENDER_OWNERSHIP.md +0 -0
  70. {docvortex-0.4.7 → docvortex-0.4.8}/docs/USAGE.md +0 -0
  71. {docvortex-0.4.7 → docvortex-0.4.8}/docs/flash-manual-annotations-2026-09-15.md +0 -0
  72. {docvortex-0.4.7 → docvortex-0.4.8}/docs/flash-round2-annotations-2026-09-15.md +0 -0
  73. {docvortex-0.4.7 → docvortex-0.4.8}/docs/flash-rule-generalization-2026-09-15.md +0 -0
  74. {docvortex-0.4.7 → docvortex-0.4.8}/docs/sdk-0.4.md +0 -0
  75. {docvortex-0.4.7 → docvortex-0.4.8}/pyproject.toml +0 -0
  76. {docvortex-0.4.7 → docvortex-0.4.8}/schemas/middle-2.0.json +0 -0
  77. {docvortex-0.4.7 → docvortex-0.4.8}/schemas/model-2.0.json +0 -0
  78. {docvortex-0.4.7 → docvortex-0.4.8}/setup.cfg +0 -0
  79. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/__init__.py +0 -0
  80. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/__init__.py +0 -0
  81. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/__init__.py +0 -0
  82. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/__init__.py +0 -0
  83. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/hyperlink.py +0 -0
  84. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/image.py +0 -0
  85. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/markup/__init__.py +0 -0
  86. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/markup/anchors.py +0 -0
  87. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/markup/formula.py +0 -0
  88. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/markup/projector.py +0 -0
  89. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/markup/styles.py +0 -0
  90. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/mathml.py +0 -0
  91. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/names.py +0 -0
  92. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/_shared/xycut.py +0 -0
  93. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/contracts.py +0 -0
  94. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/csv.py +0 -0
  95. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/__init__.py +0 -0
  96. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/constants.py +0 -0
  97. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/converter.py +0 -0
  98. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/errors.py +0 -0
  99. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/metadata.py +0 -0
  100. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/package.py +0 -0
  101. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/properties.py +0 -0
  102. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/epub/xhtml.py +0 -0
  103. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/__init__.py +0 -0
  104. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/anchors.py +0 -0
  105. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/constants.py +0 -0
  106. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/converter.py +0 -0
  107. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/document.py +0 -0
  108. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/errors.py +0 -0
  109. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/metadata.py +0 -0
  110. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/resources.py +0 -0
  111. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/html/selector.py +0 -0
  112. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/models.py +0 -0
  113. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/__init__.py +0 -0
  114. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/assembly.py +0 -0
  115. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/constants.py +0 -0
  116. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/converter.py +0 -0
  117. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/errors.py +0 -0
  118. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/geometry.py +0 -0
  119. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/images.py +0 -0
  120. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/metadata.py +0 -0
  121. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/models.py +0 -0
  122. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/package.py +0 -0
  123. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/path.py +0 -0
  124. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/reading_order.py +0 -0
  125. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/resources.py +0 -0
  126. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/scene.py +0 -0
  127. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/table.py +0 -0
  128. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/text.py +0 -0
  129. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/ofd/vector.py +0 -0
  130. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/__init__.py +0 -0
  131. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/__init__.py +0 -0
  132. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/bookmarks.py +0 -0
  133. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/doc_converter.py +0 -0
  134. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/fib.py +0 -0
  135. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/fields.py +0 -0
  136. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/formatting.py +0 -0
  137. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/images.py +0 -0
  138. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/lists.py +0 -0
  139. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/models.py +0 -0
  140. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/parser.py +0 -0
  141. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/pieces.py +0 -0
  142. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/records.py +0 -0
  143. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/sprm.py +0 -0
  144. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/doc/styles.py +0 -0
  145. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/__init__.py +0 -0
  146. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/context.py +0 -0
  147. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/docx_converter.py +0 -0
  148. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/equationxml.py +0 -0
  149. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/fields.py +0 -0
  150. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/formatting_types.py +0 -0
  151. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/main.py +0 -0
  152. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/numbering.py +0 -0
  153. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/office_xml.py +0 -0
  154. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/package_normalizer.py +0 -0
  155. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/resources.py +0 -0
  156. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/styles.py +0 -0
  157. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/docx/tables.py +0 -0
  158. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/__init__.py +0 -0
  159. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/image.py +0 -0
  160. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/latex_dict.py +0 -0
  161. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/mtef.py +0 -0
  162. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/mtef_v5.py +0 -0
  163. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/omml.py +0 -0
  164. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/equation/ooxml.py +0 -0
  165. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/errors.py +0 -0
  166. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/image.py +0 -0
  167. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/legacy/__init__.py +0 -0
  168. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/legacy/binary.py +0 -0
  169. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/legacy/officeart.py +0 -0
  170. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/legacy/ole.py +0 -0
  171. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/limits.py +0 -0
  172. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/metadata.py +0 -0
  173. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/__init__.py +0 -0
  174. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/chart.py +0 -0
  175. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/constants.py +0 -0
  176. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/converters.py +0 -0
  177. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/errors.py +0 -0
  178. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/metadata.py +0 -0
  179. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/models.py +0 -0
  180. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/package.py +0 -0
  181. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/styles.py +0 -0
  182. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/table.py +0 -0
  183. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/odf/text.py +0 -0
  184. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ooxml_chart.py +0 -0
  185. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/opc.py +0 -0
  186. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ppt/__init__.py +0 -0
  187. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ppt/models.py +0 -0
  188. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ppt/parser.py +0 -0
  189. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ppt/ppt_converter.py +0 -0
  190. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ppt/records.py +0 -0
  191. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/ppt/style_text.py +0 -0
  192. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/__init__.py +0 -0
  193. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/context.py +0 -0
  194. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/lists.py +0 -0
  195. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/main.py +0 -0
  196. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/package_normalizer.py +0 -0
  197. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/pptx_converter.py +0 -0
  198. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/resources.py +0 -0
  199. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/shapes.py +0 -0
  200. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/text_styles.py +0 -0
  201. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/pptx/titles.py +0 -0
  202. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rich_text.py +0 -0
  203. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/__init__.py +0 -0
  204. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/converter.py +0 -0
  205. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/lexer.py +0 -0
  206. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/math.py +0 -0
  207. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/metadata.py +0 -0
  208. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/models.py +0 -0
  209. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/rtf/parser.py +0 -0
  210. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/spreadsheet/__init__.py +0 -0
  211. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/spreadsheet/html.py +0 -0
  212. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/spreadsheet/models.py +0 -0
  213. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/spreadsheet/projector.py +0 -0
  214. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/streams.py +0 -0
  215. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/__init__.py +0 -0
  216. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/chart.py +0 -0
  217. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/embedded_chart.py +0 -0
  218. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/models.py +0 -0
  219. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/number_format.py +0 -0
  220. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/parser.py +0 -0
  221. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/records.py +0 -0
  222. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/strings.py +0 -0
  223. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xls/xls_converter.py +0 -0
  224. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xlsx/__init__.py +0 -0
  225. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xlsx/main.py +0 -0
  226. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xlsx/ooxml_ole.py +0 -0
  227. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xlsx/package_normalizer.py +0 -0
  228. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/office/xlsx/xlsx_converter.py +0 -0
  229. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/__init__.py +0 -0
  230. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_script_geometry.py +0 -0
  231. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/__init__.py +0 -0
  232. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/candidate.py +0 -0
  233. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/contracts.py +0 -0
  234. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/engine.py +0 -0
  235. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/geometry.py +0 -0
  236. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/rule_band.py +0 -0
  237. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/sparse_common.py +0 -0
  238. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/sparse_hybrid.py +0 -0
  239. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/sparse_multiline.py +0 -0
  240. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/text.py +0 -0
  241. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/text_grid.py +0 -0
  242. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/_table_recovery/vector.py +0 -0
  243. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/auxiliary_text.py +0 -0
  244. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/char_geometry.py +0 -0
  245. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/code_blocks.py +0 -0
  246. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/geometry.py +0 -0
  247. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/graphics.py +0 -0
  248. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/index_blocks.py +0 -0
  249. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/__init__.py +0 -0
  250. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/common.py +0 -0
  251. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/detection.py +0 -0
  252. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/matching.py +0 -0
  253. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/materialize.py +0 -0
  254. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/scripts.py +0 -0
  255. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/inline/types.py +0 -0
  256. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/layout_evidence.py +0 -0
  257. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/native_text.py +0 -0
  258. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/spatial_text.py +0 -0
  259. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_annotations.py +0 -0
  260. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_constants.py +0 -0
  261. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_detection.py +0 -0
  262. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_filled_grid.py +0 -0
  263. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_geometry.py +0 -0
  264. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_rows.py +0 -0
  265. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_rules.py +0 -0
  266. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/table_text_styles.py +0 -0
  267. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/tables.py +0 -0
  268. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/__init__.py +0 -0
  269. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/annotations.py +0 -0
  270. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/assembly.py +0 -0
  271. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/common.py +0 -0
  272. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/footnotes.py +0 -0
  273. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_assembly/rows.py +0 -0
  274. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_blocks.py +0 -0
  275. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/text_roles.py +0 -0
  276. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/__init__.py +0 -0
  277. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/body_profile.py +0 -0
  278. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/common.py +0 -0
  279. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/document_profile.py +0 -0
  280. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/title_analysis/prototype.py +0 -0
  281. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/titles.py +0 -0
  282. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/native/pdf/typography.py +0 -0
  283. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/analyzers/pdf.py +0 -0
  284. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/api.py +0 -0
  285. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/assets/__init__.py +0 -0
  286. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/assets/images.py +0 -0
  287. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/assets/store.py +0 -0
  288. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/cli.py +0 -0
  289. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/__init__.py +0 -0
  290. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/html/__init__.py +0 -0
  291. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/html/contracts.py +0 -0
  292. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/html/materializer.py +0 -0
  293. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/html/parser.py +0 -0
  294. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/html/resources.py +0 -0
  295. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/codecs/json.py +0 -0
  296. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/__init__.py +0 -0
  297. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/inline.py +0 -0
  298. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/links.py +0 -0
  299. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/markup/__init__.py +0 -0
  300. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/markup/anchors.py +0 -0
  301. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/markup/formula.py +0 -0
  302. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/markup/projector.py +0 -0
  303. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/markup/styles.py +0 -0
  304. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/mathml.py +0 -0
  305. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/normalization.py +0 -0
  306. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/spans.py +0 -0
  307. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/__init__.py +0 -0
  308. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/blocks.py +0 -0
  309. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/content.py +0 -0
  310. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/document.py +0 -0
  311. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/html.py +0 -0
  312. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/models.py +0 -0
  313. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/rules.py +0 -0
  314. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/table/structure.py +0 -0
  315. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/text.py +0 -0
  316. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/content/tree.py +0 -0
  317. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/__init__.py +0 -0
  318. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/contracts.py +0 -0
  319. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/detection.py +0 -0
  320. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/filetypes.py +0 -0
  321. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/page_range.py +0 -0
  322. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/__init__.py +0 -0
  323. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/_document.py +0 -0
  324. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/classify.py +0 -0
  325. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/constants.py +0 -0
  326. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/font_runtime.py +0 -0
  327. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/images.py +0 -0
  328. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/layout.py +0 -0
  329. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/metadata.py +0 -0
  330. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/native_annotations.py +0 -0
  331. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/native_contracts.py +0 -0
  332. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/native_coordinates.py +0 -0
  333. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/native_lifecycle.py +0 -0
  334. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/native_objects.py +0 -0
  335. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/native_text_geometry.py +0 -0
  336. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/pdfium.py +0 -0
  337. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/raster.py +0 -0
  338. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/text/__init__.py +0 -0
  339. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/text/_contracts.py +0 -0
  340. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/text/dedup.py +0 -0
  341. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/text/extract.py +0 -0
  342. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/text/geometry.py +0 -0
  343. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/text/groups.py +0 -0
  344. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/pdf/visuals.py +0 -0
  345. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/properties.py +0 -0
  346. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/document/source.py +0 -0
  347. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/errors.py +0 -0
  348. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/export/__init__.py +0 -0
  349. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/export/bundle.py +0 -0
  350. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/export/files.py +0 -0
  351. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/export/middle.py +0 -0
  352. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/__init__.py +0 -0
  353. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_coordinates.py +0 -0
  354. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_geometry.py +0 -0
  355. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_hyperlink.py +0 -0
  356. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_image.py +0 -0
  357. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_image_operations.py +0 -0
  358. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_image_payload.py +0 -0
  359. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/_text.py +0 -0
  360. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/image_encoding.py +0 -0
  361. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/language.py +0 -0
  362. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/type_identity.py +0 -0
  363. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/foundation/xml_names.py +0 -0
  364. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/geometry.py +0 -0
  365. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/metadata.py +0 -0
  366. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/options.py +0 -0
  367. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/__init__.py +0 -0
  368. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/content.py +0 -0
  369. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/document.py +0 -0
  370. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/lists.py +0 -0
  371. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/page_blocks.py +0 -0
  372. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/postprocess/visual.py +0 -0
  373. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/public_api.py +0 -0
  374. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/__init__.py +0 -0
  375. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/__init__.py +0 -0
  376. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/common/__init__.py +0 -0
  377. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/common/context.py +0 -0
  378. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/common/html_table.py +0 -0
  379. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/common/index.py +0 -0
  380. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/common/list_items.py +0 -0
  381. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/common/planner.py +0 -0
  382. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/__init__.py +0 -0
  383. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/assets.py +0 -0
  384. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/inline.py +0 -0
  385. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/math.py +0 -0
  386. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/renderer.py +0 -0
  387. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/styles.py +0 -0
  388. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/docx/table.py +0 -0
  389. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/epub/__init__.py +0 -0
  390. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/epub/assets.py +0 -0
  391. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/epub/package.py +0 -0
  392. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/epub/renderer.py +0 -0
  393. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/html/__init__.py +0 -0
  394. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/html/inline.py +0 -0
  395. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/html/renderer.py +0 -0
  396. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/html/sanitizer.py +0 -0
  397. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/html/table.py +0 -0
  398. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/latex/__init__.py +0 -0
  399. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/latex/assets.py +0 -0
  400. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/latex/inline.py +0 -0
  401. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/latex/renderer.py +0 -0
  402. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/latex/table.py +0 -0
  403. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/__init__.py +0 -0
  404. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/assets.py +0 -0
  405. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/blocks.py +0 -0
  406. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/escaping.py +0 -0
  407. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/inline.py +0 -0
  408. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/renderer.py +0 -0
  409. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/markdown/table.py +0 -0
  410. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/__init__.py +0 -0
  411. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/assets.py +0 -0
  412. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/diagnostics.py +0 -0
  413. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/font_plan.py +0 -0
  414. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/formula.py +0 -0
  415. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/formula_layout.py +0 -0
  416. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/inline.py +0 -0
  417. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/original.py +0 -0
  418. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/pagination.py +0 -0
  419. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/paragraph.py +0 -0
  420. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/renderer.py +0 -0
  421. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/styles.py +0 -0
  422. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/table.py +0 -0
  423. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/table_content.py +0 -0
  424. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/table_layout.py +0 -0
  425. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/pdf/title_layout.py +0 -0
  426. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/structured_content/__init__.py +0 -0
  427. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/_internal/structured_content/renderer.py +0 -0
  428. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/api.py +0 -0
  429. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/contracts.py +0 -0
  430. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/docx.py +0 -0
  431. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/epub.py +0 -0
  432. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/fragments.py +0 -0
  433. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/html.py +0 -0
  434. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/latex.py +0 -0
  435. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/markdown.py +0 -0
  436. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/pdf.py +0 -0
  437. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/render/structured_content.py +0 -0
  438. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/epub/docvortex.css +0 -0
  439. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/fasttext-langdetect/lid.176.ftz +0 -0
  440. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/fonts/DroidSansFallbackFull.ttf +0 -0
  441. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/fonts/NOTICE +0 -0
  442. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/fonts/manifest.json +0 -0
  443. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/html/docvortex.css +0 -0
  444. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/html/docvortex.min.css +0 -0
  445. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/resources/unicode/EquivalentUnifiedIdeograph-17.0.0.txt +0 -0
  446. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/result.py +0 -0
  447. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/schema.py +0 -0
  448. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex/visualization.py +0 -0
  449. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex.egg-info/dependency_links.txt +0 -0
  450. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex.egg-info/entry_points.txt +0 -0
  451. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex.egg-info/requires.txt +0 -0
  452. {docvortex-0.4.7 → docvortex-0.4.8}/src/docvortex.egg-info/top_level.txt +0 -0
  453. {docvortex-0.4.7 → docvortex-0.4.8}/tests/benchmarks/flash_pdf.py +0 -0
  454. {docvortex-0.4.7 → docvortex-0.4.8}/tests/benchmarks/native_pdf_table.py +0 -0
  455. {docvortex-0.4.7 → docvortex-0.4.8}/tests/benchmarks/pdf_render.py +0 -0
  456. {docvortex-0.4.7 → docvortex-0.4.8}/tests/benchmarks/pipeline.py +0 -0
  457. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/evaluate_native_pdf_table_manifest.py +0 -0
  458. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_layout_block_expectations.json +0 -0
  459. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_layout_geometry_manifest.json +0 -0
  460. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_layout_semantic_expectations.json +0 -0
  461. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_manual_annotations.json +0 -0
  462. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_manual_review_decisions.json +0 -0
  463. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_reviewed_history.json +0 -0
  464. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_round2_annotations.json +0 -0
  465. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_round2_review_decisions.json +0 -0
  466. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/flash_rule_generalization_review_decisions.json +0 -0
  467. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/generate_synthetic_pdf_fixtures.py +0 -0
  468. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/native_pdf_table_cross_page_manifest.json +0 -0
  469. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/native_pdf_table_demo_manifest.json +0 -0
  470. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/native_pdf_table_script_truth.json +0 -0
  471. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/pdf_char_dedup.json +0 -0
  472. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/pdf_mixed_font_script_line.json +0 -0
  473. {docvortex-0.4.7 → docvortex-0.4.8}/tests/fixtures/rtf/semantic.rtf +0 -0
  474. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_architecture.py +0 -0
  475. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_benchmark_entrypoint.py +0 -0
  476. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_brand_protocol.py +0 -0
  477. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_cli_logging.py +0 -0
  478. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_complete_pipeline.py +0 -0
  479. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_converter_lifecycle.py +0 -0
  480. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_document_envelope.py +0 -0
  481. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_document_metadata.py +0 -0
  482. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_format_matrix.py +0 -0
  483. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_geometry_api.py +0 -0
  484. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_history_geometry_tools.py +0 -0
  485. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_html_namespace.py +0 -0
  486. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_mixed_font_script_reference.py +0 -0
  487. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_analysis_api.py +0 -0
  488. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_font_geometry.py +0 -0
  489. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_font_runtime.py +0 -0
  490. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_model_text_normalization.py +0 -0
  491. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_output_text.py +0 -0
  492. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_render_pool.py +0 -0
  493. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_source_row_merging.py +0 -0
  494. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_pdf_symbol_normalization.py +0 -0
  495. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_public_export_api.py +0 -0
  496. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_public_image_api.py +0 -0
  497. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_public_pipeline.py +0 -0
  498. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_refactor_raster.py +0 -0
  499. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_refactor_rendering.py +0 -0
  500. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_refactor_resources.py +0 -0
  501. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_render_ownership.py +0 -0
  502. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_renderer_branding.py +0 -0
  503. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_shared_boundaries.py +0 -0
  504. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_system_font_pdf_pipeline.py +0 -0
  505. {docvortex-0.4.7 → docvortex-0.4.8}/tests/test_validated_geometry.py +0 -0
  506. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_docx_equationxml_test_utils.py +0 -0
  507. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_epub_test_utils.py +0 -0
  508. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_image_mtef_test_utils.py +0 -0
  509. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_legacy_doc_test_utils.py +0 -0
  510. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_legacy_ppt_test_utils.py +0 -0
  511. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_legacy_xls_test_utils.py +0 -0
  512. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_metafile_test_utils.py +0 -0
  513. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_mtef_test_utils.py +0 -0
  514. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_mtef_v5_test_utils.py +0 -0
  515. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_native_test_utils.py +0 -0
  516. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_odf_test_utils.py +0 -0
  517. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_ofd_test_utils.py +0 -0
  518. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_office_image_mtef_test_utils.py +0 -0
  519. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_ooxml_mtef_test_utils.py +0 -0
  520. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/_span_test_utils.py +0 -0
  521. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/connexin.pdf +0 -0
  522. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/fornax.pdf +0 -0
  523. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/frames_v1.pdf +0 -0
  524. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/frames_v2.pdf +0 -0
  525. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/k2_treap.pdf +0 -0
  526. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/mmlu_redux.pdf +0 -0
  527. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/nash_review.pdf +0 -0
  528. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/annotated/nougat.pdf +0 -0
  529. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/bloom_form_labels.pdf +0 -0
  530. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/journal_layout_tables.pdf +0 -0
  531. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/math_display_formulas.pdf +0 -0
  532. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_layout/mixed_text_layout_sample.pdf.xor +0 -0
  533. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/flash_table_annotations_synthetic.pdf +0 -0
  534. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/metabolic_pathway_page_3.pdf +0 -0
  535. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_cjk_layout_synthetic.pdf +0 -0
  536. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/annual_report_fundraising_projects_table.pdf +0 -0
  537. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/annual_report_management_roles_table.pdf +0 -0
  538. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/annual_report_research_projects_table.pdf +0 -0
  539. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/conference_schedule_tables.pdf +0 -0
  540. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/engineering_process_restrictions_table.pdf +0 -0
  541. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/fund_asset_and_transaction_tables.pdf +0 -0
  542. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/fund_manager_profile_table.pdf +0 -0
  543. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/manufacturing_facilities_cross_page_table.pdf +0 -0
  544. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/pollutant_discharge_tables.pdf +0 -0
  545. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/procurement_contract_tables.pdf +0 -0
  546. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/procurement_document_blank_page_tables.pdf +0 -0
  547. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/native_pdf_tables/quarterly_report_financial_tables.pdf +0 -0
  548. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/pdfs/test.pdf +0 -0
  549. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_backend_architecture.py +0 -0
  550. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_backend_block_object_regressions.py +0 -0
  551. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_docx_assets.py +0 -0
  552. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_docx_complex_fields.py +0 -0
  553. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_docx_math.py +0 -0
  554. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_docx_render.py +0 -0
  555. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_docx_special_char_tables.py +0 -0
  556. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_docx_table.py +0 -0
  557. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_emfplus_integration.py +0 -0
  558. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_epub_backlinks.py +0 -0
  559. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_epub_quoted_note_types.py +0 -0
  560. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_epub_render.py +0 -0
  561. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_bbox_grid_comparison.py +0 -0
  562. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_csv.py +0 -0
  563. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_docx_equationxml.py +0 -0
  564. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_epub.py +0 -0
  565. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_html.py +0 -0
  566. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_image_mtef.py +0 -0
  567. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_legacy_chart_data.py +0 -0
  568. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_legacy_doc.py +0 -0
  569. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_legacy_doc_mtef.py +0 -0
  570. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_legacy_ppt.py +0 -0
  571. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_legacy_xls.py +0 -0
  572. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_legacy_xls_ppt_mtef.py +0 -0
  573. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_markup_anchors.py +0 -0
  574. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_model.py +0 -0
  575. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_mtef_v5.py +0 -0
  576. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_odf.py +0 -0
  577. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_ofd.py +0 -0
  578. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_office_image_mtef.py +0 -0
  579. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_office_metafile.py +0 -0
  580. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_office_models.py +0 -0
  581. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_office_mtef_v5.py +0 -0
  582. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_office_package_normalizers.py +0 -0
  583. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_office_title_types.py +0 -0
  584. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_ooxml_mtef.py +0 -0
  585. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_auxiliary_text.py +0 -0
  586. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_char_geometry.py +0 -0
  587. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_code_blocks.py +0 -0
  588. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_document_profile.py +0 -0
  589. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_equation_images.py +0 -0
  590. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_extractor.py +0 -0
  591. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_formulas.py +0 -0
  592. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_graphics.py +0 -0
  593. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_index_blocks.py +0 -0
  594. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_layout_repairs.py +0 -0
  595. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_line_metadata.py +0 -0
  596. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_native_text.py +0 -0
  597. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_pipeline.py +0 -0
  598. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_reviewed_history.py +0 -0
  599. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_samples.py +0 -0
  600. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_scripts.py +0 -0
  601. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_semantics.py +0 -0
  602. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_tables.py +0 -0
  603. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_text_blocks.py +0 -0
  604. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_text_visibility.py +0 -0
  605. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_titles.py +0 -0
  606. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_pdf_visual_annotations.py +0 -0
  607. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_round2_annotations.py +0 -0
  608. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_rtf.py +0 -0
  609. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_rule_generalization.py +0 -0
  610. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_shared_helpers.py +0 -0
  611. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_flash_spreadsheet_projector.py +0 -0
  612. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_guess_suffix_ole2.py +0 -0
  613. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_html_css_build.py +0 -0
  614. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_html_render.py +0 -0
  615. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_html_security.py +0 -0
  616. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_hybrid_script_source_pdfs.py +0 -0
  617. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_latex_render.py +0 -0
  618. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_markdown_render.py +0 -0
  619. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_middle_json_block_models.py +0 -0
  620. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_middle_json_export.py +0 -0
  621. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_middle_json_validator.py +0 -0
  622. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_model_json.py +0 -0
  623. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_native_pdf_table.py +0 -0
  624. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_native_pdf_table_demo_manifest.py +0 -0
  625. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_native_pdf_table_manifest.py +0 -0
  626. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_native_pdf_table_pipeline.py +0 -0
  627. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_native_pdf_table_scripts.py +0 -0
  628. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_native_table_performance_equivalence.py +0 -0
  629. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_ofd_assembly.py +0 -0
  630. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_ofd_vector_tables.py +0 -0
  631. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_office_demo_exports.py +0 -0
  632. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_office_demo_pages.py +0 -0
  633. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_office_parser_regressions.py +0 -0
  634. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_cjk_style.py +0 -0
  635. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_cjk_wrapping.py +0 -0
  636. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_classify.py +0 -0
  637. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_demo_links.py +0 -0
  638. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_diagnostic_levels.py +0 -0
  639. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_document.py +0 -0
  640. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_formula_layout.py +0 -0
  641. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_object_clipping.py +0 -0
  642. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_original_layout.py +0 -0
  643. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_pagination.py +0 -0
  644. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_paragraph_cache.py +0 -0
  645. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_render.py +0 -0
  646. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_render_diagnostics.py +0 -0
  647. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_structured_tables.py +0 -0
  648. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_table_cache.py +0 -0
  649. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_table_round2.py +0 -0
  650. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_text_dedup.py +0 -0
  651. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_text_styles.py +0 -0
  652. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_title_font_plan.py +0 -0
  653. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_title_space.py +0 -0
  654. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_pdf_visualization.py +0 -0
  655. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_postprocess_page_blocks.py +0 -0
  656. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_postprocess_pages.py +0 -0
  657. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_postprocess_paragraphs.py +0 -0
  658. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_postprocess_visual.py +0 -0
  659. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_render_api.py +0 -0
  660. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_render_html_table.py +0 -0
  661. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_render_image_renderer.py +0 -0
  662. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_render_list_index_utils.py +0 -0
  663. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_structured_content_render.py +0 -0
  664. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_table_merge.py +0 -0
  665. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_table_merge_cell_merge.py +0 -0
  666. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_text_block_anchor.py +0 -0
  667. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_text_boundary_rules.py +0 -0
  668. {docvortex-0.4.7 → docvortex-0.4.8}/tests/unittest/test_text_utils.py +0 -0
  669. {docvortex-0.4.7 → docvortex-0.4.8}/tools/__init__.py +0 -0
  670. {docvortex-0.4.7 → docvortex-0.4.8}/tools/build_html_css.py +0 -0
  671. {docvortex-0.4.7 → docvortex-0.4.8}/tools/calibrate_pdf_geometry.py +0 -0
  672. {docvortex-0.4.7 → docvortex-0.4.8}/tools/capture_baseline.py +0 -0
  673. {docvortex-0.4.7 → docvortex-0.4.8}/tools/capture_platform_layout.py +0 -0
  674. {docvortex-0.4.7 → docvortex-0.4.8}/tools/compare_font_platforms.py +0 -0
  675. {docvortex-0.4.7 → docvortex-0.4.8}/tools/font_geometry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docvortex
3
- Version: 0.4.7
3
+ Version: 0.4.8
4
4
  Summary: A fast, multi-format document parsing and conversion engine
5
5
  License-Expression: MIT
6
6
  Project-URL: Repository, https://github.com/myhloli/DocVortex
@@ -0,0 +1,48 @@
1
+ # Flash 标题与段落成员补充修复验收
2
+
3
+ ## 结果
4
+
5
+ 本轮完成 9 组补充标注:fix P10 的附录 E 是完整的双行 `paragraph_title`;dual_caption P5、P10、P12、P15 指定的 7 处小字号粗体标题全部提升,P15 的双行标题保持一个块;dual_caption P10 的 `Prescribing` 完整、唯一地归于下一段,上一段止于 `day.`,两段行框和块框不再共享该行。
6
+
7
+ 同一规则还自然恢复了 9 个同类标题。两份原件共有 12 个变化页,均对照原文、修改前及修改后标框逐页接受。生产规则不使用文件名、页码、块号、论文原句或特定字体名称。
8
+
9
+ - 逐页画廊:`output/pdf/flash-round3-followup/final/index.html`
10
+ - 两份完整导出:`output/pdf/flash-round3-followup/exports/`(HTML、MiddleJson、图片、资产包)
11
+ - 逐项裁决:`tests/fixtures/flash_round3_followup_review_decisions.json`
12
+
13
+ ## 实现与成因
14
+
15
+ 多行标题使用后继正文重复左右缘作为额外的局部居中参照。同一物理行的字体碎片先按基线聚合,首行和列表缩进不决定栏中心;保留原有未知字重和跨页重复排版要求。
16
+
17
+ 小字号标题单独使用相对字号、可靠字重、上下独立留白、后继正文和容器排除证据。已确认的标题行组通过内部 `title_band_id` 传递给语义行连接,避免分类后重新拆开。该字段不进入公共协议。
18
+
19
+ 段首恢复只对具有共同物理行身份、同字体、同栏和后继整行支持的连续文字放宽空格距离。空间合并复用统一成员合并函数,完整传递 `_text_lines`、内容和几何元数据,解决旧实现只合并内容及框、随后又从不完整成员重建内容造成的漏词。
20
+
21
+ ## 回归与裁决
22
+
23
+ - **1480 项测试通过**,耗时 206.37 秒;包含新增的 35 项标题、成员守恒、数值列保护及真实样本检查。针对性检查单独运行 **200 项通过**。
24
+ - 历史 **19 份/168 页**相对本次冻结基线零变化。
25
+ - 第一轮 **8 份/118 页**相对本次冻结基线零变化;第二轮 **6 份/98 页**包含其中,不累计为额外独立覆盖量。
26
+ - 首个候选曾把 nougat P17 小表格的标签和百分数列连入一组,造成两条比较记录合并。对照原页后拒绝此变化,通过排除数值列的宽空格放宽修复,并增加合成与原件反例;未更新旧基线。
27
+ - 最终两份 41 页原件的非空白文本差异仅为恢复 `Prescribing`,未删除其他字符。另以源成员集合、唯一归属、行框和公共段落边界断言验证,避免仅比较旧输出遗漏已有缺字。
28
+ - 公共 `parse → MiddleJson → HTML/资产包` 全链路通过,34 个资产均可解析,缺失图片和解析诊断为空。浏览器确认附录 E 和小标题的标题层级、完整双行标题,以及独立的 `Prescribing` 段落。
29
+ - 21 个修改或新增 Python 文件通过 Ruff、格式检查,`git diff --check` 通过。
30
+
31
+ ## 冻结与重放
32
+
33
+ 冻结的是上一轮未提交源码及其输出,而非仅 Git HEAD。源码指纹 `1533f54963374b15a3cb18ff581f594a1a75fdc9eea47e88ee44cbddbf6988f8` 已与 `baseline-code/src` 逐文件核对;原输出保存在 `output/pdf/flash-round3-followup/baseline/`。本轮最终源码指纹为 `d9a40dab073789eafc52b25fd2fc5771ae0ccc930b44222735eac7c4310f774c`,画廊、历史重放和公共导出记录一致。
34
+
35
+ ```sh
36
+ PY=/Users/myhloli/projects/20240809magic_pdf/Magic-PDF/.venv1/bin/python
37
+ PYTHONPATH=src "$PY" tools/review_flash_round3.py --baseline output/pdf/flash-round3-followup/baseline/final --output output/pdf/flash-round3-followup/final
38
+ PYTHONPATH=src "$PY" tools/review_flash_annotations.py --output output/pdf/flash-round3-followup/final-manual
39
+ PYTHONPATH=src "$PY" tools/review_flash_regression.py --output output/pdf/flash-round3-followup/final-history --compare-to output/pdf/flash-round3-followup/baseline/accepted-history
40
+ PYTHONPATH=src "$PY" tools/review_flash_round2.py --manifest tests/fixtures/flash_round3_annotations.json --output output/pdf/flash-round3-followup/exports
41
+ PYTHONPATH=src "$PY" -m pytest tests/unittest/test_flash_pdf_*.py tests/unittest/test_flash_rule_generalization.py tests/unittest/test_flash_manual_annotations.py tests/unittest/test_flash_round2_annotations.py tests/unittest/test_flash_round3_annotations.py tests/unittest/test_flash_spatial_evidence.py tests/unittest/test_pdf_document.py tests/unittest/test_pdf_object_clipping.py tests/unittest/test_pdf_text_dedup.py tests/unittest/test_native_pdf_table*.py tests/unittest/test_pdf_visualization.py tests/unittest/test_pdf_text_styles.py tests/unittest/test_postprocess_paragraphs.py -q
42
+ ```
43
+
44
+ 仍位于 `codex/flash-spatial-layout-round3`,未提交或推送;结果为指定本地 macOS/Python/PDFium 运行时的验收,未运行远端 CI。本轮没有新增公共参数或输出类型。
45
+
46
+ ## 后续栏首及长标题补充
47
+
48
+ P8 与 P11 的剩余两处标题已修复,详见 [栏首与近满栏小标题验收](flash-title-coverage-2026-09-16.md)。
@@ -0,0 +1,76 @@
1
+ # Flash 原生 PDF 空间布局:第三轮修复与验收
2
+
3
+ ## 范围与证据
4
+
5
+ 基于 `a8511caa6615fcf479a2b861061b4633ae1eef5f`,开发分支为 `codex/flash-spatial-layout-round3`。两份原件共 41 页、25 个重点页、36 组人工标注。源文件和原始块锚点保存在 `tests/fixtures/flash_round3_annotations.json`,断言不依赖修复后的块编号。
6
+
7
+ - `journal_dual_caption.pdf`:20 页;SHA256 `ae9ee7db89a1ff23f9be8ecdb4ae70596ad1e3eec78c1d370f562a4aad3aa5ec`。
8
+ - `quantum_appendix_layout.pdf`:21 页;SHA256 `6f393579aacfb8119f92790e565d539856e21d901f683147d242daefd6d094bb`。
9
+ - 原页/修改前/修改后画廊:`output/pdf/flash-round3/final/index.html`。
10
+ - 公共接口导出:`output/pdf/flash-round3/final-exports/`,每份文档包含 HTML、MiddleJson、图片资产及 ZIP。
11
+ - 修改前代码的完整源码指纹为 `e5ddd06fdb910bfcb83e316e42c36b58bfb8d51baac2682f68d919be183434c6`,已与独立的只读基准 checkout 核对。
12
+
13
+ ## 实现
14
+
15
+ 1. **参考文献和局部分栏**:使用连续编号的稳定左缘确定参考区域的横向和纵向范围,支持无 References 标题、齐平或悬挂续行。局部标题限定区域起点;只有具有独立留白的章节标题才能终止区域。作者年代式条目的年份不充当编号。混合栏页上方正文独立排序,避免上标的微小高度差让右栏先读。
16
+ 2. **标题和段落**:限制正文原型对满栏连续行的提升及标题邻行传播;多行未知字重标题增加居中对齐证据。首页独立标题带和出版日期带支持文档标题及编号机构识别。同行碎片依据同栏、基线、后继整行支持恢复;段内数学前缀按成员而非外接框认领。
17
+ 3. **公式**:在原有检测结束后补齐独立数学带及右侧/右下编号,只扩充不完整区域。完整公式沿用原有结果。短标记必须有包围结构,百分数及全角百分数不能作为编号;正文短句、栏沟及表格为屏障。保留既有行内数学回退成员,不因其已被正文认领而删除。
18
+ 4. **表注与图例**:以表内规则行的结束位置分离外框包住的表注,表格恢复和投影共用收缩后的表体范围。从紧邻图片的独立图编号恢复破碎说明,完整图注不再次扩展。图例先恢复药名—符号物理行,再按分类和重复栏左缘组织阅读顺序,统一归属图片的图注释。
19
+ 5. **公共转换**:临时参考条目起点及段界证据传入页面合并阶段;新编号和已确认段界禁止续接,跨栏/跨页参考续项可保留 `continues_prev`。临时字段在 PageInfo 对象化前移除,不新增公共参数或块类型。
20
+
21
+ 生产规则没有新增文件名、页码、块号、论文原句或特定字体名称判断。新增函数均有中文说明。
22
+
23
+ ## 回归裁决
24
+
25
+ 没有通过更新旧基线消除失败。下列候选变化均通过规则收紧解决,审阅过程的失败图像仍保留在输出目录:
26
+
27
+ | 回归证据 | 裁决与处理 |
28
+ | --- | --- |
29
+ | `current-history/demo2/page-03-after.png`:短正文 `is given by` 被吸入公式 | 扩展短正文屏障,并把数学带恢复放在既有检测之后,完整公式不重建。 |
30
+ | `current-history/caibao1/page-02-after.png`:并列图片的图注归属和顺序改变 | 图注恢复入口限定为独立编号及其尚未归组的说明带;已有完整图注沿用原流程。 |
31
+ | 作者年代式参考文献被按年份重新分条;参考上下文侵入附录 | 编号模式与传统悬挂条目分组分开,仅对可靠编号区域提前保护;保留附录终止及脚注排除规则。 |
32
+ | `refined2-history/中文论文4/page-02-after.png`:正文中的行内数学内容缺失 | 区分原先用于正文恢复的已认领成员和新公式补全成员,保留前者;增加全角百分数反例。 |
33
+ | `frames_v1/v2` 附录数字列表吸入下方图说明 | 作者年代式跨页状态不激活数字参考模式;普通编号仍作为传统分组边界,保留原基线并增加四页反例。 |
34
+ | `fix.pdf` 参考条目内部的斜体行被当成区域终点 | 终点必须具有独立留白;真实样本同时检查条目数、条目完整性和无假标题,不能只数编号。 |
35
+
36
+ 两个临时字段 `_reference_start`、`_paragraph_boundary` 不进入旧可见内容指纹;只排除这两个明确字段,没有放宽类型、内容、顺序或 bbox 校验。其行为由公共页面转换测试单独断言,包括跨页数字开头续项、新编号不续接、图例归属和私有字段清理。
37
+
38
+ ## 重放
39
+
40
+ 使用用户指定的 `.venv1`,在仓库根目录执行:
41
+
42
+ ```sh
43
+ PY=/Users/myhloli/projects/20240809magic_pdf/Magic-PDF/.venv1/bin/python
44
+ PYTHONPATH=src "$PY" tools/review_flash_round3.py
45
+ PYTHONPATH=src "$PY" tools/review_flash_round2.py --manifest tests/fixtures/flash_round3_annotations.json --output output/pdf/flash-round3/final-exports
46
+ PYTHONPATH=src "$PY" tools/review_flash_regression.py --output output/pdf/flash-round3/accepted-history --compare-to output/pdf/flash-round3/baseline-history
47
+ PYTHONPATH=src "$PY" tools/review_flash_annotations.py --output output/pdf/flash-round3/accepted-manual
48
+ PYTHONPATH=src "$PY" -m pytest tests/unittest/test_flash_pdf_*.py tests/unittest/test_flash_rule_generalization.py tests/unittest/test_flash_manual_annotations.py tests/unittest/test_flash_round2_annotations.py tests/unittest/test_flash_round3_annotations.py tests/unittest/test_flash_spatial_evidence.py tests/unittest/test_pdf_document.py tests/unittest/test_pdf_object_clipping.py tests/unittest/test_pdf_text_dedup.py tests/unittest/test_native_pdf_table*.py tests/unittest/test_pdf_visualization.py tests/unittest/test_pdf_text_styles.py tests/unittest/test_postprocess_paragraphs.py -q
49
+ ```
50
+
51
+ 逐项裁决和最终运行结果见 `tests/fixtures/flash_round3_review_decisions.json`。公式继续使用现有图片资产路径;本轮不处理原 PDF 的错误字符映射或引入数学内容识别。
52
+
53
+ ## 最终验收结果
54
+
55
+ - **1445 项测试通过**,耗时 198.50 秒;日志:`output/pdf/flash-round3/accepted-tests.log`。19 个修改/新增 Python 文件通过 Ruff 和格式检查,`git diff --check` 通过。
56
+ - 两份新文档 **41 页**全部重放,**36 组标注**通过针对性结构测试及视觉审阅;画廊覆盖 **25 个标注页与 2 个额外变化页**。额外变化为第一份 P12 短尾接回同段、fix P7 附录标题与正文分离。
57
+ - 历史 **19 份/168 页**可见内容、类型、顺序和块框指纹均与修改前一致。
58
+ - 第一轮 **8 份/118 页**中 114 页一致,4 页变化逐项接受,见下表。第二轮 **6 份/98 页**是上述完整文档的子集,已全部覆盖;不将重叠页累加为独立覆盖量。
59
+ - `parse → MiddleJson → HTML/资产包` 已完成,两份导出共 34 个资产,缺失图片和解析诊断均为空。浏览器检查了正文标题、图例分组阅读顺序及图片加载。公式仍使用原生裁图,不改变数学内容识别方式。
60
+ - 对原生正文、图注、表格及公式检测内容进行非空白字符守恒核对;仅第一份 P5、P17 和 fix P20 共四处行末连字符随正常断词连接被移除,无其他非空白字符丢失或新增。
61
+ - 未修改原有测试金标。以下四页是完整重放产生的自然改善,已保存旧/新指纹和逐项接受理由;拒绝的候选变化通过收紧规则恢复原基线。
62
+
63
+ | 文档/页 | 接受理由 |
64
+ | --- | --- |
65
+ | fornax P1 | 独立双行主标题由 `paragraph_title` 恢复为 `doc_title`,作者和机构顺序保持。 |
66
+ | mmlu_redux P13 | 独立加粗的 Checklist 由正文恢复为段落标题。 |
67
+ | k2_treap P3 | 保留行内区间右括号对应的原生映射字符,避免与后继正文粘连;不做字符替换。 |
68
+ | k2_treap P9 | 保留行内矩阵维数右括号对应的原生映射字符;块框和阅读顺序不变。 |
69
+
70
+ 既有语料变化页与恢复旧基线的页面对比:`output/pdf/flash-round3/manual-visuals/index.html`。全部裁决(包括源码、原件及页面指纹)保存在 `tests/fixtures/flash_round3_review_decisions.json`。
71
+
72
+ 本次结果为指定 macOS/Python/PDFium 运行时的本地验收;未执行远端 CI,未提交或推送。原 PDF 的字符映射错误仍沿用原有处理,本轮没有引入 OCR/VLM。
73
+
74
+ ## 后续补充验收
75
+
76
+ 用户新增的标题与段落成员问题已在补充轮完成,见 [补充修复验收](flash-spatial-layout-followup-2026-09-16.md)。本报告保留第一轮实现时的验证记录。
@@ -0,0 +1,25 @@
1
+ # 栏首与近满栏小标题补充验收
2
+
3
+ 已修复 dual_caption P8 块1(Altered Protein Metabolism)和 P11 块10(Cyproheptadine and Other Antiserotonergic Drugs)。两者均输出为 `paragraph_title`,最终 HTML 均为一个 h2。
4
+
5
+ ## 原因与通用修复
6
+
7
+ - P8 标题为栏内第一行,原规则因没有上一行而直接跳过。现在允许缺少上方正文,但要求位置与全页正文区顶部相符;页眉不参与上方正文判定,字体、字重、下方留白及真实后继正文等条件仍保留。
8
+ - P11 标题约占局部正文宽度 95%,被 90% 固定比例上限排除。现在使用标题是否落在实际栏左右边界内判断,右边允许半个正文行高的几何误差;越栏标题不能通过。
9
+ - 没有增加文件名、页码、块号、原句或字体名称条件。新增 24 个合成正反例,独立改变栏宽、字号和位置,覆盖栏首、长标题、越栏与侧栏中部情形;新增两处原件断言。
10
+
11
+ ## 验收
12
+
13
+ **1506 项测试通过**(230.72 秒),其中针对性检查 123 项通过。Ruff、格式和差异检查通过。
14
+
15
+ 两份原件 41 页仅上述两个块改变类型,全部文字和块框保持不变。第一轮 8 份/118 页与历史 19 份/168 页相对本次冻结基线均零差异;第二轮 6 份/98 页包含在第一轮完整文档中,不累计覆盖量。未更新旧基线。
16
+
17
+ 完整解析、MiddleJson、HTML 和资产包重放通过;两个导出共 34 个资产,无缺失图片或解析诊断。原页与前后标框已审阅,浏览器确认两个 h2。
18
+
19
+ - 两页对比:`output/pdf/flash-title-coverage/final/changes.html`
20
+ - 完整画廊:`output/pdf/flash-title-coverage/final/index.html`
21
+ - 导出:`output/pdf/flash-title-coverage/exports/`
22
+ - 裁决:`tests/fixtures/flash_title_coverage_review_decisions.json`
23
+ - 测试日志:`output/pdf/flash-title-coverage/tests.log`
24
+
25
+ 修改前未提交代码和输出已冻结于 `output/pdf/flash-title-coverage/baseline-code/` 与 `baseline/`,源码指纹与上一轮验收记录核对一致。本轮仍在 `codex/flash-spatial-layout-round3`;未提交、推送或运行远端 CI。
@@ -0,0 +1,161 @@
1
+ """按图旁连续的物理行恢复分离图注与带符号的图例,不依赖图中文字。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import statistics
6
+ import re
7
+
8
+ from .geometry import _bbox_axis_overlap_ratio, _bbox_center_y
9
+ from .text_assembly.common import _merge_internal_text_block_group
10
+ from .text_assembly.continuity import _reassemble_member_lines
11
+ from .visual_annotations import _is_strong_caption_text, _is_strong_footnote_text
12
+
13
+
14
+ def _annotation_em(block):
15
+ """按原始行高确定图注邻接尺度,避免固定页面坐标或像素阈值。"""
16
+ return statistics.median(block.get("_line_heights") or [block["bbox"][3] - block["bbox"][1]])
17
+
18
+
19
+ def recover_image_annotation_bands(blocks, page_size, drawing_lines):
20
+ """只从紧邻图片的显式编号出发,恢复说明带及带重复符号的图例。"""
21
+ removed = set()
22
+ for image in [block for block in blocks if block.get("type") == "image"]:
23
+ bounds = image["bbox"]
24
+ seeds = [
25
+ block
26
+ for block in blocks
27
+ if _is_strong_caption_text(str(block.get("content", "")))
28
+ and block.get("_text_lines")
29
+ and block["bbox"][0] < bounds[2]
30
+ and re.fullmatch(r"\s*(?:fig(?:ure)?\.?|图)\s*(?:\d+[A-Za-z]?|[IVX]+)[.::]?\s*", str(block["content"]), re.I)
31
+ and (
32
+ abs(block["bbox"][3] - bounds[1]) < 1.5 * _annotation_em(block)
33
+ or 0 <= block["bbox"][1] - bounds[3] < 2 * _annotation_em(block)
34
+ )
35
+ ]
36
+ if not seeds:
37
+ continue
38
+ seed = min(seeds, key=lambda b: min(abs(b["bbox"][3] - bounds[1]), abs(b["bbox"][1] - bounds[3])))
39
+ heights = seed.get("_line_heights") or [seed["bbox"][3] - seed["bbox"][1]]
40
+ em = statistics.median(heights)
41
+ leading = seed["bbox"][3] <= bounds[1] + em
42
+ seed["type"] = "caption"
43
+ seed["_annotation_band_parent"] = image
44
+ candidates = [
45
+ b
46
+ for b in blocks
47
+ if b is not image
48
+ and id(b) not in removed
49
+ and b.get("_text_lines")
50
+ and b.get("type") in {"text", "paragraph_title", "caption", "footnote"}
51
+ and b["bbox"][1] >= bounds[3] - 0.25 * em
52
+ and _bbox_axis_overlap_ratio(b["bbox"], bounds, axis="x") >= 0.5
53
+ ]
54
+ candidates.sort(key=lambda b: (b["bbox"][1], b["bbox"][0]))
55
+ if not candidates:
56
+ continue
57
+ first = candidates[0] if leading else seed
58
+ if first["bbox"][1] - bounds[3] > 2 * em:
59
+ continue
60
+ left, right = first["bbox"][0], max(first["bbox"][2], bounds[2])
61
+ if not leading:
62
+ # 碎片化首行的编号很窄,后续实际满行给出图注宽度。
63
+ followers = [b for b in candidates if b["bbox"][1] <= first["bbox"][3] + em]
64
+ right = max([right] + [b["bbox"][2] for b in followers])
65
+ group = []
66
+ bottom = first["bbox"][1]
67
+ for block in candidates:
68
+ b = block["bbox"]
69
+ if b[0] < left - em or b[2] > right + em:
70
+ continue
71
+ if b[1] - bottom > 1.4 * em:
72
+ break
73
+ if leading and b[2] - b[0] < 0.65 * (right - left):
74
+ break
75
+ if block is not seed and _is_strong_caption_text(str(block.get("content", ""))):
76
+ break
77
+ if _is_strong_footnote_text(str(block.get("content", ""))):
78
+ break
79
+ group.append(block)
80
+ bottom = max(bottom, b[3])
81
+ if not group:
82
+ continue
83
+ merged = _merge_internal_text_block_group(group, list(range(len(group))))
84
+ merged["content"] = _reassemble_member_lines(merged["_text_lines"], merged["content"])
85
+ merged["type"] = "caption"
86
+ merged["_annotation_band_parent"] = image
87
+ removed.update(id(b) for b in group)
88
+ blocks.append(merged)
89
+ if not leading:
90
+ continue
91
+ separators = [
92
+ rule.bbox[1]
93
+ for rule in drawing_lines
94
+ if rule.orientation == "horizontal"
95
+ and rule.bbox[1] > bottom
96
+ and rule.bbox[2] - rule.bbox[0] >= 0.8 * (right - left)
97
+ and abs(rule.bbox[0] - left) < 2 * em
98
+ ]
99
+ if not separators:
100
+ continue
101
+ end = min(separators)
102
+ legend = [
103
+ b
104
+ for b in blocks
105
+ if id(b) not in removed
106
+ and b.get("_text_lines")
107
+ and b.get("type") in {"text", "paragraph_title"}
108
+ and bottom <= b["bbox"][1] < end
109
+ and left - em <= b["bbox"][0] < right
110
+ ]
111
+ symbols = [b for b in legend if len(str(b.get("content", "")).strip()) == 1 and str(b["content"]).strip().isalpha()]
112
+ if len(symbols) < 3:
113
+ continue
114
+ # 多栏图例按名称的实际左缘分组,同行的小字母只认领最近的左侧名称。
115
+ physical_rows = []
116
+ for block in sorted(legend, key=lambda b: (_bbox_center_y(b["bbox"]), b["bbox"][0])):
117
+ row = next(
118
+ (
119
+ r
120
+ for r in reversed(physical_rows)
121
+ if abs(_bbox_center_y(r[0]["bbox"]) - _bbox_center_y(block["bbox"])) < 0.65 * em
122
+ ),
123
+ None,
124
+ )
125
+ if row is None:
126
+ physical_rows.append([block])
127
+ else:
128
+ row.append(block)
129
+ rows = []
130
+ for physical in physical_rows:
131
+ group = []
132
+ for block in sorted(physical, key=lambda b: b["bbox"][0]):
133
+ if group and block["bbox"][0] - group[-1]["bbox"][2] > 3 * em:
134
+ rows.append(group)
135
+ group = []
136
+ group.append(block)
137
+ if group:
138
+ rows.append(group)
139
+ heading_tops = [b["bbox"][1] for b in legend if b.get("type") == "paragraph_title"]
140
+ starts = sorted(row[0]["bbox"][0] for row in rows if len(str(row[0].get("content", ""))) > 2)
141
+ columns = []
142
+ for start in starts:
143
+ if columns and start - statistics.median(columns[-1]) <= 1.5 * em:
144
+ columns[-1].append(start)
145
+ else:
146
+ columns.append([start])
147
+ stable_lefts = [statistics.median(column) for column in columns if len(column) >= 3]
148
+ for row in rows:
149
+ note = _merge_internal_text_block_group(row, list(range(len(row))), preserve_visual_spaces=True)
150
+ note["type"] = "footnote"
151
+ note["_annotation_band_parent"] = image
152
+ if len(stable_lefts) >= 2 and note["bbox"][2] - note["bbox"][0] < 0.65 * (right - left):
153
+ # 分类标题开启新分组;组内各栏自上而下,避免右栏子类标题插入左栏药名中。
154
+ section = max([bottom] + [top for top in heading_tops if top <= note["bbox"][1] + 0.25 * em])
155
+ lane = min(stable_lefts, key=lambda start: abs(start - note["bbox"][0]))
156
+ if any(block.get("type") == "paragraph_title" for block in row):
157
+ lane = left - em
158
+ note["_legend_sort_band"] = (section, lane)
159
+ blocks.append(note)
160
+ removed.update(id(b) for b in row)
161
+ blocks[:] = [block for block in blocks if id(block) not in removed]
@@ -40,6 +40,7 @@ from .line_merging import _join_formula_visual_row, _merge_overlapping_inline_cl
40
40
  from .models import _AxisLine, _FormulaAnchor, _LineItem, _PageSource, _TextLane
41
41
  from .native_text import _sanitize_pdf_control_text
42
42
  from .text_roles import has_prose, prose_residue, publication_text
43
+ from .layout_evidence import build_layout_evidence
43
44
 
44
45
  _FORMULA_NUMBER_SUFFIX_RE = re.compile(r"^(?P<prefix>.*?)(?P<marker>[((﹙][^()()﹙﹚\r\n]+[))﹚])\s*$")
45
46
  _FORMULA_NUMBER_MARKER_RE = re.compile(
@@ -844,7 +845,7 @@ def _build_formula_like_blocks(
844
845
  and _bbox_axis_overlap_ratio(bbox, line.ink_bbox or line.bbox, axis="y") >= 0.25
845
846
  and max(0.0, bbox[0] - line.bbox[2], line.bbox[0] - bbox[2]) <= 3 * _line_effective_height(line, line.bbox)
846
847
  ]
847
- if member_ids and hosts and "\\tag{" not in block["content"]:
848
+ if member_ids and hosts and "\\tag{" not in block["content"] and not block.get("_spatial_display_band"):
848
849
  claimed_source_indices.difference_update(member_ids)
849
850
  for line in lines:
850
851
  if line.source_index in member_ids:
@@ -882,6 +883,32 @@ def _build_formula_like_blocks(
882
883
  block["_tight_output_bbox"] = _bbox_union(core, ink)
883
884
  block["content"] += "\n" + text
884
885
  claimed_source_indices.add(line.source_index)
886
+ bands, _ = _build_spatial_numbered_bands(lines, table_bboxes, page_size, drawing_lines or [])
887
+ recovered_band_ids = set()
888
+ for band in bands:
889
+ bbox = band.get("_tight_output_bbox", band["bbox"])
890
+ overlaps = [
891
+ block for block in blocks if _bbox_overlap_in_smaller(bbox, block.get("_tight_output_bbox", block["bbox"])) >= 0.5
892
+ ]
893
+ if any(
894
+ all(old[i] <= bbox[i] + 1 if i < 2 else old[i] >= bbox[i] - 1 for i in range(4))
895
+ for old in [block.get("_tight_output_bbox", block["bbox"]) for block in overlaps]
896
+ ):
897
+ continue
898
+ # 只补齐缺失成员,既有完整公式的内容、裁图和顺序保持原结果。
899
+ ids = set(band["_formula_members"]).union(*(block.get("_formula_members", []) for block in overlaps))
900
+ members = [(line, line.ink_bbox or line.bbox) for line in lines if line.source_index in ids]
901
+ if not members:
902
+ continue
903
+ merged = _formula_members_to_block(
904
+ members, page_size, 0, anchor_source_index=band["_formula_members"][-1], include_member_ids=True
905
+ )
906
+ if merged:
907
+ blocks = [block for block in blocks if not any(block is old for old in overlaps)]
908
+ blocks.append(merged)
909
+ claimed_source_indices.update(ids)
910
+ recovered_band_ids.update(ids)
911
+ for block in blocks:
885
912
  block.pop("_formula_members", None)
886
913
  remaining_lines = [
887
914
  line
@@ -889,7 +916,142 @@ def _build_formula_like_blocks(
889
916
  if line.source_index not in claimed_source_indices
890
917
  and (not line.formula_candidate_only or line.paragraph_formula_context)
891
918
  ]
892
- return blocks, remaining_lines + paragraph_lines
919
+ return blocks, remaining_lines + [line for line in paragraph_lines if line.source_index not in recovered_band_ids]
920
+
921
+
922
+ def _build_spatial_numbered_bands(lines, table_bboxes, page_size, rules):
923
+ """在成员被拆散认领前,用正文栏右缘的短编号与独立数学带恢复完整公式。"""
924
+ prose = [line for line in lines if line.angle == 0 and len(line.text) >= 25 and _has_sentence_words(line.text)]
925
+ layout = build_layout_evidence(prose, page_size, barriers=table_bboxes)
926
+ blocks, claimed = [], set()
927
+ for lane in layout.lanes:
928
+ em = statistics.median(_line_effective_height(line, bounds) for line, bounds in lane.lines)
929
+
930
+ def is_body(line):
931
+ """短数学簇的拉丁变量不等同于正文词行,实际正文宽度及词组提供屏障。"""
932
+ return _has_sentence_words(line.text) and (
933
+ line.bbox[2] - line.bbox[0] >= 0.6 * (lane.right - lane.left)
934
+ or len(re.findall(r"\b[A-Za-z]{3,}\b", line.text)) >= 3
935
+ or len(re.findall(r"[\u3400-\u9fff]", line.text)) >= 3
936
+ or re.search(r"\b(?:where|with|when|which|the|this|these|is|are|from|that|then)\b", line.text, re.I)
937
+ )
938
+
939
+ local = [
940
+ line
941
+ for line in lines
942
+ if line.angle == 0
943
+ and line.paragraph_group is None
944
+ and line.semantic_type is None
945
+ and lane.left - em <= line.bbox[0]
946
+ and line.bbox[2] <= lane.right + em
947
+ ]
948
+ markers = [
949
+ line
950
+ for line in local
951
+ if 2 <= len(line.text.strip()) <= 8
952
+ and not re.search(r"\s", line.text.strip())
953
+ and re.search(r"\d", line.text)
954
+ and not line.text.strip()[0].isdigit()
955
+ and not line.text.strip()[-1].isdigit()
956
+ and (
957
+ _standalone_formula_number_marker(line.text) is not None
958
+ or re.fullmatch(r"[^A-Za-z0-9][A-Za-z]?[.]?\d+(?:[.\-]\d+)*[^A-Za-z0-9]", line.text.strip())
959
+ )
960
+ and abs(line.bbox[2] - lane.right) < 1.5 * em
961
+ and line.bbox[2] - line.bbox[0] <= 4 * em
962
+ ]
963
+ for marker in markers:
964
+ if marker.source_index in claimed:
965
+ continue
966
+ mb = marker.ink_bbox or marker.bbox
967
+ nearby = [
968
+ line
969
+ for line in local
970
+ if line is not marker
971
+ and line.source_index not in claimed
972
+ and line not in markers
973
+ and not is_body(line)
974
+ and (line.ink_bbox or line.bbox)[3] >= mb[1] - 4.5 * em
975
+ and (line.ink_bbox or line.bbox)[1] <= mb[3] + 1.1 * em
976
+ ]
977
+ if not nearby:
978
+ continue
979
+ # 先形成二维数学主体,再关联隔着水平空白或位于右下角的编号。
980
+ pending = set(range(len(nearby)))
981
+ components = []
982
+ while pending:
983
+ seed = pending.pop()
984
+ component, frontier = [seed], [seed]
985
+ while frontier:
986
+ current = nearby[frontier.pop()]
987
+ bounds = current.ink_bbox or current.bbox
988
+ connected = []
989
+ for index in pending:
990
+ other = nearby[index].ink_bbox or nearby[index].bbox
991
+ xgap = max(0.0, bounds[0] - other[2], other[0] - bounds[2])
992
+ ygap = max(0.0, bounds[1] - other[3], other[1] - bounds[3])
993
+ if (
994
+ ygap <= 0.8 * em
995
+ and _bbox_axis_overlap_ratio(bounds, other, axis="x") > 0.1
996
+ or xgap <= 3 * em
997
+ and _bbox_axis_overlap_ratio(bounds, other, axis="y") > 0.15
998
+ ):
999
+ connected.append(index)
1000
+ pending.difference_update(connected)
1001
+ frontier.extend(connected)
1002
+ component.extend(connected)
1003
+ components.append([nearby[index] for index in component])
1004
+ candidates = []
1005
+ for members in components:
1006
+ bounds = _bbox_union_many([line.ink_bbox or line.bbox for line in members])
1007
+ if (bounds[2] >= mb[0] + em and bounds[3] > mb[1]) or bounds[2] - bounds[0] < 3 * em:
1008
+ continue
1009
+ gap = max(0.0, mb[1] - bounds[3], bounds[1] - mb[3])
1010
+ if gap > 2 * em or bounds[3] - bounds[1] > 6 * em:
1011
+ continue
1012
+ if any(_bbox_intersects(bounds, table) for table in table_bboxes):
1013
+ continue
1014
+ if any(
1015
+ _bbox_axis_overlap_ratio(bounds, line.ink_bbox or line.bbox, axis="y") > 0.1
1016
+ for line in local
1017
+ if is_body(line)
1018
+ ):
1019
+ continue
1020
+ math = any(_formula_line_has_math_operator(line.text) for line in members)
1021
+ fraction = any(
1022
+ rule.orientation == "horizontal"
1023
+ and bounds[0] <= rule.bbox[0] < rule.bbox[2] <= bounds[2]
1024
+ and bounds[1] < rule.bbox[1] < bounds[3]
1025
+ for rule in rules
1026
+ )
1027
+ if (
1028
+ not math
1029
+ and not fraction
1030
+ and not (
1031
+ (len(members) >= 3 or any(line.compact_formula_cluster for line in members))
1032
+ and bounds[3] - bounds[1] >= 1.3 * em
1033
+ )
1034
+ ):
1035
+ continue
1036
+ candidates.append((gap, members))
1037
+ if not candidates:
1038
+ continue
1039
+ candidates.sort(key=lambda item: item[0])
1040
+ if len(candidates) > 1 and abs(candidates[0][0] - candidates[1][0]) < 0.25 * em:
1041
+ continue
1042
+ members = candidates[0][1] + [marker]
1043
+ block = _formula_members_to_block(
1044
+ [(line, line.ink_bbox or line.bbox) for line in members],
1045
+ page_size,
1046
+ 0,
1047
+ anchor_source_index=marker.source_index,
1048
+ include_member_ids=True,
1049
+ )
1050
+ if block:
1051
+ block["_spatial_display_band"] = True
1052
+ blocks.append(block)
1053
+ claimed.update(line.source_index for line in members)
1054
+ return blocks, claimed
893
1055
 
894
1056
 
895
1057
  def _recover_detached_display_components(
@@ -87,7 +87,8 @@ def _should_connect_semantic_rows(
87
87
  vertical_gap = _effective_text_row_gap(previous, current)
88
88
  if not -0.25 * pair_height <= vertical_gap <= max(1.25 * pair_height, regular_gap + 0.75 * pair_height):
89
89
  return False
90
- if previous_line.semantic_type == "paragraph_title" and vertical_gap > 0.5 * pair_height:
90
+ shared_title_band = previous_line.title_band_id is not None and previous_line.title_band_id == current_line.title_band_id
91
+ if previous_line.semantic_type == "paragraph_title" and vertical_gap > 0.5 * pair_height and not shared_title_band:
91
92
  return False
92
93
  font_conflicts = (
93
94
  previous_line.font_signature is not None
@@ -431,6 +431,7 @@ def _merge_post_semantic_text_runs(
431
431
  if len(lines) < 2:
432
432
  return list(lines)
433
433
  local_bboxes = [_rotate_bbox_to_upright(line.bbox, page_size, line.angle) for line in lines]
434
+ layout = build_layout_evidence(lines, page_size, barriers=table_bboxes)
434
435
  parents = list(range(len(lines)))
435
436
 
436
437
  def find(index: int) -> int:
@@ -470,11 +471,53 @@ def _merge_post_semantic_text_runs(
470
471
  continue
471
472
  second_bbox = local_bboxes[second_index]
472
473
  second_height = _line_effective_height(second_line, second_bbox)
473
- if _post_semantic_same_baseline_geometry(
474
- first_bbox,
475
- first_height,
476
- second_bbox,
477
- second_height,
474
+ left, right = sorted((first_bbox, second_bbox), key=lambda bbox: bbox[0])
475
+ pair_height = min(first_height, second_height)
476
+ shared_physical_row = (
477
+ first_line.visual_row_id is not None
478
+ and first_line.visual_row_id == second_line.visual_row_id
479
+ # 宽空格放宽只服务连续文字,数值列与标签列不能据此跨单元格连接。
480
+ and all(
481
+ any(char.isalpha() for char in member.text)
482
+ for member in lines
483
+ if member.angle == first_line.angle and member.visual_row_id == first_line.visual_row_id
484
+ )
485
+ )
486
+ row_bounds = (
487
+ _bbox_union_many(
488
+ [
489
+ local_bboxes[index]
490
+ for index, member in enumerate(lines)
491
+ if member.angle == first_line.angle and member.visual_row_id == first_line.visual_row_id
492
+ ]
493
+ )
494
+ if shared_physical_row
495
+ else _bbox_union_many([first_bbox, second_bbox])
496
+ )
497
+ justified_row = (
498
+ first_line.font_signature == second_line.font_signature
499
+ and first_line.paragraph_group == second_line.paragraph_group
500
+ and first_line.angle == 0
501
+ and abs(_bbox_center_y(first_bbox) - _bbox_center_y(second_bbox)) < 0.2 * pair_height
502
+ and 0 <= right[0] - left[2] <= (3 if shared_physical_row else 2) * pair_height
503
+ and not layout.separated(first_bbox, second_bbox)
504
+ and any(
505
+ other is not first_line
506
+ and other is not second_line
507
+ and 0 < other.bbox[1] - max(first_bbox[3], second_bbox[3]) <= pair_height
508
+ and abs(other.bbox[0] - row_bounds[0]) < (1.5 if shared_physical_row else 1) * pair_height
509
+ and other.bbox[2] >= row_bounds[2] - pair_height
510
+ for other in lines
511
+ )
512
+ )
513
+ if (
514
+ _post_semantic_same_baseline_geometry(
515
+ first_bbox,
516
+ first_height,
517
+ second_bbox,
518
+ second_height,
519
+ )
520
+ or justified_row
478
521
  ):
479
522
  union(first_index, second_index)
480
523
 
@@ -52,6 +52,8 @@ class _LineItem:
52
52
  inline_math_regions: list[BBox] = field(default_factory=list)
53
53
  paragraph_group: int | None = None
54
54
  paragraph_terminal: bool = False
55
+ reference_start: bool | None = None
56
+ title_band_id: int | None = None
55
57
  caption_start: bool = False
56
58
 
57
59
  def __post_init__(self) -> None:
@@ -193,6 +195,7 @@ class _PreparedPage:
193
195
  canonical_formula_source_lines: list[_LineItem] = field(default_factory=list)
194
196
  page_footnote_groups: list[set[int]] = field(default_factory=list)
195
197
  reference_regions: list[BBox] = field(default_factory=list)
198
+ numbered_references: bool = False
196
199
  script_lines: list[PDFTextScriptLine] = field(default_factory=list)
197
200
  formula_candidate_lines: list[_LineItem] = field(default_factory=list)
198
201
  formula_ink_bboxes: list[BBox] = field(default_factory=list)