mkaz.blog

Linting Markdown Syntax

Linting is the process to check code for potential errors and enforce a style guide, but linting is not just for code; you can lint markdown documents for the same reasons. Markdownlint is a Node package to lint markdown syntax, use markdownlint-cli for use on the command-line, or use the Visual Studio Code plugin for use in your editor.

Why lint documentation?

Markdown is a flexible format, with several different syntaxes. If you are running a project with multiple contributors, each person might use their own style. Just like code, it is a good idea to set a standard for the project and setup a tool to enforce the standards. Linting can also catch errors for invalid indentation, or differences in markdown parsers.

Here are a few example rules it can catch:

  • MD025 - Multiple top-level headings in the same document
  • MD031 - Fenced code blocks should be surrounded by blank lines
  • MD040 - Fenced code blocks should have a language specified

See the full list of rules available.

Configuration

Markdownlint comes with a default config, you will probably want to adjust to fit your needs. Create your own .markdownlint.json config file using. An example config file I use:

{
    "default": true,
    "MD003": { "style": "atx" },
    "MD007": { "indent": 4 },
    "MD013": { "line-length": false },
    "MD025": { "front_matter_title": false },
    "MD033": { "allowed_elements": ["figure", "video"] },
    "no-hard-tabs": false,
    "whitespace": false
}

By default it looks for a file named .markdownlint.json if you use a different config file name, you can specify the file using the -c option. See Usage for all command options.

To make it easier to run, I set up a script entry in my project's package.json, so then all I need to do is npm run lint each time.

"scripts": {
    "lint": "markdownlint pages/*.md"
}

Disable Rules

If you just want to disable a rule at specific locations use HTML comments to wrap.

<!-- markdownlint-disable MD001 -->
 
### Heading Increment Okay
 
<!-- markdownlint-enable MD001 -->

For more usage and examples, see the configuration docs.

Setup for Node

You can install the package using:

npm install markdownlint-cli --save-dev

If you don't have an NPM project setup, run npm init first and follow the prompts, then run install command. For details, see this tutorial for setting up a node project.

After installing, run using npx. You can specify a single file or a glob on the command-line; the following runs against all files with the markdown extension in the pages directory.

npx markdownlint pages/*.md

Setup for Visual Studio Code

To use Markdownlint in Visual Studio Code, install the extension.

When you open a markdown file, you will see a squiggly line under parts that violate a rule. Move your mouse over and see the rule and why.

Screenshot showing VSCode highlighting lint error

If you have a .markdownlint.json config file in the root of your project directory, the plugin will use the settings there. You can also specify specific rules in your user or workplace settings:

"markdownlint.config": {
    "default": true,
    "MD003": { "style": "atx" },
    "MD007": { "indent": 4 },
    "no-hard-tabs": false
}

See the extension documentation for more details.

Setup Markdownlint in Vim

If you prefer using Vim, use the coc-markdownlint plugin. You first need to install Coc that is a plugin for vim to add an Intellisense engine to vim. This enables several capabilities similar to Visual Studio Code.

I won't go into the plugin installation process for vim, see my Working with Vim plugins page for plenty of details. 💡 One tip, after installing Coc, turn off the auto pop-ups by creating ~/.vim/coc-settings.json file with:

{
    "suggest.autoTrigger": "none"
}

After Coc is installed, in Vim run: CocInstall coc-markdownlint

After this, you should start seeing any lint errors in your markdown. You can configure the markdown lint rules using:

  1. adding a global $HOME/.markdownlintrc,
  2. add a markdownlint.config section to coc-settings.json, or
  3. use a .markdownlint.json file in your project's root

Linting Source Code in Markdown

The above two examples lint the actual markup used to create the document. It is also possible to lint the source code included in documentation, for example if you have a block of JavaScript and you want to enforce it follows the same standard as the project.

To lint JavaScript code included in Markdown, use the eslint-plugin-markdown.