docvortex 0.4.24__tar.gz → 0.4.25__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.
- {docvortex-0.4.24/src/docvortex.egg-info → docvortex-0.4.25}/PKG-INFO +1 -1
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/docx_converter.py +20 -13
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/tables.py +104 -43
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/version.py +1 -1
- {docvortex-0.4.24 → docvortex-0.4.25/src/docvortex.egg-info}/PKG-INFO +1 -1
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex.egg-info/SOURCES.txt +1 -0
- docvortex-0.4.25/tests/unittest/test_docx_table_context.py +314 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/LICENSE.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/MANIFEST.in +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/README.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/README.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/demo.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ebook/epub_01.epub +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ebook/epub_02.epub +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/README.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/docx_01.doc +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/docx_01.docx +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/pptx_01.ppt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/pptx_01.pptx +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/rtf_01.rtf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/xlsx_01.xls +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ms_office_docs/xlsx_01.xlsx +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/ofd/ofd_01.ofd +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/open_office_docs/docx_01.odt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/open_office_docs/pptx_01.odp +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/open_office_docs/xlsx_01.ods +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/2407.00079v4_origi-10.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/IEBM_A_2667169_O-5.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/caibao1.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/demo1.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/demo2.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/demo3.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/demo4.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/demo6.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/mixed_elements_pages_03_06.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/mixed_elements_pages_07_10.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/mixed_elements_pages_11_15.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/mixed_elements_pages_39_40.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs/small_ocr.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/207.pdf" +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/2072.pdf" +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/2073.pdf" +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/pdfs//344/270/255/346/226/207/350/256/272/346/226/2074.pdf" +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/web_docs/html_01.html +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/demo/web_docs/mhtml_01.mhtml +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/HTML_PROTOCOL.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/JSON_PROTOCOL.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/METADATA.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/PDF_FONTS.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/RENDER_OWNERSHIP.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/USAGE.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/flash-manual-annotations-2026-09-15.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/flash-round2-annotations-2026-09-15.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/flash-rule-generalization-2026-09-15.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/flash-spatial-layout-followup-2026-09-16.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/flash-spatial-layout-round3-2026-09-16.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/flash-title-coverage-2026-09-16.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/docs/sdk-0.4.md +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/pyproject.toml +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/schemas/middle-2.0.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/schemas/model-2.0.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/setup.cfg +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/hyperlink.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/image.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/markup/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/markup/anchors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/markup/formula.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/markup/projector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/markup/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/mathml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/names.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/_shared/xycut.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/csv.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/constants.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/errors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/package.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/properties.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/epub/xhtml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/anchors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/constants.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/document.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/errors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/html/selector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/mhtml/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/mhtml/converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/mhtml/resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/assembly.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/constants.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/errors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/images.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/package.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/path.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/reading_order.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/scene.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/ofd/vector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/bookmarks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/doc_converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/fib.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/fields.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/formatting.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/images.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/lists.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/parser.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/pieces.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/records.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/sprm.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/doc/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/context.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/equationxml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/fields.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/formatting_types.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/main.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/numbering.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/office_xml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/package_normalizer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/image.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/latex_dict.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/mtef.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/mtef_v5.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/omml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/equation/ooxml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/errors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/image.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/legacy/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/legacy/binary.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/legacy/officeart.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/legacy/ole.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/limits.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/chart.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/constants.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/converters.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/errors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/package.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/odf/text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ooxml_chart.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/opc.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ppt/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ppt/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ppt/parser.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ppt/ppt_converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ppt/records.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/ppt/style_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/context.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/lists.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/main.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/package_normalizer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/pptx_converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/shapes.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/text_styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/pptx/titles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rich_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/lexer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/math.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/rtf/parser.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/spreadsheet/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/spreadsheet/html.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/spreadsheet/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/spreadsheet/projector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/spreadsheet/region_discovery.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/streams.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/chart.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/embedded_chart.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/number_format.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/parser.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/records.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/strings.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xls/xls_converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xlsx/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xlsx/main.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xlsx/ooxml_ole.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xlsx/package_normalizer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/xlsx/xlsx_converter.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_script_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/candidate.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/engine.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/rule_band.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/sparse_common.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/sparse_hybrid.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/sparse_multiline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/text_grid.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/_table_recovery/vector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/annotation_bands.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/auxiliary_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/char_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/code_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/formulas.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/graphics.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/index_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/common.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/detection.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/matching.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/materialize.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/scripts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/inline/types.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/layout_evidence.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/line_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/line_merging.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/native_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/spatial_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_constants.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_detection.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_filled_grid.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_materialization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_rows.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_rules.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/table_text_styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/tables.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/assembly.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/common.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/continuity.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/footnotes.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/merging.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_assembly/rows.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/text_roles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/body_profile.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/common.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/compact_titles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/document_profile.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/lane_titles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/page_titles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/prototype.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/title_analysis/structural.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/titles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/typography.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/pdf/visual_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/pdf.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/assets/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/assets/images.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/assets/store.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/cli.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/html/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/html/contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/html/materializer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/html/parser.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/html/resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/codecs/json.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/inline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/links.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/markup/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/markup/anchors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/markup/formula.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/markup/projector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/markup/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/mathml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/normalization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/spans.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/content.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/document.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/html.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/rules.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/table/structure.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/content/tree.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/detection.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/filetypes.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/mhtml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/page_range.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/_document.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/classify.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/constants.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/font_runtime.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/images.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/native_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/native_contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/native_coordinates.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/native_lifecycle.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/native_objects.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/native_text_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/pdfium.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/raster.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/text/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/text/_contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/text/dedup.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/text/extract.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/text/geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/text/groups.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/pdf/visuals.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/properties.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/document/source.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/errors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/export/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/export/_images.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/export/bundle.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/export/files.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/export/middle.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_coordinates.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_hyperlink.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_image.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_image_operations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_image_payload.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_svg_raster.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/image_encoding.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/language.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/magika.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/type_identity.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/foundation/xml_names.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/options.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/content.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/document.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/lists.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/page_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/pages.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/paragraphs.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/postprocess/visual.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/public_api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/common/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/common/context.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/common/html_table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/common/index.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/common/list_items.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/common/planner.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/assets.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/inline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/math.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/docx/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/epub/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/epub/assets.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/epub/package.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/epub/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/html/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/html/inline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/html/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/html/sanitizer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/html/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/latex/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/latex/assets.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/latex/inline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/latex/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/latex/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/assets.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/escaping.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/inline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/markdown/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/assets.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/diagnostics.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/font_plan.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/formula.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/formula_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/inline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/original.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/pagination.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/paragraph.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/table_content.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/table_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/pdf/title_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/structured_content/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/_internal/structured_content/renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/contracts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/docx.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/epub.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/fragments.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/html.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/latex.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/markdown.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/pdf.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/render/structured_content.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/epub/docvortex.css +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/fonts/DroidSansFallbackFull.ttf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/fonts/NOTICE +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/fonts/manifest.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/html/docvortex.css +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/html/docvortex.min.css +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/resources/unicode/EquivalentUnifiedIdeograph-17.0.0.txt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/result.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/schema.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/visualization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex.egg-info/dependency_links.txt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex.egg-info/entry_points.txt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex.egg-info/requires.txt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex.egg-info/top_level.txt +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/benchmarks/flash_pdf.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/benchmarks/native_pdf_table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/benchmarks/pdf_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/benchmarks/pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/evaluate_native_pdf_table_manifest.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_layout_block_expectations.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_layout_geometry_manifest.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_layout_semantic_expectations.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_manual_annotations.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_manual_review_decisions.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_reviewed_history.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_round2_annotations.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_round2_review_decisions.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_round3_annotations.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_round3_followup_review_decisions.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_round3_review_decisions.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_rule_generalization_review_decisions.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/flash_title_coverage_review_decisions.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/generate_synthetic_pdf_fixtures.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/native_pdf_table_cross_page_manifest.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/native_pdf_table_demo_manifest.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/native_pdf_table_script_truth.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/pdf_char_dedup.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/pdf_mixed_font_script_line.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/pdf_numeric_citations_review.json +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/fixtures/rtf/semantic.rtf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_architecture.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_benchmark_entrypoint.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_brand_protocol.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_cli_logging.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_complete_pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_converter_lifecycle.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_document_envelope.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_document_metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_export_image_names.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_format_matrix.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_geometry_api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_history_geometry_tools.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_html_namespace.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_magika_runtime.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_mixed_font_script_reference.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_analysis_api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_cpu_evidence.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_font_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_font_runtime.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_model_text_normalization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_numeric_citations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_output_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_render_pool.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_source_row_merging.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_pdf_symbol_normalization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_public_export_api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_public_image_api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_public_pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_refactor_raster.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_refactor_rendering.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_refactor_resources.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_release_ci_gate.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_render_ownership.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_renderer_branding.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_shared_boundaries.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_system_font_pdf_pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/test_validated_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_docx_equationxml_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_epub_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_flash_pdf_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_image_mtef_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_legacy_doc_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_legacy_ppt_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_legacy_xls_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_metafile_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_mhtml_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_mtef_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_mtef_v5_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_native_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_odf_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_ofd_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_office_image_mtef_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_ooxml_mtef_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/_span_test_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/connexin.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/fornax.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/frames_v1.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/frames_v2.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/k2_treap.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/mmlu_redux.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/nash_review.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/annotated/nougat.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/bloom_form_labels.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/journal_dual_caption.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/journal_layout_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/math_display_formulas.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/mixed_text_layout_sample.pdf.xor +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_layout/quantum_appendix_layout.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/flash_table_annotations_synthetic.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/metabolic_pathway_page_3.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_cjk_layout_synthetic.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/annual_report_fundraising_projects_table.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/annual_report_management_roles_table.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/annual_report_research_projects_table.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/conference_schedule_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/engineering_process_restrictions_table.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/fund_asset_and_transaction_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/fund_manager_profile_table.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/manufacturing_facilities_cross_page_table.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/pollutant_discharge_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/procurement_contract_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/procurement_document_blank_page_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/native_pdf_tables/quarterly_report_financial_tables.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/numeric_citations_introduction.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/pdfs/test.pdf +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_backend_architecture.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_backend_block_object_regressions.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_docx_assets.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_docx_complex_fields.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_docx_math.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_docx_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_docx_special_char_tables.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_docx_table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_emfplus_integration.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_epub_backlinks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_epub_quoted_note_types.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_epub_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_bbox_grid_comparison.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_csv.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_docx_equationxml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_epub.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_html.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_image_mtef.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_legacy_chart_data.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_legacy_doc.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_legacy_doc_mtef.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_legacy_ppt.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_legacy_xls.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_legacy_xls_ppt_mtef.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_manual_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_markup_anchors.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_mhtml.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_model.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_mtef_v5.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_odf.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_ofd.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_office_image_mtef.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_office_metafile.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_office_models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_office_mtef_v5.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_office_package_normalizers.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_office_title_types.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_ooxml_mtef.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_auxiliary_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_char_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_code_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_document_profile.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_equation_images.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_extractor.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_formulas.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_graphics.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_index_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_layout_repairs.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_line_metadata.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_native_text.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_reviewed_history.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_samples.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_scripts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_semantics.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_short_tails.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_tables.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_text_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_text_visibility.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_titles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_pdf_visual_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_round2_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_round3_annotations.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_rtf.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_rule_generalization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_shared_helpers.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_spatial_evidence.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_flash_spreadsheet_projector.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_guess_suffix_ole2.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_html_css_build.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_html_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_html_security.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_hybrid_script_source_pdfs.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_latex_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_markdown_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_middle_json_block_models.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_middle_json_export.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_middle_json_validator.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_model_json.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_native_pdf_table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_native_pdf_table_demo_manifest.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_native_pdf_table_manifest.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_native_pdf_table_pipeline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_native_pdf_table_scripts.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_native_table_performance_equivalence.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_ofd_assembly.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_ofd_vector_tables.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_office_demo_exports.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_office_demo_pages.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_office_parser_regressions.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_cjk_objects.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_cjk_style.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_cjk_wrapping.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_classify.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_demo_links.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_diagnostic_levels.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_document.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_formula_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_object_clipping.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_original_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_pagination.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_paragraph_cache.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_render_diagnostics.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_structured_tables.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_table_cache.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_table_round2.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_text_dedup.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_text_styles.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_title_font_plan.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_title_space.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_pdf_visualization.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_postprocess_page_blocks.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_postprocess_pages.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_postprocess_paragraphs.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_postprocess_visual.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_render_api.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_render_html_table.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_render_image_renderer.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_render_list_index_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_structured_content_render.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_svg_raster.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_table_merge.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_table_merge_cell_merge.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_text_block_anchor.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_text_boundary_rules.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tests/unittest/test_text_utils.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/__init__.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/build_html_css.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/calibrate_pdf_geometry.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/capture_baseline.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/capture_platform_layout.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/compare_font_platforms.py +0 -0
- {docvortex-0.4.24 → docvortex-0.4.25}/tools/font_geometry.py +0 -0
{docvortex-0.4.24 → docvortex-0.4.25}/src/docvortex/analyzers/native/office/docx/docx_converter.py
RENAMED
|
@@ -48,6 +48,8 @@ class DocxConverter(_DocxConstants, _DocxResources, _DocxStyles, _DocxNumbering,
|
|
|
48
48
|
|
|
49
49
|
def _reset_document_state(self) -> None:
|
|
50
50
|
"""每次转换重新创建可变状态及解码器,避免失败或复用实例残留旧文档。"""
|
|
51
|
+
self._close_mammoth_fallback_context()
|
|
52
|
+
self._fallback_docx_bytes: Optional[bytes] = None # 仅转换期间保留规范化后的原包
|
|
51
53
|
self.docx_obj = None
|
|
52
54
|
self.pages = []
|
|
53
55
|
self.cur_page = []
|
|
@@ -149,19 +151,24 @@ class DocxConverter(_DocxConstants, _DocxResources, _DocxStyles, _DocxNumbering,
|
|
|
149
151
|
self._reset_document_state()
|
|
150
152
|
# 读取文件字节,以便 mammoth 和 python-docx 各自使用独立读取流
|
|
151
153
|
file_bytes = self._sanitize_missing_internal_relationships(file_stream.read())
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
self.toc_anchor_set
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
154
|
+
self._fallback_docx_bytes = file_bytes
|
|
155
|
+
try:
|
|
156
|
+
# 使用完整 DOCX 上下文预解析顶层表格,避免转换非表格正文带来的资源浪费
|
|
157
|
+
self._mammoth_tables_html = self._preparse_tables_with_mammoth(file_bytes)
|
|
158
|
+
self._mammoth_table_idx = 0
|
|
159
|
+
self.docx_obj = Document(BytesIO(file_bytes))
|
|
160
|
+
self.toc_anchor_set = self._collect_toc_anchor_set()
|
|
161
|
+
self.toc_anchor_aliases = self._collect_toc_anchor_aliases(
|
|
162
|
+
self.toc_anchor_set,
|
|
163
|
+
)
|
|
164
|
+
# 预扫描文档,识别用作章节标题的列表numId
|
|
165
|
+
self.heading_list_numids = self._detect_heading_list_numids()
|
|
166
|
+
self.pages.append(self.cur_page)
|
|
167
|
+
self._walk_linear(self.docx_obj.element.body)
|
|
168
|
+
self._add_header_footer(self.docx_obj)
|
|
169
|
+
finally:
|
|
170
|
+
self._close_mammoth_fallback_context()
|
|
171
|
+
self._fallback_docx_bytes = None
|
|
165
172
|
|
|
166
173
|
def _close_active_list(self) -> None:
|
|
167
174
|
"""关闭当前活跃列表块,但保留 Word numId 的连续编号计数。"""
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"""DOCX 表格处理;共享当前 Converter 的单文档状态。"""
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
+
from contextlib import ExitStack
|
|
4
5
|
from io import BytesIO
|
|
5
6
|
from typing import Any, Optional
|
|
6
7
|
from docx import Document
|
|
7
8
|
from docx.oxml.xmlchemy import BaseOxmlElement
|
|
8
9
|
from loguru import logger
|
|
10
|
+
from mammoth import docx as mammoth_docx
|
|
11
|
+
from mammoth import read_embedded_style_map
|
|
9
12
|
from mammoth.conversion import convert_document_element_to_html
|
|
10
|
-
from mammoth.
|
|
13
|
+
from mammoth.options import read_options
|
|
14
|
+
from mammoth.zips import open_zip
|
|
11
15
|
from .office_xml import read_str
|
|
12
16
|
from .....schema import BlockType
|
|
13
17
|
|
|
@@ -43,7 +47,7 @@ class _DocxTables:
|
|
|
43
47
|
|
|
44
48
|
Returns:
|
|
45
49
|
list[str | None]: 与正文顶层表格对齐的 HTML 列表;None 表示该表格
|
|
46
|
-
未找到可靠 Mammoth
|
|
50
|
+
未找到可靠 Mammoth 结果,后续走完整文档上下文回退解析
|
|
47
51
|
"""
|
|
48
52
|
try:
|
|
49
53
|
import mammoth as _mammoth
|
|
@@ -206,10 +210,41 @@ class _DocxTables:
|
|
|
206
210
|
if vmerge.get(f"{{{w_ns}}}val") in (None, "continue"):
|
|
207
211
|
continuation_nodes.update(cell.iter())
|
|
208
212
|
|
|
213
|
+
ignored_nodes = set(continuation_nodes)
|
|
214
|
+
mc_ns = "http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
215
|
+
for alternate in xml_table.iter(f"{{{mc_ns}}}AlternateContent"):
|
|
216
|
+
# Mammoth 的 Office XML 读取器仅展开 Fallback 分支。
|
|
217
|
+
for branch in alternate:
|
|
218
|
+
if branch.tag != f"{{{mc_ns}}}Fallback":
|
|
219
|
+
ignored_nodes.update(branch.iter())
|
|
220
|
+
for simple_field in xml_table.iter(f"{{{w_ns}}}fldSimple"):
|
|
221
|
+
# Mammoth 不解析简单域,其内部的缓存文字也不参与匹配。
|
|
222
|
+
ignored_nodes.update(simple_field.iter())
|
|
223
|
+
|
|
224
|
+
wordml_ns = "http://schemas.microsoft.com/office/word/2010/wordml"
|
|
225
|
+
for content_control in xml_table.iter(f"{{{w_ns}}}sdt"):
|
|
226
|
+
properties = content_control.find(f"{{{w_ns}}}sdtPr")
|
|
227
|
+
if properties is None or properties.find(f"{{{wordml_ns}}}checkbox") is None:
|
|
228
|
+
continue
|
|
229
|
+
content = content_control.find(f"{{{w_ns}}}sdtContent")
|
|
230
|
+
if content is None:
|
|
231
|
+
continue
|
|
232
|
+
# Mammoth 以复选框替换内容控件里的首个非空 Text 节点。
|
|
233
|
+
first_text = next(
|
|
234
|
+
(
|
|
235
|
+
node
|
|
236
|
+
for node in content.iter()
|
|
237
|
+
if node not in ignored_nodes and node.tag in char_tags and _DocxTables._xml_table_char_fragment(node)
|
|
238
|
+
),
|
|
239
|
+
None,
|
|
240
|
+
)
|
|
241
|
+
if first_text is not None:
|
|
242
|
+
ignored_nodes.add(first_text)
|
|
243
|
+
|
|
209
244
|
text = "".join(
|
|
210
245
|
_DocxTables._xml_table_char_fragment(node)
|
|
211
246
|
for node in xml_table.iter()
|
|
212
|
-
if node not in
|
|
247
|
+
if node not in ignored_nodes and node.tag in char_tags
|
|
213
248
|
)
|
|
214
249
|
return {
|
|
215
250
|
"row_count": len(xml_table.xpath('.//*[local-name()="tr"]')),
|
|
@@ -221,11 +256,20 @@ class _DocxTables:
|
|
|
221
256
|
@staticmethod
|
|
222
257
|
def _html_table_signature(html_table) -> dict:
|
|
223
258
|
"""提取 HTML 表格的轻量签名,用于过滤 Mammoth 额外生成的表格。"""
|
|
259
|
+
text_fragments = []
|
|
260
|
+
for fragment in html_table.strings:
|
|
261
|
+
anchor = fragment.find_parent("a")
|
|
262
|
+
if anchor is not None and anchor.parent.name == "sup":
|
|
263
|
+
marker = re.fullmatch(r"(footnote|endnote)-ref-(\d+)", anchor.get("id", ""))
|
|
264
|
+
if marker and anchor.get("href") == f"#{marker.group(1)}-{marker.group(2)}":
|
|
265
|
+
# 只忽略 Mammoth 生成的脚注引用,保留正文中的普通 [1]。
|
|
266
|
+
continue
|
|
267
|
+
text_fragments.append(fragment.strip())
|
|
224
268
|
return {
|
|
225
269
|
"row_count": len(html_table.find_all("tr")),
|
|
226
270
|
"cell_count": len(html_table.find_all(["td", "th"])),
|
|
227
271
|
"image_count": len(html_table.find_all("img")),
|
|
228
|
-
"text": _DocxTables._normalize_table_match_text(
|
|
272
|
+
"text": _DocxTables._normalize_table_match_text("".join(text_fragments)),
|
|
229
273
|
}
|
|
230
274
|
|
|
231
275
|
@staticmethod
|
|
@@ -396,47 +440,64 @@ class _DocxTables:
|
|
|
396
440
|
return None
|
|
397
441
|
return f"<p>{''.join(items)}</p>"
|
|
398
442
|
|
|
399
|
-
def
|
|
400
|
-
"""
|
|
401
|
-
|
|
443
|
+
def _close_mammoth_fallback_context(self) -> None:
|
|
444
|
+
"""关闭当前文档回退解析持有的 ZIP 资源,并清除其缓存。"""
|
|
445
|
+
context = getattr(self, "_mammoth_fallback_context", None)
|
|
446
|
+
self._mammoth_fallback_context = None
|
|
447
|
+
if context is not None:
|
|
448
|
+
context[0].close()
|
|
449
|
+
|
|
450
|
+
def _mammoth_fallback_html(self, element: BaseOxmlElement) -> str:
|
|
451
|
+
"""在原 DOCX 的样式、编号、关系和图片上下文中转换当前表格。"""
|
|
452
|
+
context = self._mammoth_fallback_context
|
|
453
|
+
if context is None:
|
|
454
|
+
file_bytes = self._fallback_docx_bytes
|
|
455
|
+
if file_bytes is None:
|
|
456
|
+
raise ValueError("DOCX fallback source is unavailable")
|
|
457
|
+
resources = ExitStack()
|
|
458
|
+
try:
|
|
459
|
+
package = resources.enter_context(open_zip(BytesIO(file_bytes), "r"))
|
|
460
|
+
paths = mammoth_docx._find_part_paths(package)
|
|
461
|
+
read_part = mammoth_docx._part_with_body_reader(None, package, paths, False)
|
|
462
|
+
embedded_style_map = read_embedded_style_map(BytesIO(file_bytes))
|
|
463
|
+
conversion_options = read_options({"embedded_style_map": embedded_style_map}).value
|
|
464
|
+
context = (resources, read_part, paths.main_document, conversion_options)
|
|
465
|
+
self._mammoth_fallback_context = context
|
|
466
|
+
except Exception:
|
|
467
|
+
resources.close()
|
|
468
|
+
raise
|
|
469
|
+
|
|
470
|
+
_, read_part, main_part, conversion_options = context
|
|
471
|
+
table = read_str(element.xml)
|
|
402
472
|
|
|
403
|
-
|
|
404
|
-
|
|
473
|
+
def read_selected_table(_root: Any, body_reader: Any) -> Any:
|
|
474
|
+
"""每次获取独立 reader,只解析当前 XML 表格并沿用主文档关系。"""
|
|
475
|
+
return body_reader.read_all([table])
|
|
405
476
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
"""
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
html = self._inject_equations_into_table_html(
|
|
431
|
-
html,
|
|
432
|
-
element,
|
|
433
|
-
self._require_document_part(),
|
|
434
|
-
)
|
|
435
|
-
table_block = {
|
|
436
|
-
"type": BlockType.TABLE,
|
|
437
|
-
"content": html,
|
|
438
|
-
}
|
|
439
|
-
self.cur_page.append(table_block)
|
|
477
|
+
result = read_part(main_part, read_selected_table)
|
|
478
|
+
return convert_document_element_to_html(result.value[0], **conversion_options).value
|
|
479
|
+
|
|
480
|
+
def _handle_tables(self, element: BaseOxmlElement) -> None:
|
|
481
|
+
"""按正文顺序输出表格;预匹配失败时使用完整 DOCX 上下文回退。"""
|
|
482
|
+
table_index = self._mammoth_table_idx
|
|
483
|
+
self._mammoth_table_idx += 1
|
|
484
|
+
html = self._mammoth_tables_html[table_index] if table_index < len(self._mammoth_tables_html) else None
|
|
485
|
+
stage = "full-context fallback"
|
|
486
|
+
try:
|
|
487
|
+
if html is None:
|
|
488
|
+
html = self._mammoth_fallback_html(element)
|
|
489
|
+
stage = "colspan normalization"
|
|
490
|
+
html = self._normalize_table_colspans(html)
|
|
491
|
+
if table_index >= len(self._mammoth_tables_html) or self._mammoth_tables_html[table_index] is None:
|
|
492
|
+
stage = "equation injection"
|
|
493
|
+
html = self._inject_equations_into_table_html(
|
|
494
|
+
html,
|
|
495
|
+
element,
|
|
496
|
+
self._require_document_part(),
|
|
497
|
+
)
|
|
498
|
+
except Exception as exc:
|
|
499
|
+
raise RuntimeError(f"table #{table_index + 1}, {stage}: {exc}") from exc
|
|
500
|
+
self.cur_page.append({"type": BlockType.TABLE, "content": html})
|
|
440
501
|
|
|
441
502
|
def _normalize_table_colspans(self, html: str) -> str:
|
|
442
503
|
"""
|
|
@@ -540,6 +540,7 @@ tests/unittest/test_docx_math.py
|
|
|
540
540
|
tests/unittest/test_docx_render.py
|
|
541
541
|
tests/unittest/test_docx_special_char_tables.py
|
|
542
542
|
tests/unittest/test_docx_table.py
|
|
543
|
+
tests/unittest/test_docx_table_context.py
|
|
543
544
|
tests/unittest/test_emfplus_integration.py
|
|
544
545
|
tests/unittest/test_epub_backlinks.py
|
|
545
546
|
tests/unittest/test_epub_quoted_note_types.py
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"""DOCX 表格匹配与完整文档上下文回退的回归测试。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from io import BytesIO
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import mammoth
|
|
10
|
+
import pytest
|
|
11
|
+
from bs4 import BeautifulSoup
|
|
12
|
+
from docx import Document
|
|
13
|
+
from docx.opc.constants import RELATIONSHIP_TYPE as RT
|
|
14
|
+
from docx.opc.packuri import PackURI
|
|
15
|
+
from docx.opc.part import Part
|
|
16
|
+
from docx.oxml import parse_xml
|
|
17
|
+
from docx.oxml.ns import qn
|
|
18
|
+
from lxml import etree
|
|
19
|
+
from PIL import Image
|
|
20
|
+
from loguru import logger
|
|
21
|
+
|
|
22
|
+
from docvortex.analyzers.native.office.docx.docx_converter import DocxConverter
|
|
23
|
+
from docvortex.api import parse
|
|
24
|
+
|
|
25
|
+
NS = (
|
|
26
|
+
'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" '
|
|
27
|
+
'xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" '
|
|
28
|
+
'xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" '
|
|
29
|
+
'xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"'
|
|
30
|
+
)
|
|
31
|
+
ISSUE_CASES = ("control", "footnote", "endnote", "checkbox", "alternate", "field")
|
|
32
|
+
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _save(document: Document) -> bytes:
|
|
36
|
+
"""把内存中的 DOCX 文档序列化为字节。"""
|
|
37
|
+
output = BytesIO()
|
|
38
|
+
document.save(output)
|
|
39
|
+
return output.getvalue()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _table_html(converter: DocxConverter) -> list[str]:
|
|
43
|
+
"""按正文顺序提取转换器输出的表格 HTML。"""
|
|
44
|
+
return [block["content"] for page in converter.pages for block in page if block["type"] == "table"]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _attach_note(document: Document, *, note_type: str) -> None:
|
|
48
|
+
"""为脚注或尾注引用添加真实的 OOXML 包成员。"""
|
|
49
|
+
relation_type = RT.FOOTNOTES if note_type == "footnote" else RT.ENDNOTES
|
|
50
|
+
part = Part(
|
|
51
|
+
PackURI(f"/word/{note_type}s.xml"),
|
|
52
|
+
f"application/vnd.openxmlformats-officedocument.wordprocessingml.{note_type}s+xml",
|
|
53
|
+
(
|
|
54
|
+
f'<w:{note_type}s {NS}><w:{note_type} w:id="1">'
|
|
55
|
+
"<w:p><w:r><w:t>注释正文</w:t></w:r></w:p>"
|
|
56
|
+
f"</w:{note_type}></w:{note_type}s>"
|
|
57
|
+
).encode(),
|
|
58
|
+
document.part.package,
|
|
59
|
+
)
|
|
60
|
+
document.part.relate_to(part, relation_type)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _issue_trigger(name: str, *, checked: bool) -> str | None:
|
|
64
|
+
"""生成 issue 中会造成 XML 与 Mammoth 文本签名不一致的元素。"""
|
|
65
|
+
if name in {"footnote", "endnote"}:
|
|
66
|
+
return f'<w:r {NS}><w:{name}Reference w:id="1"/></w:r>'
|
|
67
|
+
if name == "checkbox":
|
|
68
|
+
value = "1" if checked else "0"
|
|
69
|
+
return (
|
|
70
|
+
f'<w:sdt {NS}><w:sdtPr><w14:checkbox><w14:checked w14:val="{value}"/>'
|
|
71
|
+
"</w14:checkbox></w:sdtPr><w:sdtContent><w:r><w:t>☐</w:t></w:r>"
|
|
72
|
+
"</w:sdtContent></w:sdt>"
|
|
73
|
+
)
|
|
74
|
+
if name == "alternate":
|
|
75
|
+
return (
|
|
76
|
+
f'<mc:AlternateContent {NS}><mc:Choice Requires="w14"><w:r><w:t>Choice</w:t></w:r>'
|
|
77
|
+
"</mc:Choice><mc:Fallback><w:r><w:t>Fallback</w:t></w:r>"
|
|
78
|
+
"</mc:Fallback></mc:AlternateContent>"
|
|
79
|
+
)
|
|
80
|
+
if name == "field":
|
|
81
|
+
return f'<w:fldSimple {NS} w:instr=" FILENAME "><w:r><w:t>report.docx</w:t></w:r></w:fldSimple>'
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _build_issue_document(*, styled: bool, checked: bool) -> bytes:
|
|
86
|
+
"""构造普通表、脚注、尾注、复选框、兼容分支和简单域混合文档。"""
|
|
87
|
+
document = Document()
|
|
88
|
+
_attach_note(document, note_type="footnote")
|
|
89
|
+
_attach_note(document, note_type="endnote")
|
|
90
|
+
for name in ISSUE_CASES:
|
|
91
|
+
table = document.add_table(rows=2, cols=2)
|
|
92
|
+
first = table.cell(0, 0).paragraphs[0]
|
|
93
|
+
if styled:
|
|
94
|
+
first.style = document.styles["List Paragraph"]
|
|
95
|
+
trigger = _issue_trigger(name, checked=checked)
|
|
96
|
+
if trigger:
|
|
97
|
+
first._p.append(parse_xml(trigger))
|
|
98
|
+
first.add_run(f"{name} A1")
|
|
99
|
+
for row, col in ((0, 1), (1, 0), (1, 1)):
|
|
100
|
+
table.cell(row, col).text = f"{name} {'AB'[col]}{row + 1}"
|
|
101
|
+
return _save(document)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@pytest.mark.parametrize("styled", (True, False))
|
|
105
|
+
@pytest.mark.parametrize("checked", (True, False))
|
|
106
|
+
def test_issue_11_tables_match_and_survive(styled: bool, checked: bool) -> None:
|
|
107
|
+
"""验证所有触发条件均能匹配原表,并保持六张表的内容与顺序。"""
|
|
108
|
+
file_bytes = _build_issue_document(styled=styled, checked=checked)
|
|
109
|
+
converter = DocxConverter()
|
|
110
|
+
preparsed = converter._preparse_tables_with_mammoth(file_bytes)
|
|
111
|
+
|
|
112
|
+
assert len(preparsed) == len(ISSUE_CASES)
|
|
113
|
+
assert all(html is not None for html in preparsed)
|
|
114
|
+
converter.convert(BytesIO(file_bytes))
|
|
115
|
+
html_tables = _table_html(converter)
|
|
116
|
+
assert len(html_tables) == len(ISSUE_CASES)
|
|
117
|
+
for name, html in zip(ISSUE_CASES, html_tables):
|
|
118
|
+
cells = BeautifulSoup(html, "html.parser").find_all("td")
|
|
119
|
+
assert len(cells) == 4
|
|
120
|
+
assert f"{name} A1" in cells[0].get_text()
|
|
121
|
+
assert cells[-1].get_text() == f"{name} B2"
|
|
122
|
+
checkbox = BeautifulSoup(html_tables[3], "html.parser").find("input")
|
|
123
|
+
assert checkbox is not None
|
|
124
|
+
assert checkbox.has_attr("checked") is checked
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_issue_11_public_parse_keeps_all_tables() -> None:
|
|
128
|
+
"""从公开 parse 入口验证 issue 的各张表仍在结构化结果中。"""
|
|
129
|
+
result = parse(_build_issue_document(styled=True, checked=True), file_suffix="docx")
|
|
130
|
+
serialized = json.dumps(result.to_dict(), ensure_ascii=False)
|
|
131
|
+
assert all(f"{name} B2" in serialized for name in ISSUE_CASES)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_note_marker_filter_keeps_literal_bracketed_number() -> None:
|
|
135
|
+
"""只从签名排除 Mammoth 生成的注释引用,保留单元格正文中的 [1]。"""
|
|
136
|
+
html = BeautifulSoup(
|
|
137
|
+
'<table><tr><td>[1]<sup><a id="footnote-ref-1" href="#footnote-1">[1]</a></sup>'
|
|
138
|
+
'<sup><a id="endnote-ref-2" href="#endnote-2">[2]</a></sup></td></tr></table>',
|
|
139
|
+
"html.parser",
|
|
140
|
+
).table
|
|
141
|
+
assert html is not None
|
|
142
|
+
assert DocxConverter._html_table_signature(html)["text"] == "[1]"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _build_fallback_document() -> bytes:
|
|
146
|
+
"""构造带显式编号、样式、链接、图片、公式和纵向合并的回退表格。"""
|
|
147
|
+
document = Document()
|
|
148
|
+
for label in ("first", "second"):
|
|
149
|
+
table = document.add_table(rows=2, cols=3)
|
|
150
|
+
table.cell(0, 0).merge(table.cell(1, 0))
|
|
151
|
+
cell = table.cell(0, 0)
|
|
152
|
+
paragraph = cell.paragraphs[0]
|
|
153
|
+
paragraph.style = document.styles["List Number"]
|
|
154
|
+
paragraph.add_run(label)
|
|
155
|
+
if label == "first":
|
|
156
|
+
ppr = paragraph._p.get_or_add_pPr()
|
|
157
|
+
ppr.append(parse_xml(f'<w:numPr {NS}><w:ilvl w:val="0"/><w:numId w:val="1"/></w:numPr>'))
|
|
158
|
+
rid = document.part.relate_to("https://example.com/docx-table", RT.HYPERLINK, is_external=True)
|
|
159
|
+
paragraph._p.append(parse_xml(f'<w:hyperlink {NS} r:id="{rid}"><w:r><w:t>linked</w:t></w:r></w:hyperlink>'))
|
|
160
|
+
png = BytesIO()
|
|
161
|
+
Image.new("RGB", (3, 3), "red").save(png, format="PNG")
|
|
162
|
+
png.seek(0)
|
|
163
|
+
paragraph.add_run().add_picture(png)
|
|
164
|
+
styled = cell.add_paragraph("styled")
|
|
165
|
+
styled.style = document.styles["List Paragraph"]
|
|
166
|
+
formula_paragraph = table.cell(0, 2).paragraphs[0]
|
|
167
|
+
math = etree.SubElement(formula_paragraph._p, qn("m:oMath"))
|
|
168
|
+
math_run = etree.SubElement(math, qn("m:r"))
|
|
169
|
+
etree.SubElement(math_run, qn("m:t")).text = "x+y"
|
|
170
|
+
table.cell(0, 1).text = f"{label} B1"
|
|
171
|
+
table.cell(1, 1).text = f"{label} B2"
|
|
172
|
+
table.cell(1, 2).text = f"{label} C2"
|
|
173
|
+
output = BytesIO(_save(document))
|
|
174
|
+
mammoth.embed_style_map(output, "p[style-name='List Paragraph'] => h6:fresh")
|
|
175
|
+
return output.getvalue()
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@pytest.mark.parametrize("preparsed", ([], [None, None]))
|
|
179
|
+
def test_forced_fallback_keeps_full_document_context(monkeypatch: pytest.MonkeyPatch, preparsed: list) -> None:
|
|
180
|
+
"""强制跳过预匹配,验证回退在两张表中保留全部受支持的上下文内容。"""
|
|
181
|
+
file_bytes = _build_fallback_document()
|
|
182
|
+
converter = DocxConverter()
|
|
183
|
+
|
|
184
|
+
def skip_preparse(_data: bytes) -> list:
|
|
185
|
+
"""按参数强制表格走完整上下文回退。"""
|
|
186
|
+
return preparsed
|
|
187
|
+
|
|
188
|
+
monkeypatch.setattr(converter, "_preparse_tables_with_mammoth", skip_preparse)
|
|
189
|
+
converter.convert(BytesIO(file_bytes))
|
|
190
|
+
html_tables = _table_html(converter)
|
|
191
|
+
assert len(html_tables) == 2
|
|
192
|
+
first, second = [BeautifulSoup(html, "html.parser") for html in html_tables]
|
|
193
|
+
assert first.find("li") is not None
|
|
194
|
+
assert first.find("a", href="https://example.com/docx-table") is not None
|
|
195
|
+
image = first.find("img")
|
|
196
|
+
assert image is not None
|
|
197
|
+
assert image.get("src", "").startswith("data:image/")
|
|
198
|
+
assert first.find("eq") is not None
|
|
199
|
+
assert first.find("h6") is not None
|
|
200
|
+
assert first.find("td", rowspan="2") is not None
|
|
201
|
+
assert "first B2" in first.get_text()
|
|
202
|
+
assert "second B2" in second.get_text()
|
|
203
|
+
assert converter._mammoth_fallback_context is None
|
|
204
|
+
assert converter._fallback_docx_bytes is None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def test_alignment_skips_extra_non_body_table() -> None:
|
|
208
|
+
"""额外的文本框候选表不得抢占正文表格的匹配位置。"""
|
|
209
|
+
file_bytes = _build_issue_document(styled=True, checked=False)
|
|
210
|
+
document = Document(BytesIO(file_bytes))
|
|
211
|
+
body_tables = [child for child in document.element.body if child.tag == qn("w:tbl")]
|
|
212
|
+
converter = DocxConverter()
|
|
213
|
+
raw = mammoth.convert_to_html(BytesIO(file_bytes), transform_document=converter._mammoth_top_level_table_document).value
|
|
214
|
+
html_tables = BeautifulSoup(raw, "html.parser").find_all("table")
|
|
215
|
+
extra = BeautifulSoup("<table><tr><td>textbox only</td></tr></table>", "html.parser").table
|
|
216
|
+
aligned = converter._align_mammoth_tables_to_xml_tables([extra, *html_tables], body_tables, document.part)
|
|
217
|
+
assert len(aligned) == len(ISSUE_CASES)
|
|
218
|
+
assert all(html is not None for html in aligned)
|
|
219
|
+
assert "textbox only" not in "".join(aligned)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_fallback_failure_does_not_skip_later_table(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
223
|
+
"""一张回退表解析失败时,警告定位表号且后续表仍输出。"""
|
|
224
|
+
converter = DocxConverter()
|
|
225
|
+
|
|
226
|
+
def skip_preparse(_data: bytes) -> list:
|
|
227
|
+
"""强制后续两张表进入完整上下文回退。"""
|
|
228
|
+
return []
|
|
229
|
+
|
|
230
|
+
monkeypatch.setattr(converter, "_preparse_tables_with_mammoth", skip_preparse)
|
|
231
|
+
original = converter._mammoth_fallback_html
|
|
232
|
+
attempts = 0
|
|
233
|
+
|
|
234
|
+
def fail_first(element: object) -> str:
|
|
235
|
+
"""仅模拟首张表发生上下文回退异常。"""
|
|
236
|
+
nonlocal attempts
|
|
237
|
+
attempts += 1
|
|
238
|
+
if attempts == 1:
|
|
239
|
+
raise ValueError("injected failure")
|
|
240
|
+
return original(element)
|
|
241
|
+
|
|
242
|
+
warnings = []
|
|
243
|
+
sink_id = logger.add(warnings.append, level="WARNING")
|
|
244
|
+
try:
|
|
245
|
+
monkeypatch.setattr(converter, "_mammoth_fallback_html", fail_first)
|
|
246
|
+
converter.convert(BytesIO(_build_fallback_document()))
|
|
247
|
+
finally:
|
|
248
|
+
logger.remove(sink_id)
|
|
249
|
+
assert len(_table_html(converter)) == 1
|
|
250
|
+
assert "second B2" in _table_html(converter)[0]
|
|
251
|
+
assert any("table #1, full-context fallback" in str(warning) for warning in warnings)
|
|
252
|
+
assert converter._mammoth_fallback_context is None
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def test_fallback_converter_reuse_and_error_release(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
256
|
+
"""同一转换器的连续调用和失败重试都释放旧包及回退状态。"""
|
|
257
|
+
converter = DocxConverter()
|
|
258
|
+
|
|
259
|
+
def skip_preparse(_data: bytes) -> list:
|
|
260
|
+
"""强制各次转换均使用完整上下文回退。"""
|
|
261
|
+
return []
|
|
262
|
+
|
|
263
|
+
monkeypatch.setattr(converter, "_preparse_tables_with_mammoth", skip_preparse)
|
|
264
|
+
first = _build_fallback_document()
|
|
265
|
+
converter.convert(BytesIO(first))
|
|
266
|
+
first_tables = _table_html(converter)
|
|
267
|
+
assert converter._mammoth_fallback_context is None
|
|
268
|
+
|
|
269
|
+
original_add_header_footer = converter._add_header_footer
|
|
270
|
+
|
|
271
|
+
def fail_after_tables(_document: Document) -> None:
|
|
272
|
+
"""模拟完成表格回退后发生的文档级异常。"""
|
|
273
|
+
raise RuntimeError("injected lifecycle failure")
|
|
274
|
+
|
|
275
|
+
monkeypatch.setattr(converter, "_add_header_footer", fail_after_tables)
|
|
276
|
+
with pytest.raises(RuntimeError, match="injected lifecycle failure"):
|
|
277
|
+
converter.convert(BytesIO(first))
|
|
278
|
+
assert converter._mammoth_fallback_context is None
|
|
279
|
+
assert converter._fallback_docx_bytes is None
|
|
280
|
+
|
|
281
|
+
monkeypatch.setattr(converter, "_add_header_footer", original_add_header_footer)
|
|
282
|
+
with pytest.raises(Exception):
|
|
283
|
+
converter.convert(BytesIO(b"invalid docx"))
|
|
284
|
+
assert converter._mammoth_fallback_context is None
|
|
285
|
+
assert converter._fallback_docx_bytes is None
|
|
286
|
+
|
|
287
|
+
converter.convert(BytesIO(_build_issue_document(styled=True, checked=True)))
|
|
288
|
+
assert len(_table_html(converter)) == len(ISSUE_CASES)
|
|
289
|
+
assert "first B2" not in "".join(_table_html(converter))
|
|
290
|
+
converter.convert(BytesIO(first))
|
|
291
|
+
assert _table_html(converter) == first_tables
|
|
292
|
+
assert converter._mammoth_fallback_context is None
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@pytest.mark.parametrize(
|
|
296
|
+
("path", "expected_count", "expected_rows"),
|
|
297
|
+
[
|
|
298
|
+
("tests/fixtures/docx/issue9-merged-cells.docx", 1, 37),
|
|
299
|
+
("demo/ms_office_docs/docx_01.docx", 8, None),
|
|
300
|
+
],
|
|
301
|
+
)
|
|
302
|
+
def test_existing_docx_samples_keep_tables(path: str, expected_count: int, expected_rows: int | None) -> None:
|
|
303
|
+
"""回放真实 DOCX 样本,检查表格数量及 issue #9 的完整行数。"""
|
|
304
|
+
file_bytes = (PROJECT_ROOT / path).read_bytes()
|
|
305
|
+
converter = DocxConverter()
|
|
306
|
+
preparsed = converter._preparse_tables_with_mammoth(file_bytes)
|
|
307
|
+
assert len(preparsed) == expected_count
|
|
308
|
+
assert all(html is not None for html in preparsed)
|
|
309
|
+
converter.convert(BytesIO(file_bytes))
|
|
310
|
+
html_tables = _table_html(converter)
|
|
311
|
+
assert len(html_tables) == expected_count
|
|
312
|
+
assert html_tables == [converter._normalize_table_colspans(html) for html in preparsed]
|
|
313
|
+
if expected_rows is not None:
|
|
314
|
+
assert len(BeautifulSoup(html_tables[0], "html.parser").find_all("tr")) == expected_rows
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|