Markup

Learn about Vale's syntax-aware scoping system.

Heads up: Our documentation has moved -- you can find the new docs at https://docs.errata.ai/vale/scoping.

Overview

Vale is "syntax aware," which means that it's capable of both applying rules to and ignoring certain sections of text. This functionality is implemented through a scoping system. A scope is specified through a selector such as paragraph.rst, which indicates that the rule applies to all paragraphs in reStructuredText files. Here are a few examples:

  • comment matches all source code comments;

  • comment.line matches all source code line comments;

  • heading.md matches all Markdown headings; and

  • text.html matches all HTML scopes.

The type of file you're working with determines what scopes are available. The supported types are markup, code, and text.

Available scopes

markup

Scope

Description

heading

Matches all <h{1,...}> tags. You can specify an exact level by appending a tags—for example, heading.h1 matches all h1 tags.

table.header

Matches all <th> tags.

table.cell

Matches all <td> tags.

list

Matches all <li> tags.

paragraph

Matches all paragraphs (segments of text separated by two newlines).

sentence

Matches all sentences.

link

Matches all <a> tags.

alt

Matches all alt attributes.

blockquote

Matches all <blockquote> tags.

summary

Matches all body text (excluding list items, headings, and table cells).

code

Matches all <code> tags.

strong

Matches all <strong> and <b> tags.

emphasis

Matches all <em> and <i> tags

code

There are two code scopes: comment.line and comment.block.

text

Any format not listed below is considered to be text and has no special scoping rules applied.

Formats

Markdown [markup]

Vale has built-in support for GitHub-Flavored Markdown. By default, it ignores indented blocks, fenced blocks, and code spans.

HTML [markup]

Vale has built-in support for HTML. By default, it ignores script, style, pre, code, and tt tags.

reStructuredText [markup]

Vale supports reStructuredText through the external program rst2html. You can get rst2html by installing either Sphinx or docutils.

By default, literal blocks, inline literals, and code-blocks are ignored.

AsciiDoc [markup]

Vale supports AsciiDoc through the external program Asciidoctor.

By default, listing blocks and inline literals are ignored.

DITA [markup]

Requires Vale >= v2.0!

Note: You'll likely experience worse performance with DITA files compared to other formats (including plain XML, discussed below) since the underlying dita command is slow — it incurs about 4 seconds of overhead per file.

Vale supports DITA through the DITA Open Toolkit. You'll need to follow the installation instructions, including the optional step of adding the absolute path for the bin directory to the PATH system variable.

By default, <codeblock>, <tt>, and <codeph> elements are ignored.

XML [markup]

Requires Vale >= v2.0!

Vale supports XML through the external program xsltproc.

In order for Vale to understand your XML, you need to provide a version 1.0 XSL Transformation (XSLT) for converting to HTML:

[*.xml]
Transform = docbook-xsl-snapshot/html/docbook.xsl

Source Code [code]

Language

Extensions

Tokens (scope)

C

.c, .h

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

C#

.cs, .csx

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

C++

.cpp, .cc, .cxx, .hpp

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

CSS

.css

/*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

Go

.go

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

Haskell

.hs

-- (text.comment.line.ext), {- (text.comment.block.ext)

Java

.java, .bsh

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

JavaScript

.js

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

LESS

.less

//(text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

Lua

.lua

-- (text.comment.line.ext), --[[ (text.comment.block.ext)

Perl

.pl, .pm, .pod

# (text.comment.line.ext)

PHP

.php

// (text.comment.line.ext), # (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

Python

.py, .py3, .pyw, .pyi, .rpy

# (text.comment.line.ext), """ (text.comment.block.ext)

R

.r, .R

# (text.comment.line.ext)

Ruby

.rb

# (text.comment.line.ext), ^=begin (text.comment.block.ext)

Sass

.sass

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

Scala

.scala, .sbt

//(text.comment.line.ext),

Swift

.swift

// (text.comment.line.ext), /*...*/ (text.comment.line.ext), /* (text.comment.block.ext)

Non-standard markup

When working with non-HTML markup, you'll probably find that there are certain non-standard sections of text you'd like to ignore. Vale supports doing this at both the block and inline levels.

To ignore entire blocks of text—for example, Hugo's shortcodes—you'll want to define BlockIgnores. For example, consider the following shortcode-like file snippet:

{< file "hello.go" go >}
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
{</ file >}

To ignore all instances of file, we'd use a pattern along the lines of the following:

BlockIgnores = (?s) *({< file [^>]* >}.*?{</ ?file >})

The basic idea is to capture the entire snippet in the first grouping. See regex101 for a more thorough explanation.

You can also define more than one by using a list (the \ allows for line breaks):

BlockIgnores = (?s) *({< output >}.*?{< ?/ ?output >}), \
(?s) *({< highlight .* >}.*?{< ?/ ?highlight >})

To ignore an inline section of text, you'll want to define TokenIgnores. For example, let's say we want to ignore math equations of the form $...$:

$\begin{bmatrix} k & k & k \end{bmatrix}^T$

Similar to BlockIgnores, we just need to define a pattern:

TokenIgnores = (\$+[^\n$]+\$+)

See Configuration for more details.

Markup-based configuration

Vale supports selective, in-text configuration through markup comments in certain formats. The follow sections describe the comment style required for each supported format.

Markdown / HTML

Markdown and HTML use HTML-style comments:

<!-- vale off -->
This is some text
more text here...
<!-- vale on -->
<!-- vale Style.Rule = NO -->
This is some text
<!-- vale Style.Rule = YES -->

reStructuredText

reStructuredText uses its own comment style:

.. vale off
This is some text
.. vale on

AsciiDoc

AsciiDoc uses HTML-style comments with its passthrough functionality:

pass:[<!-- vale Microsoft.GenderBias = NO -->]
This steward is ignored.
pass:[<!-- vale Microsoft.GenderBias = YES -->]
This is a steward that raises an alert.