2015-03-12 23:42:06 -07:00
|
|
|
# markdownlint
|
|
|
|
|
2016-03-11 21:36:39 -08:00
|
|
|
> A Node.js style checker and lint tool for Markdown/CommonMark files.
|
2015-03-12 23:42:06 -07:00
|
|
|
|
2015-03-17 22:58:26 -07:00
|
|
|
[![npm version][npm-image]][npm-url]
|
|
|
|
[![GitHub tag][github-tag-image]][github-tag-url]
|
|
|
|
[![Build status][travis-image]][travis-url]
|
|
|
|
[![Coverage][coveralls-image]][coveralls-url]
|
|
|
|
[![License][license-image]][license-url]
|
|
|
|
|
2015-03-12 23:42:06 -07:00
|
|
|
## Install
|
|
|
|
|
|
|
|
```shell
|
|
|
|
npm install markdownlint --save-dev
|
|
|
|
```
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
2016-10-05 22:50:21 -07:00
|
|
|
The [Markdown](https://en.wikipedia.org/wiki/Markdown) markup language is
|
2015-03-14 22:34:28 -07:00
|
|
|
designed to be easy to read, write, and understand. It succeeds - and its
|
|
|
|
flexibility is both a benefit and a drawback. Many styles are possible, so
|
|
|
|
formatting can be inconsistent. Some constructs don't work well in all
|
2016-03-11 21:36:39 -08:00
|
|
|
parsers and should be avoided. The [CommonMark](http://commonmark.org/)
|
|
|
|
specification standardizes parsers - but not authors.
|
2015-03-12 23:42:06 -07:00
|
|
|
|
2016-10-05 22:50:21 -07:00
|
|
|
`markdownlint` is a [static analysis](https://en.wikipedia.org/wiki/Static_program_analysis)
|
2015-03-12 23:42:06 -07:00
|
|
|
tool for [Node.js](https://nodejs.org/) and [io.js](https://iojs.org/) with a
|
2015-03-14 22:34:28 -07:00
|
|
|
library of rules to enforce standards and consistency for Markdown files. It
|
|
|
|
was inspired by - and heavily influenced by - Mark Harrison's
|
2017-06-18 15:49:33 -07:00
|
|
|
[markdownlint](https://github.com/markdownlint/markdownlint) for
|
2017-05-19 22:36:46 -07:00
|
|
|
[Ruby](https://www.ruby-lang.org/). The initial rules, rule documentation, and
|
|
|
|
test cases came directly from that project.
|
2015-03-12 23:42:06 -07:00
|
|
|
|
2016-01-14 22:15:44 -08:00
|
|
|
### Related
|
|
|
|
|
2016-01-19 21:15:15 -08:00
|
|
|
* [markdownlint-cli command-line interface for Node.js](https://github.com/igorshubovych/markdownlint-cli)
|
2016-09-28 21:45:26 -07:00
|
|
|
* [grunt-markdownlint for the Grunt task runner](https://github.com/sagiegurari/grunt-markdownlint)
|
2016-01-14 22:15:44 -08:00
|
|
|
* [vscode-markdownlint extension for VS Code](https://marketplace.visualstudio.com/items/DavidAnson.vscode-markdownlint)
|
|
|
|
* [markdownlint/mdl gem for Ruby](https://rubygems.org/gems/mdl)
|
2015-03-12 23:42:06 -07:00
|
|
|
|
2015-05-07 18:24:35 -07:00
|
|
|
## Demonstration
|
|
|
|
|
2016-10-05 22:50:21 -07:00
|
|
|
[`markdownlint` demo](https://dlaa.me/markdownlint/), an interactive, in-browser
|
2015-05-07 18:24:35 -07:00
|
|
|
playground for learning and exploring.
|
|
|
|
|
2016-01-12 21:29:17 -08:00
|
|
|
## Rules / Aliases
|
|
|
|
|
2017-05-07 12:48:04 -07:00
|
|
|
* **[MD001](doc/Rules.md#md001)** *header-increment* - Header levels should only increment by one level at a time
|
|
|
|
* **[MD002](doc/Rules.md#md002)** *first-header-h1* - First header should be a top level header
|
|
|
|
* **[MD003](doc/Rules.md#md003)** *header-style* - Header style
|
|
|
|
* **[MD004](doc/Rules.md#md004)** *ul-style* - Unordered list style
|
|
|
|
* **[MD005](doc/Rules.md#md005)** *list-indent* - Inconsistent indentation for list items at the same level
|
|
|
|
* **[MD006](doc/Rules.md#md006)** *ul-start-left* - Consider starting bulleted lists at the beginning of the line
|
|
|
|
* **[MD007](doc/Rules.md#md007)** *ul-indent* - Unordered list indentation
|
|
|
|
* **[MD009](doc/Rules.md#md009)** *no-trailing-spaces* - Trailing spaces
|
|
|
|
* **[MD010](doc/Rules.md#md010)** *no-hard-tabs* - Hard tabs
|
|
|
|
* **[MD011](doc/Rules.md#md011)** *no-reversed-links* - Reversed link syntax
|
|
|
|
* **[MD012](doc/Rules.md#md012)** *no-multiple-blanks* - Multiple consecutive blank lines
|
|
|
|
* **[MD013](doc/Rules.md#md013)** *line-length* - Line length
|
|
|
|
* **[MD014](doc/Rules.md#md014)** *commands-show-output* - Dollar signs used before commands without showing output
|
|
|
|
* **[MD018](doc/Rules.md#md018)** *no-missing-space-atx* - No space after hash on atx style header
|
|
|
|
* **[MD019](doc/Rules.md#md019)** *no-multiple-space-atx* - Multiple spaces after hash on atx style header
|
|
|
|
* **[MD020](doc/Rules.md#md020)** *no-missing-space-closed-atx* - No space inside hashes on closed atx style header
|
|
|
|
* **[MD021](doc/Rules.md#md021)** *no-multiple-space-closed-atx* - Multiple spaces inside hashes on closed atx style header
|
|
|
|
* **[MD022](doc/Rules.md#md022)** *blanks-around-headers* - Headers should be surrounded by blank lines
|
|
|
|
* **[MD023](doc/Rules.md#md023)** *header-start-left* - Headers must start at the beginning of the line
|
|
|
|
* **[MD024](doc/Rules.md#md024)** *no-duplicate-header* - Multiple headers with the same content
|
|
|
|
* **[MD025](doc/Rules.md#md025)** *single-h1* - Multiple top level headers in the same document
|
|
|
|
* **[MD026](doc/Rules.md#md026)** *no-trailing-punctuation* - Trailing punctuation in header
|
|
|
|
* **[MD027](doc/Rules.md#md027)** *no-multiple-space-blockquote* - Multiple spaces after blockquote symbol
|
|
|
|
* **[MD028](doc/Rules.md#md028)** *no-blanks-blockquote* - Blank line inside blockquote
|
|
|
|
* **[MD029](doc/Rules.md#md029)** *ol-prefix* - Ordered list item prefix
|
|
|
|
* **[MD030](doc/Rules.md#md030)** *list-marker-space* - Spaces after list markers
|
|
|
|
* **[MD031](doc/Rules.md#md031)** *blanks-around-fences* - Fenced code blocks should be surrounded by blank lines
|
|
|
|
* **[MD032](doc/Rules.md#md032)** *blanks-around-lists* - Lists should be surrounded by blank lines
|
|
|
|
* **[MD033](doc/Rules.md#md033)** *no-inline-html* - Inline HTML
|
|
|
|
* **[MD034](doc/Rules.md#md034)** *no-bare-urls* - Bare URL used
|
|
|
|
* **[MD035](doc/Rules.md#md035)** *hr-style* - Horizontal rule style
|
|
|
|
* **[MD036](doc/Rules.md#md036)** *no-emphasis-as-header* - Emphasis used instead of a header
|
|
|
|
* **[MD037](doc/Rules.md#md037)** *no-space-in-emphasis* - Spaces inside emphasis markers
|
|
|
|
* **[MD038](doc/Rules.md#md038)** *no-space-in-code* - Spaces inside code span elements
|
|
|
|
* **[MD039](doc/Rules.md#md039)** *no-space-in-links* - Spaces inside link text
|
|
|
|
* **[MD040](doc/Rules.md#md040)** *fenced-code-language* - Fenced code blocks should have a language specified
|
|
|
|
* **[MD041](doc/Rules.md#md041)** *first-line-h1* - First line in file should be a top level header
|
|
|
|
* **[MD042](doc/Rules.md#md042)** *no-empty-links* - No empty links
|
|
|
|
* **[MD043](doc/Rules.md#md043)** *required-headers* - Required header structure
|
|
|
|
* **[MD044](doc/Rules.md#md044)** *proper-names* - Proper names should have the correct capitalization
|
2015-03-14 22:34:28 -07:00
|
|
|
|
|
|
|
See [Rules.md](doc/Rules.md) for more details.
|
2015-03-12 23:42:06 -07:00
|
|
|
|
2015-03-16 22:31:18 -07:00
|
|
|
## Tags
|
|
|
|
|
|
|
|
* **atx** - MD018, MD019
|
|
|
|
* **atx_closed** - MD020, MD021
|
|
|
|
* **blank_lines** - MD012, MD022, MD031, MD032
|
|
|
|
* **blockquote** - MD027, MD028
|
|
|
|
* **bullet** - MD004, MD005, MD006, MD007, MD032
|
2015-04-16 09:13:56 -07:00
|
|
|
* **code** - MD014, MD031, MD038, MD040
|
2015-04-15 17:50:01 -07:00
|
|
|
* **emphasis** - MD036, MD037
|
2015-03-17 22:34:47 -07:00
|
|
|
* **hard_tab** - MD010
|
2015-03-16 22:31:18 -07:00
|
|
|
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
|
2016-07-02 22:37:52 -07:00
|
|
|
MD024, MD025, MD026, MD036, MD041, MD043
|
2015-04-14 09:40:16 -07:00
|
|
|
* **hr** - MD035
|
2015-04-14 00:01:57 -07:00
|
|
|
* **html** - MD033
|
2015-03-16 22:31:18 -07:00
|
|
|
* **indentation** - MD005, MD006, MD007, MD027
|
2015-04-16 09:13:56 -07:00
|
|
|
* **language** - MD040
|
2015-03-16 22:31:18 -07:00
|
|
|
* **line_length** - MD013
|
2016-06-27 22:19:02 -07:00
|
|
|
* **links** - MD011, MD034, MD039, MD042
|
2015-03-16 22:31:18 -07:00
|
|
|
* **ol** - MD029, MD030, MD032
|
|
|
|
* **spaces** - MD018, MD019, MD020, MD021, MD023
|
2016-12-22 13:34:18 -08:00
|
|
|
* **spelling** - MD044
|
2015-03-16 22:31:18 -07:00
|
|
|
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
|
2015-04-14 00:01:57 -07:00
|
|
|
* **url** - MD034
|
2015-04-15 18:24:42 -07:00
|
|
|
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039
|
2015-03-16 22:31:18 -07:00
|
|
|
|
2015-09-26 16:55:33 -07:00
|
|
|
## Configuration
|
|
|
|
|
2017-07-16 23:08:47 -07:00
|
|
|
Text passed to `markdownlint` is parsed as Markdown, analyzed, and any issues reported.
|
|
|
|
Two kinds of text are ignored:
|
|
|
|
|
|
|
|
* [HTML comments](https://www.w3.org/TR/html5/syntax.html#comments)
|
|
|
|
* [Front matter](https://jekyllrb.com/docs/frontmatter/) (see `options.frontMatter` below)
|
|
|
|
|
2015-09-26 16:55:33 -07:00
|
|
|
Rules can be enabled, disabled, and configured via `options.config` (described
|
|
|
|
below) to define the expected behavior for a set of inputs. To enable or disable
|
|
|
|
rules within a file, add one of these markers to the appropriate place (HTML
|
|
|
|
comments don't appear in the final markup):
|
|
|
|
|
|
|
|
* Disable all rules: `<!-- markdownlint-disable -->`
|
|
|
|
* Enable all rules: `<!-- markdownlint-enable -->`
|
|
|
|
* Disable one or more rules: `<!-- markdownlint-disable MD001 MD002 -->`
|
|
|
|
* Enable one or more rules: `<!-- markdownlint-enable MD001 MD002 -->`
|
|
|
|
|
|
|
|
For example:
|
|
|
|
|
|
|
|
```md
|
|
|
|
<!-- markdownlint-disable MD037 -->
|
|
|
|
deliberate space * in * emphasis
|
|
|
|
<!-- markdownlint-enable MD037 -->
|
|
|
|
```
|
|
|
|
|
|
|
|
Changes take effect starting with the line a comment is on, so the following
|
|
|
|
has no effect:
|
|
|
|
|
|
|
|
```md
|
|
|
|
space * in * emphasis <!-- markdownlint-disable --> <!-- markdownlint-enable -->
|
|
|
|
```
|
|
|
|
|
2015-03-15 23:39:17 -07:00
|
|
|
## API
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
### Linting
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Standard asynchronous interface:
|
|
|
|
|
2015-03-15 23:39:17 -07:00
|
|
|
```js
|
|
|
|
/**
|
2017-05-19 22:36:46 -07:00
|
|
|
* Lint specified Markdown files.
|
2015-03-15 23:39:17 -07:00
|
|
|
*
|
|
|
|
* @param {Object} options Configuration options.
|
|
|
|
* @param {Function} callback Callback (err, result) function.
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
function markdownlint(options, callback) { ... }
|
|
|
|
```
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Synchronous interface (for build scripts, etc.):
|
|
|
|
|
|
|
|
```js
|
|
|
|
/**
|
2017-05-19 22:36:46 -07:00
|
|
|
* Lint specified Markdown files synchronously.
|
2015-03-20 00:09:55 -07:00
|
|
|
*
|
|
|
|
* @param {Object} options Configuration options.
|
|
|
|
* @returns {Object} Result object.
|
|
|
|
*/
|
|
|
|
function markdownlint.sync(options) { ... }
|
|
|
|
```
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
#### options
|
2015-03-15 23:39:17 -07:00
|
|
|
|
|
|
|
Type: `Object`
|
|
|
|
|
|
|
|
Configures the function.
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
##### options.files
|
2015-03-15 23:39:17 -07:00
|
|
|
|
|
|
|
Type: `Array` of `String`
|
|
|
|
|
|
|
|
List of files to lint.
|
|
|
|
|
|
|
|
Each array element should be a single file (via relative or absolute path);
|
2016-10-05 22:50:21 -07:00
|
|
|
[globbing](https://en.wikipedia.org/wiki/Glob_%28programming%29) is the caller's
|
2015-03-15 23:39:17 -07:00
|
|
|
responsibility.
|
|
|
|
|
|
|
|
Example: `[ "one.md", "dir/two.md" ]`
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
##### options.strings
|
2015-04-29 18:46:52 -07:00
|
|
|
|
|
|
|
Type: `Object` mapping `String` to `String`
|
|
|
|
|
|
|
|
Map of identifiers to strings for linting.
|
|
|
|
|
|
|
|
When Markdown content is not available as files, it can be passed as strings.
|
|
|
|
The keys of the `strings` object are used to identify each input value in the
|
|
|
|
`result` summary.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"readme": "# README\n...",
|
|
|
|
"changelog": "# CHANGELOG\n..."
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
##### options.config
|
2015-03-15 23:39:17 -07:00
|
|
|
|
2015-03-16 22:31:18 -07:00
|
|
|
Type: `Object` mapping `String` to `Boolean | Object`
|
2015-03-15 23:39:17 -07:00
|
|
|
|
|
|
|
Configures the rules to use.
|
|
|
|
|
2016-01-12 21:29:17 -08:00
|
|
|
Object keys are rule names or aliases and values are the rule's configuration.
|
2015-03-15 23:39:17 -07:00
|
|
|
The value `false` disables a rule, `true` enables its default configuration,
|
|
|
|
and passing an object customizes its settings. Setting the special `default`
|
2015-03-18 09:38:32 -07:00
|
|
|
rule to `true` or `false` includes/excludes all rules by default. Enabling or
|
|
|
|
disabling a tag name (ex: `whitespace`) affects all rules having that tag.
|
|
|
|
|
|
|
|
The `default` rule is applied first, then keys are processed in order from top
|
2015-09-26 16:55:33 -07:00
|
|
|
to bottom with later values overriding earlier ones. Keys (including rule names,
|
2016-01-12 21:29:17 -08:00
|
|
|
aliases, tags, and `default`) are not case-sensitive.
|
2015-03-15 23:39:17 -07:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"default": true,
|
2015-03-18 09:38:32 -07:00
|
|
|
"MD003": { "style": "atx_closed" },
|
|
|
|
"MD007": { "indent": 4 },
|
2016-01-12 21:29:17 -08:00
|
|
|
"no-hard-tabs": false,
|
2015-03-18 09:40:01 -07:00
|
|
|
"whitespace": false
|
2015-03-15 23:39:17 -07:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2015-03-18 09:38:32 -07:00
|
|
|
Sets of rules (known as a "style") can be stored separately and loaded as
|
2016-10-05 22:50:21 -07:00
|
|
|
[JSON](https://en.wikipedia.org/wiki/JSON).
|
2015-03-18 09:38:32 -07:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var options = {
|
|
|
|
"files": [ "..." ],
|
|
|
|
"config": require("style/relaxed.json")
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
See the [style](style) directory for more samples.
|
|
|
|
|
2016-10-05 22:21:54 -07:00
|
|
|
See [markdownlint-config-schema.json](schema/markdownlint-config-schema.json)
|
|
|
|
for the [JSON Schema](http://json-schema.org/) of the `options.config` object.
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
For more advanced scenarios, styles can reference and extend other styles. The
|
|
|
|
`readConfig` and `readConfigSync` functions can be used to read such styles.
|
|
|
|
|
|
|
|
For example, assuming a `base.json` configuration file:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"default": true
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
And a `custom.json` configuration file:
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"extends": "base.json",
|
|
|
|
"line-length": false
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Then code like the following:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var options = {
|
|
|
|
"config": markdownlint.readConfigSync("./custom.json")
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
|
|
|
Merges `custom.json` and `base.json` and is equivalent to:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var options = {
|
|
|
|
"config": {
|
|
|
|
"default": true,
|
|
|
|
"line-length": false
|
|
|
|
}
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
2017-05-21 22:58:10 -07:00
|
|
|
##### options.frontMatter
|
|
|
|
|
|
|
|
Type: `RegExp`
|
|
|
|
|
|
|
|
Matches any [front matter](https://jekyllrb.com/docs/frontmatter/) found at the
|
|
|
|
beginning of a file.
|
|
|
|
|
|
|
|
Some Markdown content begins with metadata; the default `RegExp` for this option
|
|
|
|
ignores common forms of "front matter". To match differently, specify a custom
|
|
|
|
`RegExp` or use the value `null` to disable the feature.
|
|
|
|
|
2017-07-02 20:33:29 -07:00
|
|
|
The default value:
|
2017-05-21 22:58:10 -07:00
|
|
|
|
|
|
|
```js
|
2017-07-02 20:33:29 -07:00
|
|
|
/^(---|\+\+\+)$[^]*?^\1$(\r\n|\r|\n)/m
|
2017-05-21 22:58:10 -07:00
|
|
|
```
|
|
|
|
|
2017-07-02 20:33:29 -07:00
|
|
|
Ignores [YAML](https://en.wikipedia.org/wiki/YAML) and [TOML](https://en.wikipedia.org/wiki/TOML) such as:
|
2017-05-21 22:58:10 -07:00
|
|
|
|
|
|
|
```text
|
|
|
|
---
|
|
|
|
layout: post
|
|
|
|
title: Title
|
|
|
|
---
|
|
|
|
```
|
|
|
|
|
2017-07-02 20:33:29 -07:00
|
|
|
Note: Matches must occur at the start of the file.
|
|
|
|
|
2017-05-21 22:58:10 -07:00
|
|
|
##### options.noInlineConfig
|
|
|
|
|
|
|
|
Type: `Boolean`
|
|
|
|
|
|
|
|
Disables the use of HTML comments like `<!-- markdownlint-disable -->` to toggle
|
|
|
|
rules within the body of Markdown content.
|
|
|
|
|
|
|
|
By default, properly-formatted inline comments can be used to create exceptions
|
|
|
|
for parts of a document. Setting `noInlineConfig` to `true` ignores all such
|
|
|
|
comments.
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
##### options.resultVersion
|
2016-10-16 21:46:02 -07:00
|
|
|
|
|
|
|
Type: `Number`
|
|
|
|
|
|
|
|
Specifies which version of the `result` object to return (see the "Usage" section
|
|
|
|
below for examples).
|
|
|
|
|
|
|
|
Passing a `resultVersion` of `0` corresponds to the original, simple format where
|
2017-07-05 21:53:21 -07:00
|
|
|
each error is identified by rule name and line number. This is deprecated.
|
2016-10-16 21:46:02 -07:00
|
|
|
|
2017-07-05 21:53:21 -07:00
|
|
|
Passing a `resultVersion` of `1` corresponds to a detailed format where each error
|
|
|
|
includes information about the line number, rule name, alias, description, as well
|
|
|
|
as any additional detail or context that is available. This is the default.
|
2016-10-16 21:46:02 -07:00
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
#### callback
|
2015-03-15 23:39:17 -07:00
|
|
|
|
|
|
|
Type: `Function` taking (`Error`, `Object`)
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Standard completion callback.
|
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
#### result
|
2015-03-20 00:09:55 -07:00
|
|
|
|
|
|
|
Type: `Object`
|
2015-03-15 23:39:17 -07:00
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Call `result.toString()` for convenience or see below for an example of the
|
2016-01-12 21:29:17 -08:00
|
|
|
structure of the `result` object. Passing the value `true` to `toString()`
|
|
|
|
uses rule aliases (ex: `no-hard-tabs`) instead of names (ex: `MD010`).
|
2015-03-15 23:39:17 -07:00
|
|
|
|
2017-05-19 22:36:46 -07:00
|
|
|
### Config
|
|
|
|
|
|
|
|
The `options.config` configuration object is simple and can be loaded as JSON
|
|
|
|
in many cases. To take advantage of shared configuration where one file `extends`
|
|
|
|
another, the following functions are useful.
|
|
|
|
|
|
|
|
Asynchronous interface:
|
|
|
|
|
|
|
|
```js
|
|
|
|
/**
|
|
|
|
* Read specified configuration file.
|
|
|
|
*
|
|
|
|
* @param {String} file Configuration file name/path.
|
|
|
|
* @param {Function} callback Callback (err, result) function.
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
function readConfig(file, callback) { ... }
|
|
|
|
```
|
|
|
|
|
|
|
|
Synchronous interface:
|
|
|
|
|
|
|
|
```js
|
|
|
|
/**
|
|
|
|
* Read specified configuration file synchronously.
|
|
|
|
*
|
|
|
|
* @param {String} file Configuration file name/path.
|
|
|
|
* @returns {Object} Configuration object.
|
|
|
|
*/
|
|
|
|
function readConfigSync(file) { ... }
|
|
|
|
```
|
|
|
|
|
|
|
|
#### file
|
|
|
|
|
|
|
|
Type: `String`
|
|
|
|
|
|
|
|
Location of JSON configuration file to read.
|
|
|
|
|
|
|
|
The `file` is resolved relative to the current working directory. If an `extends`
|
|
|
|
key is present once read, its value will be resolved as a path relative to `file`
|
|
|
|
and loaded recursively. Settings from a file referenced by `extends` are applied
|
|
|
|
first, then those of `file` are applied on top (overriding any of the same keys
|
|
|
|
appearing in the referenced file).
|
|
|
|
|
|
|
|
#### callback
|
|
|
|
|
|
|
|
Type: `Function` taking (`Error`, `Object`)
|
|
|
|
|
|
|
|
Standard completion callback.
|
|
|
|
|
|
|
|
#### result
|
|
|
|
|
|
|
|
Type: `Object`
|
|
|
|
|
|
|
|
Configuration object.
|
|
|
|
|
2015-03-12 23:42:06 -07:00
|
|
|
## Usage
|
|
|
|
|
2015-03-14 22:34:28 -07:00
|
|
|
Invoke `markdownlint` and use the `result` object's `toString` method:
|
2015-03-12 23:42:06 -07:00
|
|
|
|
|
|
|
```js
|
2015-03-14 23:47:34 -07:00
|
|
|
var markdownlint = require("markdownlint");
|
2015-03-14 22:34:28 -07:00
|
|
|
|
|
|
|
var options = {
|
2015-04-29 18:46:52 -07:00
|
|
|
"files": [ "good.md", "bad.md" ],
|
|
|
|
"strings": {
|
|
|
|
"good.string": "# good.string\n\nThis string passes all rules.",
|
|
|
|
"bad.string": "#bad.string\n\n#This string fails\tsome rules."
|
|
|
|
}
|
2015-03-14 22:34:28 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
markdownlint(options, function callback(err, result) {
|
|
|
|
if (!err) {
|
|
|
|
console.log(result.toString());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2016-01-12 21:29:17 -08:00
|
|
|
Output:
|
2015-03-14 22:34:28 -07:00
|
|
|
|
|
|
|
```text
|
2017-07-05 21:53:21 -07:00
|
|
|
bad.string: 3: MD010/no-hard-tabs Hard tabs [Column: 19]
|
|
|
|
bad.string: 1: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#bad.string"]
|
|
|
|
bad.string: 3: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#This string fails some rules."]
|
|
|
|
bad.string: 1: MD041/first-line-h1 First line in file should be a top level header [Context: "#bad.string"]
|
|
|
|
bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
|
|
|
|
bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#bad.md"]
|
|
|
|
bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#This file fails some rules."]
|
|
|
|
bad.md: 1: MD041/first-line-h1 First line in file should be a top level header [Context: "#bad.md"]
|
2015-03-14 22:34:28 -07:00
|
|
|
```
|
|
|
|
|
2017-07-05 21:53:21 -07:00
|
|
|
Or invoke `markdownlint.sync` for a synchronous call:
|
2016-01-12 21:29:17 -08:00
|
|
|
|
|
|
|
```js
|
|
|
|
var result = markdownlint.sync(options);
|
2017-07-05 21:53:21 -07:00
|
|
|
console.log(result.toString());
|
2016-01-12 21:29:17 -08:00
|
|
|
```
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
To examine the `result` object directly:
|
2015-03-14 22:34:28 -07:00
|
|
|
|
|
|
|
```js
|
|
|
|
markdownlint(options, function callback(err, result) {
|
|
|
|
if (!err) {
|
2017-07-05 21:53:21 -07:00
|
|
|
console.dir(result, { "colors": true, "depth": null });
|
2015-03-14 22:34:28 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Output:
|
2015-03-14 22:34:28 -07:00
|
|
|
|
2016-10-16 21:46:02 -07:00
|
|
|
```json
|
|
|
|
{
|
|
|
|
"good.md": [],
|
|
|
|
"bad.md": [
|
2016-10-16 21:46:02 -07:00
|
|
|
{ "lineNumber": 3,
|
|
|
|
"ruleName": "MD010",
|
|
|
|
"ruleAlias": "no-hard-tabs",
|
|
|
|
"ruleDescription": "Hard tabs",
|
|
|
|
"errorDetail": "Column: 17",
|
2016-10-31 22:53:46 -07:00
|
|
|
"errorContext": null,
|
|
|
|
"errorRange": [ 17, 1 ] },
|
2016-10-16 21:46:02 -07:00
|
|
|
{ "lineNumber": 1,
|
|
|
|
"ruleName": "MD018",
|
|
|
|
"ruleAlias": "no-missing-space-atx",
|
|
|
|
"ruleDescription": "No space after hash on atx style header",
|
|
|
|
"errorDetail": null,
|
2016-10-31 22:53:46 -07:00
|
|
|
"errorContext": "#bad.md",
|
|
|
|
"errorRange": [ 1, 2 ] },
|
2016-10-16 21:46:02 -07:00
|
|
|
{ "lineNumber": 3,
|
|
|
|
"ruleName": "MD018",
|
|
|
|
"ruleAlias": "no-missing-space-atx",
|
|
|
|
"ruleDescription": "No space after hash on atx style header",
|
|
|
|
"errorDetail": null,
|
2016-10-31 22:53:46 -07:00
|
|
|
"errorContext": "#This file fails\tsome rules.",
|
2017-07-05 21:53:21 -07:00
|
|
|
"errorRange": [ 1, 2 ] },
|
|
|
|
{ "lineNumber": 1,
|
|
|
|
"ruleName": "MD041",
|
|
|
|
"ruleAlias": "first-line-h1",
|
|
|
|
"ruleDescription": "First line in file should be a top level header",
|
|
|
|
"errorDetail": null,
|
|
|
|
"errorContext": "#bad.md",
|
|
|
|
"errorRange": null }
|
2016-10-16 21:46:02 -07:00
|
|
|
]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2015-03-14 22:34:28 -07:00
|
|
|
Integration with the [gulp](http://gulpjs.com/) build system is straightforward:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var gulp = require("gulp");
|
|
|
|
var through2 = require("through2");
|
2015-03-14 23:47:34 -07:00
|
|
|
var markdownlint = require("markdownlint");
|
2015-03-14 22:34:28 -07:00
|
|
|
|
|
|
|
gulp.task("markdownlint", function task() {
|
|
|
|
return gulp.src("*.md", { "read": false })
|
|
|
|
.pipe(through2.obj(function obj(file, enc, next) {
|
|
|
|
markdownlint(
|
|
|
|
{ "files": [ file.relative ] },
|
|
|
|
function callback(err, result) {
|
|
|
|
var resultString = (result || "").toString();
|
|
|
|
if (resultString) {
|
|
|
|
console.log(resultString);
|
|
|
|
}
|
|
|
|
next(err, file);
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Output:
|
2015-03-14 22:34:28 -07:00
|
|
|
|
|
|
|
```text
|
|
|
|
[00:00:00] Starting 'markdownlint'...
|
2017-07-05 21:53:21 -07:00
|
|
|
bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
|
|
|
|
bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#bad.md"]
|
|
|
|
bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#This file fails some rules."]
|
|
|
|
bad.md: 1: MD041/first-line-h1 First line in file should be a top level header [Context: "#bad.md"]
|
2015-03-14 22:34:28 -07:00
|
|
|
[00:00:00] Finished 'markdownlint' after 10 ms
|
2015-03-12 23:42:06 -07:00
|
|
|
```
|
|
|
|
|
2015-03-14 23:47:34 -07:00
|
|
|
Integration with the [Grunt](http://gruntjs.com/) build system is similar:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var markdownlint = require("markdownlint");
|
|
|
|
|
|
|
|
module.exports = function wrapper(grunt) {
|
|
|
|
grunt.initConfig({
|
|
|
|
"markdownlint": {
|
|
|
|
"example": {
|
|
|
|
"src": [ "*.md" ]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
grunt.registerMultiTask("markdownlint", function task() {
|
|
|
|
var done = this.async();
|
|
|
|
markdownlint(
|
|
|
|
{ "files": this.filesSrc },
|
|
|
|
function callback(err, result) {
|
|
|
|
var resultString = err || ((result || "").toString());
|
|
|
|
if (resultString) {
|
|
|
|
grunt.fail.warn("\n" + resultString + "\n");
|
|
|
|
}
|
|
|
|
done(!err || !resultString);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
```
|
|
|
|
|
2015-03-20 00:09:55 -07:00
|
|
|
Output:
|
2015-03-14 23:47:34 -07:00
|
|
|
|
|
|
|
```text
|
|
|
|
Running "markdownlint:example" (markdownlint) task
|
|
|
|
Warning:
|
2017-07-05 21:53:21 -07:00
|
|
|
bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
|
|
|
|
bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#bad.md"]
|
|
|
|
bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style header [Context: "#This file fails some rules."]
|
|
|
|
bad.md: 1: MD041/first-line-h1 First line in file should be a top level header [Context: "#bad.md"]
|
2015-03-14 23:47:34 -07:00
|
|
|
Use --force to continue.
|
|
|
|
```
|
|
|
|
|
2015-06-17 18:35:11 -07:00
|
|
|
## Browser
|
|
|
|
|
2016-01-12 21:29:17 -08:00
|
|
|
`markdownlint` also works in the browser.
|
2015-06-17 18:35:11 -07:00
|
|
|
|
|
|
|
Generate normal and minified scripts with:
|
|
|
|
|
|
|
|
```shell
|
|
|
|
npm run build-demo
|
|
|
|
```
|
|
|
|
|
|
|
|
Then reference `markdown-it` and `markdownlint`:
|
|
|
|
|
|
|
|
```html
|
|
|
|
<script src="demo/markdown-it.min.js"></script>
|
|
|
|
<script src="demo/markdownlint-browser.min.js"></script>
|
|
|
|
```
|
|
|
|
|
|
|
|
And call it like so:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var options = {
|
|
|
|
"strings": {
|
|
|
|
"content": "Some Markdown to lint."
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var results = window.markdownlint.sync(options).toString();
|
|
|
|
```
|
|
|
|
|
2015-04-17 21:57:10 -07:00
|
|
|
## History
|
2015-03-12 23:42:06 -07:00
|
|
|
|
2015-04-17 22:04:45 -07:00
|
|
|
* 0.0.1 - Initial release, includes tests MD001-MD032.
|
2015-03-17 23:05:37 -07:00
|
|
|
* 0.0.2 - Improve documentation, tests, and code.
|
2015-03-20 00:29:36 -07:00
|
|
|
* 0.0.3 - Add synchronous API, improve documentation and code.
|
2015-04-17 22:04:45 -07:00
|
|
|
* 0.0.4 - Add tests MD033-MD040, update dependencies.
|
2015-05-11 20:57:51 -07:00
|
|
|
* 0.0.5 - Add `strings` option to enable file-less scenarios, add in-browser demo.
|
2015-06-19 18:48:54 -07:00
|
|
|
* 0.0.6 - Improve performance, simplify in-browser, update dependencies.
|
2015-07-30 21:41:25 -07:00
|
|
|
* 0.0.7 - Add MD041, improve MD003, ignore front matter, update dependencies.
|
2015-09-27 12:07:54 -07:00
|
|
|
* 0.0.8 - Support disabling/enabling rules inline, improve code fence, dependencies.
|
2016-01-16 22:04:37 -08:00
|
|
|
* 0.1.0 - Add aliases, exceptions for MD033, exclusions for MD013, dependencies.
|
2016-11-12 20:25:07 -08:00
|
|
|
* 0.1.1 - Fix bug handling HTML in tables, reference markdownlint-cli.
|
2016-07-05 15:03:40 -07:00
|
|
|
* 0.2.0 - Add MD042/MD043, enhance MD002/MD003/MD004/MD007/MD011/MD025/MD041, dependencies.
|
2016-11-02 22:26:07 -07:00
|
|
|
* 0.3.0 - More detailed error reporting with `resultVersion`, enhance MD010/MD012/MD036,
|
|
|
|
fixes for MD027/MD029/MD030, include JSON schema, dependencies.
|
2016-11-12 20:25:07 -08:00
|
|
|
* 0.3.1 - Fix regressions in MD032/MD038, update dependencies.
|
2017-03-03 23:02:27 -08:00
|
|
|
* 0.4.0 - Add MD044, enhance MD013/MD032/MD041/MD042/MD043, fix for MD038, dependencies.
|
2017-03-19 21:14:00 -07:00
|
|
|
* 0.4.1 - Fixes for MD038/front matter, improvements to MD044, update dependencies.
|
2017-05-22 20:04:37 -07:00
|
|
|
* 0.5.0 - Add shareable configuration, noInlineConfig option, README links, fix MD030,
|
|
|
|
improve MD009/MD041, update dependencies.
|
2015-03-17 22:58:26 -07:00
|
|
|
|
|
|
|
[npm-image]: https://img.shields.io/npm/v/markdownlint.svg
|
|
|
|
[npm-url]: https://www.npmjs.com/package/markdownlint
|
|
|
|
[github-tag-image]: https://img.shields.io/github/tag/DavidAnson/markdownlint.svg
|
|
|
|
[github-tag-url]: https://github.com/DavidAnson/markdownlint
|
2015-06-16 18:20:27 -07:00
|
|
|
[travis-image]: https://img.shields.io/travis/DavidAnson/markdownlint/master.svg
|
2015-03-17 22:58:26 -07:00
|
|
|
[travis-url]: https://travis-ci.org/DavidAnson/markdownlint
|
2015-06-16 18:20:27 -07:00
|
|
|
[coveralls-image]: https://img.shields.io/coveralls/DavidAnson/markdownlint/master.svg
|
2015-03-17 22:58:26 -07:00
|
|
|
[coveralls-url]: https://coveralls.io/r/DavidAnson/markdownlint
|
|
|
|
[license-image]: https://img.shields.io/npm/l/markdownlint.svg
|
2016-10-05 22:50:21 -07:00
|
|
|
[license-url]: https://opensource.org/licenses/MIT
|