Skip to content

fix(converter): honor <ol start> in html → markdown - #270

Merged
pchuri merged 2 commits into
mainfrom
fix/html-ol-start
Oct 4, 2026
Merged

pchuri merged 2 commits into
mainfrom
fix/html-ol-start

Conversation

@pchuri

@pchuri pchuri commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Problem

storage → markdown has honored <ol start="N"> since #246, but html → markdown (lib/html-to-markdown.js, used by convert --input-format html) always numbered ordered lists from 1, so the two converters disagreed on the same markup.

htmlToMarkdown('<ol start="3"><li>a</li><li>b</li></ol>')
// before: "1. a\n2. b"
// after:  "3. a\n4. b"

Changes

  • An opening <ol> now keeps its attributes through tag normalization, and tokenizeLists reads start from it (double-quoted, single-quoted or unquoted). Attributes are parsed one by one and the first start wins, so start=7 inside another attribute's value is not read; the name is matched case-insensitively as in HTML (the walker's XML parser is case-sensitive), and numeric character references in the value are decoded. Only a real <ol followed by whitespace or > keeps its attributes, so <ol-x> and <ol/...> are normalised like any other tag. Keeping the attributes on the tag, instead of collecting them in a separate list, means a list inside a table cell (whose tags are stripped earlier) cannot shift the start of a later list.
  • The numbering rules now live in lib/list-start.js and are shared with StorageWalker: resolveListStart moved there unchanged (non-negative integers, at most nine digits including the run of items, otherwise 1), along with the "marker that cannot interrupt a paragraph" pattern. Empty items are not counted, as in the walker.
  • A list that does not start at 1 cannot interrupt a paragraph, so it gets a blank line before it, at top level and when nested in a list item. This is the same rule the walker applies.
  • The continuation indent was already derived from the marker width, so 9. → 10. indents nested content correctly.

Behavior notes

  • Only html input that carries <ol start> produces different output; everything else is unchanged.
  • start on <ul> is ignored, and other tags still have their attributes stripped.

Testing

  • New <ol start> (#252) tests: the repro, 0, whitespace and leading zeros, quote styles, invalid values falling back to 1, the nine-digit limit, empty items, marker widening past 9, several lists in one document, a list in a table cell before another list, nested and after-text blank-line rules, and an unpaired <ol start>.
  • Parity tests run the same markup through htmlToMarkdown and storageToMarkdown and expect identical output.
  • npm test (40 suites, 1616 tests) and eslint pass.

Fixes #252

pchuri added 2 commits October 4, 2026 21:21
html → markdown always numbered ordered lists from 1, while storage →
markdown has honored <ol start> since #246, so the two converters
disagreed on the same markup.

Keep the attributes of an opening <ol> through tag normalization and read
`start` when tokenizing lists. Share the numbering rules with the walker
(non-negative integers, at most nine digits, otherwise 1) by moving
resolveListStart into lib/list-start.js, and apply the same blank-line
rule for a list that does not start at 1 and so cannot interrupt a
paragraph, at top level and when nested in an item.

Fixes #252
- Keep the attributes of a tag only when it is a real `<ol` followed by
  whitespace or `>`, so `<ol-x>` and `<ol/...>` are normalised like
  any other tag instead of losing the list.
- Parse attributes one by one and take the first `start`, so
  `start=7` inside another attribute's value is not read. The name is
  matched case-insensitively, as in HTML.
- Decode numeric character references in the value, matching the
  walker's parser.
@pchuri
pchuri merged commit ca153e3 into main Oct 4, 2026
6 checks passed
@pchuri
pchuri deleted the fix/html-ol-start branch October 4, 2026 12:27
github-actions Bot pushed a commit that referenced this pull request Oct 4, 2026
## [2.27.2](v2.27.1...v2.27.2) (2026-10-04)

### Bug Fixes

* **converter:** honor <ol start> in html → markdown ([#270](#270)) ([ca153e3](ca153e3)), closes [#246](#246) [#252](#252)
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 2.27.2 🎉

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.

html → markdown ignores <ol start> (storage → markdown honors it since #246)

1 participant