Skip to content

fix(storage-walker): honor <ol start> in storage → markdown - #246

Merged
pchuri merged 4 commits into
mainfrom
fix/ordered-list-start
Sep 30, 2026
Merged

pchuri merged 4 commits into
mainfrom
fix/ordered-list-start

Conversation

@pchuri

@pchuri pchuri commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Pull Request Template

Description

Storage → markdown now numbers ordered lists from <ol start> instead of always starting at 1.

<ol start="3"><li>three</li><li>four</li></ol>

now becomes 3. three\n4. four (it used to be 1. three\n2. four).

  • Start validation: CommonMark ordered list markers are 1–9 digits. A start value that markdown cannot express falls back to 1. That covers negative, signed, non-integer and empty values, and runs whose last number would go past 999999999. Leading zeros and surrounding whitespace are ignored, and start="0" is kept. Empty <li> items still don't use up a number.
  • Paragraph interruption: In CommonMark, only an ordered list that starts at 1 can interrupt a paragraph. Without a blank line, - Parent\n 3. Child is parsed as the single paragraph Parent 3. Child. A list with any other start is therefore separated by a blank line in three places:
    • after inline text (Steps:<ol start="3">…);
    • after a nested item's lead-in text;
    • after a callout header (> **INFO**\n>\n> 3. a). This uses a structural check that skips empty or comment nodes, looks through transparent wrappers (div, p, span, ac:layout*), and stops at leading prose, so a paragraph <p>3. a</p> or text like 3. fake is not affected.
  • Where lists stay tight: after headings, thematic breaks and code fences, because those blocks can't absorb the next line.
  • Marker width: since fix(storage-walker): preserve nested list structure in storage → markdown (#238) #239, the continuation indent comes from marker.length, so 9. → 10. indents nested content by 4 automatically.
  • Markdown → storage: this already emits start, through markdown-it plus html-to-storage's attribute pass-through. Round trips md → storage → md → storage are now stable, and tests cover them.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Testing

  • Tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

npx jest: 39 suites and 1363 tests pass (after merging current main, including #247, #249 and #250). npx eslint lib tests is clean. The new tests in tests/macro-converter.test.js ("ordered list start (#241)") check exact output with toBe, including exact storage in the round-trip cases.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules

Additional Context

Follow-up to #238 / #239. The callout header separator is built on #249's quoteLines. These are known and left out of scope:

  • Adjacent lists merge: <ol>…</ol><ol>…</ol> is read back as one markdown list, so the second list's start is lost. This already happens on main with plain <ol>s.
  • reversed: markdown has no way to express this attribute.
  • HTML → markdown path: lib/html-to-markdown.js, a separate converter, also ignores start. That is left for a follow-up.

Fixes #241

Number ordered lists from the start attribute instead of always 1.
Values markdown cannot express (negative, non-integer, or a run that
would exceed CommonMark's 9-digit marker) fall back to 1.

Only an ordered list starting at 1 may interrupt a paragraph, so a
list with another start is now separated by a blank line after inline
text, after a nested item's lead-in paragraph, and after a callout
header. Headings, thematic breaks and code fences cannot absorb the
list, so nested lists stay tight after them.

Markdown → storage already emits start via markdown-it, so round trips
now keep the numbering.

Fixes #241
…t's leading list

Also stop at leading prose text so it is not mistaken for a list, and
add round-trip coverage for code-first items, the nine-digit limit with
empty items, tight lists after headings and fences, and start="0".
@pchuri
pchuri merged commit b115d36 into main Sep 30, 2026
6 checks passed
@pchuri
pchuri deleted the fix/ordered-list-start branch September 30, 2026 00:35
github-actions Bot pushed a commit that referenced this pull request Sep 30, 2026
## [2.25.6](v2.25.5...v2.25.6) (2026-09-30)

### Bug Fixes

* **storage-walker:** honor <ol start> in storage → markdown ([#246](#246)) ([b115d36](b115d36)), closes [#241](#241)
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.25.6 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ordered list start attribute (<ol start>) is ignored in storage → markdown

1 participant