Need more than a rule playground?

Explore Vale CMS
Why Vale

Parses your source instead of pattern-matching it

Markup-aware

A prose linter that treats your source as plain text will flag your code samples, your URLs, and your syntax. Vale doesn't read the file—it parses it, the same way your site generator does, and then walks the result. Rules see prose. Everything else is structure.

Scopes reference

One rule, every syntax

These three files say the same thing in three markup languages. Vale parses each with its own parser and hands the linter the same prose, so a rule written once fires in all three.

example.md
## Getting started
 
You can utilize the `--output` flag to
change the [report format](/docs/output).
warning Use 'use' instead of 'utilize'. Microsoft.Vocab

The dimmed characters never reach a rule. Neither does --output or the link target—but report format, which a reader actually reads, does.

Vale does not implement any of these syntaxes itself. Markdown goes through goldmark, AsciiDoc through Asciidoctor, and reStructuredText through Docutils—the same tools your site generator is likely using. Whatever they call a heading is what a rule scoped to heading sees.

Rules can aim at structure

Because the document is a tree by the time rules run, a rule can restrict itself to part of it. Pick a selector and watch which blocks it claims.

Getting started
text.heading.h2.md
Install the binary, then run it against a file you already have.
text.md
• Download a release for your platform.
text.list.md
• Add a .vale.ini to the project root.
text.list.md
Vale reads configuration from the closest .vale.ini it can find.
text.blockquote.md
Flag
text.table.header.md
Sets the reporting style.
text.table.cell.md

The default: every block Vale extracts from the file.

7 of 7 blocks

A selector matches when every part of it appears in the block's scope, in any order—so md.list and list.md select the same thing. Combine parts with & to require both at once, or lead with ~ to invert the whole thing.

Inline spans—link, strong, emphasis, code—are scopes of their own, offered alongside the surrounding text rather than nested inside it. A rule that asks for link sees only link text; every other rule pays nothing for the privilege.

Front matter is content too

A title and a description are read more often than the page they sit on—they land in search results, navigation, and social cards. Vale parses front matter in Markdown, AsciiDoc, reStructuredText, MDX, and Org, and gives every field a scope of its own.

---
title: 'Getting started with Vale'
description: 'Install it, then run it.'
---
The body starts here.
Scopes produced
text.frontmatter.title.md text.frontmatter.description.md

Title case, titles only

The field name is part of the scope, so a rule can pick out one key and ignore every other.

extends: capitalization
scope: text.frontmatter.title
match: $title

No filler in the description

This is the sentence that lands in search results. It is the wrong place for words that carry no information.

extends: existence
scope: text.frontmatter.description
message: "Drop '%s' from the description."
tokens:
- simply
- easy to use

Front matter is skipped entirely unless a rule asks for it, so nothing starts firing on your build configuration by accident.

Scope a rule in three lines

Every rule takes a scope. Set it, and the rule stops firing anywhere else.

Headings only

Enforce sentence case where it matters, and leave body text alone.

extends: capitalization
scope: heading
match: $sentence

Everything but tables

Scopes negate. Terse table cells shouldn't trip a rule about full sentences.

extends: existence
scope: ~table
tokens:
- click here

What a rule never sees

Exclusions are structural, not a list of patterns you maintain. If the parser calls it code, it is code.

Fenced and indented code

Whole blocks, in every format that has them.

Inline code spans

Backticks, ``literals``, and +passthroughs+ alike.

URLs and link targets

The destination is skipped; the link text is not.

Front matter

YAML and TOML headers, unless you ask for them by key.

HTML attributes

Except the human-readable ones, like alt text.

Directives and macros

Roles, shortcodes, and template tags.

Formats

Each is handed to the parser that owns it, not to a shared approximation of all of them. Follow a tile to the project doing the work.