You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Docling already converts to a structured DoclingDocument and exports retrieval chunks as JSONL via --to chunks. Each ChunkedDocumentResultItem carries text, raw_text, headings, captions, doc_items, page_numbers, and metadata (including origin). It does not carry the HTML of the items in that chunk.
Marker's --output_format chunks puts full HTML on each flat block so a RAG ingest job does not have to walk a tree. Users who want HTML tables (rowspan/colspan) currently run a second --to html export and try to join it to chunks themselves. docs/concepts/serialization.md already notes that HTML keeps table structure that Markdown flattens.
This is a small, default-off field on the existing chunk record, filled by HTMLDocSerializer over that chunk's doc_items. The serializer is already imported in docling/cli/main.py. docs/examples/trivial_chunking.py already serializes per item.
This feature was proposed from code analysis without any hands-on usage.
Research Summary
General Project Dogfooding (Phase 0.5 Step 1e / Phase 1b.5)
Installed and ran project: NO
Score: 0/10
Screenshots: none
Key observations: bulk skip. Clone inspected at 890dd42.
Feature-Specific Validation (Phase 2d)
Feature validated: HTML field on ChunkedDocumentResultItem
Key finding: ChunkedDocumentResultItem (docling/datamodel/service/responses.py:156-195) has no html. CLI writer (docling/cli/main.py:658-706) dumps model_dump(mode="json") with text/raw_text only. HTMLDocSerializer is imported at main.py:39-43. Per-item serialize lives at docs/examples/trivial_chunking.py:76-81. tests/test_cli.py covers doclang/dclx/latex/html, not chunks.
Marker (datalab-to/marker) --output_format chunks emits FlatBlockOutput with html, id, block_type, page, polygon, bbox, section_hierarchy. README: "full HTML of each block inside, so you don't need to crawl the tree. This enable flexible and easy chunking for RAG." Renderer: https://github.com/datalab-to/marker/blob/6ae38895/marker/renderers/chunk.py
Docling --to chunks already flattens to JSONL records with doc_items refs. The missing piece is the HTML payload Marker puts on each record. Full-document save_as_html exists and is a different export.
Maintainer Analysis
@cau-git: extraction, pdfium, in-flight #4201 and #3457. Not the chunk HTML owner.
@dolfim-ibm / @vagenas: core IR, serializers, chunking docs. Likely reviewers for this PR.
Rejected / delayed: unsigned DCO; feature PRs with no prior issue/Discussion; label code agent slop.
Proposed Solution
Add an optional html: str | None = None field on ChunkedDocumentResultItem. Default omitted / null so existing JSONL stays byte-compatible when the flag is off.
Add include_html: bool = False on BaseChunkerOptions (same shape as include_raw_text).
Add CLI --chunks-include-html (default false). When set, export_documents fills html by serializing the chunk's doc_items with HTMLDocSerializer.
Put the serialize loop in docling/utils/chunk_html.py so the CLI and any later serve path share one helper. Helper signature:
Implementation: construct HTMLDocSerializer(doc=doc) once per document (caller may pass a cached serializer), then for each item call ser.serialize(item=item) as trivial_chunking.py:81 does, concatenate non-empty ser_res.text. Do not wrap a fake mini-document. Do not change the existing text / raw_text fields.
Default off. No new OutputFormat. No change to Marker-incompatible fields (polygon, block_type).
Add include_html: bool = False with a description matching include_raw_text.
docling/utils/chunk_html.py (new)
SPDX header (MIT).
html_for_chunk(doc, items, *, serializer=None) -> str.
Empty items -> "".
Skip items whose serialize result is empty (same skip as trivial_chunking).
docling/cli/main.py
New typer option --chunks-include-html next to --chunks-tokenizer (~line 786-800).
Thread bool into export_documents (signature ~480, call site ~1733).
Inside the JSONL loop (~686-699): if flag, html=html_for_chunk(conv_res.document, doc_chunk.meta.doc_items).
Reuse one HTMLDocSerializer(doc=conv_res.document) per file, not per chunk.
Tests
tests/test_chunk_html.py (new): load docs/examples/data/normal_4pages.json or a tiny constructed DoclingDocument; assert helper returns a string containing a tag from a known item; empty items -> "".
tests/test_cli.py: add test_cli_exports_chunks mirroring test_cli_exports_latex (markdown source, --to chunks, read *.chunks.jsonl, parse first line). Default run: html is null/absent. Flag run: html is a non-empty string. Keep hybrid tokenizer cost down: --chunks-type hierarchical if hierarchical does not pull HuggingFace.
Docs
docs/concepts/chunking.md: one short subsection under Usage that --to chunks --chunks-include-html adds html on each JSONL record.
docs/examples/hybrid_chunking.ipynb: one cell showing the field when using CLI or constructing ChunkedDocumentResultItem.
Estimated scope: ~80-120 lines of implementation plus tests and a notebook cell. S.
Do not: change text contextualize; add HTML to HierarchicalChunker itself; wait on serve-side chunk assembly (CLI is the only ChunkedDocumentResultItem(...) constructor today; include_html on options is the serve hook).
Alternatives Considered
Full-document HTML plus client-side split. Rejected: that is --to html today. The Marker gap is per-chunk HTML so ingest does not walk a tree.
Put HTML only in metadata. Rejected: Marker and the CLI record already use first-class fields (text, raw_text). A first-class optional html matches that shape. metadata stays for origin.
Happy to follow maintainer guidance before any PR (CLA noted).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
feat: optional HTML field on RAG chunk records
Motivation
Docling already converts to a structured
DoclingDocumentand exports retrieval chunks as JSONL via--to chunks. EachChunkedDocumentResultItemcarriestext,raw_text,headings,captions,doc_items,page_numbers, andmetadata(includingorigin). It does not carry the HTML of the items in that chunk.Marker's
--output_format chunksputs full HTML on each flat block so a RAG ingest job does not have to walk a tree. Users who want HTML tables (rowspan/colspan) currently run a second--to htmlexport and try to join it to chunks themselves.docs/concepts/serialization.mdalready notes that HTML keeps table structure that Markdown flattens.This is a small, default-off field on the existing chunk record, filled by
HTMLDocSerializerover that chunk'sdoc_items. The serializer is already imported indocling/cli/main.py.docs/examples/trivial_chunking.pyalready serializes per item.This feature was proposed from code analysis without any hands-on usage.
Research Summary
General Project Dogfooding (Phase 0.5 Step 1e / Phase 1b.5)
890dd42.Feature-Specific Validation (Phase 2d)
ChunkedDocumentResultItemChunkedDocumentResultItem(docling/datamodel/service/responses.py:156-195) has nohtml. CLI writer (docling/cli/main.py:658-706) dumpsmodel_dump(mode="json")withtext/raw_textonly.HTMLDocSerializeris imported atmain.py:39-43. Per-item serialize lives atdocs/examples/trivial_chunking.py:76-81.tests/test_cli.pycovers doclang/dclx/latex/html, not chunks.Project Context
DoclingDocumentas the structured IR for gen-AI (convert, extract, chunk, serve)Related Issues & Community Signals
html chunks jsonl serialize HTMLDocSerializer rag chunk html(PHASE_3A CLEAN).Social Search Results
Consumed from parent host_handoff. last30days was not run on this host. Path B was not taken.
Competitive Analysis
Marker (
datalab-to/marker)--output_format chunksemitsFlatBlockOutputwithhtml,id,block_type,page,polygon,bbox,section_hierarchy. README: "full HTML of each block inside, so you don't need to crawl the tree. This enable flexible and easy chunking for RAG." Renderer: https://github.com/datalab-to/marker/blob/6ae38895/marker/renderers/chunk.pyDocling
--to chunksalready flattens to JSONL records withdoc_itemsrefs. The missing piece is the HTML payload Marker puts on each record. Full-documentsave_as_htmlexists and is a different export.Maintainer Analysis
What Gets Merged vs Rejected
feat(cli):,feat(chunking):), tests + docs checklist, DCO-s.code agent slop.Proposed Solution
Add an optional
html: str | None = Nonefield onChunkedDocumentResultItem. Default omitted / null so existing JSONL stays byte-compatible when the flag is off.Add
include_html: bool = FalseonBaseChunkerOptions(same shape asinclude_raw_text).Add CLI
--chunks-include-html(default false). When set,export_documentsfillshtmlby serializing the chunk'sdoc_itemswithHTMLDocSerializer.Put the serialize loop in
docling/utils/chunk_html.pyso the CLI and any later serve path share one helper. Helper signature:Implementation: construct
HTMLDocSerializer(doc=doc)once per document (caller may pass a cached serializer), then for each item callser.serialize(item=item)astrivial_chunking.py:81does, concatenate non-emptyser_res.text. Do not wrap a fake mini-document. Do not change the existingtext/raw_textfields.Default off. No new OutputFormat. No change to Marker-incompatible fields (
polygon,block_type).Approach
docling/datamodel/service/responses.py(ChunkedDocumentResultItem, ~line 156)htmlwith Field description: HTML serialization of this chunk'sdoc_items, omitted unless requested.docling/datamodel/service/chunking.py(BaseChunkerOptions, ~line 23)include_html: bool = Falsewith a description matchinginclude_raw_text.docling/utils/chunk_html.py(new)html_for_chunk(doc, items, *, serializer=None) -> str."".docling/cli/main.py--chunks-include-htmlnext to--chunks-tokenizer(~line 786-800).export_documents(signature ~480, call site ~1733).html=html_for_chunk(conv_res.document, doc_chunk.meta.doc_items).HTMLDocSerializer(doc=conv_res.document)per file, not per chunk.tests/test_chunk_html.py(new): loaddocs/examples/data/normal_4pages.jsonor a tiny constructedDoclingDocument; assert helper returns a string containing a tag from a known item; empty items ->"".tests/test_cli.py: addtest_cli_exports_chunksmirroringtest_cli_exports_latex(markdown source,--to chunks, read*.chunks.jsonl, parse first line). Default run:htmlis null/absent. Flag run:htmlis a non-empty string. Keep hybrid tokenizer cost down:--chunks-type hierarchicalif hierarchical does not pull HuggingFace.docs/concepts/chunking.md: one short subsection under Usage that--to chunks --chunks-include-htmladdshtmlon each JSONL record.docs/examples/hybrid_chunking.ipynb: one cell showing the field when using CLI or constructingChunkedDocumentResultItem.Estimated scope: ~80-120 lines of implementation plus tests and a notebook cell. S.
Do not: change
textcontextualize; add HTML to HierarchicalChunker itself; wait on serve-side chunk assembly (CLI is the onlyChunkedDocumentResultItem(...)constructor today;include_htmlon options is the serve hook).Alternatives Considered
--to htmltoday. The Marker gap is per-chunk HTML so ingest does not walk a tree.metadata. Rejected: Marker and the CLI record already use first-class fields (text,raw_text). A first-class optionalhtmlmatches that shape.metadatastays fororigin.Happy to follow maintainer guidance before any PR (CLA noted).
All reactions