Skip to main content

Overview

The line output format provides a simple, grep-friendly output style where each alert is printed on a single line. This format is compatible with many text editors and IDE error parsers that expect compiler-style error messages.
The line format is ideal for integration with editors like Vim, Emacs, and tools that expect traditional compiler error output.

Usage

Enable line output with the --output flag:
vale --output=line document.md
The format name is case-sensitive. Use lowercase line.

Output Format

Each alert is printed on a single line with the following structure:
path:line:column:check:message
path
string
required
The file path where the issue was found. May be absolute or relative depending on configuration.
line
integer
required
The line number where the issue was found (1-indexed).
column
integer
required
The column number where the match begins (0-indexed). This corresponds to Span[0] in the Alert structure.
check
string
required
The name of the rule that generated this alert (e.g., “Vale.Spelling”, “Google.Acronyms”).
message
string
required
The alert message describing the issue.

Example Output

Here are real examples of what the line output looks like:
/path/to/document.md:12:5:Vale.Spelling:Did you really mean 'teh'?
/path/to/document.md:15:34:Vale.ReadabilityGrade:Grade level (12.3) too high!
/path/to/document.md:23:8:Google.Acronyms:Spell out 'HTTP' on first use.
/another/file.md:8:15:Microsoft.Terms:Use 'and' instead of '&'.
The line format uses no colors or special formatting, making it perfect for piping to other tools or parsing with scripts.

Path Handling

By default, Vale outputs the full absolute path for each file. The path format can be controlled with the --relative flag.

Absolute Paths (Default)

vale --output=line document.md
/home/user/projects/docs/document.md:12:5:Vale.Spelling:Did you really mean 'teh'?

Relative Paths

vale --output=line --relative document.md
docs/document.md:12:5:Vale.Spelling:Did you really mean 'teh'?
The --relative flag behavior has known limitations and is considered experimental. It attempts to create relative paths based on the executable directory.

Implementation Details

The line output is implemented in cmd/vale/line.go:13-41:
func PrintLineAlerts(linted []*core.File, relative bool) bool {
    var base string
    exeDir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
    
    alertCount := 0
    for _, f := range linted {
        // Handle relative paths if requested
        if relative && strings.Contains(f.Path, exeDir) {
            base = strings.Split(f.Path, exeDir)[1]
        } else {
            base = f.Path
        }
        
        for _, a := range f.SortedAlerts() {
            if a.Severity == "error" {
                alertCount++
            }
            fmt.Printf("%s:%d:%d:%s:%s\n",
                base, a.Line, a.Span[0], a.Check, a.Message)
        }
    }
    return alertCount != 0
}
Alerts are automatically sorted by position (line, then column) before being printed, ensuring consistent output order.

Exit Code Behavior

The line output format follows Vale’s standard exit code behavior:
  • Exit 0: No errors found (warnings and suggestions are OK)
  • Exit 1: One or more errors found
vale --output=line document.md
if [ $? -eq 0 ]; then
    echo "No errors found"
else
    echo "Errors detected"
fi

Editor Integration

Many text editors can parse the line format automatically:

Vim

Set Vale as the compiler for your filetype:
:set makeprg=vale\ --output=line\ %
:set errorformat=%f:%l:%c:%m
Then use :make to run Vale and populate the quickfix list.

Emacs

Use compilation mode with Vale:
(compilation-start "vale --output=line *.md")
Emacs will automatically parse the output and allow jumping to errors.

VS Code

Configure a problem matcher in .vscode/tasks.json:
{
  "problemMatcher": {
    "owner": "vale",
    "fileLocation": ["absolute"],
    "pattern": {
      "regexp": "^(.*):(\\d+):(\\d+):(.*):(.*)",
      "file": 1,
      "line": 2,
      "column": 3,
      "code": 4,
      "message": 5
    }
  }
}
The line format’s simplicity makes it easy to write custom parsers and integrations.

Parsing Examples

Using awk

Extract only error lines from a specific file:
vale --output=line *.md | awk -F: '$4 == "Vale.Spelling" {print $5}'

Using grep

Filter alerts by severity (requires additional metadata):
vale --output=line *.md | grep "Vale.Spelling"

Using Python

Parse line output programmatically:
import subprocess

result = subprocess.run(
    ['vale', '--output=line', 'document.md'],
    capture_output=True,
    text=True
)

for line in result.stdout.strip().split('\n'):
    if not line:
        continue
    parts = line.split(':', 4)
    if len(parts) == 5:
        path, line_num, col, check, message = parts
        print(f"File: {path}, Line: {line_num}, Issue: {message}")
When parsing line output, remember that the message field (the last colon-separated component) may itself contain colons.

Limitations

The line format has some inherent limitations compared to JSON output:
Missing Information: The line format doesn’t include:
  • Severity level (error/warning/suggestion)
  • Match text
  • Action hints
  • Description or Link fields
  • Span end position
If you need this information, consider using JSON output instead:
vale --output=JSON document.md

Comparison with Other Formats

FeatureLineCLIJSON
Single line per alert
Easy to parse
Editor integration⚠️
Includes severity
Includes colors
Shows full metadata⚠️
grep-friendly

Common Use Cases

Continuous Integration

Simple error detection in CI:
GitHub Actions
- name: Run Vale
  run: |
    vale --output=line docs/ > vale.txt
    if [ $? -ne 0 ]; then
      cat vale.txt
      exit 1
    fi

Pre-commit Hooks

Check staged files:
#!/bin/bash
files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.md$')
if [ -n "$files" ]; then
    vale --output=line $files
fi

Automated Reports

Generate simple text reports:
vale --output=line docs/ | tee vale-report.txt
echo "Total issues: $(wc -l < vale-report.txt)"
Combine with grep, awk, or sed for quick filtering and analysis of results.
  • Use --output=CLI for human-readable, color-coded output
  • Use --output=JSON for complete structured data
  • Use --relative to output relative paths (experimental)
  • Use --sort to ensure consistent file ordering
  • Use custom templates for complete control over output format

Build docs developers (and LLMs) love