MD093 - Headings should not contain inline formatting¶
Aliases: no-formatting-in-headings
This rule is opt-in. Enable it with extend-enable = ["MD093"] in the [global]
section of your config.
What this rule does¶
Reports an inline code span, strong emphasis or emphasis inside a heading, in both ATX and setext form.
Why this matters¶
A heading is not only text on the page. It is also the source of generated
artifacts: a table of contents, an anchor, a sidebar or outline entry, a PDF
bookmark. Inline markup reaches those inconsistently — one generator strips the
markers, another emits them literally, a third keeps the markup in the page and
drops it from the anchor — so the same heading can read Method map() in the
body and Method `map()` in the table of contents. Nothing in the source
says which will happen, because the answer belongs to the tool that consumes the
document rather than to the document.
The other half of the problem is that markup in a heading is often
unintentional. A name that contains _ or * becomes emphasis on its own:
That heading renders as tests/gt.test.js. The underscores are gone from the
page, from the anchor and from the table of contents, and the document lints
clean, so nothing tells the author that the path they published is not the path
they wrote. The same happens to *args, to a heading naming a file such as
__init__.py, and to a snake_case_name whose parts are separated by single
underscores.
Examples¶
Incorrect¶
## Method `map()`
### **Practice**
## The _.env_ file
## __tests__/gt.test.js
Heading with `code`
-------------------
Correct¶
The identifier spelled without markup:
An escape keeps a name that markdown would otherwise read as emphasis:
Formatting outside headings is untouched, so the identifier can keep its code span in the sentence below the heading:
Configuration¶
One switch per construct. All three are on once the rule is enabled, because they are three shapes of the same problem, but they have different justifications: a code span in a heading is usually deliberate and only breaks generated artifacts, while emphasis is often an accident of a name. A project that wants only one of them reported turns the other two off.
| Option | Type | Default | Description |
|---|---|---|---|
code |
boolean | true |
Report inline code spans in headings |
strong |
boolean | true |
Report strong emphasis (**/__) in headings |
emphasis |
boolean | true |
Report emphasis (*/_) in headings |
[global]
extend-enable = ["MD093"]
[MD093]
code = false # keep `identifier` in headings, report only emphasis
strong = true
emphasis = true
What this rule leaves alone¶
Formatting outside a heading. Only the heading line itself is examined.
Headings inside code blocks. A fenced or indented block is content, and the
## in it is a character rather than a heading.
A link, an image or HTML in a heading. A link in a heading is normal and
survives generated artifacts, and inline HTML in a heading is
MD033 - No inline HTML's subject. Markup inside a link's text is
reported, because the link text is what a table of contents carries: the
heading ## [The `map()` docs](url) is a finding on the code span, not on
the link.
Automatic fixes¶
None, by design. Removing the markers changes what renders rather than only how
the source reads. Dropping the backticks from a path in a code span can turn the
path into bold text, and dropping the emphasis from ## **tests**/sort.test.js
yields tests/sort.test.js — a plausible path that was never in the source.
Both rewrites are silent corruptions, and which remedy the author meant (rewrite
the heading, escape the markers, move the identifier into the text below) is not
derivable from the source.
Related rules¶
- MD036 - Emphasis should not be used instead of a heading, the inverse case: emphasis where a heading was meant
- MD063 - Heading capitalization, another rule about the text of a heading
- MD081 - Inline emphasis should not be excessive, for emphasis density in a document as a whole