# MD026 - Keep headings clean and professional
Aliases: `no-trailing-punctuation`
## What this rule does
Removes trailing punctuation from the end of headings to maintain a clean, professional appearance. Question marks are allowed by default for FAQ-style headings.
## Why this matters
- **Professional appearance**: Clean headings look more polished and professional
- **Better readability**: Unnecessary punctuation can distract readers
- **Consistent style**: Maintains a uniform look throughout your document
- **Navigation clarity**: Clean headings work better in tables of contents and outlines
## Examples
### ✅ Correct
```markdown
# Introduction
## What is Markdown?
### FAQ: Frequently Asked Questions
#### Step 1: Getting Started
##### Chapter 2: Configuration
```
### ❌ Incorrect
```markdown
# This is a sentence.
## Random heading;
### This seems wrong,
#### Important!
##### Ending with colon:
```
### 🔧 Fixed
```markdown
# This is a sentence
## Random heading
### This seems wrong
#### Important
##### Ending with colon
```
## Configuration
```toml
[MD026]
punctuation = ".,;:!" # Characters to remove from heading endings (default: ".,;:!")
```
To allow exclamation marks in headings, remove `!` from the list:
```toml
[MD026]
punctuation = ".,;:"
```
## Automatic fixes
This rule will:
- Remove periods, commas, semicolons, colons, and exclamation marks from heading endings (default: `.,;:!`)
- Preserve question marks for FAQ-style headings ("What is Markdown?")
- You can customize the punctuation list if you want to allow certain characters
## Exceptions
A punctuation character that closes an HTML entity reference or an emoji
shortcode is that construct's delimiter, not trailing punctuation. Removing it
would turn the construct into literal text, so these headings are left alone:
```markdown
# Fish &
# Copyright ©
# Semicolon ;
# Release day :tada:
```
Punctuation written after such a construct is still reported, and only that
punctuation is removed: `# Fish &.` becomes `# Fish &`.
This exception is decided by shape, not by decoding the entity. `.` ends
with an entity delimiter and is not flagged even though it renders as a period,
and a name that is not a real entity (`&foo;`) is treated the same way.
## Markdown with Gherkin
Under the `mdg` flavor, the ASCII colon leaves the `punctuation` set, whether it
arrived from the default or from an explicit configuration. A Gherkin structure
is an ATX heading spelled `Keyword: name`, so the colon after the keyword is
what makes the keyword a keyword, and this rule must never be able to delete it.
Because MD026 matches punctuation only at the very end of a heading, dropping
the colon from the set is complete: no heading whose last character is a colon
is inspected at all, so `## Scenario!:` is left exactly as written. Only the
ASCII colon leaves the set — a full-width `:` carries no structural meaning, so
a `punctuation` value that lists one keeps enforcing it.
When MD026 reaches relevant content with an explicit `punctuation` value
containing a colon, it prints one `[config warning]` line on stderr; the colon
is dropped either way.
See [Markdown with Gherkin Flavor](flavors/mdg.md) for the full flavor
specification.
## Learn more
- [CommonMark Spec: ATX headings](https://spec.commonmark.org/0.31.2/#atx-headings)
- [CommonMark Spec: Setext headings](https://spec.commonmark.org/0.31.2/#setext-headings)
## Related rules
- [MD001 - Keep heading levels organized](md001.md)
- [MD003 - Use consistent heading styles](md003.md)
- [MD025 - Keep your document organized with one main title](md025.md)