#

Formatting and linting markdown files

Sunday, May 7, 2023

Format and lint markdown files in codebase

TL;DR Formatting with Prettier, linting with markdownlint

This site is powered by Nextra, which uses markdown-based contents to generate static sites. It’s good to have markdown and mdx formatter and linter in the codebase. In this post, only markdown formatting and linting will be covered.

Prettier

Prettier, the opinionated code formatter, is used to format the whole codebase. Followings are the Prettier config and the project formatting script respectively. The CLI flags are listed here.

{
  "arrowParens": "always",
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "none",
  "semi": false
}
...
"format": "prettier -w -u --cache --cache-strategy content pages",
...

markdownlint

markdownlint is into consideration due to thriving popularity, configurable with Prettier and good clear rules. With markdownlint-cli, it can fix some lint errors automatically.

According to this blog and this discussion, it’s very straightforward to disable all formatting lint rules which might conflict with Prettier.

The config in .markdownlint.json file is like this in my codebase:

{
  "extends": "markdownlint/style/prettier",
  "single-title": false,
  "no-inline-html": false,
  "line-length": false
}

The reason I turned the single-title rule off is that the rule is not only checking h1 tag but also the word title which will cause lint error if yaml styled meta data is in the top of the markdown file.

The CLI script can be like this:

...
"lint:md": "markdownlint \"pages/**/*.md\" -f"
...

Husky and Lint-staged

Husky is a tool that allows us to easily wrangle Git hooks and run the scripts we want at those stages, I introduce Husky in this project to automatically run lint and formatting work before git commit. Lint-staged is a tool that allows us to run linters against staged git files and prevent them from slipping into our code base.

Until now only markdown files are hosted in the codebase, so I configured formatting and linting against markdown files only.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged --verbose

Following is the lint-staged object in package.json.

"lint-staged": {
    "pages/!*.md": "prettier --write",
    "pages/*.md": [
      "markdownlint -c .markdownlint.json -f",
      "prettier --write"
    ]
  }