Skip to content
Last updated

Migrate from markdownlint and Vale

The recheck command covers the ground of markdownlint and Vale in one tool and one configuration file. This guide maps the configuration of each tool onto Recheck.

The first step is to install Redocly CLI.

Replace markdownlint

Update the command

Replace markdownlint docs or markdownlint-cli2 "docs/**/*.md" with:

redocly recheck docs

Replace --fix with the same flag:

redocly recheck docs --fix

Translate the configuration

Every markdownlint rule has a Recheck rule with the same name under the recheck/ prefix. Start from the preset that matches your markdownlint style, then move each override from .markdownlint.yaml into the recheck block:

markdownlintRecheck
default: trueextends: [recheck/markdown]
extends: style/relaxed.jsonextends: [recheck/markdown-relaxed]
MD013: falserecheck/line-length: off
MD013: { line_length: 120 }recheck/line-length with assertions.line-length.lineLength: 120
blank_lines: falseThe five blanks-around-* and no-multiple-blanks rules set to off

Option names use camel case instead of snake case: line_length becomes lineLength, and siblings_only becomes siblingsOnly.

For example, this .markdownlint.yaml:

default: true
MD004: false
MD013:
  line_length: 120
  tables: false
MD024:
  siblings_only: true
MD033: false

becomes this redocly.yaml:

extends:
  - recheck/markdown
recheck:
  rules:
    recheck/ul-style: off
    recheck/line-length:
      severity: error
      assertions:
        line-length:
          lineLength: 120
          tables: false
    recheck/no-duplicate-heading:
      severity: error
      assertions:
        no-duplicate-heading:
          siblingsOnly: true
    recheck/no-inline-html: off

The Markdown rules page lists every rule with its markdownlint id and options.

Replace inline comments

Recheck does not read markdownlint's HTML comment directives. Replace each one with the equivalent Recheck directive, written as an HTML comment in the same place:

markdownlint commentRecheck comment
markdownlint-disable MD013recheck-disable line-length
markdownlint-enable MD013recheck-enable line-length
markdownlint-disable-next-line MD013recheck-disable-next-line line-length
markdownlint-disable-filerecheck-disable-file

Recheck names rules by name, not by MD id.

Two differences in defaults

  • no-trailing-spaces allows exactly two trailing spaces by default, because that is a Markdown hard line break. Set strict: true to report every trailing space, as markdownlint does.
  • no-duplicate-heading adds the respectSections, caseSensitive, and ignoreCommonHeadings options. Their defaults match markdownlint.

Replace Vale

Update the command

Replace vale docs with the same recheck command. Structural and prose rules run in one pass:

redocly recheck docs

Translate styles

A Vale style is a folder of YAML rule files. Each file becomes one entry in recheck.rules, and the Vale extends type becomes the Recheck assertion:

Vale extendsRecheck assertion
substitutionswap
existencepattern
occurrenceoccurrence
repetitionrepetition
consistencyconsistency
conditionalconditional
capitalizationcapitalization
metricmetric
spellingspelling
sequenceNo equivalent. These rules need part-of-speech tagging.

The other Vale keys map one to one: message stays message, level becomes severity (suggestion becomes info), scope stays scope, link stays link, ignorecase becomes ignoreCase, and nonword stays nonword. Vale's swap, tokens, and either keys move under the assertion.

For example, this Vale rule in styles/Acme/BritishEnglish.yml:

extends: substitution
message: 'Use the US spelling "%s" instead of British "%s".'
level: error
ignorecase: true
swap:
  colour: color
  behaviour: behavior

becomes:

recheck:
  rules:
    acme/british-english:
      severity: error
      scope: summary
      message: 'Use the US spelling "%s" instead of British "%s".'
      assertions:
        swap:
          ignoreCase: true
          wordBoundary: true
          pairs:
            colour: color
            behaviour: behavior

Vale skips code by default, and Recheck's prose scopes do the same. Set scope: summary to read the document's prose, or a narrower scope such as sentence or heading. The default scope all reads the whole file, code included. The Prose rules page lists every assertion and option.

Replace packages

Vale packages for the Google and Microsoft style guides have Recheck presets:

Vale packageRecheck preset
Googlerecheck/google
Microsoftrecheck/microsoft
alex or Inclusiverecheck/inclusive-language
proselint (in part)recheck/plain-language
write-good (in part)recheck/prose and recheck/plain-language

The presets are adapted from the live style guides, not from the Vale packages, so their rule sets differ in detail. See Presets for what each one contains.

Replace the vocabulary

Vale's accept.txt becomes the exceptions list of a capitalization rule or the vocab list of a spelling rule. Vale's reject.txt becomes a pattern rule. Recheck adds a built-in list of technical proper nouns to both, so most entries for product names are no longer needed.

Replace in-text comments

Vale's vale off and vale on comments become recheck-disable and recheck-enable. A comment that turns one Vale rule off, such as vale Acme.Rule = NO, becomes recheck-disable acme/rule. Each one stays an HTML comment in the same place.

Run both tools during the transition

Recheck reports in the formats that CI expects: github-actions for pull request annotations, sarif for code scanning, and json for scripts. Run Recheck next to the old tools for a few pull requests, compare the findings, then remove the old configuration. A baseline keeps the switch from failing the build on findings the old tools never reported.