docling-rs 2.2.0__tar.gz → 2.2.2__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.
Potentially problematic release.
This version of docling-rs might be problematic. Click here for more details.
- {docling_rs-2.2.0 → docling_rs-2.2.2}/PKG-INFO +1 -1
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/Cargo.toml +4 -4
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/error.rs +24 -1
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/Cargo.toml +3 -3
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/Cargo.toml +1 -1
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/chunker.rs +2 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/doclang.rs +14 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/document.rs +29 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/json.rs +44 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/latex.rs +3 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/markdown.rs +1 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-onnx/Cargo.toml +2 -2
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/Cargo.toml +3 -3
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/assemble.rs +32 -10
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/lib.rs +34 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/pdfium_backend.rs +5 -3
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/text_layer.rs +12 -3
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/Cargo.lock +5 -5
- {docling_rs-2.2.0 → docling_rs-2.2.2}/pyproject.toml +1 -1
- {docling_rs-2.2.0 → docling_rs-2.2.2}/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/examples/convert.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/examples/perf_serialize.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/examples/profile_declarative.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/examples/stream.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/sample.html +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/sample.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/archive.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/abw.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/asciidoc.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/browser.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/cfb.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/chandra.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/csv.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/deepseek.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/djvu.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/doc.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/doclang.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/doclang_tree.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/docling_json.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/docx.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/docx_tree.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/ebcdic.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/ebcdic_tables.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/email.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/epub.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/html.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/html_tree.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/images.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/interchange.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/iwork.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/iwork_charts.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/jats.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/keynote.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/keynote_iwa.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/keynote_xml.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/latex.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/latex_walker.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/lotus.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/markdown.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/mc.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/md_tree.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/metafile.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/mhtml.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/mod.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/msg.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/odf.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/odf_tree.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/officeart.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/omml.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/ooxml.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/pages.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/pages_iwa.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/pages_xml.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/ppt.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/pptx.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/quattro.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/rtf.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/staroffice5.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/svg.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/symbol_fonts.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/uspto.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/uspto_entities.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/visio.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/webvtt.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/wpd.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/wps.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/xbrl.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/xbrl_dts.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/xls.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/xlsx.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/xlsx_drawings.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/backend/xml_depth.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/chunks.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/converter.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/dclx.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/email_attachments.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/format.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/lib.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/options.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/result.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/sniff.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/source.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/stream.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/video.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling/src/vlm.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/examples/preset_check.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/audio.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/lib.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/mel.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/nemo_mel.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/parakeet.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/tokenizer.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/vad.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-asr/src/whisper.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/assets.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/base64.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/confidence.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/doctags.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/env.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/html.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/jpeg.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/labels.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/lib.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/mathml/mod.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/mathml/symbols.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/pandoc.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/pixel_digest.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-core/src/tree.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-onnx/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-onnx/src/lib.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/dump_page_png.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/dump_regions.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/dump_stages.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/extract.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/layout.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/render_compare.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/snapshot.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/text_layer.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/textparse_dump.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/textparse_glyphs.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/tf_otsl.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/examples/word_cells.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/ffi/docling-parse-render/dparse_render.cpp +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/checkbox.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/dp_lines.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/dparse_render.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/enrich.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/font_style.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/heading_hierarchy.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/layout.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/mets.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/ocr.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/ocr_det.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/ocr_prep.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/orient.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/outline.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/pdf_meta.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/quality.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/raster/fax.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/raster/filters.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/raster/jpeg_tests.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/raster/mod.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/raster/stretch.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/reading_order.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/color.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/content.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/font/cmap.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/font/dotsection.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/font/encodings.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/font/fallback.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/font/mod.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/font/type1.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/function.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/geom.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/image.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/jpx.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/mod.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/objects.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/render/prepass.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/resample.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/scanned.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/std14.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/tableformer.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/tesseract.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/textparse.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/tf_core.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/tf_match.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/src/timing.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/fax/shapes.g3 +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/fax/shapes.g3_2d +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/fax/shapes.g4 +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/fax/shapes.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/gray_444.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/gray_444.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/gray_progressive.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/gray_progressive.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420_big.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420_big.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420_progressive.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420_progressive.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420_restart.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_420_restart.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_422.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_422.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_422_optimize.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_422_optimize.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_444.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_444.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_444_progressive.jpg +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpeg/rgb_444_progressive.png +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpx/gray_12x9.j2k +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpx/gray_12x9.jp2 +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpx/rgb_8x6.jp2 +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-pdf/tests/data/jpx/rgba_8x6.jp2 +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/Cargo.toml +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/examples/langchain/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/examples/langchain/loader_basics.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/examples/langchain/picture_description.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/examples/langchain/rag_agent.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/src/lib.rs +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/data/langchain/README.md +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/data/langchain/dl_doc_1.json +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/data/langchain/lc_doc_chunks_1.json +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/data/langchain/lc_doc_md_1.json +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_archive.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_chunking.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_config.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_dropin.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_email.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_langchain.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_namespace_parity.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/docling-py/tests/test_pandoc.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/__init__.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/chunking.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/datamodel/__init__.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/datamodel/accelerator_options.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/datamodel/base_models.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/datamodel/document.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/datamodel/pipeline_options.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/document_converter.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/exceptions.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/langchain/__init__.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/langchain/loader.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/langchain/picture_description.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/models.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/options.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/pandoc.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/picture_description.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/utils/__init__.py +0 -0
- {docling_rs-2.2.0 → docling_rs-2.2.2}/python/docling_rs/utils/model_downloader.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "docling"
|
|
3
3
|
description = "DocumentConverter and format backends for docling.rs (a Rust port of docling)."
|
|
4
|
-
version = "2.2.
|
|
4
|
+
version = "2.2.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/docling-project/docling.rs"
|
|
@@ -79,9 +79,9 @@ headless_chrome = { version = "1.0", optional = true }
|
|
|
79
79
|
# O_EXCL temp file with an unpredictable name for the browser pre-render page
|
|
80
80
|
# (avoids a predictable /tmp path a local attacker could pre-plant a symlink at).
|
|
81
81
|
tempfile = { version = "3", optional = true }
|
|
82
|
-
docling-asr = { path = "../docling-asr", version = "2.2.
|
|
83
|
-
docling-core = { path = "../docling-core", version = "2.2.
|
|
84
|
-
docling-pdf = { path = "../docling-pdf", version = "2.2.
|
|
82
|
+
docling-asr = { path = "../docling-asr", version = "2.2.2", optional = true }
|
|
83
|
+
docling-core = { path = "../docling-core", version = "2.2.2" }
|
|
84
|
+
docling-pdf = { path = "../docling-pdf", version = "2.2.2", optional = true, default-features = false }
|
|
85
85
|
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "gif", "bmp", "tiff", "webp"] }
|
|
86
86
|
mail-parser = "0.11"
|
|
87
87
|
pulldown-cmark = { version = "0.13.4", default-features = false }
|
|
@@ -81,7 +81,14 @@ impl fmt::Display for ConversionError {
|
|
|
81
81
|
ConversionError::Panic(msg) => write!(f, "conversion panicked: {msg}"),
|
|
82
82
|
ConversionError::Timeout(msg) => write!(f, "document timeout: {msg}"),
|
|
83
83
|
ConversionError::WithSource { context, source } => {
|
|
84
|
-
|
|
84
|
+
// A source that already names its format (`PdfError`'s
|
|
85
|
+
// `pdf: …`) is not prefixed twice (`pdf: pdf: …`).
|
|
86
|
+
let msg = source.to_string();
|
|
87
|
+
if msg.starts_with(&format!("{context}: ")) {
|
|
88
|
+
write!(f, "parse error: {msg}")
|
|
89
|
+
} else {
|
|
90
|
+
write!(f, "parse error: {context}: {msg}")
|
|
91
|
+
}
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
}
|
|
@@ -121,6 +128,22 @@ mod tests {
|
|
|
121
128
|
);
|
|
122
129
|
}
|
|
123
130
|
|
|
131
|
+
/// A source whose message already names the context is not prefixed
|
|
132
|
+
/// with it again (`parse error: pdf: pdf: …`).
|
|
133
|
+
#[test]
|
|
134
|
+
fn with_source_does_not_repeat_the_context() {
|
|
135
|
+
let cause = std::io::Error::other("pdf: not a readable PDF");
|
|
136
|
+
assert_eq!(
|
|
137
|
+
ConversionError::with_source("pdf", cause).to_string(),
|
|
138
|
+
"parse error: pdf: not a readable PDF"
|
|
139
|
+
);
|
|
140
|
+
let cause = std::io::Error::other("bad header");
|
|
141
|
+
assert_eq!(
|
|
142
|
+
ConversionError::with_source("pdf", cause).to_string(),
|
|
143
|
+
"parse error: pdf: bad header"
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
124
147
|
#[test]
|
|
125
148
|
fn stringly_variants_have_no_source() {
|
|
126
149
|
assert!(ConversionError::Parse("x".into()).source().is_none());
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "docling-asr"
|
|
3
3
|
description = "Audio/ASR pipeline for docling.rs (Whisper via ONNX; a Rust port of docling's ASR pipeline)."
|
|
4
|
-
version = "2.2.
|
|
4
|
+
version = "2.2.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/docling-project/docling.rs"
|
|
@@ -25,10 +25,10 @@ xnnpack = ["docling-onnx/xnnpack"]
|
|
|
25
25
|
ort-load-dynamic = ["docling-onnx/load-dynamic", "ort/load-dynamic"]
|
|
26
26
|
|
|
27
27
|
[dependencies]
|
|
28
|
-
docling-core = { path = "../docling-core", version = "2.2.
|
|
28
|
+
docling-core = { path = "../docling-core", version = "2.2.2" }
|
|
29
29
|
# Shared ONNX execution-provider selection (DOCLING_RS_EP, #288) — routes the
|
|
30
30
|
# Whisper encoder/decoder sessions through the same switch as docling-pdf.
|
|
31
|
-
docling-onnx = { path = "../docling-onnx", version = "2.2.
|
|
31
|
+
docling-onnx = { path = "../docling-onnx", version = "2.2.2" }
|
|
32
32
|
# Same ort as docling-pdf so the workspace keeps a single ONNX runtime.
|
|
33
33
|
ort = { version = "2.0.0-rc.13", default-features = false, features = ["std", "download-binaries", "tls-rustls"] }
|
|
34
34
|
serde_json = "1"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "docling-core"
|
|
3
3
|
description = "Core DoclingDocument data model and serializers for docling.rs (a Rust port of docling)."
|
|
4
|
-
version = "2.2.
|
|
4
|
+
version = "2.2.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/docling-project/docling.rs"
|
|
@@ -471,6 +471,7 @@ impl Walker<'_> {
|
|
|
471
471
|
let self_ref = self.alloc.text();
|
|
472
472
|
self.emit_inline(text, self_ref);
|
|
473
473
|
}
|
|
474
|
+
Node::LabeledText { .. } => self.one(&node.labeled_as_paragraph()),
|
|
474
475
|
Node::CheckboxItem { checked, text } => {
|
|
475
476
|
let self_ref = self.alloc.text();
|
|
476
477
|
let mark = if *checked { "- [x] " } else { "- [ ] " };
|
|
@@ -1120,6 +1121,7 @@ fn cell_chunk_text(t: &Table, r: usize, c: usize) -> String {
|
|
|
1120
1121
|
fn block_chunk_text(node: &Node) -> String {
|
|
1121
1122
|
match node {
|
|
1122
1123
|
Node::Paragraph { text } => unescape_text(text),
|
|
1124
|
+
Node::LabeledText { .. } => block_chunk_text(&node.labeled_as_paragraph()),
|
|
1123
1125
|
Node::InlineGroup { md_text, .. } => unescape_text(md_text),
|
|
1124
1126
|
Node::Code { text, .. } => format!("```\n{}\n```", unescape_text(text)),
|
|
1125
1127
|
Node::Table(inner) => triplet_table_text(inner),
|
|
@@ -901,6 +901,17 @@ fn emit_nodes(out: &mut Out, depth: i32, nodes: &[Node], i: &mut usize, level: u
|
|
|
901
901
|
emit_caption(out, depth, text, href.as_deref());
|
|
902
902
|
*i += 1;
|
|
903
903
|
}
|
|
904
|
+
Node::LabeledText { .. } => {
|
|
905
|
+
let para = nodes[*i].labeled_as_paragraph();
|
|
906
|
+
emit_nodes(
|
|
907
|
+
out,
|
|
908
|
+
depth,
|
|
909
|
+
std::slice::from_ref(para.as_ref()),
|
|
910
|
+
&mut 0,
|
|
911
|
+
level,
|
|
912
|
+
);
|
|
913
|
+
*i += 1;
|
|
914
|
+
}
|
|
904
915
|
Node::CheckboxItem { checked, text } => {
|
|
905
916
|
// A `<text>` with a `<checkbox class="selected|unselected"/>` head
|
|
906
917
|
// element and the label text child (block form).
|
|
@@ -1722,6 +1733,9 @@ fn emit_located(out: &mut Out, depth: i32, location: &[u16; 4], inner: &Node) {
|
|
|
1722
1733
|
Node::Paragraph { text } => {
|
|
1723
1734
|
emit_text_element(out, depth, "text", "text", text, Some(location));
|
|
1724
1735
|
}
|
|
1736
|
+
Node::LabeledText { .. } => {
|
|
1737
|
+
emit_located(out, depth, location, &inner.labeled_as_paragraph())
|
|
1738
|
+
}
|
|
1725
1739
|
Node::Picture {
|
|
1726
1740
|
caption,
|
|
1727
1741
|
caption_href,
|
|
@@ -173,6 +173,18 @@ pub enum Node {
|
|
|
173
173
|
/// renders it as `[text](href)`, JSON puts `hyperlink` on the caption
|
|
174
174
|
/// item, DocLang emits the block-form `<caption>` with an `<href>` head.
|
|
175
175
|
Caption { text: String, href: Option<String> },
|
|
176
|
+
/// A body text item with a docling label of its own and an optional
|
|
177
|
+
/// hyperlink — the PDF pipeline's `footnote` regions, whose item docling
|
|
178
|
+
/// keeps as a `footnote` text with the link annotation covering it as its
|
|
179
|
+
/// `hyperlink` (`PageAssembleModel._match_hyperlink`). The JSON writes
|
|
180
|
+
/// exactly that (label, raw text, `hyperlink`); every other serializer
|
|
181
|
+
/// renders it as the paragraph [`Self::labeled_markdown`] spells —
|
|
182
|
+
/// docling's Markdown wraps a linked item's whole text, `[text](uri)`.
|
|
183
|
+
LabeledText {
|
|
184
|
+
label: String,
|
|
185
|
+
text: String,
|
|
186
|
+
href: Option<String>,
|
|
187
|
+
},
|
|
176
188
|
/// A chart (docling's `PictureItem` classified as a chart, carrying a
|
|
177
189
|
/// `PictureTabularChartData` annotation). Markdown and JSON render it exactly
|
|
178
190
|
/// like a [`Node::Picture`] placeholder (an `<!-- image -->` / `picture`
|
|
@@ -658,6 +670,23 @@ pub struct ListItemDclx {
|
|
|
658
670
|
pub runs: Vec<InlineRun>,
|
|
659
671
|
}
|
|
660
672
|
|
|
673
|
+
impl Node {
|
|
674
|
+
/// The paragraph a [`Node::LabeledText`] renders as outside the JSON:
|
|
675
|
+
/// its text, wrapped as `[text](uri)` when it carries a hyperlink. Any
|
|
676
|
+
/// other node is returned unchanged.
|
|
677
|
+
pub fn labeled_as_paragraph(&self) -> std::borrow::Cow<'_, Node> {
|
|
678
|
+
match self {
|
|
679
|
+
Node::LabeledText { text, href, .. } => std::borrow::Cow::Owned(Node::Paragraph {
|
|
680
|
+
text: match href {
|
|
681
|
+
Some(uri) => format!("[{text}]({uri})"),
|
|
682
|
+
None => text.clone(),
|
|
683
|
+
},
|
|
684
|
+
}),
|
|
685
|
+
other => std::borrow::Cow::Borrowed(other),
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
661
690
|
impl InlineRun {
|
|
662
691
|
/// A run with no active formatting (renders as bare inline text).
|
|
663
692
|
pub fn is_plain(&self) -> bool {
|
|
@@ -1103,6 +1103,15 @@ impl Builder {
|
|
|
1103
1103
|
};
|
|
1104
1104
|
Some(self.add_text("caption", text, parent, extra))
|
|
1105
1105
|
}
|
|
1106
|
+
// A PDF footnote: docling's own label, and its link as the item's
|
|
1107
|
+
// `hyperlink` rather than Markdown baked into the text.
|
|
1108
|
+
Node::LabeledText { label, text, href } => {
|
|
1109
|
+
let extra = match href {
|
|
1110
|
+
Some(url) => json!({ "hyperlink": url }),
|
|
1111
|
+
None => json!({}),
|
|
1112
|
+
};
|
|
1113
|
+
Some(self.add_text(label, text, parent, extra))
|
|
1114
|
+
}
|
|
1106
1115
|
Node::Paragraph { text } => {
|
|
1107
1116
|
// A whole-paragraph display equation is a formula item (docling
|
|
1108
1117
|
// wraps it in `$$…$$` and, unlike a text item, never escapes it).
|
|
@@ -3624,4 +3633,39 @@ mod tests {
|
|
|
3624
3633
|
assert_eq!(v["pictures"][0]["children"], serde_json::json!([]));
|
|
3625
3634
|
assert_eq!(v["tables"][0]["children"], serde_json::json!([]));
|
|
3626
3635
|
}
|
|
3636
|
+
|
|
3637
|
+
/// A PDF footnote (#620 follow-up): the JSON keeps docling's
|
|
3638
|
+
/// `footnote` label, the raw text and the link as `hyperlink`; the
|
|
3639
|
+
/// Markdown still wraps the whole item as `[text](uri)`, and the plain
|
|
3640
|
+
/// text drops the link like docling-core's `export_to_text`.
|
|
3641
|
+
#[test]
|
|
3642
|
+
fn a_labeled_text_keeps_its_label_and_hyperlink_out_of_the_text() {
|
|
3643
|
+
let mut doc = DoclingDocument::new("t");
|
|
3644
|
+
doc.push(Node::LabeledText {
|
|
3645
|
+
label: "footnote".into(),
|
|
3646
|
+
text: "1 https://example.com/a\\_b".into(),
|
|
3647
|
+
href: Some("https://example.com/a_b".into()),
|
|
3648
|
+
});
|
|
3649
|
+
doc.push(Node::LabeledText {
|
|
3650
|
+
label: "footnote".into(),
|
|
3651
|
+
text: "© 2022 the authors".into(),
|
|
3652
|
+
href: None,
|
|
3653
|
+
});
|
|
3654
|
+
let v: Value = serde_json::from_str(&doc.export_to_json()).unwrap();
|
|
3655
|
+
let t = &v["texts"][0];
|
|
3656
|
+
assert_eq!(t["label"], "footnote");
|
|
3657
|
+
assert_eq!(t["text"], "1 https://example.com/a_b");
|
|
3658
|
+
assert_eq!(t["orig"], "1 https://example.com/a_b");
|
|
3659
|
+
assert_eq!(t["hyperlink"], "https://example.com/a_b");
|
|
3660
|
+
assert_eq!(v["texts"][1]["label"], "footnote");
|
|
3661
|
+
assert!(v["texts"][1].get("hyperlink").is_none());
|
|
3662
|
+
assert_eq!(
|
|
3663
|
+
doc.export_to_markdown(),
|
|
3664
|
+
"[1 https://example.com/a\\_b](https://example.com/a_b)\n\n© 2022 the authors\n"
|
|
3665
|
+
);
|
|
3666
|
+
assert_eq!(
|
|
3667
|
+
doc.export_to_text(),
|
|
3668
|
+
"1 https://example.com/a_b\n\n© 2022 the authors"
|
|
3669
|
+
);
|
|
3670
|
+
}
|
|
3627
3671
|
}
|
|
@@ -458,6 +458,9 @@ fn render_one(node: &Node, list_level: usize, inline: bool, parts: &mut Vec<Stri
|
|
|
458
458
|
}
|
|
459
459
|
// A standalone caption item is a text item to the LaTeX serializer.
|
|
460
460
|
Node::Caption { text, .. } => push(parts, inline_md(text)),
|
|
461
|
+
Node::LabeledText { .. } => {
|
|
462
|
+
render_one(&node.labeled_as_paragraph(), list_level, inline, parts)
|
|
463
|
+
}
|
|
461
464
|
Node::Paragraph { text } => {
|
|
462
465
|
// A whole-paragraph `$$…$$` is a formula item in the JSON — never
|
|
463
466
|
// escaped, re-wrapped by the serializer.
|
|
@@ -959,6 +959,7 @@ fn render_item(node: &Node, blocks: &mut Vec<String>, ctx: &mut Ctx) {
|
|
|
959
959
|
// nothing to Markdown — only DocLang/JSON keep it.
|
|
960
960
|
Node::Paragraph { text } if text.is_empty() => {}
|
|
961
961
|
Node::Paragraph { text } => blocks.push(ctx.breaks(&ctx.text(text))),
|
|
962
|
+
Node::LabeledText { .. } => render_item(&node.labeled_as_paragraph(), blocks, ctx),
|
|
962
963
|
// A standalone caption item renders like a text item; its hyperlink
|
|
963
964
|
// annotation becomes a Markdown link around the whole caption.
|
|
964
965
|
Node::Caption { text, .. } if text.is_empty() => {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "docling-onnx"
|
|
3
3
|
description = "Shared ONNX Runtime execution-provider selection for docling.rs (DOCLING_RS_EP)."
|
|
4
|
-
version = "2.2.
|
|
4
|
+
version = "2.2.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/docling-project/docling.rs"
|
|
@@ -41,7 +41,7 @@ xnnpack = ["ort/xnnpack"]
|
|
|
41
41
|
load-dynamic = ["ort/load-dynamic", "dep:libloading"]
|
|
42
42
|
|
|
43
43
|
[dependencies]
|
|
44
|
-
docling-core = { path = "../docling-core", version = "2.2.
|
|
44
|
+
docling-core = { path = "../docling-core", version = "2.2.2" }
|
|
45
45
|
# Same ort build as docling-pdf/docling-asr so the workspace keeps a single
|
|
46
46
|
# ONNX Runtime.
|
|
47
47
|
ort = { version = "2.0.0-rc.13", default-features = false, features = ["std", "download-binaries", "tls-rustls"] }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "docling-pdf"
|
|
3
3
|
description = "PDF/image backend for docling.rs: pure-Rust text layer and page renderer + ONNX layout/table/OCR pipeline."
|
|
4
|
-
version = "2.2.
|
|
4
|
+
version = "2.2.2"
|
|
5
5
|
edition = "2021"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/docling-project/docling.rs"
|
|
@@ -71,10 +71,10 @@ ort-load-dynamic = ["ml", "docling-onnx/load-dynamic", "ort/load-dynamic"]
|
|
|
71
71
|
# what current LTS distros ship (Ubuntu 24.04 = 1.17). Newer libheif-rs
|
|
72
72
|
# requires libheif >= 1.18 and can be selected once baselines move.
|
|
73
73
|
libheif-rs = { version = "~1.0", default-features = false, optional = true }
|
|
74
|
-
docling-core = { path = "../docling-core", version = "2.2.
|
|
74
|
+
docling-core = { path = "../docling-core", version = "2.2.2" }
|
|
75
75
|
# Shared ONNX execution-provider selection (DOCLING_RS_EP, #74/#288);
|
|
76
76
|
# re-exported as `docling_pdf::ep`.
|
|
77
|
-
docling-onnx = { path = "../docling-onnx", version = "2.2.
|
|
77
|
+
docling-onnx = { path = "../docling-onnx", version = "2.2.2", optional = true }
|
|
78
78
|
pdfium-render = { version = "0.8", optional = true }
|
|
79
79
|
# Runtime loading of the opt-in docling-parse renderer plugin (#478,
|
|
80
80
|
# `dparse_render.rs`) — the same mechanism pdfium-render uses for libpdfium.
|
|
@@ -3516,18 +3516,27 @@ pub fn assemble_page(
|
|
|
3516
3516
|
let hyperlink = (region.label == "footnote")
|
|
3517
3517
|
.then(|| region_hyperlink(region, &page.links))
|
|
3518
3518
|
.flatten();
|
|
3519
|
-
let
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3519
|
+
if let Some(uri) = &hyperlink {
|
|
3520
|
+
// The strict-mode anchor pairs this item covers are
|
|
3521
|
+
// superseded by the whole-item link.
|
|
3522
|
+
links.retain(|(anchor, href)| {
|
|
3523
|
+
!(href == uri && region_texts[i].contains(anchor.as_str()))
|
|
3524
|
+
});
|
|
3525
|
+
}
|
|
3526
|
+
// A footnote keeps docling's label and carries its link as
|
|
3527
|
+
// the item's `hyperlink` (the JSON's `text` stays the raw
|
|
3528
|
+
// footnote, not Markdown); every other serializer renders it
|
|
3529
|
+
// as the `[text](uri)` paragraph it was before.
|
|
3530
|
+
let node = if region.label == "footnote" {
|
|
3531
|
+
Node::LabeledText {
|
|
3532
|
+
label: "footnote".into(),
|
|
3533
|
+
text: escaped,
|
|
3534
|
+
href: hyperlink,
|
|
3527
3535
|
}
|
|
3528
|
-
|
|
3536
|
+
} else {
|
|
3537
|
+
Node::Paragraph { text: escaped }
|
|
3529
3538
|
};
|
|
3530
|
-
nodes.push(located(loc,
|
|
3539
|
+
nodes.push(located(loc, node))
|
|
3531
3540
|
}
|
|
3532
3541
|
}
|
|
3533
3542
|
}
|
|
@@ -3711,9 +3720,22 @@ fn is_merge_trailer(n: &Node) -> bool {
|
|
|
3711
3720
|
| Node::PictureChildren(_)
|
|
3712
3721
|
)
|
|
3713
3722
|
|| matches!(n, Node::Located { inner, .. } if matches!(inner.as_ref(), Node::Table(_)))
|
|
3723
|
+
|| is_footnote_node(n)
|
|
3714
3724
|
|| as_paragraph(n).is_some_and(looks_like_caption)
|
|
3715
3725
|
}
|
|
3716
3726
|
|
|
3727
|
+
/// Whether a node is a footnote item (a [`Node::LabeledText`] labelled
|
|
3728
|
+
/// `footnote`), looking through a [`Node::Located`] wrapper — one of
|
|
3729
|
+
/// docling's merge skip-labels: a footnote between the two halves of a
|
|
3730
|
+
/// paragraph is looked past, never merged into.
|
|
3731
|
+
fn is_footnote_node(n: &Node) -> bool {
|
|
3732
|
+
let n = match n {
|
|
3733
|
+
Node::Located { inner, .. } => inner.as_ref(),
|
|
3734
|
+
other => other,
|
|
3735
|
+
};
|
|
3736
|
+
matches!(n, Node::LabeledText { label, .. } if label == "footnote")
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3717
3739
|
/// Rebuild node `i` as a paragraph with `text`, preserving its `<location>`
|
|
3718
3740
|
/// wrapper (and thus provenance) if it had one.
|
|
3719
3741
|
fn reparagraph(node: &Node, text: String) -> Node {
|
|
@@ -263,6 +263,12 @@ pub fn convert_text_layer(bytes: &[u8], name: &str) -> Result<DoclingDocument, P
|
|
|
263
263
|
convert_text_layer_pages(bytes, name, None)
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
/// The error for bytes no reader here can parse as a PDF — not a PDF at
|
|
267
|
+
/// all, or one damaged past the parser's repairs. Said about the file, not
|
|
268
|
+
/// about a missing renderer or text layer: no library would read it either.
|
|
269
|
+
pub(crate) const UNREADABLE: &str =
|
|
270
|
+
"not a readable PDF: the file is damaged or not a PDF (its structure could not be parsed)";
|
|
271
|
+
|
|
266
272
|
/// [`convert_text_layer`] restricted to a **1-based inclusive** page window
|
|
267
273
|
/// (issue #80's `--pages`); `None` converts everything. The window is
|
|
268
274
|
/// validated the same way as [`Pipeline::pages`]: `first <= last`, 1-based,
|
|
@@ -282,6 +288,11 @@ pub fn convert_text_layer_pages(
|
|
|
282
288
|
let mut doc = DoclingDocument::new(name);
|
|
283
289
|
let mut total = 0usize;
|
|
284
290
|
let parsed = textparse::pdf_text_pages(bytes);
|
|
291
|
+
// No pages at all: tell a file nothing can open apart from a PDF that
|
|
292
|
+
// merely has no text layer (the caller's "scanned? needs OCR" hint).
|
|
293
|
+
if parsed.is_empty() && textparse::load_document(bytes).is_none() {
|
|
294
|
+
return Err(PdfError::Document(UNREADABLE.into()));
|
|
295
|
+
}
|
|
285
296
|
// A vestigial layer (a few typed-in form fields over scanned pages) is not
|
|
286
297
|
// the document's text: return the empty document, which callers already
|
|
287
298
|
// report as "no text layer" — so an OCR-capable caller falls back to OCR
|
|
@@ -3499,6 +3510,29 @@ mod median_tests {
|
|
|
3499
3510
|
}
|
|
3500
3511
|
}
|
|
3501
3512
|
|
|
3513
|
+
#[cfg(test)]
|
|
3514
|
+
mod unreadable_tests {
|
|
3515
|
+
/// The text-layer path (the wasm build's only one) tells a file nothing
|
|
3516
|
+
/// can open apart from a PDF that merely has no text layer: garbage is
|
|
3517
|
+
/// an error about the file, a real PDF converts.
|
|
3518
|
+
#[test]
|
|
3519
|
+
fn text_layer_path_reports_an_unreadable_file() {
|
|
3520
|
+
for bytes in [b"garbage".as_slice(), b"", b"%PDF-1.7\n%%EOF\n"] {
|
|
3521
|
+
let err = super::convert_text_layer(bytes, "x.pdf").unwrap_err();
|
|
3522
|
+
assert!(err.to_string().contains("not a readable PDF"), "{err}");
|
|
3523
|
+
}
|
|
3524
|
+
let real = std::fs::read(
|
|
3525
|
+
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
|
3526
|
+
.join("../../tests/data/pdf/sources/multi_page.pdf"),
|
|
3527
|
+
)
|
|
3528
|
+
.unwrap();
|
|
3529
|
+
assert!(!super::convert_text_layer(&real, "multi_page.pdf")
|
|
3530
|
+
.unwrap()
|
|
3531
|
+
.nodes
|
|
3532
|
+
.is_empty());
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
|
|
3502
3536
|
#[cfg(test)]
|
|
3503
3537
|
mod send_check {
|
|
3504
3538
|
/// The Node bindings (`docling-node`) run a shared [`super::Pipeline`] on
|
|
@@ -1302,10 +1302,12 @@ mod native {
|
|
|
1302
1302
|
pub(super) struct Session<'a>(Infallible, PhantomData<&'a ()>);
|
|
1303
1303
|
pub(super) struct Page<'a>(Infallible, PhantomData<&'a ()>);
|
|
1304
1304
|
|
|
1305
|
+
/// Reached only for a file the pure-Rust object model could not read
|
|
1306
|
+
/// (every entry point tries it first), so the error is about the file:
|
|
1307
|
+
/// naming the missing library sent users of a corrupt or non-PDF upload
|
|
1308
|
+
/// looking for a pdfium install that would not have helped either.
|
|
1305
1309
|
pub(super) fn bind() -> Result<Lib, PdfError> {
|
|
1306
|
-
Err(PdfError::Document(
|
|
1307
|
-
"pdfium support is not compiled in (docling-pdf feature `pdfium`)".into(),
|
|
1308
|
-
))
|
|
1310
|
+
Err(PdfError::Document(crate::UNREADABLE.into()))
|
|
1309
1311
|
}
|
|
1310
1312
|
|
|
1311
1313
|
impl Lib {
|
|
@@ -89,10 +89,19 @@ fn scanned_page_extracts_table_and_keeps_chart() {
|
|
|
89
89
|
|
|
90
90
|
#[test]
|
|
91
91
|
fn scanned_pdf_yields_empty_document() {
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
let
|
|
92
|
+
// An image-only page — the no-text-layer contract is an empty doc, not
|
|
93
|
+
// an error (callers decide whether to fall back to OCR).
|
|
94
|
+
let scan = std::fs::read(
|
|
95
|
+
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
|
96
|
+
.join("../../tests/data/scanned/sources/ocr_test_raster.pdf"),
|
|
97
|
+
)
|
|
98
|
+
.unwrap();
|
|
99
|
+
let doc = docling_pdf::convert_text_layer(&scan, "scan.pdf").expect("no error");
|
|
95
100
|
assert!(doc.nodes.is_empty());
|
|
101
|
+
// Bytes that are no readable PDF at all are an error about the file,
|
|
102
|
+
// not an empty "scanned" document.
|
|
103
|
+
let err = docling_pdf::convert_text_layer(b"%PDF-1.4\n%%EOF", "x.pdf").unwrap_err();
|
|
104
|
+
assert!(err.to_string().contains("not a readable PDF"), "{err}");
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
/// #211: HEIC is detected by content, and without the `heif` feature the
|
|
@@ -764,7 +764,7 @@ dependencies = [
|
|
|
764
764
|
|
|
765
765
|
[[package]]
|
|
766
766
|
name = "docling"
|
|
767
|
-
version = "2.2.
|
|
767
|
+
version = "2.2.2"
|
|
768
768
|
dependencies = [
|
|
769
769
|
"calamine",
|
|
770
770
|
"csv",
|
|
@@ -794,7 +794,7 @@ dependencies = [
|
|
|
794
794
|
|
|
795
795
|
[[package]]
|
|
796
796
|
name = "docling-asr"
|
|
797
|
-
version = "2.2.
|
|
797
|
+
version = "2.2.2"
|
|
798
798
|
dependencies = [
|
|
799
799
|
"docling-core",
|
|
800
800
|
"docling-onnx",
|
|
@@ -805,7 +805,7 @@ dependencies = [
|
|
|
805
805
|
|
|
806
806
|
[[package]]
|
|
807
807
|
name = "docling-core"
|
|
808
|
-
version = "2.2.
|
|
808
|
+
version = "2.2.2"
|
|
809
809
|
dependencies = [
|
|
810
810
|
"png 0.18.1",
|
|
811
811
|
"pulldown-cmark",
|
|
@@ -816,7 +816,7 @@ dependencies = [
|
|
|
816
816
|
|
|
817
817
|
[[package]]
|
|
818
818
|
name = "docling-onnx"
|
|
819
|
-
version = "2.2.
|
|
819
|
+
version = "2.2.2"
|
|
820
820
|
dependencies = [
|
|
821
821
|
"docling-core",
|
|
822
822
|
"libloading 0.8.9",
|
|
@@ -825,7 +825,7 @@ dependencies = [
|
|
|
825
825
|
|
|
826
826
|
[[package]]
|
|
827
827
|
name = "docling-pdf"
|
|
828
|
-
version = "2.2.
|
|
828
|
+
version = "2.2.2"
|
|
829
829
|
dependencies = [
|
|
830
830
|
"docling-core",
|
|
831
831
|
"docling-onnx",
|
|
@@ -10,7 +10,7 @@ build-backend = "maturin"
|
|
|
10
10
|
name = "docling-rs"
|
|
11
11
|
# Fallback for local maturin builds — pypi-publish.yml overwrites this with the
|
|
12
12
|
# workspace version (root Cargo.toml) on every release.
|
|
13
|
-
version = "2.2.
|
|
13
|
+
version = "2.2.2"
|
|
14
14
|
description = "Rust port of docling (docling.rs): convert PDF/DOCX/HTML/... to Markdown or docling JSON. Python bindings."
|
|
15
15
|
readme = "README.md"
|
|
16
16
|
license = { text = "MIT" }
|
|
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
|
|
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
|