vale
Vale Tool Analysis
Overview
Vale is a syntax-aware linter for prose and documentation. It checks
Markdown, reStructuredText, AsciiDoc, HTML, and plain text against configurable style
guides (Microsoft, Google, write-good, proselint, alex, and custom rules). This analysis
compares Lintro’s wrapper with the upstream vale behavior.
Vale requires a
.vale.iniconfiguration to run. When no config is resolvable, Lintro skips vale as a non-error (rather than surfacing vale’s hardE100runtime error), keepinglintro checkclean on projects that do not use Vale.
Core Tool Capabilities
- Prose linting for Markdown, reStructuredText, AsciiDoc, HTML, and plain text
- Configurable style guides via
BasedOnStylesin.vale.ini - Custom rule support authored in YAML
- Fast (written in Go) with editor integrations
- Machine-readable output via
--output=JSON
Built-in and Community Styles
- Microsoft Writing Style Guide
- Google Developer Documentation Style Guide
- write-good
- proselint
- alex (inclusive language)
- The bundled
Valestyle (ships with the binary; novale syncrequired)
External styles are installed with vale sync after listing Packages in .vale.ini.
Lintro Implementation Analysis
✅ Preserved Features
- Standard prose linting via
vale --output=JSON - Native config discovery respected (
.vale.ini,_vale.ini,vale.ini); vale resolves configuration by walking up from each linted file - File targeting for documentation patterns (
*.md,*.rst,*.adoc,*.txt) - Minimum alert level control via
vale:min_alert_level - Explicit config path via
vale:config - Timeout control (default 30s) via
vale:timeout
⚠️ Limited / Missing
- Config is required. Vale cannot run without a resolvable configuration. When none
is found, Lintro skips the tool as a non-error (with a helpful message) rather than
surfacing vale’s
E100runtime error (exit 2). - No auto-fix. Vale reports prose and style violations only;
fix()raisesNotImplementedError. - No pass-through of advanced CLI flags (e.g.
--glob,--filter,--ignore-syntax) beyond--configand--minAlertLevel. - No custom formatter selection; the JSON output is used internally for parsing.
🚀 Enhancements
- Graceful skip when no config is present, keeping mixed-language runs clean
- Unified
ToolResultwith normalized issues fromvale_parser - Per-issue documentation links are taken from vale’s
Linkfield when a style provides them - Vale’s
suggestionalert level is normalized to Lintro’sINFOseverity - Safe version check with a skip result when vale is missing or below the required version
Usage Comparison
# Core vale
vale --output=JSON docs/
# Lintro wrapper
lintro check docs/ --tools vale
lintro check docs/ --tools vale --tool-options vale:min_alert_level=warning
lintro check docs/ --tools vale --tool-options vale:config=.vale.ini
lintro check docs/ --tools vale --tool-options vale:timeout=60
Output Format
Vale emits a JSON object keyed by file path; each value is a list of alerts:
{
"docs/example.md": [
{
"Action": { "Name": "edit", "Params": ["truncate", " "] },
"Span": [1, 7],
"Check": "Vale.Repetition",
"Description": "",
"Link": "",
"Message": "'the' is repeated!",
"Severity": "error",
"Match": "The the",
"Line": 3
}
]
}
Lintro’s parser maps Check to the display code (with the leading <Style> recorded
separately), Span[0] to the column, Severity to the normalized severity, and Link
to the documentation URL when present.
Configuration Strategy
-
Prefers native configs:
.vale.ini,_vale.ini, orvale.ini. -
A minimal self-contained config uses only the bundled
Valestyle:MinAlertLevel = suggestion [*.md] BasedOnStyles = Vale -
Richer setups add
BasedOnStyles = Microsoft, Googleand runvale syncto download the referenced style packages.
Comparison with markdownlint
- markdownlint checks Markdown syntax and formatting (headings, list spacing, line length).
- vale checks prose quality and style (repetition, passive voice, jargon, inclusive language).
The two are complementary and can run together on the same documentation set.