What is a scope?
A scope is a named section of text identified by its position in the document structure. Vale uses scope selectors (similar to CSS selectors) to target markup elements. For example:heading.h1targets level-1 headingsparagraphtargets paragraphscodetargets code spanstexttargets all text content
Defining scopes in rules
Add ascope key to any rule to control where it applies:
scope key, rules default to scope: text, which applies to most text content but excludes code and URLs.
Scope selectors
Scope selectors use dot notation to specify nested elements:- Basic selectors
- Specific levels
- Format-specific
- Combined scopes
Target common markup elements:
Negated scopes
Use the~ prefix to exclude specific scopes:
Multiple scopes
Apply a rule to multiple scopes by passing a list:The raw scope
Theraw scope provides access to the original markup before Vale processes it. This is useful for:
- Markup-specific rules: Check Markdown link syntax, HTML attributes, etc.
- Cross-element patterns: Find patterns spanning multiple elements
- Custom scripts: Access the full document structure
The summary scope
Thesummary scope is special—it applies to document-level metrics rather than text spans:
metric or readability extensions automatically use summary scope. You can’t change this.
How scoping works internally
Vale converts documents into a structured representation before applying rules:- Parse: Convert markup to an internal format
- Tokenize: Break content into blocks with scope labels
- Match: Compare block scopes against rule scopes
- Apply: Run matching rules on corresponding blocks
Scope: The block’s scope identifier (e.g., “heading.h1”)Parent: The parent scope (if nested)Text: The actual content
internal/check/scope.go:49-60:
Scope matching rules
Vale uses hierarchical matching for scopes:Split into parts
Convert selectors into dot-separated parts:
heading.h1becomes["heading", "h1"]text.htmlbecomes["text", "html"]
Check containment
A block matches if its scope contains all parts of the selector.Example: A block with scope
heading.h1.markdown matches:heading✓heading.h1✓heading.h1.markdown✓
heading.h2✗paragraph✗
Apply negations
Check negated selectors against the block’s parent scope.For
scope: heading & ~heading.h1:- Must have “heading” in scope ✓
- Must not have “heading.h1” in parent ✓
Common patterns
Check only headings
Check only headings
Check everything except headings
Check everything except headings
Check specific heading levels
Check specific heading levels
Check code blocks only
Check code blocks only
Check raw markup
Check raw markup
Deprecated scopes
These scopes were removed in Vale v3: Frominternal/check/definition.go:406-411:
Validation
Vale validates scopes when loading rules:- No spaces:
heading.h1✓,heading. h1✗ - Known selectors: Warns about unrecognized scope names
- No deprecated selectors: Errors on old inline scopes
internal/check/scope.go:10-121, internal/check/definition.go:391-423