Skip to content

fix(html): number ordered list items by their type, reversed and value attributes - #4900

Open
morten-lagabote wants to merge 1 commit into
docling-project:mainfrom
morten-lagabote:fix/html-ol-type-reversed-value
Open

morten-lagabote wants to merge 1 commit into
docling-project:mainfrom
morten-lagabote:fix/html-ol-type-reversed-value

Conversation

@morten-lagabote

Copy link
Copy Markdown
Contributor

The HTML backend numbered the items of an <ol> from its start attribute only. The kind of marker was lost, so lettered and Roman-numbered lists got decimal numbers.

The marker of each item now follows the ordinal value of the item and the kind of marker of the list:

  • The kind of marker comes from the type attribute (1, a, A, i, I), or from a list-style-type keyword in the inline style of the <ol> (decimal, lower-alpha, lower-latin, upper-alpha, upper-latin, lower-roman, upper-roman). The inline style wins, as in browsers. In the new helper _format_ol_marker, letters count a to z, then aa, ab, and Roman numerals cover 1 to 3999, as the CSS counter styles. Outside that range, the marker is decimal.
  • A reversed list counts down, by default from its number of items.
  • The value attribute of an <li> sets the number of the item, and the items after it continue from it. The value is parsed with _parse_ol_start (fix(html): parse the start of an ordered list by the HTML rules for integers #4713), so a negative value is ignored, as a negative start.

A list without these attributes is unchanged: its items keep an empty marker. In Markdown, a letter or Roman numeral is written as - a. first, as the serializer writes other markers that are not decimal.

Issue resolved by this Pull Request:
Resolves #4899

Checklist:

  • Documentation has been updated, if necessary.
  • Examples have been added, if necessary.
  • Tests have been added, if necessary.

Review evidence:

  • Before (main 7a25855) / after, on the public documents of HTML backend: lettered and Roman-numbered lists get decimal numbers #4899:
    • Finanstilsynet, Veileder til hvitvaskingsloven: the 8 lists are numbered 1., 2., ... before. After, they have the letters and Roman numerals that Chrome shows. Nothing else changes in the Markdown export.
    • NAV, Rundskriv til ftrl kap. 11: the 3 lists with type="a" are numbered 1., 2., ... before, and a., b., ... after. Nothing else changes in the Markdown export.
  • Behavior: I compared the markers of 43 small lists with the markers that Chrome 155 shows (from its accessibility tree). 33 are the same. This PR does not change the 10 differences:
    • A decimal list without start (also type="1", an unknown type and list-style-type: decimal): Docling keeps an empty marker, and the Markdown serializer numbers the items.
    • A negative value: Chrome counts from it, Docling from 1, as for a negative start.
    • <ul>, and keywords such as lower-greek: not supported.
  • Test: test_ordered_list_item_marker_from_attributes (12 cases). 11 cases fail without the fix.
  • Reference data: no change. The 30 backend test modules that do not need models pass: 1194 passed, 13 skipped.
  • Checks: the hooks pass on the two changed files (Ruff, ty, Tach, license header, max lines).
  • Not run: the PDF and OCR tests (no change in those code paths).

…e attributes

The HTML backend numbered the items of an `<ol>` only from its `start`
attribute. A list with `type="a"`, `"A"`, `"i"` or `"I"`, or with the same
kind of marker set by a `list-style-type` keyword in its inline style, got
decimal numbers. A `reversed` list counted up, and the `value` attribute of
an `<li>` had no effect. Legal texts refer to list items by their letter
("bokstav a"), so the letters were lost.

The marker of each item now follows the ordinal values of the HTML
specification and the counter styles that browsers render. A list without
these attributes is unchanged.

Signed-off-by: Morten Dæhli Aslesen <morten@lagabote.no>
@github-actions

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @morten-lagabote, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) bug Something isn't working html issue related to html backend labels Oct 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

AI triage (advisory)

Checked commit b441869591. The analysis read the diff only. It did not run code from this pull request.

The HTML backend now numbers <ol> items by the type attribute, the inline list-style-type, the reversed attribute, and the value attribute of each <li>. A new helper, _format_ol_marker, writes letter and Roman numeral markers.

Topic labels added: bug, html.

CI safety: no concern found. A maintainer must still approve CI.

2 related pull request(s) in the same code
PR State Signal Assessment
#4848 open changes the same code related: This PR changes the same file, but it changes convert() to add convert_into() and edits a docstring. This PR changes list marker numbering.
#4713 merged referenced as #4713 related: This PR is merged and added _parse_ol_start for the start attribute. This PR reuses that helper to add marker types, reversed, and value, so it does not repeat the change.

The ai:* labels are advisory. They do not approve CI and they do not add tests:full. A new push runs this check again.

@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 19, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI first review (advisory): no blocker found

This review covers the full diff at b441869591. It read the code and did not run it.

The PR adds letter, Roman numeral, reversed, and value marker support to the HTML ordered-list backend. The logic is self-consistent and the new test covers boundary values, interrupted lists, and fallback to decimal. No regressions are visible from code inspection: plain <ol> without attributes follows the same code path as before (start=None, ordinal=None, marker ""), and decimal <ol start="N"> produces the same result via _format_ol_marker(ordinal, "1"). The one deviation from the HTML spec — negative <li value> is ignored — is stated in the PR description and matches the existing start behavior.

A maintainer makes the merge decision. This review never approves the pull request.

@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.45455% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
docling/backend/html_backend.py 95.45% 0 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) bug Something isn't working html issue related to html backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTML backend: lettered and Roman-numbered lists get decimal numbers

1 participant