rumdl 0.1.51

A fast Markdown linter written in Rust (Ru(st) MarkDown Linter)
Documentation
# MD018 - No missing space after hash in heading

Aliases: `no-missing-space-atx`

## What this rule does

Ensures there's a space between the # symbols and the heading text.

## Why this matters

- **Readability**: Headings without spaces look cramped and are harder to read
- **Compatibility**: Some Markdown processors won't recognize headings without spaces
- **Standards**: Proper spacing follows Markdown best practices

## Examples

### ✅ Correct

<!-- rumdl-disable MD022 -->

```markdown
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
```

<!-- rumdl-enable MD022 -->

### ❌ Incorrect

<!-- rumdl-disable MD018 MD022 -->

```markdown
#Heading 1
##Heading 2
###Heading 3
####Heading 4
#####Heading 5
######Heading 6
```

<!-- rumdl-enable MD018 MD022 -->

### 🔧 Fixed

<!-- rumdl-disable MD022 -->

```markdown
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
```

<!-- rumdl-enable MD022 -->

## Configuration

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `magiclink` | boolean | `false` | Enable MagicLink support for issue/PR references |

### MagicLink support

When `magiclink = true`, this rule skips [PyMdown MagicLink](https://facelessuser.github.io/pymdown-extensions/extensions/magiclink/) issue/PR references at the start of a line. This prevents false positives when using MagicLink's auto-linking syntax for patterns like `#123`.

```toml
[MD018]
magiclink = true
```

#### Example

<!-- rumdl-disable MD018 MD022 MD025 -->

```markdown
# PRs that are helpful for context

#10 discusses the philosophy behind the project, and #37 shows a good example.

#Summary
```

<!-- rumdl-enable MD018 MD022 MD025 -->

With `magiclink = true`:

- `#10` and `#37` are **not flagged** (MagicLink issue references)
- `#Summary` is **flagged** (non-numeric, likely a malformed heading)

## Special cases

This rule correctly handles:

- Emoji hashtags like #️⃣ and #⃣ (not treated as headings)
- Content inside HTML blocks and comments (e.g., CSS selectors like `#id`)
- YAML frontmatter comments
- Indented patterns (not at column 1)

## Obsidian flavor: Tag syntax support

When using `flavor = "obsidian"`, this rule automatically skips Obsidian tag syntax at the start of a line. In Obsidian, `#tagname` is used for organizing notes with tags, not as headings.

### Example

<!-- rumdl-disable MD018 MD022 MD025 -->

```markdown
# Real Heading

#todo this is a tag

#project/active nested tag

##Introduction
```

<!-- rumdl-enable MD018 MD022 MD025 -->

With `flavor = "obsidian"`:

- `#todo` and `#project/active` are **not flagged** (Obsidian tags)
- `##Introduction` is **flagged** (multi-hash, clearly a malformed heading)
- `#123` is **flagged** (tags cannot start with digits)

### Configuration

```toml
[global]
flavor = "obsidian"
```

This allows Obsidian users to use tag syntax without triggering false positives from MD018.

## Automatic fixes

This rule automatically adds a space after the # symbols to properly format the heading.

## Learn more

- [CommonMark specification for headings]https://spec.commonmark.org/0.31.2/#atx-headings - Technical details about heading syntax

## Related rules

- [MD019]md019.md - No multiple spaces after hash in heading
- [MD020]md020.md - No missing space in closed heading
- [MD021]md021.md - No multiple spaces in closed heading
- [MD022]md022.md - Headings should be surrounded by blank lines