fix(docx): Missing list items after numbered header (#2665) (#2678)
* fix(docx): Correct list numbering with interleaved numIds and hierarchical markers
Fixes incorrect numbering and missing items in DOCX documents that use
multiple interleaved numbering sequences (numIds).
Changes:
* Reset sub-level counters in _get_list_counter when a parent level
advances, preventing counter bleed-across (e.g. "4. Functional
Requirements" now correctly renders as "1. Functional Requirements")
* Add _build_enum_marker helper to produce hierarchical markers in
"1.2.3." format instead of flat single-level counters
* Fix anchor-based level calculation in new-sequence branch: use
level_at_new_list + ilevel instead of _get_level() to correctly
place items from a different numId at the right document level
* Only set level_at_new_list in the else case (when None) to avoid
corrupting the anchor when switching between interleaved numIds
* Remove _reset_list_counters_for_new_sequence from new-sequence branch
so that returning to a previously seen numId continues its counter
(e.g. Appendix A=1, B=2, C=3 instead of A=1, B=1, C=1)
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com>
* style(docx): apply Ruff formatting to msword_backend
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com>
* test(docx): add unit tests for list counter, enum marker, and sequence reset helpers
Adds test_list_counter_and_enum_marker covering helper methods introduced
in the list numbering fix: counter increment, sub-level reset on parent
advance, hierarchical marker building, and selective sequence reset.
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com>
* fix(docx): read start values from abstractNum for correct numbering
When Word creates a new numbering definition that continues from a
previous list, it embeds start values in the abstractNum XML instead of
reusing the same numId. Docling previously ignored these start values
and always initialized counters from 1, producing incorrect markers
like "1.1.1." instead of "2.3.1.".
Changes:
* Add _get_level_element helper to extract level XML from abstractNum,
eliminating duplicated XML traversal in _is_numbered_list
* Add _get_start_value to read w:start from the numbering definition
* Initialize counters in _get_list_counter using start values
* Use start values as fallback in _build_enum_marker for parent levels
that have not been explicitly incremented
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com>
* test(docx): add interleaved numId edge case to unit_test_headers_numbered
Extends the existing test document with an Appendix section that uses a
different numId, followed by list items that resume the original
numbering sequence with Word-embedded start values (e.g. 2.3.1.).
Updates groundtruth files accordingly.
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com>
* style(docx): add return type annotation to _get_level_element
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com>
---------
Signed-off-by: Emre Çalışır <emrecalisir95@gmail.com> E
Emre Çalışır committed
2f7c09e0d8f07a5fa0aaf4f33bdfb1f71d3f3063
Parent: 96d7c7e
Committed by GitHub <noreply@github.com>
on 3/20/2026, 8:24:27 PM