MD044 - Use Proper Capitalization for Names¶
Aliases: proper-names
What this rule does¶
Ensures brand names, product names, and technical terms are consistently capitalized throughout your documents.
Why this matters¶
- Professional appearance: Incorrect capitalization looks careless and unprofessional
- Brand respect: Shows you care about getting company and product names right
- Consistency: Readers won't be confused by different variations of the same name
- Searchability: Consistent naming improves search results and indexing
Examples¶
✅ Correct¶
With configured names:
# JavaScript Development Guide
This guide covers JavaScript best practices for GitHub projects.
We'll be using Node.js and TypeScript for our examples.
❌ Incorrect¶
# Javascript Development Guide <!-- Should be "JavaScript" -->
This guide covers javascript best practices for github projects.
<!-- "javascript" and "github" are incorrectly capitalized -->
We'll be using NodeJS and typescript for our examples.
<!-- "NodeJS" should be "Node.js", "typescript" should be "TypeScript" -->
🔧 Fixed¶
# JavaScript Development Guide
This guide covers JavaScript best practices for GitHub projects.
We'll be using Node.js and TypeScript for our examples.
Configuration¶
[MD044]
names = [] # List of properly capitalized names
code-blocks = false # Check inside code blocks (default: false)
html-elements = true # Check inside HTML elements (default: true)
html-comments = true # Check inside HTML comments (default: true)
whole-words = false # Preserve names inside compound identifiers (default: false)
ignore-frontmatter-fields = [] # Frontmatter fields to skip (default: check all)
Automatic fixes¶
When enabled, this rule will:
- Replace all incorrect capitalizations with the proper version
- Preserve the context and meaning of your text
- Work across headings, paragraphs, and lists
Special cases¶
- Only checks names you've configured
- Set
whole-words = trueto match a configured name only when it occupies a whole prose token. With this option, runs of hyphens and underscores between Unicode letters or numbers join identifier components, soabcis checked in(abc)and[abc]but not in123-abc-def,foo_abc_bar,foo__abc__bar, or Unicode compounds such ascafé_abc_menu. Underscores parsed as Markdown emphasis delimiters do not join tokens:_abc_,__abc__, and the emphasizedabcinfoo-__abc__-barare still checked. Emphasizing an entire identifier, such as_foo_abc_bar_or_abc_def_, still protects its embedded components. The default isfalsefor markdownlint compatibility, so compound components continue to be checked unless this option is enabled. This setting does not add a general path or URL exemption; existing link and URL exclusions still apply. - Won't check inside URLs
- Preserves filename extension suffixes such as
favorite.toml,.toml, andconfig.toml.examplewhenTOMLis configured. This applies in both body text and frontmatter without an additional setting. Only the suffix is exempt: standalonenode.jsis still checked against the complete nameNode.js, and a configured name in a filename stem such asmyapp.pngis still checked. The dot is a syntax cue, so dotfiles such as.githuband dotted suffixes such asapi.node.jsalso retain their spelling. A missing space after a sentence period can therefore hide a capitalization error; text after ellipses or a period followed by a space is still checked - Won't check inside a file path in a frontmatter value, such as
docs/myapp.md,./myapp.md, or/abs/path/myapp.md, since rewriting a name there would break the reference. A slash is required for this exemption: a slash-less value likeimage: myapp.pnghas no path signal, so a configured name in its stem is still flagged and fixed. This whole-path exemption applies to frontmatter values only; names in body-prose paths are still checked, apart from extension suffixes. A path is recognized when it has a leading./,../,~/, or/, or its final segment has a file extension. A bare relative path with a literal space and no extension (docs/My App/myapp) is not recognized and is still checked - Won't check inside a wiki embed (
![[myapp.png]],![[myapp.png|300]]). The whole construct names a file, so rewriting any part of it changes what the embed resolves to - In a wikilink, checks what the reader sees: the display text of
[[page|the myapp guide]], and the page name of a plain[[myapp]], which doubles as its own display text. The page name in front of a|is left alone, since renaming it changes what the link resolves to without changing anything on the page - Won't check inside a template shortcode tag (
{{% nodejs %}},{{< figure alt="nodejs" >}}). A shortcode is resolved by name against a template, so the text in the tag names what to invoke rather than mentioning a product, and rewriting it points the invocation at a template that does not exist. Only the tag itself is exempt: prose on the same line is still checked, and so is the body between a paired{{% note %}}and{{% /note %}}, which the site generator renders as ordinary Markdown - By default, skips code blocks and inline code. Wrap function calls such as
oklch(.5 .5 255)in backticks to preserve their spelling. Unformatted calls are checked like prose. Setcode-blocks = trueto check both code blocks and inline code - Set
html-comments = falseto skip HTML comment content - Some names are intentionally lowercase (like "npm")
Frontmatter¶
rumdl checks proper names inside frontmatter values, not just body text,
since fields like title and description often hold prose. Frontmatter
keys themselves are never checked.
To exclude specific fields (for example machine-readable slugs or SEO
metadata that happen to contain a configured name), list their top-level
keys in ignore-frontmatter-fields:
Field names are matched case-insensitively against top-level frontmatter
keys only. Excluding a parent key excludes everything nested under it,
including nested maps, sequence items, and multi-line values. In TOML
frontmatter, excluding a key also excludes its [table] and
[[array-of-tables]] sections.
One YAML shape is not covered: a flow collection whose contents continue on
a following line that begins at column zero (seo: [ then myapp on the
next line) attributes that line to its own text rather than to seo, so
ignore-frontmatter-fields = ["seo"] does not exclude it. The value keeps
being checked, which is the safe direction. Put the collection on a single
line, or indent its continuation, to have it excluded.