From 1568a8910f60829adfbc1eff43151090b73806b9 Mon Sep 17 00:00:00 2001 From: Vincent Gao Date: Sat, 20 Jun 2026 19:22:54 +0200 Subject: [PATCH] Honor the value attribute on
  • in ordered lists markdownify numbered
      items purely by position, so an explicit value attribute on an
    1. was ignored. Per the HTML spec, value sets that item's ordinal and the following items continue counting from it, e.g. '
      1. a
      2. b
      3. c' is 1, 5, 6 (not 1, 2, 3). Walk from the item backwards for the nearest numeric value and offset by the number of items that follow it. Non-numeric or negative values fall back to positional numbering, mirroring the existing start guard. --- markdownify/__init__.py | 12 +++++++++++- tests/test_lists.py | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/markdownify/__init__.py b/markdownify/__init__.py index 148d340..c271bbb 100644 --- a/markdownify/__init__.py +++ b/markdownify/__init__.py @@ -638,7 +638,17 @@ def convert_li(self, el, text, parent_tags): start = int(parent.get("start")) else: start = 1 - bullet = '%s.' % (start + len(el.find_previous_siblings('li'))) + # An explicit `value` on an
      4. sets that item's ordinal and the + # following items continue counting from it (per the HTML spec). + # Walk from this item backwards (nearest first) for the closest + # numeric `value`; the offset is how many items follow it. + number = start + len(el.find_previous_siblings('li')) + for offset, li in enumerate([el] + el.find_previous_siblings('li')): + value = li.get("value") + if value and str(value).isnumeric(): + number = int(value) + offset + break + bullet = '%s.' % number else: depth = -1 while el: diff --git a/tests/test_lists.py b/tests/test_lists.py index e9480ab..9b68ced 100644 --- a/tests/test_lists.py +++ b/tests/test_lists.py @@ -49,6 +49,13 @@ def test_ol(): assert md('
        1. a
        2. b
        ') == '\n\n1. a\n2. b\n' assert md('
        1. a
        2. b
        ') == '\n\n1. a\n2. b\n' assert md('
        1. first para

          second para

        2. third para

          fourth para

        ') == '\n\n1234. first para\n\n second para\n1235. third para\n\n fourth para\n' + # An explicit `value` sets the item's ordinal; following items continue from it. + assert md('
        1. a
        2. b
        3. c
        ') == '\n\n1. a\n5. b\n6. c\n' + assert md('
        1. a
        2. b
        ') == '\n\n7. a\n8. b\n' + assert md('
        1. a
        2. b
        3. c
        4. d
        ') == '\n\n2. a\n10. b\n4. c\n5. d\n' + # Non-numeric or negative `value` falls back to positional numbering. + assert md('
        1. a
        2. b
        ') == '\n\n1. a\n2. b\n' + assert md('
        1. a
        2. b
        ') == '\n\n1. a\n2. b\n' def test_nested_ols():