Sashmark / Blog

Markdown numbered list not working? Why it restarts

Bobby Huang ·

When a Markdown numbered list is not working, this page gives each cause its own section. The sections below cover the start number, the two marker styles, blank lines, the line just above a list and how far to indent content under an item, with a pandoc test for every fix. Nesting has its own post.

Key takeaways

  • Section one covers what happens to numbers typed after the first.
  • One section compares the period and parenthesis marker styles and what mixing them does.
  • The restart section shows one reason a count starts over, with a fix you can test.
  • A section on blank lines covers loose lists and two lists that run together.
  • A numbered check pass near the end works through a broken list one rule at a time.

You wrote five steps. What renders is steps 1 and 2, a code sample, then a fresh list that counts from 1 again. Or you typed 4, 9 and 2, and the page counts 4, 5, 6.

The parser is following the rules. CommonMark keeps its list rules short, and each of these surprises maps to one of them. You'll find sections on the start number, the two marker styles, blank lines, the line just above a list and indenting content under an item. Every fix was checked with pandoc 3.8.3. For bullets inside quotes and lists inside lists, read block quotes and nested lists.

Only the first number counts

The first item of an ordered list sets where the count begins. Later item numbers are ignored, per the spec. So this file:

3. Jane Doe
7. Doe Holdings
1. Doe Lane

fed to pandoc -f commonmark -t html start.md comes out as <ol start="3" type="1"> with three items. The 7 and the 1 leave no trace in the HTML. The list counts 3, 4, 5.

That rule helps as much as it hurts. You can write 1. on every line and still get a list that counts up; a test file with three 1. items came out as one plain <ol>. When an agent inserts a step in a list like that, no other line has to change, which keeps the diff to one line. Our post on small agent diffs explains why that matters in review.

The start number has limits. A marker is one to nine digits followed by a period or a closing parenthesis. Tested locally, 123456789. ok became a list starting at 123456789, while 1234567890. not ok stayed a plain paragraph. Leading zeros are fine, so 003. starts at 3. A minus sign is not, so -1. stays text.

Period or parenthesis

Both 1. and 1) start an ordered list. The trouble starts when one file mixes them. Two items belong to the same list only when their markers use the same delimiter, and the spec puts it plainly: changing the delimiter starts a new list.

1. Jane Doe
2. Doe Holdings
3) Doe Lane

Pandoc turns that into two lists. The first holds two items. The second opens with <ol start="3" type="1"> and holds one. The numbers still read 1, 2, 3, but many viewers add space where one list ends and another begins, so the third step can look cut off from the others. Pick one delimiter per file and keep it.

Why a list starts over at 1

A list is a run of list items of the same type. Any block that isn't inside an item ends the run; blank lines don't count, which a later section covers. The next item then opens a new list with its own start number, and if you wrote 1. on every line, that number is 1 again.

One culprit is a code fence placed at the left margin between two steps:

1. Install the tool

```
pandoc --version
```

1. Run the check

Pandoc prints an <ol> with one item, then a <pre> block, then a second <ol> that starts at 1. The fence sits outside the list because it isn't indented far enough to belong to the first item. A plain paragraph or a block quote at the left margin does the same thing; in local tests, pandoc split the list around each one.

Indent the fence so it falls under the step:

1. Install the tool

   ```
   pandoc --version
   ```

1. Run the check

Now pandoc prints a single <ol> with two items, and the code block sits inside the first one. Fences themselves get their own code block post.

Indenting content under a step

The amount comes from the marker. When one to four spaces follow the marker, take the marker's width, add those spaces, and indent the item's later lines by that total. With five or more spaces, the spec reads the text as an indented code block that starts one space after the marker, so later lines need the marker's width plus one. The spec stresses that the position of the text after the marker sets how much indent the following blocks need.

For 1. that's two characters plus one space, so three spaces. Long lists change the count. At 10. the marker is three characters wide, so the item's content needs four spaces:

10. Jane Doe

    Second paragraph

Pandoc keeps both paragraphs inside one <li>. With three spaces instead of four, Second paragraph drops outside the list and becomes its own <p> after it. Writing 1. on every line sidesteps this, since the marker stays the same width all the way down.

Blank lines: loose lists and lists that merge

Blank lines between items don't end a list. The spec lets items be separated by any number of blank lines. That has two effects that can look like bugs.

First, the list turns loose. A list is loose when blank lines separate any of its items, or when one item directly contains two blocks separated by an empty line. Loose lists wrap paragraph text in <p> tags. Pandoc showed this for a two-item list with one blank line: each item became <li><p>...</p></li>. Many viewers add vertical space around those paragraphs, so the list looks spread out.

Second, two lists you meant to keep apart can merge. Two ordered lists with the same delimiter and only blank lines between them parse as one list. Given items 1 and 2, two blank lines, then a new 1 and 2, pandoc produced one <ol> holding four items.

The spec offers a fix for exactly this case: place a blank HTML comment, <!-- -->, alone on a line between the lists, with a blank line on each side. Pandoc then printed two separate <ol> elements and passed the comment through. Switching the second list to the other delimiter also splits them, as covered above. A heading between them works too; pandoc printed a list, the <h2>, then a second list.

Lists that won't start under a sentence

In CommonMark a list can interrupt a paragraph, so no blank line is needed between a sentence and the list below it. The spec adds two limits for that case: a numbered list must start at 1, and the first item of any list can't start with a blank line. Its stated purpose is to stop most stray lists in prose where a wrapped line happens to begin with a number.

Steps for Jane Doe:
2. Open the file
3. Save it

Pandoc prints one paragraph: <p>Steps for Jane Doe: 2. Open the file 3. Save it</p>. Two fixes work. Start the list at 1, or leave an empty line under the sentence. With the blank line, pandoc printed the paragraph and then <ol start="2" type="1">.

The reverse trap catches prose. A wrapped line that begins with 1. and a space does start a list under the line above it. Pandoc split Jane Doe owns from 1. Doe Lane and two other lots. into a paragraph and a one-item list. Escape the period as 1\. and the line stays in the paragraph, which pandoc confirmed.

A check pass for a broken list

When a list renders wrong, work through this list from the top:

  1. Read the first marker. Its number is the start number. Later numbers don't matter.
  2. Compare delimiters. Every item should use . or every item should use ).
  3. Locate the restart. Look at the line just above that item. If it's a fence, a paragraph or a quote at the left margin, indent it under the previous step.
  4. Count the indent. With one to four spaces after the marker, use the marker width plus those spaces. With the same spacing after it, a two-digit marker needs one more space than a one-digit marker.
  5. Look above the list. If a sentence sits directly on top and the list starts at anything other than 1, add a blank line.
  6. Look for merged lists. If two lists became one, add <!-- --> between them or change the delimiter.
  7. Render it. Count the <ol tags that pandoc -f commonmark -t html steps.md prints. One list should mean one tag.

Keep the Markdown cheat sheet open to see list syntax next to the rest of Markdown.

Where Sashmark fits

For Markdown that an agent rewrites over and over, Sashmark is a desktop reader and editor in the works. It is in development and has not been released. The app itself has no AI features. Work planned for the first version covers a live render of lists, code blocks and check-box lists; direct edits on that rendered page, where any line you leave alone is saved exactly as it was; and Live Reload when the file changes outside the app, holding your reading position. The plan also lists a Changes View, marking what is new since the last snapshot you saw. The help pages, planned features and roadmap track what is built so far and what comes next.

Project updates live at sashmark.com.

Questions

Why does my numbered list start over at 1?
The restart section in the body names one cause and shows how to keep the steps in one list.
Why are the numbers I typed not the numbers I see?
The opening section on start numbers explains which number the parser keeps.
Why won't my list show up under a sentence?
The section on lists after a paragraph covers this case and two ways around it.
How far should I indent a code sample under a step?
The indenting section works through the count with tested examples.

What Sashmark plans for v1: Features · Roadmap

View as Markdown