rumdl 0.3.0

A fast Markdown linter and formatter written in Rust
Documentation
# MD069 - No duplicate list markers

Aliases: `no-duplicate-list-markers`

## What this rule does

Detects duplicate list markers that typically occur from copy-paste with editor auto-list-continuation, such as `- - text` instead of `- text`.

## Why this matters

- **Unintended nesting**: CommonMark parses `- - text` as a nested list, which is almost never the intended behavior
- **Visual confusion**: The extra marker clutters the document and creates unexpected formatting
- **Copy-paste artifacts**: This pattern commonly occurs when copying list items while editors auto-continue lists
- **Easy to overlook**: The duplicate marker blends in and can be missed during review

## Examples

### ✅ Correct

```markdown
- First item
- Second item
- Third item
```

### ❌ Incorrect

<!-- rumdl-disable MD069 -->

```markdown
- - First item (accidental duplicate)
* * Second item
- * Mixed markers
```

<!-- rumdl-enable MD069 -->

### 🔧 Fixed

```markdown
- First item
* Second item
- Mixed markers
```

## How this happens

This pattern typically occurs when:

1. **Copy-paste in editors**: You copy a list item, move to the next line (where the editor auto-inserts a list marker), then paste. Result: two markers.

2. **Double keystroke**: Accidentally pressing the marker key twice.

3. **Merge conflicts**: Git merge artifacts can create duplicate markers.

## Configuration

This rule has no configuration options.

## Automatic fixes

This rule collapses the run of markers into the first one and keeps its indentation. For example:

- `- - text` becomes `- text`
- `* * text` becomes `* text`
- `- * text` becomes `- text` (keeps the first marker)
- `- - - text` becomes `- text` (the whole run is collapsed, so one pass is enough)

The first marker is kept, not the second, because it is the marker of the list the line is already in. Keeping the second one changed the bullet character, which split a list (`- a`, `- * b`, `- c` became three lists) or merged it into a neighbouring one, and a run of three or more markers needed several passes to settle.

The fix is withheld, and the warning kept, when the collapse is not safe:

- A later line that is indented to the content of the inner item (a continuation paragraph, a nested item, a setext underline) would end up in a different place, because the collapse moves the content column of the item. Fix such a line by hand.
- The collapsed line would itself be a thematic break, as in `- * - - -`.

## What this rule does NOT flag

- `- - -`, `* * *`, `_ _ _` - thematic breaks, also when nested in a list item (`1.` followed by an indented `- - -`) or when the item holds one (`- * * *`)
- `- --flag` - CLI flags (the second `-` is not followed by a space)
- `* *emphasis*` - Emphasis markers (the second `*` starts emphasis, not a list)
- `- **bold**` - Bold text starting a list item
- `- -` and `- - ` - an empty inner item, which cannot be collapsed without leaving an empty item
- Lines that are not list items, such as paragraph continuation text (`a` followed by an indented `- - b`) or indented code
- Properly indented nested lists - these are intentional

## Learn more

- [CommonMark list specification](https://spec.commonmark.org/0.31.2/#lists) - How lists are parsed
- [Nested lists](https://www.markdownguide.org/basic-syntax/#nested-lists) - How to create intentional nested lists

## Related rules

- [MD004](md004.md) - Consistent unordered list style
- [MD007](md007.md) - Unordered list indentation
- [MD030](md030.md) - Spaces after list markers