markdownlint
Advanced tools
Comparing version 0.26.2 to 0.27.0
# Contributing | ||
Interested in contributing? Great! Here are some suggestions to make it a good experience: | ||
Interested in contributing? Great! Here are some suggestions to make it a good | ||
experience: | ||
Start by [opening an issue](https://github.com/DavidAnson/markdownlint/issues), whether to identify a problem or outline a change. | ||
That issue should be used to discuss the situation and agree on a plan of action before writing code or sending a pull request. | ||
Maybe the problem isn't really a problem, or maybe there are more things to consider. | ||
If so, it's best to realize that before spending time and effort writing code that may not get used. | ||
Start by [opening an issue](https://github.com/DavidAnson/markdownlint/issues), | ||
whether to identify a problem or outline a change. That issue should be used to | ||
discuss the situation and agree on a plan of action before writing code or | ||
sending a pull request. Maybe the problem isn't really a problem, or maybe there | ||
are more things to consider. If so, it's best to realize that before spending | ||
time and effort writing code that may not get used. | ||
Match the coding style of the files you edit. | ||
Although everyone has their own preferences and opinions, a pull request is not the right forum to debate them. | ||
Match the coding style of the files you edit. Although everyone has their own | ||
preferences and opinions, a pull request is not the right forum to debate them. | ||
Do not add new [`dependencies` to `package.json`](https://docs.npmjs.com/files/package.json#dependencies). | ||
The excellent Markdown parser [markdown-it](https://www.npmjs.com/package/markdown-it) is this project's one and only dependency. | ||
Do not add new [`dependencies` to `package.json`][dependencies]. The excellent | ||
Markdown parser [markdown-it][markdown-it] is this project's one and only | ||
dependency. | ||
If developing a new rule, start by creating a [custom rule](doc/CustomRules.md) in its own project. | ||
Once written, published, and tested in real world scenarios, open an issue to consider adding it to this project. | ||
For rule ideas, see [issues tagged with the `new rule` label](https://github.com/DavidAnson/markdownlint/labels/new%20rule). | ||
If developing a new rule, start by creating a [custom rule][custom-rules] in its | ||
own project. Once written, published, and tested in real world scenarios, open | ||
an issue to consider adding it to this project. For rule ideas, see [issues | ||
tagged with the `new rule` label][new-rule]. | ||
Add tests for all new/changed functionality. | ||
Test positive and negative scenarios. | ||
Try to break the new code now, or else it will get broken later. | ||
Add tests for all new/changed functionality. Test positive and negative | ||
scenarios. Try to break the new code now, or else it will get broken later. | ||
Run tests before sending a pull request via `npm test` in the [usual manner](https://docs.npmjs.com/misc/scripts). | ||
Tests should all pass on all platforms. | ||
The test runner is [AVA](https://github.com/avajs/ava) and test cases are located in `test/markdownlint-test*.js`. | ||
When running tests, `test/*.md` files are enumerated, linted, and fail if any violations are missing a corresponding `{MD###}` marker in the test file. | ||
For example, the line `### Heading {MD001}` is expected to trigger the rule `MD001`. | ||
For cases where the marker text can not be present on the same line, the syntax `{MD###:#}` can be used to include a line number. | ||
If `some-test.md` needs custom configuration, a `some-test.json` is used to provide a custom `options.config` for that scenario. | ||
Tests run by `markdownlint-test-scenarios.js` use [AVA's snapshot feature](https://github.com/avajs/ava/blob/main/docs/04-snapshot-testing.md). | ||
To update snapshots (for example, after modifying a test file), run `npm run update-snapshots` and include the updated files with the pull request. | ||
Run tests before sending a pull request via `npm test` in the [usual | ||
manner][npm-scripts]. Tests should all pass on all platforms. The test runner is | ||
[AVA][ava] and test cases are located in `test/markdownlint-test*.js`. When | ||
running tests, `test/*.md` files are enumerated, linted, and fail if any | ||
violations are missing a corresponding `{MD###}` marker in the test file. For | ||
example, the line `### Heading {MD001}` is expected to trigger the rule `MD001`. | ||
For cases where the marker text can not be present on the same line, the syntax | ||
`{MD###:#}` can be used to include a line number. If `some-test.md` needs custom | ||
configuration, a `some-test.json` is used to provide a custom `options.config` | ||
for that scenario. Tests run by `markdownlint-test-scenarios.js` use [AVA's | ||
snapshot feature][ava-snapshots]. To update snapshots (for example, after | ||
modifying a test file), run `npm run update-snapshots` and include the updated | ||
files with the pull request. | ||
Lint before sending a pull request by running `npm run lint`. | ||
There should be no issues. | ||
Lint before sending a pull request by running `npm run lint`. There should be no | ||
issues. | ||
Run a full continuous integration pass before sending a pull request via `npm run ci`. | ||
Code coverage should always be 100%. | ||
As part of a continuous integration run, generated files may get updated and fail the run - commit them to the repository and rerun continuous integration. | ||
Run a full continuous integration pass before sending a pull request via `npm | ||
run ci`. Code coverage should always be 100%. As part of a continuous | ||
integration run, generated files may get updated and fail the run - commit them | ||
to the repository and rerun continuous integration. | ||
Pull requests should contain a single commit. | ||
If necessary, squash multiple commits before creating the pull request and when making changes. | ||
(See [Git Tools - Rewriting History](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) for details.) | ||
Pull requests should contain a single commit. If necessary, squash multiple | ||
commits before creating the pull request and when making changes. (See [Git | ||
Tools - Rewriting History][rewriting-history] for details.) | ||
Open pull requests against the `next` branch. | ||
That's where the latest changes are staged for the next release. | ||
Include the text "(fixes #??)" at the end of the commit message so the pull request will be associated with the relevant issue. | ||
End commit messages with a period (`.`). | ||
Once accepted, the tag `fixed in next` will be added to the issue. | ||
When the commit is merged to the main branch during the release process, the issue will be closed automatically. | ||
(See [Closing issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/) for details.) | ||
Open pull requests against the `next` branch. That's where the latest changes | ||
are staged for the next release. Include the text "(fixes #??)" at the end of | ||
the commit message so the pull request will be associated with the relevant | ||
issue. End commit messages with a period (`.`). Once accepted, the tag `fixed in | ||
next` will be added to the issue. When the commit is merged to the main branch | ||
during the release process, the issue will be closed automatically. (See | ||
[Closing issues using keywords][closing-keywords] for details.) | ||
Please refrain from using slang or meaningless placeholder words. | ||
Sample content can be "text", "code", "heading", or the like. | ||
Sample URLs should use [example.com](https://en.wikipedia.org/wiki/Example.com) which is safe for this purpose. | ||
Profanity is not allowed. | ||
Please refrain from using slang or meaningless placeholder words. Sample content | ||
can be "text", "code", "heading", or the like. Sample URLs should use | ||
[example.com][example-com] which is safe for this purpose. Profanity is not | ||
allowed. | ||
In order to maintain the permissive MIT license this project uses, all contributions must be your own and released under that license. | ||
Code you add should be an original work and should not be copied from elsewhere. | ||
Taking code from a different project, Stack Overflow, or the like is not allowed. | ||
The use of tools such as GitHub Copilot that generate code from other projects is not allowed. | ||
In order to maintain the permissive MIT license this project uses, all | ||
contributions must be your own and released under that license. Code you add | ||
should be an original work and should not be copied from elsewhere. Taking code | ||
from a different project, Stack Overflow, or the like is not allowed. The use of | ||
tools such as GitHub Copilot that generate code from other projects is not | ||
allowed. | ||
Thank you! | ||
[ava]: https://github.com/avajs/ava | ||
[ava-snapshots]: https://github.com/avajs/ava/blob/main/docs/04-snapshot-testing.md | ||
[closing-keywords]: https://help.github.com/articles/closing-issues-using-keywords/ | ||
[custom-rules]: doc/CustomRules.md | ||
[dependencies]: https://docs.npmjs.com/files/package.json#dependencies | ||
[example-com]: https://en.wikipedia.org/wiki/Example.com | ||
[markdown-it]: https://www.npmjs.com/package/markdown-it | ||
[new-rule]: https://github.com/DavidAnson/markdownlint/labels/new%20rule | ||
[npm-scripts]: https://docs.npmjs.com/misc/scripts | ||
[rewriting-history]: https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History |
# Custom Rules | ||
In addition to its built-in rules, `markdownlint` lets you enhance the linting experience by passing a list of custom rules using the | ||
[`options.customRules` property](../README.md#optionscustomrules). | ||
Custom rules can do everything the built-in rules can and are defined inline or imported from another package | ||
([keyword `markdownlint-rule` on npm](https://www.npmjs.com/search?q=keywords:markdownlint-rule)). | ||
Custom rules can be disabled, enabled, and customized using the same syntax as built-in rules. | ||
In addition to its built-in rules, `markdownlint` lets you enhance the linting | ||
experience by passing a list of custom rules using the [`options.customRules` | ||
property][options-custom-rules]. Custom rules can do everything the built-in | ||
rules can and are defined inline or imported from another package ([keyword | ||
`markdownlint-rule` on npm][markdownlint-rule]). Custom rules can be disabled, | ||
enabled, and customized using the same syntax as built-in rules. | ||
## Implementing Simple Rules | ||
For simple requirements like disallowing certain characters or patterns, | ||
the community-developed | ||
[markdownlint-rule-search-replace][markdownlint-rule-search-replace] | ||
plug-in can be used. | ||
This plug-in allows anyone to create a set of simple text-replacement rules in | ||
JSON without needing to write any code. | ||
[markdownlint-rule-search-replace]: https://www.npmjs.com/package/markdownlint-rule-search-replace | ||
## Authoring | ||
Rules are defined by a name (or multiple names), a description, an optional link to more information, one or more tags, and a function that implements | ||
the rule's behavior. | ||
That function is called once for each file/string input and is passed the parsed input and a function to log any violations. | ||
Rules are defined by a name (or multiple names), a description, an optional link | ||
to more information, one or more tags, and a function that implements the rule's | ||
behavior. That function is called once for each file/string input and is passed | ||
the parsed input and a function to log any violations. | ||
A simple rule implementation looks like: | ||
```js | ||
```javascript | ||
module.exports = { | ||
@@ -38,58 +51,83 @@ "names": [ "any-blockquote" ], | ||
A rule is implemented as an `Object` with one optional and four required properties: | ||
A rule is implemented as an `Object` with one optional and four required | ||
properties: | ||
- `names` is a required `Array` of `String` values that identify the rule in output messages and config. | ||
- `description` is a required `String` value that describes the rule in output messages. | ||
- `information` is an optional (absolute) `URL` of a link to more information about the rule. | ||
- `tags` is a required `Array` of `String` values that groups related rules for easier customization. | ||
- `asynchronous` is an optional `Boolean` value that indicates whether the rule returns a `Promise` and runs asynchronously. | ||
- `function` is a required `Function` that implements the rule and is passed two parameters: | ||
- `params` is an `Object` with properties that describe the content being analyzed: | ||
- `names` is a required `Array` of `String` values that identify the rule in | ||
output messages and config. | ||
- `description` is a required `String` value that describes the rule in output | ||
messages. | ||
- `information` is an optional (absolute) `URL` of a link to more information | ||
about the rule. | ||
- `tags` is a required `Array` of `String` values that groups related rules for | ||
easier customization. | ||
- `asynchronous` is an optional `Boolean` value that indicates whether the rule | ||
returns a `Promise` and runs asynchronously. | ||
- `function` is a required `Function` that implements the rule and is passed two | ||
parameters: | ||
- `params` is an `Object` with properties that describe the content being | ||
analyzed: | ||
- `name` is a `String` that identifies the input file/string. | ||
- `tokens` is an `Array` of [`markdown-it` `Token` objects](https://markdown-it.github.io/markdown-it/#Token) | ||
with added `line` and `lineNumber` properties. | ||
- `lines` is an `Array` of `String` values corresponding to the lines of the input file/string. | ||
- `frontMatterLines` is an `Array` of `String` values corresponding to any front matter (not present in `lines`). | ||
- `config` is an `Object` corresponding to the rule's entry in `options.config` (if present). | ||
- `onError` is a function that takes a single `Object` parameter with one required and four optional properties: | ||
- `lineNumber` is a required `Number` specifying the 1-based line number of the error. | ||
- `detail` is an optional `String` with information about what caused the error. | ||
- `context` is an optional `String` with relevant text surrounding the error location. | ||
- `range` is an optional `Array` with two `Number` values identifying the 1-based column and length of the error. | ||
- `fixInfo` is an optional `Object` with information about how to fix the error (all properties are optional, but | ||
at least one of `deleteCount` and `insertText` should be present; when applying a fix, the delete should be | ||
- `tokens` is an `Array` of [`markdown-it` `Token`s][markdown-it-token] with | ||
added `line` and `lineNumber` properties. | ||
- `lines` is an `Array` of `String` values corresponding to the lines of the | ||
input file/string. | ||
- `frontMatterLines` is an `Array` of `String` values corresponding to any | ||
front matter (not present in `lines`). | ||
- `config` is an `Object` corresponding to the rule's entry in | ||
`options.config` (if present). | ||
- `onError` is a function that takes a single `Object` parameter with one | ||
required and four optional properties: | ||
- `lineNumber` is a required `Number` specifying the 1-based line number of | ||
the error. | ||
- `detail` is an optional `String` with information about what caused the | ||
error. | ||
- `context` is an optional `String` with relevant text surrounding the error | ||
location. | ||
- `range` is an optional `Array` with two `Number` values identifying the | ||
1-based column and length of the error. | ||
- `fixInfo` is an optional `Object` with information about how to fix the | ||
error (all properties are optional, but at least one of `deleteCount` and | ||
`insertText` should be present; when applying a fix, the delete should be | ||
performed before the insert): | ||
- `lineNumber` is an optional `Number` specifying the 1-based line number of the edit. | ||
- `editColumn` is an optional `Number` specifying the 1-based column number of the edit. | ||
- `deleteCount` is an optional `Number` specifying the number of characters to delete (the value `-1` is used to delete the line). | ||
- `insertText` is an optional `String` specifying the text to insert. `\n` is the platform-independent way to add | ||
a line break; line breaks should be added at the beginning of a line instead of at the end). | ||
- `lineNumber` is an optional `Number` specifying the 1-based line number | ||
of the edit. | ||
- `editColumn` is an optional `Number` specifying the 1-based column | ||
number of the edit. | ||
- `deleteCount` is an optional `Number` specifying the number of | ||
characters to delete (the value `-1` is used to delete the line). | ||
- `insertText` is an optional `String` specifying the text to insert. `\n` | ||
is the platform-independent way to add a line break; line breaks should | ||
be added at the beginning of a line instead of at the end. | ||
The collection of helper functions shared by the built-in rules is available for use by custom rules in the | ||
[markdownlint-rule-helpers package](https://www.npmjs.com/package/markdownlint-rule-helpers). | ||
The collection of helper functions shared by the built-in rules is available for | ||
use by custom rules in the [markdownlint-rule-helpers package][rule-helpers]. | ||
### Asynchronous Rules | ||
If a rule needs to perform asynchronous operations (such as fetching a network resource), it can specify the value `true` for its `asynchronous` property. | ||
Asynchronous rules should return a `Promise` from their `function` implementation that is resolved when the rule completes. | ||
(The value passed to `resolve(...)` is ignored.) | ||
Linting violations from asynchronous rules are reported via the `onError` function just like for synchronous rules. | ||
If a rule needs to perform asynchronous operations (such as fetching a network | ||
resource), it can specify the value `true` for its `asynchronous` property. | ||
Asynchronous rules should return a `Promise` from their `function` | ||
implementation that is resolved when the rule completes. (The value passed to | ||
`resolve(...)` is ignored.) Linting violations from asynchronous rules are | ||
reported via the `onError` function just like for synchronous rules. | ||
**Note**: Asynchronous rules cannot be referenced in a synchronous calling context (i.e., `markdownlint.sync(...)`). | ||
Attempting to do so throws an exception. | ||
**Note**: Asynchronous rules cannot be referenced in a synchronous calling | ||
context (i.e., `markdownlint.sync(...)`). Attempting to do so throws an | ||
exception. | ||
## Examples | ||
- [Simple rules used by the project's test cases](../test/rules) | ||
- [Code for all `markdownlint` built-in rules](../lib) | ||
- [Package configuration for publishing to npm](../test/rules/npm) | ||
- [Simple rules used by the project's test cases][test-rules] | ||
- [Code for all `markdownlint` built-in rules][lib] | ||
- [Package configuration for publishing to npm][test-rules-npm] | ||
- Packages should export a single rule object or an `Array` of rule objects | ||
- [Custom rules from the Microsoft/vscode-docs-authoring repository](https://github.com/microsoft/vscode-docs-authoring/tree/main/packages/docs-linting/markdownlint-custom-rules) | ||
- [Custom rules from the axibase/docs-util repository](https://github.com/axibase/docs-util/tree/master/linting-rules) | ||
- [Custom rules from the webhintio/hint repository](https://github.com/webhintio/hint/blob/main/scripts/lint-markdown.js) | ||
- [Custom rules from the Microsoft/vscode-docs-authoring | ||
repository][vscode-docs-authoring] | ||
- [Custom rules from the axibase/docs-util repository][docs-util] | ||
- [Custom rules from the webhintio/hint repository][hint] | ||
## References | ||
- [CommonMark documentation and specification](https://commonmark.org/) | ||
- [`markdown-it` Markdown parser project page](https://github.com/markdown-it/markdown-it) | ||
- [CommonMark documentation and specification][commonmark] | ||
- [`markdown-it` Markdown parser project page][markdown-it] | ||
@@ -328,1 +366,14 @@ ## Params | ||
``` | ||
[commonmark]: https://commonmark.org/ | ||
[docs-util]: https://github.com/axibase/docs-util/tree/master/linting-rules | ||
[hint]: https://github.com/webhintio/hint/blob/main/scripts/lint-markdown.js | ||
[lib]: ../lib | ||
[markdown-it]: https://github.com/markdown-it/markdown-it | ||
[markdown-it-token]: https://markdown-it.github.io/markdown-it/#Token | ||
[markdownlint-rule]: https://www.npmjs.com/search?q=keywords:markdownlint-rule | ||
[rule-helpers]: https://www.npmjs.com/package/markdownlint-rule-helpers | ||
[options-custom-rules]: ../README.md#optionscustomrules | ||
[test-rules]: ../test/rules | ||
[test-rules-npm]: ../test/rules/npm | ||
[vscode-docs-authoring]: https://github.com/microsoft/vscode-docs-authoring/tree/main/packages/docs-linting/markdownlint-custom-rules |
@@ -1,7 +0,11 @@ | ||
# Using markdownlint with Prettier | ||
# Using `markdownlint` with Prettier | ||
[`Prettier`](https://prettier.io) is a popular code formatter. For the most part, | ||
it works seamlessly with `markdownlint`. Special situations are documented | ||
below. | ||
[`Prettier`](https://prettier.io) is a popular code formatter. | ||
For the most part, Prettier works seamlessly with `markdownlint`. | ||
You can `extend` the [`prettier.json`](../style/prettier.json) style to disable | ||
all `markdownlint` rules that overlap with Prettier. | ||
Other scenarios are documented below. | ||
## List item indentation | ||
@@ -11,14 +15,14 @@ | ||
result in any linting violations. If `Prettier` is used with `--tab-width` set | ||
to `4`, the following `markdownlint` configuration can be used: | ||
to `4` (vs. `2`), the following `markdownlint` configuration can be used: | ||
```json | ||
{ | ||
"MD007": { | ||
"list-marker-space": { | ||
"ul_multi": 3, | ||
"ul_single": 3 | ||
}, | ||
"ul-indent": { | ||
"indent": 4 | ||
}, | ||
"MD030": { | ||
"ul_single": 3, | ||
"ul_multi": 3 | ||
} | ||
} | ||
``` |
749
doc/Rules.md
@@ -10,7 +10,7 @@ # Rules | ||
## MD001 - Heading levels should only increment by one level at a time | ||
## `MD001` - Heading levels should only increment by one level at a time | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: heading-increment, header-increment | ||
Aliases: `header-increment`, `heading-increment` | ||
@@ -51,12 +51,16 @@ This rule is triggered when you skip heading levels in a Markdown document, for | ||
## ~~MD002 - First heading should be a top-level heading~~ | ||
## ~~`MD002` - First heading should be a top-level heading~~ | ||
Tags: headings, headers | ||
> This rule is deprecated and provided for backward-compatibility | ||
Aliases: first-heading-h1, first-header-h1 | ||
Tags: `headers`, `headings` | ||
Parameters: level (number; default 1) | ||
Aliases: `first-header-h1`, `first-heading-h1` | ||
Parameters: | ||
- `level`: Heading level (`integer`, default `1`) | ||
> Note: *MD002 has been deprecated and is disabled by default.* | ||
> [MD041/first-line-heading](#md041) offers an improved implementation. | ||
> [MD041/first-line-heading](md041.md) offers an improved implementation. | ||
@@ -88,14 +92,17 @@ This rule is intended to ensure document headings start at the top level and | ||
## MD003 - Heading style | ||
## `MD003` - Heading style | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: heading-style, header-style | ||
Aliases: `header-style`, `heading-style` | ||
Parameters: style ("consistent", "atx", "atx_closed", "setext", | ||
"setext_with_atx", "setext_with_atx_closed"; default "consistent") | ||
Parameters: | ||
This rule is triggered when different heading styles (atx, setext, and 'closed' | ||
atx) are used in the same document: | ||
- `style`: Heading style (`string`, default `consistent`, values `atx` / | ||
`atx_closed` / `consistent` / `setext` / `setext_with_atx` / | ||
`setext_with_atx_closed`) | ||
This rule is triggered when different heading styles are used in the same | ||
document: | ||
```markdown | ||
@@ -110,3 +117,3 @@ # ATX style H1 | ||
Be consistent with the style of heading used in a document: | ||
To fix the issue, use consistent heading styles throughout the document: | ||
@@ -119,4 +126,5 @@ ```markdown | ||
The setext_with_atx and setext_with_atx_closed doc styles allow atx-style | ||
headings of level 3 or more in documents with setext style headings: | ||
The `setext_with_atx` and `setext_with_atx_closed` settings allow ATX-style | ||
headings of level 3 or more in documents with setext-style headings (which only | ||
support level 1 and 2 headings): | ||
@@ -133,6 +141,14 @@ ```markdown | ||
Note: the configured heading style can be a specific style to use (atx, | ||
atx_closed, setext, setext_with_atx, setext_with_atx_closed), or simply require | ||
that the usage is consistent within the document. | ||
Note: The configured heading style can be a specific style to require (`atx`, | ||
`atx_closed`, `setext`, `setext_with_atx`, `setext_with_atx_closed`), or may | ||
just require that usage is consistent within the document via `consistent`. | ||
Note: The placement of a horizontal rule directly below a line of text can | ||
trigger this rule by turning that text into a level 2 setext-style heading: | ||
```markdown | ||
A line of text followed by a horizontal rule becomes a heading | ||
--- | ||
``` | ||
Rationale: Consistent formatting makes it easier to understand a document. | ||
@@ -142,13 +158,15 @@ | ||
## MD004 - Unordered list style | ||
## `MD004` - Unordered list style | ||
Tags: bullet, ul | ||
Tags: `bullet`, `ul` | ||
Aliases: ul-style | ||
Aliases: `ul-style` | ||
Parameters: style ("consistent", "asterisk", "plus", "dash", "sublist"; default | ||
"consistent") | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `style`: List style (`string`, default `consistent`, values `asterisk` / | ||
`consistent` / `dash` / `plus` / `sublist`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when the symbols used in the document for unordered | ||
@@ -172,9 +190,9 @@ list items do not match the configured unordered list style: | ||
The configured list style can be a specific symbol to use (asterisk, plus, dash), | ||
to ensure that all list styling is consistent, or to ensure that each | ||
The configured list style can be a specific symbol to use (asterisk, plus, | ||
dash), to ensure that all list styling is consistent, or to ensure that each | ||
sublist has a consistent symbol that differs from its parent list. | ||
For example, the following is valid for the `sublist` style because the outer-most | ||
indent uses asterisk, the middle indent uses plus, and the inner-most indent uses | ||
dash: | ||
For example, the following is valid for the `sublist` style because the | ||
outer-most indent uses asterisk, the middle indent uses plus, and the inner-most | ||
indent uses dash: | ||
@@ -194,9 +212,9 @@ ```markdown | ||
## MD005 - Inconsistent indentation for list items at the same level | ||
## `MD005` - Inconsistent indentation for list items at the same level | ||
Tags: bullet, ul, indentation | ||
Tags: `bullet`, `indentation`, `ul` | ||
Aliases: list-indent | ||
Aliases: `list-indent` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -251,10 +269,12 @@ This rule is triggered when list items are parsed as being at the same level, | ||
## ~~MD006 - Consider starting bulleted lists at the beginning of the line~~ | ||
## ~~`MD006` - Consider starting bulleted lists at the beginning of the line~~ | ||
Tags: bullet, ul, indentation | ||
> This rule is deprecated and provided for backward-compatibility | ||
Aliases: ul-start-left | ||
Tags: `bullet`, `indentation`, `ul` | ||
Fixable: Most violations can be fixed by tooling | ||
Aliases: `ul-start-left` | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when top-level lists don't start at the beginning of a | ||
@@ -299,16 +319,18 @@ line: | ||
## MD007 - Unordered list indentation | ||
## `MD007` - Unordered list indentation | ||
Tags: bullet, ul, indentation | ||
Tags: `bullet`, `indentation`, `ul` | ||
Aliases: ul-indent | ||
Aliases: `ul-indent` | ||
<!-- markdownlint-disable line-length --> | ||
Parameters: | ||
Parameters: indent, start_indented, start_indent (number; default 2, boolean; default false, number; defaults to indent) | ||
- `indent`: Spaces for indent (`integer`, default `2`) | ||
- `start_indent`: Spaces for first level indent (when start_indented is set) | ||
(`integer`, default `2`) | ||
- `start_indented`: Whether to indent the first level of the list (`boolean`, | ||
default `false`) | ||
<!-- markdownlint-restore --> | ||
Fixable: Some violations can be fixed by tooling | ||
Fixable: Most violations can be fixed by tooling | ||
This rule is triggered when list items are not indented by the configured | ||
@@ -337,5 +359,5 @@ number of spaces (default: 2). | ||
the configured number of spaces rather than starting at zero (the inverse of | ||
MD006). The `start_indent` parameter allows the first level of lists to be indented | ||
by a different number of spaces than the rest (ignored when `start_indented` is not | ||
set). | ||
MD006). The `start_indent` parameter allows the first level of lists to be | ||
indented by a different number of spaces than the rest (ignored when | ||
`start_indented` is not set). | ||
@@ -346,27 +368,31 @@ Rationale: Indenting by 2 spaces allows the content of a nested list to be in | ||
and simpler for editors to implement. Additionally, this can be a compatibility | ||
issue for other Markdown parsers, which require 4-space indents. More information: | ||
<https://cirosantilli.com/markdown-style-guide#indentation-of-content-inside-lists> | ||
and <http://support.markedapp.com/discussions/problems/21-sub-lists-not-indenting>. | ||
issue for other Markdown parsers, which require 4-space indents. More | ||
information: [Markdown Style Guide][markdown-style-guide] and [Marked app\ | ||
support][marked-app-support]. | ||
Note: See [Prettier.md](Prettier.md) for compatibility information. | ||
[markdown-style-guide]: https://cirosantilli.com/markdown-style-guide#indentation-of-content-inside-lists | ||
[marked-app-support]: http://support.markedapp.com/discussions/problems/21-sub-lists-not-indenting | ||
<a name="md009"></a> | ||
## MD009 - Trailing spaces | ||
## `MD009` - Trailing spaces | ||
Tags: whitespace | ||
Tags: `whitespace` | ||
Aliases: no-trailing-spaces | ||
Aliases: `no-trailing-spaces` | ||
<!-- markdownlint-disable line-length --> | ||
Parameters: | ||
Parameters: br_spaces, list_item_empty_lines, strict (number; default 2, boolean; default false, boolean; default false) | ||
- `br_spaces`: Spaces for line break (`integer`, default `2`) | ||
- `list_item_empty_lines`: Allow spaces for empty lines in list items | ||
(`boolean`, default `false`) | ||
- `strict`: Include unnecessary breaks (`boolean`, default `false`) | ||
<!-- markdownlint-restore --> | ||
Fixable: Some violations can be fixed by tooling | ||
Fixable: Most violations can be fixed by tooling | ||
This rule is triggered on any lines that end with unexpected whitespace. To fix | ||
this, remove the trailing space from the end of the line. | ||
This rule is triggered on any lines that end with unexpected whitespace. To fix this, | ||
remove the trailing space from the end of the line. | ||
Note: Trailing space is allowed in indented and fenced code blocks because some | ||
@@ -379,8 +405,10 @@ languages require it. | ||
Note: You must set `br_spaces` to a value >= 2 for this parameter to take effect. | ||
Setting `br_spaces` to 1 behaves the same as 0, disallowing any trailing spaces. | ||
Note: You must set `br_spaces` to a value >= 2 for this parameter to take | ||
effect. Setting `br_spaces` to 1 behaves the same as 0, disallowing any trailing | ||
spaces. | ||
By default, this rule will not trigger when the allowed number of spaces is used, | ||
even when it doesn't create a hard break (for example, at the end of a paragraph). | ||
To report such instances as well, set the `strict` parameter to `true`. | ||
By default, this rule will not trigger when the allowed number of spaces is | ||
used, even when it doesn't create a hard break (for example, at the end of a | ||
paragraph). To report such instances as well, set the `strict` parameter to | ||
`true`. | ||
@@ -407,12 +435,17 @@ ```markdown | ||
## MD010 - Hard tabs | ||
## `MD010` - Hard tabs | ||
Tags: whitespace, hard_tab | ||
Tags: `hard_tab`, `whitespace` | ||
Aliases: no-hard-tabs | ||
Aliases: `no-hard-tabs` | ||
Parameters: code_blocks, ignore_code_languages, spaces_per_tab (boolean; default true, array of string; default empty, number; default 1) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `code_blocks`: Include code blocks (`boolean`, default `true`) | ||
- `ignore_code_languages`: Fenced code languages to ignore (`string[]`, default | ||
`[]`) | ||
- `spaces_per_tab`: Number of spaces for each hard tab (`integer`, default `1`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered by any lines that contain hard tab characters instead | ||
@@ -462,9 +495,9 @@ of using spaces for indentation. To fix this, replace any hard tab characters | ||
## MD011 - Reversed link syntax | ||
## `MD011` - Reversed link syntax | ||
Tags: links | ||
Tags: `links` | ||
Aliases: no-reversed-links | ||
Aliases: `no-reversed-links` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -496,12 +529,14 @@ This rule is triggered when text that appears to be a link is encountered, but | ||
## MD012 - Multiple consecutive blank lines | ||
## `MD012` - Multiple consecutive blank lines | ||
Tags: whitespace, blank_lines | ||
Tags: `blank_lines`, `whitespace` | ||
Aliases: no-multiple-blanks | ||
Aliases: `no-multiple-blanks` | ||
Parameters: maximum (number; default 1) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `maximum`: Consecutive blank lines (`integer`, default `1`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when there are multiple consecutive blank lines in the | ||
@@ -536,14 +571,22 @@ document: | ||
## MD013 - Line length | ||
## `MD013` - Line length | ||
Tags: line_length | ||
Tags: `line_length` | ||
Aliases: line-length | ||
Aliases: `line-length` | ||
<!-- markdownlint-disable line-length --> | ||
Parameters: | ||
Parameters: line_length, heading_line_length, code_block_line_length, code_blocks, tables, headings, headers, strict, stern (number; default 80 for *_length, boolean; default true (except strict/stern which default false)) | ||
- `code_block_line_length`: Number of characters for code blocks (`integer`, | ||
default `80`) | ||
- `code_blocks`: Include code blocks (`boolean`, default `true`) | ||
- `headers`: Include headings (`boolean`, default `true`) | ||
- `heading_line_length`: Number of characters for headings (`integer`, default | ||
`80`) | ||
- `headings`: Include headings (`boolean`, default `true`) | ||
- `line_length`: Number of characters (`integer`, default `80`) | ||
- `stern`: Stern length checking (`boolean`, default `false`) | ||
- `strict`: Strict length checking (`boolean`, default `false`) | ||
- `tables`: Include tables (`boolean`, default `true`) | ||
<!-- markdownlint-restore --> | ||
> If `headings` is not provided, `headers` (deprecated) will be used. | ||
@@ -558,7 +601,7 @@ | ||
This rule has an exception when there is no whitespace beyond the configured | ||
line length. This allows you to still include items such as long URLs without | ||
being forced to break them in the middle. To disable this exception, set the | ||
`strict` parameter to `true` to report an issue when any line is too long. | ||
To warn for lines that are too long and could be fixed but allow lines without | ||
spaces, set the `stern` parameter to `true`. | ||
line length. This allows you to include items such as long URLs without being | ||
forced to break them in the middle. To disable this exception, set the `strict` | ||
parameter to `true` and an issue will be reported when any line is too long. To | ||
warn for lines that are too long and could be fixed but allow long lines | ||
without spaces, set the `stern` parameter to `true`. | ||
@@ -584,2 +627,6 @@ For example (assuming normal behavior): | ||
Lines with link/image reference definitions are always exempted from this rule | ||
(even in `strict` mode) because there is generally no way to split such lines | ||
without breaking the URL. | ||
Rationale: Extremely long lines can be difficult to work with in some editors. | ||
@@ -590,9 +637,9 @@ More information: <https://cirosantilli.com/markdown-style-guide#line-wrapping>. | ||
## MD014 - Dollar signs used before commands without showing output | ||
## `MD014` - Dollar signs used before commands without showing output | ||
Tags: code | ||
Tags: `code` | ||
Aliases: commands-show-output | ||
Aliases: `commands-show-output` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -648,9 +695,9 @@ This rule is triggered when there are code blocks showing shell commands to be | ||
## MD018 - No space after hash on atx style heading | ||
## `MD018` - No space after hash on atx style heading | ||
Tags: headings, headers, atx, spaces | ||
Tags: `atx`, `headers`, `headings`, `spaces` | ||
Aliases: no-missing-space-atx | ||
Aliases: `no-missing-space-atx` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -679,9 +726,9 @@ This rule is triggered when spaces are missing after the hash characters | ||
## MD019 - Multiple spaces after hash on atx style heading | ||
## `MD019` - Multiple spaces after hash on atx style heading | ||
Tags: headings, headers, atx, spaces | ||
Tags: `atx`, `headers`, `headings`, `spaces` | ||
Aliases: no-multiple-space-atx | ||
Aliases: `no-multiple-space-atx` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -711,9 +758,9 @@ This rule is triggered when more than one space is used to separate the | ||
## MD020 - No space inside hashes on closed atx style heading | ||
## `MD020` - No space inside hashes on closed atx style heading | ||
Tags: headings, headers, atx_closed, spaces | ||
Tags: `atx_closed`, `headers`, `headings`, `spaces` | ||
Aliases: no-missing-space-closed-atx | ||
Aliases: `no-missing-space-closed-atx` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -744,9 +791,9 @@ This rule is triggered when spaces are missing inside the hash characters | ||
## MD021 - Multiple spaces inside hashes on closed atx style heading | ||
## `MD021` - Multiple spaces inside hashes on closed atx style heading | ||
Tags: headings, headers, atx_closed, spaces | ||
Tags: `atx_closed`, `headers`, `headings`, `spaces` | ||
Aliases: no-multiple-space-closed-atx | ||
Aliases: `no-multiple-space-closed-atx` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -779,12 +826,15 @@ This rule is triggered when more than one space is used to separate the | ||
## MD022 - Headings should be surrounded by blank lines | ||
## `MD022` - Headings should be surrounded by blank lines | ||
Tags: headings, headers, blank_lines | ||
Tags: `blank_lines`, `headers`, `headings` | ||
Aliases: blanks-around-headings, blanks-around-headers | ||
Aliases: `blanks-around-headers`, `blanks-around-headings` | ||
Parameters: lines_above, lines_below (number; default 1) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `lines_above`: Blank lines above heading (`integer`, default `1`) | ||
- `lines_below`: Blank lines below heading (`integer`, default `1`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when headings (any style) are either not preceded or not | ||
@@ -814,21 +864,21 @@ followed by at least one blank line: | ||
The `lines_above` and `lines_below` parameters can be used to specify a different | ||
number of blank lines (including 0) above or below each heading. | ||
The `lines_above` and `lines_below` parameters can be used to specify a | ||
different number of blank lines (including 0) above or below each heading. | ||
Note: If `lines_above` or `lines_below` are configured to require more than one | ||
blank line, [MD012/no-multiple-blanks](#md012) should also be customized. | ||
blank line, [MD012/no-multiple-blanks](md012.md) should also be customized. | ||
Rationale: Aside from aesthetic reasons, some parsers, including `kramdown`, will | ||
not parse headings that don't have a blank line before, and will parse them as | ||
regular text. | ||
Rationale: Aside from aesthetic reasons, some parsers, including `kramdown`, | ||
will not parse headings that don't have a blank line before, and will parse them | ||
as regular text. | ||
<a name="md023"></a> | ||
## MD023 - Headings must start at the beginning of the line | ||
## `MD023` - Headings must start at the beginning of the line | ||
Tags: headings, headers, spaces | ||
Tags: `headers`, `headings`, `spaces` | ||
Aliases: heading-start-left, header-start-left | ||
Aliases: `header-start-left`, `heading-start-left` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -856,10 +906,14 @@ This rule is triggered when a heading is indented by one or more spaces: | ||
## MD024 - Multiple headings with the same content | ||
## `MD024` - Multiple headings with the same content | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: no-duplicate-heading, no-duplicate-header | ||
Aliases: `no-duplicate-header`, `no-duplicate-heading` | ||
Parameters: siblings_only, allow_different_nesting (boolean; default `false`) | ||
Parameters: | ||
- `allow_different_nesting`: Only check sibling headings (`boolean`, default | ||
`false`) | ||
- `siblings_only`: Only check sibling headings (`boolean`, default `false`) | ||
This rule is triggered if there are multiple headings in the document that have | ||
@@ -903,10 +957,14 @@ the same text: | ||
## MD025 - Multiple top-level headings in the same document | ||
## `MD025` - Multiple top-level headings in the same document | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: single-title, single-h1 | ||
Aliases: `single-h1`, `single-title` | ||
Parameters: level, front_matter_title (number; default 1, string; default "^\s*"?title"?\s*[:=]") | ||
Parameters: | ||
- `front_matter_title`: RegExp for matching title in front matter (`string`, | ||
default `^\s*title\s*[:=]`) | ||
- `level`: Heading level (`integer`, default `1`) | ||
This rule is triggered when a top-level heading is in use (the first line of | ||
@@ -937,26 +995,30 @@ the file is an h1 heading), and more than one h1 heading is in use in the | ||
If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and contains | ||
a `title` property (commonly used with blog posts), this rule treats that as a top | ||
level heading and will report a violation for any subsequent top-level headings. | ||
To use a different property name in the front matter, specify the text of a regular | ||
expression via the `front_matter_title` parameter. To disable the use of front | ||
matter by this rule, specify `""` for `front_matter_title`. | ||
If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and | ||
contains a `title` property (commonly used with blog posts), this rule treats | ||
that as a top level heading and will report a violation for any subsequent | ||
top-level headings. To use a different property name in the front matter, | ||
specify the text of a regular expression via the `front_matter_title` parameter. | ||
To disable the use of front matter by this rule, specify `""` for | ||
`front_matter_title`. | ||
Rationale: A top-level heading is an h1 on the first line of the file, and | ||
serves as the title for the document. If this convention is in use, then there | ||
can not be more than one title for the document, and the entire document | ||
should be contained within this heading. | ||
can not be more than one title for the document, and the entire document should | ||
be contained within this heading. | ||
<a name="md026"></a> | ||
## MD026 - Trailing punctuation in heading | ||
## `MD026` - Trailing punctuation in heading | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: no-trailing-punctuation | ||
Aliases: `no-trailing-punctuation` | ||
Parameters: punctuation (string; default ".,;:!。,;:!") | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `punctuation`: Punctuation characters not allowed at end of headings | ||
(`string`, default `.,;:!。,;:!`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered on any heading that has one of the specified normal or | ||
@@ -978,22 +1040,24 @@ full-width punctuation characters as the last character in the line: | ||
`".,;:"` to allow headings that end with an exclamation point. `?` is | ||
allowed by default because of how common it is in headings of FAQ-style documents. | ||
Setting the `punctuation` parameter to `""` allows all characters - and is | ||
equivalent to disabling the rule. | ||
allowed by default because of how common it is in headings of FAQ-style | ||
documents. Setting the `punctuation` parameter to `""` allows all characters - | ||
and is equivalent to disabling the rule. | ||
Note: The trailing semicolon of | ||
[HTML entity references](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references) | ||
Note: The trailing semicolon of [HTML entity references][html-entity-references] | ||
like `©`, `©`, and `©` is ignored by this rule. | ||
Rationale: Headings are not meant to be full sentences. More information: | ||
<https://cirosantilli.com/markdown-style-guide#punctuation-at-the-end-of-headers> | ||
[Punctuation at the end of headers][end-punctuation]. | ||
[end-punctuation]: https://cirosantilli.com/markdown-style-guide#punctuation-at-the-end-of-headers | ||
[html-entity-references]: https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references | ||
<a name="md027"></a> | ||
## MD027 - Multiple spaces after blockquote symbol | ||
## `MD027` - Multiple spaces after blockquote symbol | ||
Tags: blockquote, whitespace, indentation | ||
Tags: `blockquote`, `indentation`, `whitespace` | ||
Aliases: no-multiple-space-blockquote | ||
Aliases: `no-multiple-space-blockquote` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1019,7 +1083,7 @@ This rule is triggered when blockquotes have more than one space after the | ||
## MD028 - Blank line inside blockquote | ||
## `MD028` - Blank line inside blockquote | ||
Tags: blockquote, whitespace | ||
Tags: `blockquote`, `whitespace` | ||
Aliases: no-blanks-blockquote | ||
Aliases: `no-blanks-blockquote` | ||
@@ -1063,10 +1127,13 @@ This rule is triggered when two blockquote blocks are separated by nothing | ||
## MD029 - Ordered list item prefix | ||
## `MD029` - Ordered list item prefix | ||
Tags: ol | ||
Tags: `ol` | ||
Aliases: ol-prefix | ||
Aliases: `ol-prefix` | ||
Parameters: style ("one", "ordered", "one_or_ordered", "zero"; default "one_or_ordered") | ||
Parameters: | ||
- `style`: List style (`string`, default `one_or_ordered`, values `one` / | ||
`one_or_ordered` / `ordered` / `zero`) | ||
This rule is triggered for ordered lists that do not either start with '1.' or | ||
@@ -1162,12 +1229,20 @@ do not have a prefix that increases in numerical order (depending on the | ||
## MD030 - Spaces after list markers | ||
## `MD030` - Spaces after list markers | ||
Tags: ol, ul, whitespace | ||
Tags: `ol`, `ul`, `whitespace` | ||
Aliases: list-marker-space | ||
Aliases: `list-marker-space` | ||
Parameters: ul_single, ol_single, ul_multi, ol_multi (number; default 1) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `ol_multi`: Spaces for multi-line ordered list items (`integer`, default `1`) | ||
- `ol_single`: Spaces for single-line ordered list items (`integer`, default | ||
`1`) | ||
- `ul_multi`: Spaces for multi-line unordered list items (`integer`, default | ||
`1`) | ||
- `ul_single`: Spaces for single-line unordered list items (`integer`, default | ||
`1`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule checks for the number of spaces between a list marker (e.g. '`-`', | ||
@@ -1240,12 +1315,14 @@ '`*`', '`+`' or '`1.`') and the text of the list item. | ||
## MD031 - Fenced code blocks should be surrounded by blank lines | ||
## `MD031` - Fenced code blocks should be surrounded by blank lines | ||
Tags: code, blank_lines | ||
Tags: `blank_lines`, `code` | ||
Aliases: blanks-around-fences | ||
Aliases: `blanks-around-fences` | ||
Parameters: list_items (boolean; default true) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `list_items`: Include list items (`boolean`, default `true`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when fenced code blocks are either not preceded or not | ||
@@ -1292,9 +1369,9 @@ followed by a blank line: | ||
## MD032 - Lists should be surrounded by blank lines | ||
## `MD032` - Lists should be surrounded by blank lines | ||
Tags: bullet, ul, ol, blank_lines | ||
Tags: `blank_lines`, `bullet`, `ol`, `ul` | ||
Aliases: blanks-around-lists | ||
Aliases: `blanks-around-lists` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1334,10 +1411,12 @@ This rule is triggered when lists (of any kind) are either not preceded or not | ||
## MD033 - Inline HTML | ||
## `MD033` - Inline HTML | ||
Tags: html | ||
Tags: `html` | ||
Aliases: no-inline-html | ||
Aliases: `no-inline-html` | ||
Parameters: allowed_elements (array of string; default empty) | ||
Parameters: | ||
- `allowed_elements`: Allowed elements (`string[]`, default `[]`) | ||
This rule is triggered whenever raw HTML is used in a Markdown document: | ||
@@ -1363,9 +1442,9 @@ | ||
## MD034 - Bare URL used | ||
## `MD034` - Bare URL used | ||
Tags: links, url | ||
Tags: `links`, `url` | ||
Aliases: no-bare-urls | ||
Aliases: `no-bare-urls` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1411,11 +1490,12 @@ This rule is triggered whenever a URL is given that isn't surrounded by angle | ||
## MD035 - Horizontal rule style | ||
## `MD035` - Horizontal rule style | ||
Tags: hr | ||
Tags: `hr` | ||
Aliases: hr-style | ||
Aliases: `hr-style` | ||
Parameters: style ("consistent", "---", "***", "___", or other string specifying | ||
the horizontal rule; default "consistent") | ||
Parameters: | ||
- `style`: Horizontal rule style (`string`, default `consistent`) | ||
This rule is triggered when inconsistent styles of horizontal rules are used | ||
@@ -1456,10 +1536,12 @@ in the document: | ||
## MD036 - Emphasis used instead of a heading | ||
## `MD036` - Emphasis used instead of a heading | ||
Tags: headings, headers, emphasis | ||
Tags: `emphasis`, `headers`, `headings` | ||
Aliases: no-emphasis-as-heading, no-emphasis-as-header | ||
Aliases: `no-emphasis-as-header`, `no-emphasis-as-heading` | ||
Parameters: punctuation (string; default ".,;:!?。,;:!?") | ||
Parameters: | ||
- `punctuation`: Punctuation characters (`string`, default `.,;:!?。,;:!?`) | ||
This check looks for instances where emphasized (i.e. bold or italic) text is | ||
@@ -1503,9 +1585,9 @@ used to separate sections, where a heading should be used instead: | ||
## MD037 - Spaces inside emphasis markers | ||
## `MD037` - Spaces inside emphasis markers | ||
Tags: whitespace, emphasis | ||
Tags: `emphasis`, `whitespace` | ||
Aliases: no-space-in-emphasis | ||
Aliases: `no-space-in-emphasis` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1544,9 +1626,9 @@ This rule is triggered when emphasis markers (bold, italic) are used, but they | ||
## MD038 - Spaces inside code span elements | ||
## `MD038` - Spaces inside code span elements | ||
Tags: whitespace, code | ||
Tags: `code`, `whitespace` | ||
Aliases: no-space-in-code | ||
Aliases: `no-space-in-code` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1569,3 +1651,3 @@ This rule is triggered for code span elements that have spaces adjacent to the | ||
Note: A single leading and trailing space is allowed by the specification and | ||
automatically trimmed (to allow for embedded backticks): | ||
automatically trimmed (in order to allow for code spans that embed backticks): | ||
@@ -1576,4 +1658,4 @@ ```markdown | ||
Note: A single leading or trailing space is allowed if used to separate code span | ||
markers from an embedded backtick: | ||
Note: A single leading or trailing space is allowed if used to separate code | ||
span markers from an embedded backtick (though the space is not trimmed): | ||
@@ -1584,13 +1666,15 @@ ```markdown | ||
Rationale: Violations of this rule can lead to improperly rendered content. | ||
Rationale: Violations of this rule are usually unintentional and may lead to | ||
improperly-rendered content. If spaces beside backticks are intentional, this | ||
rule can be disabled for that line or file. | ||
<a name="md039"></a> | ||
## MD039 - Spaces inside link text | ||
## `MD039` - Spaces inside link text | ||
Tags: whitespace, links | ||
Tags: `links`, `whitespace` | ||
Aliases: no-space-in-links | ||
Aliases: `no-space-in-links` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1613,8 +1697,13 @@ This rule is triggered on links that have spaces surrounding the link text: | ||
## MD040 - Fenced code blocks should have a language specified | ||
## `MD040` - Fenced code blocks should have a language specified | ||
Tags: code, language | ||
Tags: `code`, `language` | ||
Aliases: fenced-code-language | ||
Aliases: `fenced-code-language` | ||
Parameters: | ||
- `allowed_languages`: List of languages (`string[]`, default `[]`) | ||
- `language_only`: Require language only (`boolean`, default `false`) | ||
This rule is triggered when fenced code blocks are used, but a language isn't | ||
@@ -1647,2 +1736,13 @@ specified: | ||
You can configure the `allowed_languages` parameter to specify a list of | ||
languages code blocks could use. Languages are case sensitive. The default value | ||
is `[]` which means any language specifier is valid. | ||
You can prevent extra data from being present in the info string of fenced code | ||
blocks. To do so, set the `language_only` parameter to `true`. | ||
<!-- markdownlint-disable-next-line no-space-in-code --> | ||
Info strings with leading/trailing whitespace (ex: `js `) or other content (ex: | ||
`ruby startline=3`) will trigger this rule. | ||
Rationale: Specifying a language improves content rendering by using the | ||
@@ -1654,10 +1754,14 @@ correct syntax highlighting for code. More information: | ||
## MD041 - First line in a file should be a top-level heading | ||
## `MD041` - First line in a file should be a top-level heading | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: first-line-heading, first-line-h1 | ||
Aliases: `first-line-h1`, `first-line-heading` | ||
Parameters: level, front_matter_title (number; default 1, string; default "^\s*"?title"?\s*[:=]") | ||
Parameters: | ||
- `front_matter_title`: RegExp for matching title in front matter (`string`, | ||
default `^\s*title\s*[:=]`) | ||
- `level`: Heading level (`integer`, default `1`) | ||
This rule is intended to ensure documents have a title and is triggered when | ||
@@ -1688,4 +1792,4 @@ the first line in the file isn't a top-level (h1) heading: | ||
Note: The `level` parameter can be used to change the top-level (ex: to h2) in cases | ||
where an h1 is added externally. | ||
Note: The `level` parameter can be used to change the top-level (ex: to h2) in | ||
cases where an h1 is added externally. | ||
@@ -1696,3 +1800,4 @@ If [YAML](https://en.wikipedia.org/wiki/YAML) front matter is present and | ||
specify the text of a regular expression via the `front_matter_title` parameter. | ||
To disable the use of front matter by this rule, specify `""` for `front_matter_title`. | ||
To disable the use of front matter by this rule, specify `""` for | ||
`front_matter_title`. | ||
@@ -1704,7 +1809,7 @@ Rationale: The top-level heading often acts as the title of a document. More | ||
## MD042 - No empty links | ||
## `MD042` - No empty links | ||
Tags: links | ||
Tags: `links` | ||
Aliases: no-empty-links | ||
Aliases: `no-empty-links` | ||
@@ -1735,14 +1840,19 @@ This rule is triggered when an empty link is encountered: | ||
Rationale: Empty links do not lead anywhere and therefore don't function as links. | ||
Rationale: Empty links do not lead anywhere and therefore don't function as | ||
links. | ||
<a name="md043"></a> | ||
## MD043 - Required heading structure | ||
## `MD043` - Required heading structure | ||
Tags: headings, headers | ||
Tags: `headers`, `headings` | ||
Aliases: required-headings, required-headers | ||
Aliases: `required-headers`, `required-headings` | ||
Parameters: headings, headers (array of string; default `null` for disabled) | ||
Parameters: | ||
- `headers`: List of headings (`string[]`, default `[]`) | ||
- `headings`: List of headings (`string[]`, default `[]`) | ||
- `match_case`: Match case of headings (`boolean`, default `false`) | ||
> If `headings` is not provided, `headers` (deprecated) will be used. | ||
@@ -1799,5 +1909,9 @@ | ||
Note that while the `headings` parameter uses the "## Text" ATX heading style for | ||
simplicity, a file may use any supported heading style. | ||
Note that while the `headings` parameter uses the "## Text" ATX heading style | ||
for simplicity, a file may use any supported heading style. | ||
By default, the case of headings in the document is not required to match that | ||
of `headings`. To require that case match exactly, set the `match_case` | ||
parameter to `true`. | ||
Rationale: Projects may wish to enforce a consistent document structure across | ||
@@ -1808,12 +1922,16 @@ a set of similar content. | ||
## MD044 - Proper names should have the correct capitalization | ||
## `MD044` - Proper names should have the correct capitalization | ||
Tags: spelling | ||
Tags: `spelling` | ||
Aliases: proper-names | ||
Aliases: `proper-names` | ||
Parameters: names, code_blocks, html_elements (string array; default `null`, boolean; default `true`, boolean; default `true`) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `code_blocks`: Include code blocks (`boolean`, default `true`) | ||
- `html_elements`: Include HTML elements (`boolean`, default `true`) | ||
- `names`: List of proper names (`string[]`, default `[]`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when any of the strings in the `names` array do not have | ||
@@ -1824,4 +1942,5 @@ the specified capitalization. It can be used to enforce a standard letter case | ||
For example, the language "JavaScript" is usually written with both the 'J' and | ||
'S' capitalized - though sometimes the 's' or 'j' appear in lower-case. To enforce | ||
the proper capitalization, specify the desired letter case in the `names` array: | ||
'S' capitalized - though sometimes the 's' or 'j' appear in lower-case. To | ||
enforce the proper capitalization, specify the desired letter case in the | ||
`names` array: | ||
@@ -1843,9 +1962,10 @@ ```json | ||
## MD045 - Images should have alternate text (alt text) | ||
## `MD045` - Images should have alternate text (alt text) | ||
Tags: accessibility, images | ||
Tags: `accessibility`, `images` | ||
Aliases: no-alt-text | ||
Aliases: `no-alt-text` | ||
This rule is triggered when an image is missing alternate text (alt text) information. | ||
This rule is triggered when an image is missing alternate text (alt text) | ||
information. | ||
@@ -1868,5 +1988,4 @@ Alternate text is commonly specified inline as: | ||
Guidance for writing alternate text is available from the [W3C](https://www.w3.org/WAI/alt/), | ||
[Wikipedia](https://en.wikipedia.org/wiki/Alt_attribute), and | ||
[other locations](https://www.phase2technology.com/blog/no-more-excuses). | ||
Guidance for writing alternate text is available from the [W3C][w3c], | ||
[Wikipedia][wikipedia], and [other locations][phase2technology]. | ||
@@ -1876,16 +1995,24 @@ Rationale: Alternate text is important for accessibility and describes the | ||
[phase2technology]: https://www.phase2technology.com/blog/no-more-excuses | ||
[w3c]: https://www.w3.org/WAI/alt/ | ||
[wikipedia]: https://en.wikipedia.org/wiki/Alt_attribute | ||
<a name="md046"></a> | ||
## MD046 - Code block style | ||
## `MD046` - Code block style | ||
Tags: code | ||
Tags: `code` | ||
Aliases: code-block-style | ||
Aliases: `code-block-style` | ||
Parameters: style ("consistent", "fenced", "indented"; default "consistent") | ||
Parameters: | ||
- `style`: Block style (`string`, default `consistent`, values `consistent` / | ||
`fenced` / `indented`) | ||
This rule is triggered when unwanted or different code block styles are used in | ||
the same document. | ||
In the default configuration this rule reports a violation for the following document: | ||
In the default configuration this rule reports a violation for the following | ||
document: | ||
@@ -1918,9 +2045,9 @@ <!-- markdownlint-disable code-block-style --> | ||
## MD047 - Files should end with a single newline character | ||
## `MD047` - Files should end with a single newline character | ||
Tags: blank_lines | ||
Tags: `blank_lines` | ||
Aliases: single-trailing-newline | ||
Aliases: `single-trailing-newline` | ||
Fixable: Most violations can be fixed by tooling | ||
Fixable: Some violations can be fixed by tooling | ||
@@ -1948,14 +2075,21 @@ This rule is triggered when there is not a single newline character at the end | ||
Rationale: Some programs have trouble with files that do not end with a newline. | ||
More information: <https://unix.stackexchange.com/questions/18743/whats-the-point-in-adding-a-new-line-to-the-end-of-a-file>. | ||
More information: [What's the point in adding a new line to the end of a | ||
file?][stack-exchange] | ||
[stack-exchange]: https://unix.stackexchange.com/questions/18743/whats-the-point-in-adding-a-new-line-to-the-end-of-a-file | ||
<a name="md048"></a> | ||
## MD048 - Code fence style | ||
## `MD048` - Code fence style | ||
Tags: code | ||
Tags: `code` | ||
Aliases: code-fence-style | ||
Aliases: `code-fence-style` | ||
Parameters: style ("consistent", "tilde", "backtick"; default "consistent") | ||
Parameters: | ||
- `style`: Code fence style (`string`, default `consistent`, values `backtick` | ||
/ `consistent` / `tilde`) | ||
This rule is triggered when the symbols used in the document for fenced code | ||
@@ -1994,12 +2128,15 @@ blocks do not match the configured code fence style: | ||
## MD049 - Emphasis style should be consistent | ||
## `MD049` - Emphasis style should be consistent | ||
Tags: emphasis | ||
Tags: `emphasis` | ||
Aliases: emphasis-style | ||
Aliases: `emphasis-style` | ||
Parameters: style ("consistent", "asterisk", "underscore"; default "consistent") | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `style`: Emphasis style should be consistent (`string`, default `consistent`, | ||
values `asterisk` / `consistent` / `underscore`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when the symbols used in the document for emphasis do not | ||
@@ -2027,12 +2164,15 @@ match the configured emphasis style: | ||
## MD050 - Strong style should be consistent | ||
## `MD050` - Strong style should be consistent | ||
Tags: emphasis | ||
Tags: `emphasis` | ||
Aliases: strong-style | ||
Aliases: `strong-style` | ||
Parameters: style ("consistent", "asterisk", "underscore"; default "consistent") | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `style`: Strong style should be consistent (`string`, default `consistent`, | ||
values `asterisk` / `consistent` / `underscore`) | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when the symbols used in the document for strong do not | ||
@@ -2060,11 +2200,13 @@ match the configured strong style: | ||
## MD051 - Link fragments should be valid | ||
## `MD051` - Link fragments should be valid | ||
Tags: links | ||
Tags: `links` | ||
Aliases: link-fragments | ||
Aliases: `link-fragments` | ||
This rule is triggered when a link fragment does not correspond to a heading | ||
in the document: | ||
Fixable: Some violations can be fixed by tooling | ||
This rule is triggered when a link fragment does not match any of the fragments | ||
that are automatically generated for headings in a document: | ||
```markdown | ||
@@ -2076,30 +2218,43 @@ # Title | ||
To fix the issue, change the fragment to reference an existing heading: | ||
To fix this issue, change the link fragment to reference an existing heading: | ||
```markdown | ||
# Title | ||
[Link](#title) | ||
``` | ||
Alternatively, an HTML `a` tag with an `id` (or a `name`) attribute defines a | ||
valid anchor: | ||
Alternatively, an HTML `a` tag with an `id` or a `name` attribute can be used to | ||
define a fragment: | ||
```markdown | ||
<a id="fragment"></a> | ||
<a id="bookmark"></a> | ||
[Link](#bookmark) | ||
``` | ||
Some platforms (e.g., [GitHub][github-section-links]) automatically create HTML | ||
anchors for every heading. This makes it easy to link to different sections in | ||
a document. These internal links can break over time as headings are renamed. | ||
An `a` tag can be useful in scenarios where a heading is not appropriate or for | ||
control over the text of the fragment identifier. | ||
Note: Creating anchors for headings is not part of the CommonMark specification. | ||
Rationale: [GitHub section links][github-section-links] are created | ||
automatically for every heading when Markdown content is displayed on GitHub. | ||
This makes it easy to link directly to different sections within a document. | ||
However, section links change if headings are renamed or removed. This rule | ||
helps identify broken section links within a document. | ||
Section links are **not** part of the CommonMark specification. This rule | ||
enforces the [GitHub heading algorithm][github-heading-algorithm] which is: | ||
convert heading to lowercase, remove punctuation, convert spaces to dashes, | ||
append an incrementing integer as needed for uniqueness. | ||
[github-section-links]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#section-links | ||
[github-heading-algorithm]: https://github.com/gjtorikian/html-pipeline/blob/main/lib/html/pipeline/toc_filter.rb | ||
<a name="md052"></a> | ||
## MD052 - Reference links and images should use a label that is defined | ||
## `MD052` - Reference links and images should use a label that is defined | ||
Tags: images, links | ||
Tags: `images`, `links` | ||
Aliases: reference-links-images | ||
Aliases: `reference-links-images` | ||
@@ -2136,12 +2291,14 @@ Links and images in Markdown can provide the link destination or image source | ||
## MD053 - Link and image reference definitions should be needed | ||
## `MD053` - Link and image reference definitions should be needed | ||
Tags: images, links | ||
Tags: `images`, `links` | ||
Aliases: link-image-reference-definitions | ||
Aliases: `link-image-reference-definitions` | ||
Parameters: ignored_definitions (array of string; default [ "//" ]) | ||
Parameters: | ||
Fixable: Most violations can be fixed by tooling | ||
- `ignored_definitions`: Ignored definitions (`string[]`, default `["//"]`) | ||
Fixable: Some violations can be fixed by tooling | ||
Links and images in Markdown can provide the link destination or image source | ||
@@ -2158,3 +2315,3 @@ at the time of use or can define it elsewhere and use a label for reference. | ||
definition is unused and can be deleted. | ||
1. If a label is defined multiple times in a document, the first definition is | ||
2. If a label is defined multiple times in a document, the first definition is | ||
used and the others can be deleted. | ||
@@ -2171,3 +2328,3 @@ | ||
```md | ||
```markdown | ||
[//]: # (This behaves like a comment) | ||
@@ -2174,0 +2331,0 @@ ``` |
@@ -13,3 +13,3 @@ // @ts-check | ||
// eslint-disable-next-line max-len | ||
/((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$)|(^\{\s*$[^]*?^\}\s*$))(\r\n|\r|\n|$)/m; | ||
/((^---\s*$[\s\S]*?^---\s*)|(^\+\+\+\s*$[\s\S]*?^(\+\+\+|\.\.\.)\s*)|(^\{\s*$[\s\S]*?^\}\s*))(\r\n|\r|\n|$)/m; | ||
@@ -19,11 +19,10 @@ // Regular expression for matching the start of inline disable/enable comments | ||
// eslint-disable-next-line max-len | ||
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/ig; | ||
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/gi; | ||
module.exports.inlineCommentStartRe = inlineCommentStartRe; | ||
// Regular expression for matching HTML elements | ||
const htmlElementRe = /<(([A-Za-z][A-Za-z0-9-]*)(?:\s[^`>]*)?)\/?>/g; | ||
const htmlElementRe = /<(([A-Za-z][A-Za-z\d-]*)(?:\s[^`>]*)?)\/?>/g; | ||
module.exports.htmlElementRe = htmlElementRe; | ||
// Regular expressions for range matching | ||
module.exports.bareUrlRe = /(?:http|ftp)s?:\/\/[^\s\]"']*(?:\/|[^\s\]"'\W])/ig; | ||
module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/; | ||
@@ -41,6 +40,6 @@ module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/; | ||
const referenceLinkRe = | ||
/!?\\?\[((?:\[[^\]\0]*]|[^\]\0])*)](?:(?:\[([^\]\0]*)\])|([^(])|$)/g; | ||
/!?\\?\[((?:\[[^\]\0]*\]|[^[\]\0])*)\](?:\[([^\]\0]*)\]|([^(])|$)/g; | ||
// Regular expression for link reference definitions | ||
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])]:/; | ||
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])\]:/; | ||
module.exports.linkReferenceDefinitionRe = linkReferenceDefinitionRe; | ||
@@ -148,2 +147,8 @@ | ||
const htmlCommentEnd = "-->"; | ||
const safeCommentCharacter = "."; | ||
const startsWithPipeRe = /^ *\|/; | ||
const notCrLfRe = /[^\r\n]/g; | ||
const notSpaceCrLfRe = /[^ \r\n]/g; | ||
const trailingSpaceRe = / +[\r\n]/g; | ||
const replaceTrailingSpace = (s) => s.replace(notCrLfRe, safeCommentCharacter); | ||
module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) { | ||
@@ -159,21 +164,27 @@ let i = 0; | ||
if (j > i + htmlCommentBegin.length) { | ||
let k = i - 1; | ||
while (text[k] === " ") { | ||
k--; | ||
const content = text.slice(i + htmlCommentBegin.length, j); | ||
const lastLf = text.lastIndexOf("\n", i) + 1; | ||
const preText = text.slice(lastLf, i); | ||
const isBlock = preText.trim().length === 0; | ||
const couldBeTable = startsWithPipeRe.test(preText); | ||
const spansTableCells = couldBeTable && content.includes("\n"); | ||
const isValid = | ||
isBlock || | ||
!( | ||
spansTableCells || | ||
content.startsWith(">") || | ||
content.startsWith("->") || | ||
content.endsWith("-") || | ||
content.includes("--") | ||
); | ||
// If a valid block/inline comment... | ||
if (isValid) { | ||
const clearedContent = content | ||
.replace(notSpaceCrLfRe, safeCommentCharacter) | ||
.replace(trailingSpaceRe, replaceTrailingSpace); | ||
text = | ||
text.slice(0, i + htmlCommentBegin.length) + | ||
clearedContent + | ||
text.slice(j); | ||
} | ||
// If comment is not within an indented code block... | ||
if (k >= i - 4) { | ||
const content = text.slice(i + htmlCommentBegin.length, j); | ||
const isBlock = (k < 0) || (text[k] === "\n"); | ||
const isValid = isBlock || | ||
(!content.startsWith(">") && !content.startsWith("->") && | ||
!content.endsWith("-") && !content.includes("--")); | ||
// If a valid block/inline comment... | ||
if (isValid) { | ||
text = | ||
text.slice(0, i + htmlCommentBegin.length) + | ||
content.replace(/[^\r\n]/g, ".") + | ||
text.slice(j); | ||
} | ||
} | ||
} | ||
@@ -414,13 +425,18 @@ i = j + htmlCommentEnd.length; | ||
// Calls the provided function for each specified inline child token | ||
module.exports.forEachInlineChild = | ||
/** | ||
* Calls the provided function for each specified inline child token. | ||
* | ||
* @param {Object} params RuleParams instance. | ||
* @param {string} type Token type identifier. | ||
* @param {Function} handler Callback function. | ||
* @returns {void} | ||
*/ | ||
function forEachInlineChild(params, type, handler) { | ||
filterTokens(params, "inline", function forToken(token) { | ||
for (const child of token.children) { | ||
if (child.type === type) { | ||
handler(child, token); | ||
} | ||
filterTokens(params, "inline", (token) => { | ||
for (const child of token.children.filter((c) => c.type === type)) { | ||
handler(child, token); | ||
} | ||
}); | ||
}; | ||
} | ||
module.exports.forEachInlineChild = forEachInlineChild; | ||
@@ -605,2 +621,3 @@ // Calls the provided function for each heading's content | ||
const exclusions = []; | ||
// Match with htmlElementRe | ||
forEachLine(lineMetadata, (line, lineIndex, inCode) => { | ||
@@ -613,2 +630,27 @@ let match = null; | ||
}); | ||
// Match with html_inline | ||
forEachInlineChild(params, "html_inline", (token, parent) => { | ||
const parentContent = parent.content; | ||
let tokenContent = token.content; | ||
const parentIndex = parentContent.indexOf(tokenContent); | ||
let deltaLines = 0; | ||
let indent = 0; | ||
for (let i = parentIndex - 1; i >= 0; i--) { | ||
if (parentContent[i] === "\n") { | ||
deltaLines++; | ||
} else if (deltaLines === 0) { | ||
indent++; | ||
} | ||
} | ||
let lineIndex = token.lineNumber - 1 + deltaLines; | ||
do { | ||
const index = tokenContent.indexOf("\n"); | ||
const length = (index === -1) ? tokenContent.length : index; | ||
exclusions.push([ lineIndex, indent, length ]); | ||
tokenContent = tokenContent.slice(length + 1); | ||
lineIndex++; | ||
indent = 0; | ||
} while (tokenContent.length > 0); | ||
}); | ||
// Return results | ||
return exclusions; | ||
@@ -793,5 +835,6 @@ }; | ||
const references = new Map(); | ||
const shortcuts = new Set(); | ||
const shortcuts = new Map(); | ||
const definitions = new Map(); | ||
const duplicateDefinitions = []; | ||
const definitionLineIndices = []; | ||
// Define helper functions | ||
@@ -836,3 +879,9 @@ const normalizeLabel = (s) => s.toLowerCase().trim().replace(/\s+/g, " "); | ||
} | ||
exclusions.push([ 0, lineOffsets[lineIndex], line.length ]); | ||
const labelLength = linkReferenceDefinitionMatch[0].length; | ||
exclusions.push([ 0, lineOffsets[lineIndex], labelLength ]); | ||
const hasDefinition = line.slice(labelLength).trim().length > 0; | ||
definitionLineIndices.push(lineIndex); | ||
if (!hasDefinition) { | ||
definitionLineIndices.push(lineIndex + 1); | ||
} | ||
} | ||
@@ -884,13 +933,18 @@ } | ||
(topLevel ? -lineOffsets[lineIndex] : contentIndex); | ||
const referenceDatum = [ | ||
lineIndex, | ||
referenceIndex, | ||
matchString.length, | ||
matchText.length, | ||
(matchLabel || "").length | ||
]; | ||
if (shortcutLink) { | ||
// Track separately due to ambiguity in "text [text] text" | ||
shortcuts.add(label); | ||
const shortcutData = shortcuts.get(label) || []; | ||
shortcutData.push(referenceDatum); | ||
shortcuts.set(label, shortcutData); | ||
} else { | ||
// Track reference and location | ||
const referenceData = references.get(label) || []; | ||
referenceData.push([ | ||
lineIndex, | ||
referenceIndex, | ||
matchString.length | ||
]); | ||
referenceData.push(referenceDatum); | ||
references.set(label, referenceData); | ||
@@ -915,3 +969,4 @@ } | ||
definitions, | ||
duplicateDefinitions | ||
duplicateDefinitions, | ||
definitionLineIndices | ||
}; | ||
@@ -1004,3 +1059,3 @@ } | ||
function applyFixes(input, errors) { | ||
const lineEnding = getPreferredLineEnding(input, require("os")); | ||
const lineEnding = getPreferredLineEnding(input, require("node:os")); | ||
const lines = input.split(newLineRe); | ||
@@ -1148,1 +1203,108 @@ // Normalize fixInfo objects | ||
module.exports.expandTildePath = expandTildePath; | ||
/** | ||
* RegExp.exec-style implementation of function expressions. | ||
* | ||
* @param {Function} funcExp Function that takes string and returns | ||
* [index, length] or null. | ||
* @param {string} input String to search. | ||
* @returns {string[] | null} RegExp.exec-style [match] with an index property. | ||
*/ | ||
function funcExpExec(funcExp, input) { | ||
// Start or resume match | ||
// @ts-ignore | ||
const lastIndex = funcExp.lastIndex || 0; | ||
const result = funcExp(input.slice(lastIndex)); | ||
if (result) { | ||
// Update lastIndex and return match | ||
const [ subIndex, length ] = result; | ||
const index = lastIndex + subIndex; | ||
// @ts-ignore | ||
funcExp.lastIndex = index + length; | ||
const match = [ input.slice(index, index + length) ]; | ||
// @ts-ignore | ||
match.index = index; | ||
return match; | ||
} | ||
// Reset lastIndex and return no match | ||
// @ts-ignore | ||
funcExp.lastIndex = 0; | ||
return null; | ||
} | ||
module.exports.funcExpExec = funcExpExec; | ||
const urlFeProtocolRe = /(?:http|ftp)s?:\/\//i; | ||
const urlFeAutolinkTerminalsRe = / |$/; | ||
const urlFeBareTerminalsRe = /[ ,!`'"\]]|$/; | ||
const urlFeNonTerminalsRe = "-#/"; | ||
const urlFePunctuationRe = /\p{Punctuation}/u; | ||
const urlFePrefixToPostfix = new Map([ | ||
[ " ", " " ], | ||
[ "`", "`" ], | ||
[ "'", "'" ], | ||
[ "\"", "\"" ], | ||
[ "‘", "’" ], | ||
[ "“", "”" ], | ||
[ "«", "»" ], | ||
[ "*", "*" ], | ||
[ "_", "_" ], | ||
[ "(", ")" ], | ||
[ "[", "]" ], | ||
[ "{", "}" ], | ||
[ "<", ">" ], | ||
[ ">", "<" ] | ||
]); | ||
/** | ||
* Function expression that matches URLs. | ||
* | ||
* @param {string} input Substring to search for a URL. | ||
* @returns {Array | null} [index, length] of URL or null. | ||
*/ | ||
function urlFe(input) { | ||
// Find start of URL by searching for protocol | ||
const match = input.match(urlFeProtocolRe); | ||
if (match) { | ||
// Look for matching pre/postfix characters (ex: <...>) | ||
const start = match.index || 0; | ||
const length = match[0].length; | ||
const prefix = input[start - 1] || " "; | ||
const postfix = urlFePrefixToPostfix.get(prefix); | ||
// @ts-ignore | ||
let endPostfix = input.indexOf(postfix, start + length); | ||
if (endPostfix === -1) { | ||
endPostfix = input.length; | ||
} | ||
// Look for characters that terminate a URL | ||
const terminalsRe = | ||
(prefix === "<") ? urlFeAutolinkTerminalsRe : urlFeBareTerminalsRe; | ||
const endTerminal = start + input.slice(start).search(terminalsRe); | ||
// Determine tentative end of URL | ||
let end = Math.min(endPostfix, endTerminal); | ||
if (prefix === " ") { | ||
// If the URL used " " as pre/postfix characters, trim the end | ||
if (input[end - 1] === ")") { | ||
// Trim any ")" beyond the last "(...)" pair | ||
const lastOpenParen = input.lastIndexOf("(", end - 2); | ||
if (lastOpenParen <= start) { | ||
end--; | ||
} else { | ||
const nextCloseParen = input.indexOf(")", lastOpenParen + 1); | ||
end = nextCloseParen + 1; | ||
} | ||
} else { | ||
// Trim unwanted punctuation | ||
while ( | ||
!urlFeNonTerminalsRe.includes(input[end - 1]) && | ||
urlFePunctuationRe.test(input[end - 1]) | ||
) { | ||
end--; | ||
} | ||
} | ||
} | ||
return [ start, end - start ]; | ||
} | ||
// No match | ||
return null; | ||
} | ||
module.exports.urlFe = urlFe; |
{ | ||
"name": "markdownlint-rule-helpers", | ||
"version": "0.17.2", | ||
"version": "0.18.0", | ||
"description": "A collection of markdownlint helper functions for custom rules", | ||
@@ -16,3 +16,3 @@ "main": "./helpers.js", | ||
"engines": { | ||
"node": ">=12" | ||
"node": ">=14.18.0" | ||
}, | ||
@@ -19,0 +19,0 @@ "keywords": [ |
@@ -7,19 +7,20 @@ # markdownlint-rule-helpers | ||
The [Markdown](https://en.wikipedia.org/wiki/Markdown) linter | ||
[`markdownlint`](https://github.com/DavidAnson/markdownlint) offers a variety of built-in validation | ||
[rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) and supports the | ||
creation of [custom rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/CustomRules.md). | ||
The internal rules share various helper functions; this package exposes those for reuse by custom rules. | ||
The [Markdown][markdown] linter [`markdownlint`][markdownlint] offers a variety | ||
of built-in validation [rules][rules] and supports the creation of [custom | ||
rules][custom-rules]. The internal rules share various helper functions; this | ||
package exposes those for reuse by custom rules. | ||
## API | ||
_Undocumented_ - This package exports the internal functions as-is. The APIs were not originally meant | ||
to be public, are not officially supported, and may change from release to release. There are brief | ||
descriptive comments above each function, but no [JSDoc](https://en.m.wikipedia.org/wiki/JSDoc) | ||
annotations. That said, some of what's here will be useful to custom rule authors and may avoid | ||
duplicating code. | ||
*Undocumented* - This package exports the internal functions as-is. The APIs | ||
were not originally meant to be public, are not officially supported, and may | ||
change from release to release. There are brief descriptive comments above each | ||
function, but no [JSDoc][jsdoc] annotations. That said, some of what's here will | ||
be useful to custom rule authors and may avoid duplicating code. | ||
## Example | ||
## Examples | ||
```js | ||
### Using Helpers from a Custom Rule | ||
```javascript | ||
const { forEachLine, getLineMetadata } = require("markdownlint-rule-helpers"); | ||
@@ -46,7 +47,26 @@ | ||
See also: [`markdownlint` built-in rule implementations](https://github.com/DavidAnson/markdownlint/tree/main/lib). | ||
### Applying Recommended Fixes | ||
```javascript | ||
const { "sync": markdownlintSync } = require("markdownlint"); | ||
const markdownlintRuleHelpers = require("markdownlint-rule-helpers"); | ||
function fixMarkdownlintViolations(content) { | ||
const fixResults = markdownlintSync({ strings: { content } }); | ||
return markdownlintRuleHelpers.applyFixes(content, fixResults.content); | ||
} | ||
``` | ||
See also: [`markdownlint` built-in rule implementations][lib]. | ||
## Tests | ||
_None_ - The entire body of code is tested to 100% coverage by the core `markdownlint` project, | ||
so there are no additional tests here. | ||
*None* - The entire body of code is tested to 100% coverage by the core | ||
`markdownlint` project, so there are no additional tests here. | ||
[custom-rules]: https://github.com/DavidAnson/markdownlint/blob/main/doc/CustomRules.md | ||
[jsdoc]: https://en.m.wikipedia.org/wiki/JSDoc | ||
[lib]: https://github.com/DavidAnson/markdownlint/tree/main/lib | ||
[markdown]: https://en.wikipedia.org/wiki/Markdown | ||
[markdownlint]: https://github.com/DavidAnson/markdownlint | ||
[rules]: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md |
@@ -6,3 +6,10 @@ // @ts-check | ||
module.exports.deprecatedRuleNames = [ "MD002", "MD006" ]; | ||
module.exports.fixableRuleNames = [ | ||
"MD004", "MD005", "MD006", "MD007", "MD009", "MD010", | ||
"MD011", "MD012", "MD014", "MD018", "MD019", "MD020", | ||
"MD021", "MD022", "MD023", "MD026", "MD027", "MD030", | ||
"MD031", "MD032", "MD034", "MD037", "MD038", "MD039", | ||
"MD044", "MD047", "MD049", "MD050", "MD051", "MD053" | ||
]; | ||
module.exports.homepage = "https://github.com/DavidAnson/markdownlint"; | ||
module.exports.version = "0.26.2"; | ||
module.exports.version = "0.27.0"; |
@@ -5,4 +5,4 @@ // @ts-check | ||
const path = require("path"); | ||
const { promisify } = require("util"); | ||
const path = require("node:path"); | ||
const { promisify } = require("node:util"); | ||
const markdownIt = require("markdown-it"); | ||
@@ -878,3 +878,3 @@ const { deprecatedRuleNames } = require("./constants"); | ||
} | ||
const fs = options.fs || require("fs"); | ||
const fs = options.fs || require("node:fs"); | ||
const results = newResults(ruleList); | ||
@@ -1085,6 +1085,6 @@ let done = false; | ||
if (!fs) { | ||
fs = require("fs"); | ||
fs = require("node:fs"); | ||
} | ||
// Read file | ||
const os = require("os"); | ||
const os = require("node:os"); | ||
file = helpers.expandTildePath(file, os); | ||
@@ -1161,6 +1161,6 @@ fs.readFile(file, "utf8", (err, content) => { | ||
if (!fs) { | ||
fs = require("fs"); | ||
fs = require("node:fs"); | ||
} | ||
// Read file | ||
const os = require("os"); | ||
const os = require("node:os"); | ||
file = helpers.expandTildePath(file, os); | ||
@@ -1167,0 +1167,0 @@ const content = fs.readFileSync(file, "utf8"); |
@@ -9,3 +9,3 @@ // @ts-check | ||
const reversedLinkRe = | ||
/(^|[^\\])\(([^)]+)\)\[([^\]^][^\]]*)](?!\()/g; | ||
/(^|[^\\])\(([^()]+)\)\[([^\]^][^\]]*)\](?!\()/g; | ||
@@ -34,3 +34,3 @@ module.exports = { | ||
reversedLink.slice(preChar.length), | ||
null, | ||
undefined, | ||
[ index + 1, length ], | ||
@@ -37,0 +37,0 @@ { |
@@ -6,4 +6,4 @@ // @ts-check | ||
const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, | ||
includesSorted, linkReferenceDefinitionRe } = require("../helpers"); | ||
const { lineMetadata } = require("./cache"); | ||
includesSorted } = require("../helpers"); | ||
const { lineMetadata, referenceLinkImageData } = require("./cache"); | ||
@@ -13,4 +13,4 @@ const longLineRePrefix = "^.{"; | ||
const longLineRePostfixStrict = "}.+$"; | ||
const linkOrImageOnlyLineRe = /^[es]*(lT?L|I)[ES]*$/; | ||
const sternModeRe = /^([#>\s]*\s)?\S*$/; | ||
const linkOrImageOnlyLineRe = /^[es]*(?:lT?L|I)[ES]*$/; | ||
const sternModeRe = /^(?:[#>\s]*\s)?\S*$/; | ||
const tokenTypeMap = { | ||
@@ -72,2 +72,3 @@ "em_open": "e", | ||
}); | ||
const { definitionLineIndices } = referenceLinkImageData(); | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence, inTable) => { | ||
@@ -85,6 +86,6 @@ const lineNumber = lineIndex + 1; | ||
(includeHeadings || !isHeading) && | ||
!includesSorted(definitionLineIndices, lineIndex) && | ||
(strict || | ||
(!(stern && sternModeRe.test(line)) && | ||
!includesSorted(linkOnlyLineNumbers, lineNumber) && | ||
!linkReferenceDefinitionRe.test(line))) && | ||
!includesSorted(linkOnlyLineNumbers, lineNumber))) && | ||
lengthRe.test(line)) { | ||
@@ -91,0 +92,0 @@ addErrorDetailIf( |
@@ -16,3 +16,3 @@ // @ts-check | ||
const { line, lineNumber } = token; | ||
const match = /^(#+)([ \t]{2,})(?:\S)/.exec(line); | ||
const match = /^(#+)([ \t]{2,})\S/.exec(line); | ||
if (match) { | ||
@@ -19,0 +19,0 @@ const [ |
@@ -5,4 +5,14 @@ // @ts-check | ||
const { addErrorDetailIf, filterTokens, isBlankLine } = require("../helpers"); | ||
const { addErrorDetailIf, blockquotePrefixRe, filterTokens, isBlankLine } = | ||
require("../helpers"); | ||
const getBlockQuote = (str, count) => ( | ||
(str || "") | ||
.match(blockquotePrefixRe)[0] | ||
.trimEnd() | ||
// eslint-disable-next-line unicorn/prefer-spread | ||
.concat("\n") | ||
.repeat(count) | ||
); | ||
module.exports = { | ||
@@ -35,3 +45,4 @@ "names": [ "MD022", "blanks-around-headings", "blanks-around-headers" ], | ||
{ | ||
"insertText": "".padEnd(linesAbove - actualAbove, "\n") | ||
"insertText": | ||
getBlockQuote(lines[topIndex - 1], linesAbove - actualAbove) | ||
}); | ||
@@ -54,3 +65,4 @@ let actualBelow = 0; | ||
"lineNumber": nextIndex + 1, | ||
"insertText": "".padEnd(linesBelow - actualBelow, "\n") | ||
"insertText": | ||
getBlockQuote(lines[nextIndex], linesBelow - actualBelow) | ||
}); | ||
@@ -57,0 +69,0 @@ }); |
@@ -7,3 +7,3 @@ // @ts-check | ||
const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/; | ||
const spaceBeforeHeadingRe = /^(\s+|[>\s]+\s\s)[^>\s]/; | ||
@@ -10,0 +10,0 @@ module.exports = { |
@@ -8,3 +8,3 @@ // @ts-check | ||
const endOfLineHtmlEntityRe = /&#?[0-9a-zA-Z]+;$/; | ||
const endOfLineHtmlEntityRe = /&#?[\da-zA-Z]+;$/; | ||
@@ -11,0 +11,0 @@ module.exports = { |
@@ -8,9 +8,10 @@ // @ts-check | ||
} = require("../helpers"); | ||
const { codeBlockAndSpanRanges, lineMetadata } = require("./cache"); | ||
const { codeBlockAndSpanRanges, lineMetadata, referenceLinkImageData } = | ||
require("./cache"); | ||
const linkDestinationRe = /]\(\s*$/; | ||
const linkDestinationRe = /\]\(\s*$/; | ||
// See https://spec.commonmark.org/0.29/#autolinks | ||
const emailAddressRe = | ||
// eslint-disable-next-line max-len | ||
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; | ||
/^[\w.!#$%&'*+/=?^`{|}~-]+@[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?(?:\.[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?)*$/; | ||
@@ -26,2 +27,11 @@ module.exports = { | ||
const exclusions = codeBlockAndSpanRanges(); | ||
const { references, definitionLineIndices } = referenceLinkImageData(); | ||
for (const datas of references.values()) { | ||
for (const data of datas) { | ||
const [ lineIndex, index, , textLength, labelLength ] = data; | ||
if (labelLength > 0) { | ||
exclusions.push([ lineIndex, index + 3 + textLength, labelLength ]); | ||
} | ||
} | ||
} | ||
forEachLine(lineMetadata(), (line, lineIndex, inCode) => { | ||
@@ -36,3 +46,4 @@ let match = null; | ||
!emailAddressRe.test(content) && | ||
!withinAnyRange(exclusions, lineIndex, match.index, match[0].length) | ||
!withinAnyRange(exclusions, lineIndex, match.index, tag.length) && | ||
!definitionLineIndices.includes(lineIndex) | ||
) { | ||
@@ -39,0 +50,0 @@ const prefix = line.substring(0, match.index); |
115
lib/md034.js
@@ -5,4 +5,9 @@ // @ts-check | ||
const { addErrorContext, bareUrlRe, filterTokens } = require("../helpers"); | ||
const { addErrorContext, filterTokens, funcExpExec, urlFe, withinAnyRange } = | ||
require("../helpers"); | ||
const { codeBlockAndSpanRanges, htmlElementRanges, referenceLinkImageData } = | ||
require("./cache"); | ||
const htmlLinkRe = /<a(?:\s[^>]*)?>[^<>]*<\/a\s*>/gi; | ||
module.exports = { | ||
@@ -13,51 +18,71 @@ "names": [ "MD034", "no-bare-urls" ], | ||
"function": function MD034(params, onError) { | ||
filterTokens(params, "inline", (token) => { | ||
let inLink = false; | ||
for (const child of token.children) { | ||
const { content, line, lineNumber, type } = child; | ||
const { lines } = params; | ||
const codeExclusions = [ | ||
...codeBlockAndSpanRanges(), | ||
...htmlElementRanges() | ||
]; | ||
filterTokens(params, "html_block", (token) => { | ||
for (let i = token.map[0]; i < token.map[1]; i++) { | ||
codeExclusions.push([ i, 0, lines[i].length ]); | ||
} | ||
}); | ||
const { definitionLineIndices } = referenceLinkImageData(); | ||
for (const [ lineIndex, line ] of lines.entries()) { | ||
if (definitionLineIndices[0] === lineIndex) { | ||
definitionLineIndices.shift(); | ||
} else { | ||
let match = null; | ||
if (type === "link_open") { | ||
inLink = true; | ||
} else if (type === "link_close") { | ||
inLink = false; | ||
} else if ((type === "text") && !inLink) { | ||
while ((match = bareUrlRe.exec(content)) !== null) { | ||
const [ bareUrl ] = match; | ||
const matchIndex = match.index; | ||
const bareUrlLength = bareUrl.length; | ||
// Allow "[https://example.com]" to avoid conflicts with | ||
// MD011/no-reversed-links; allow quoting as another way | ||
// of deliberately including a bare URL | ||
const leftChar = content[matchIndex - 1]; | ||
const rightChar = content[matchIndex + bareUrlLength]; | ||
if ( | ||
!((leftChar === "[") && (rightChar === "]")) && | ||
!((leftChar === "\"") && (rightChar === "\"")) && | ||
!((leftChar === "'") && (rightChar === "'")) | ||
) { | ||
const index = line.indexOf(content); | ||
const range = (index === -1) ? null : [ | ||
index + matchIndex + 1, | ||
bareUrlLength | ||
]; | ||
const fixInfo = range ? { | ||
"editColumn": range[0], | ||
"deleteCount": range[1], | ||
"insertText": `<${bareUrl}>` | ||
} : null; | ||
addErrorContext( | ||
onError, | ||
lineNumber, | ||
bareUrl, | ||
null, | ||
null, | ||
range, | ||
fixInfo | ||
); | ||
} | ||
const lineExclusions = []; | ||
while ((match = htmlLinkRe.exec(line)) !== null) { | ||
lineExclusions.push([ lineIndex, match.index, match[0].length ]); | ||
} | ||
while ((match = funcExpExec(urlFe, line)) !== null) { | ||
const [ bareUrl ] = match; | ||
// @ts-ignore | ||
const matchIndex = match.index; | ||
const bareUrlLength = bareUrl.length; | ||
const prefix = line.slice(0, matchIndex); | ||
const postfix = line.slice(matchIndex + bareUrlLength); | ||
if ( | ||
// Allow <...> to avoid reporting non-bare links | ||
!(prefix.endsWith("<") && postfix.startsWith(">")) && | ||
// Allow >...</ to avoid reporting <code>...</code> | ||
!(prefix.endsWith(">") && postfix.startsWith("</")) && | ||
// Allow "..." and '...' to allow quoting a bare link | ||
!(prefix.endsWith("\"") && postfix.startsWith("\"")) && | ||
!(prefix.endsWith("'") && postfix.startsWith("'")) && | ||
// Allow ](... to avoid reporting Markdown-style links | ||
!(/\]\(\s*$/.test(prefix)) && | ||
// Allow [...] to avoid MD011/no-reversed-links and nested links | ||
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) && | ||
!withinAnyRange( | ||
lineExclusions, lineIndex, matchIndex, bareUrlLength | ||
) && | ||
!withinAnyRange( | ||
codeExclusions, lineIndex, matchIndex, bareUrlLength | ||
) | ||
) { | ||
const range = [ | ||
matchIndex + 1, | ||
bareUrlLength | ||
]; | ||
const fixInfo = { | ||
"editColumn": range[0], | ||
"deleteCount": range[1], | ||
"insertText": `<${bareUrl}>` | ||
}; | ||
addErrorContext( | ||
onError, | ||
lineIndex + 1, | ||
bareUrl, | ||
null, | ||
null, | ||
range, | ||
fixInfo | ||
); | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
}; |
@@ -16,3 +16,3 @@ // @ts-check | ||
let { markup } = token; | ||
const match = line.match(/[_*\-\s\t]+$/); | ||
const match = line.match(/[_*\-\s]+$/); | ||
if (match) { | ||
@@ -19,0 +19,0 @@ markup = match[0].trim(); |
@@ -9,4 +9,4 @@ // @ts-check | ||
const emphasisRe = /(^|[^\\]|\\\\)(?:(\*\*?\*?)|(__?_?))/g; | ||
const embeddedUnderscoreRe = /([A-Za-z0-9])_([A-Za-z0-9])/g; | ||
const emphasisRe = /(^|[^\\]|\\\\)(?:(\*{1,3})|(_{1,3}))/g; | ||
const embeddedUnderscoreRe = /([A-Za-z\d])_([A-Za-z\d])/g; | ||
const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/; | ||
@@ -13,0 +13,0 @@ const leftSpaceRe = /^\s+/; |
@@ -8,3 +8,3 @@ // @ts-check | ||
const leftSpaceRe = /^\s([^`]|$)/; | ||
const leftSpaceRe = /^\s(?:[^`]|$)/; | ||
const rightSpaceRe = /[^`]\s$/; | ||
@@ -11,0 +11,0 @@ |
@@ -8,3 +8,3 @@ // @ts-check | ||
const spaceInLinkRe = | ||
/\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=((?:\([^)]*\))|(?:\[[^\]]*\])))/; | ||
/\[(?:\s[^\]]*|[^\]]*?\s)\](?=(\([^)]*\)|\[[^\]]*\]))/; | ||
@@ -11,0 +11,0 @@ module.exports = { |
@@ -5,3 +5,3 @@ // @ts-check | ||
const { addErrorContext, filterTokens } = require("../helpers"); | ||
const { addError, addErrorContext, filterTokens } = require("../helpers"); | ||
@@ -13,8 +13,27 @@ module.exports = { | ||
"function": function MD040(params, onError) { | ||
let allowed = params.config.allowed_languages; | ||
allowed = Array.isArray(allowed) ? allowed : []; | ||
const languageOnly = !!params.config.language_only; | ||
filterTokens(params, "fence", function forToken(token) { | ||
if (!token.info.trim()) { | ||
const lang = token.info.trim().split(/\s+/u).shift(); | ||
if (lang === "") { | ||
addErrorContext(onError, token.lineNumber, token.line); | ||
} else if ((allowed.length > 0) && !allowed.includes(lang)) { | ||
addError( | ||
onError, | ||
token.lineNumber, | ||
`"${lang}" is not allowed` | ||
); | ||
} | ||
if (languageOnly && (token.info !== lang)) { | ||
addError( | ||
onError, | ||
token.lineNumber, | ||
`Info string contains more than language: "${token.info}"` | ||
); | ||
} | ||
}); | ||
} | ||
}; |
@@ -14,2 +14,3 @@ // @ts-check | ||
const requiredHeadings = params.config.headings || params.config.headers; | ||
const matchCase = params.config.match_case || false; | ||
if (Array.isArray(requiredHeadings)) { | ||
@@ -25,2 +26,3 @@ const levels = {}; | ||
const getExpected = () => requiredHeadings[i++] || "[None]"; | ||
const handleCase = (str) => (matchCase ? str : str.toLowerCase()); | ||
forEachHeading(params, (heading, content) => { | ||
@@ -33,3 +35,3 @@ if (!hasError) { | ||
const nextExpected = getExpected(); | ||
if (nextExpected.toLowerCase() !== actual.toLowerCase()) { | ||
if (handleCase(nextExpected) !== handleCase(actual)) { | ||
matchAny = true; | ||
@@ -40,3 +42,3 @@ i--; | ||
matchAny = true; | ||
} else if (expected.toLowerCase() === actual.toLowerCase()) { | ||
} else if (handleCase(expected) === handleCase(actual)) { | ||
matchAny = false; | ||
@@ -43,0 +45,0 @@ } else if (matchAny) { |
@@ -5,4 +5,4 @@ // @ts-check | ||
const { addErrorDetailIf, bareUrlRe, escapeForRegExp, forEachLine, | ||
forEachLink, withinAnyRange, linkReferenceDefinitionRe } = | ||
const { addErrorDetailIf, escapeForRegExp, forEachLine, forEachLink, | ||
funcExpExec, linkReferenceDefinitionRe, urlFe, withinAnyRange } = | ||
require("../helpers"); | ||
@@ -32,3 +32,4 @@ const { codeBlockAndSpanRanges, htmlElementRanges, lineMetadata } = | ||
let match = null; | ||
while ((match = bareUrlRe.exec(line)) !== null) { | ||
while ((match = funcExpExec(urlFe, line)) !== null) { | ||
// @ts-ignore | ||
exclusions.push([ lineIndex, match.index, match[0].length ]); | ||
@@ -35,0 +36,0 @@ } |
@@ -5,4 +5,4 @@ // @ts-check | ||
const { addError, escapeForRegExp, filterTokens, forEachInlineChild, | ||
forEachHeading, htmlElementRe } = require("../helpers"); | ||
const { addError, addErrorDetailIf, escapeForRegExp, filterTokens, | ||
forEachInlineChild, forEachHeading, htmlElementRe } = require("../helpers"); | ||
@@ -77,2 +77,3 @@ // Regular expression for identifying HTML anchor names | ||
let range = null; | ||
let fixInfo = null; | ||
const match = line.match( | ||
@@ -82,6 +83,37 @@ new RegExp(`\\[.*?\\]\\(${escapeForRegExp(context)}\\)`) | ||
if (match) { | ||
context = match[0]; | ||
range = [ match.index + 1, match[0].length ]; | ||
[ context ] = match; | ||
const index = match.index; | ||
const length = context.length; | ||
range = [ index + 1, length ]; | ||
fixInfo = { | ||
"editColumn": index + (length - id.length), | ||
"deleteCount": id.length, | ||
"insertText": null | ||
}; | ||
} | ||
addError(onError, lineNumber, undefined, context, range); | ||
const idLower = id.toLowerCase(); | ||
const mixedCaseKey = [ ...fragments.keys() ] | ||
.find((key) => idLower === key.toLowerCase()); | ||
if (mixedCaseKey) { | ||
(fixInfo || {}).insertText = mixedCaseKey; | ||
addErrorDetailIf( | ||
onError, | ||
lineNumber, | ||
mixedCaseKey, | ||
id, | ||
undefined, | ||
context, | ||
range, | ||
fixInfo | ||
); | ||
} else { | ||
addError( | ||
onError, | ||
lineNumber, | ||
undefined, | ||
context, | ||
// @ts-ignore | ||
range | ||
); | ||
} | ||
} | ||
@@ -88,0 +120,0 @@ }); |
@@ -61,4 +61,4 @@ // @ts-check | ||
rule["information"] = | ||
new URL(`${homepage}/blob/v${version}/doc/Rules.md#${name}`); | ||
new URL(`${homepage}/blob/v${version}/doc/${name}.md`); | ||
} | ||
module.exports = rules; |
{ | ||
"name": "markdownlint", | ||
"version": "0.26.2", | ||
"version": "0.27.0", | ||
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.", | ||
@@ -9,3 +9,7 @@ "type": "commonjs", | ||
".": "./lib/markdownlint.js", | ||
"./helpers": "./helpers/helpers.js" | ||
"./helpers": "./helpers/helpers.js", | ||
"./style/all": "./style/all.json", | ||
"./style/cirosantilli": "./style/cirosantilli.json", | ||
"./style/prettier": "./style/prettier.json", | ||
"./style/relaxed": "./style/relaxed.json" | ||
}, | ||
@@ -27,6 +31,10 @@ "types": "./lib/markdownlint.d.ts", | ||
"build-demo": "node scripts copy node_modules/markdown-it/dist/markdown-it.min.js demo/markdown-it.min.js && cd demo && webpack --no-stats", | ||
"build-docs": "node doc-build/build-rules.mjs", | ||
"build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", | ||
"ci": "npm-run-all --continue-on-error --parallel build-config lint serial-declaration-demo test-cover && git diff --exit-code", | ||
"ci": "npm-run-all --continue-on-error --parallel lint serial-config-docs serial-declaration-demo test-cover && git diff --exit-code", | ||
"clone-test-repos-apache-airflow": "cd test-repos && git clone https://github.com/apache/airflow apache-airflow --depth 1 --no-tags --quiet", | ||
"clone-test-repos-dotnet-docs": "cd test-repos && git clone https://github.com/dotnet/docs dotnet-docs --depth 1 --no-tags --quiet", | ||
"clone-test-repos-electron-electron": "cd test-repos && git clone https://github.com/electron/electron electron-electron --depth 1 --no-tags --quiet", | ||
"clone-test-repos-eslint-eslint": "cd test-repos && git clone https://github.com/eslint/eslint eslint-eslint --depth 1 --no-tags --quiet", | ||
"clone-test-repos-mdn-content": "cd test-repos && git clone https://github.com/mdn/content mdn-content --depth 1 --no-tags --quiet", | ||
"clone-test-repos-mkdocs-mkdocs": "cd test-repos && git clone https://github.com/mkdocs/mkdocs mkdocs-mkdocs --depth 1 --no-tags --quiet", | ||
@@ -38,4 +46,3 @@ "clone-test-repos-mochajs-mocha": "cd test-repos && git clone https://github.com/mochajs/mocha mochajs-mocha --depth 1 --no-tags --quiet", | ||
"clone-test-repos-webpack-webpack-js-org": "cd test-repos && git clone https://github.com/webpack/webpack.js.org webpack-webpack-js-org --depth 1 --no-tags --quiet", | ||
"clone-test-repos": "mkdir test-repos && cd test-repos && npm run clone-test-repos-eslint-eslint && npm run clone-test-repos-mkdocs-mkdocs && npm run clone-test-repos-mochajs-mocha && npm run clone-test-repos-pi-hole-docs && npm run clone-test-repos-webhintio-hint && npm run clone-test-repos-webpack-webpack-js-org", | ||
"clone-test-repos-large": "npm run clone-test-repos && cd test-repos && npm run clone-test-repos-dotnet-docs && npm run clone-test-repos-v8-v8-dev", | ||
"clone-test-repos": "mkdir test-repos && cd test-repos && npm run clone-test-repos-apache-airflow && npm run clone-test-repos-dotnet-docs && npm run clone-test-repos-electron-electron && npm run clone-test-repos-eslint-eslint && npm run clone-test-repos-mdn-content && npm run clone-test-repos-mkdocs-mkdocs && npm run clone-test-repos-mochajs-mocha && npm run clone-test-repos-pi-hole-docs && npm run clone-test-repos-v8-v8-dev && npm run clone-test-repos-webhintio-hint && npm run clone-test-repos-webpack-webpack-js-org", | ||
"declaration": "npm run build-declaration && npm run test-declaration", | ||
@@ -45,4 +52,5 @@ "example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint", | ||
"docker-npm-run-upgrade": "docker run --rm --tty --name npm-run-upgrade --volume $PWD:/home/workdir --workdir /home/workdir --user node node:16 npm run upgrade", | ||
"lint": "eslint --max-warnings 0 .", | ||
"lint": "eslint --ext .js,.mjs --max-warnings 0 .", | ||
"lint-test-repos": "ava --timeout=5m test/markdownlint-test-repos.js", | ||
"serial-config-docs": "npm run build-config && npm run build-docs", | ||
"serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration", | ||
@@ -57,3 +65,3 @@ "test": "ava test/markdownlint-test.js test/markdownlint-test-config.js test/markdownlint-test-custom-rules.js test/markdownlint-test-helpers.js test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js", | ||
"engines": { | ||
"node": ">=14" | ||
"node": ">=14.18.0" | ||
}, | ||
@@ -64,11 +72,13 @@ "dependencies": { | ||
"devDependencies": { | ||
"ava": "4.3.0", | ||
"c8": "7.11.3", | ||
"eslint": "8.18.0", | ||
"ava": "5.1.0", | ||
"c8": "7.12.0", | ||
"eslint": "8.30.0", | ||
"eslint-plugin-es": "4.1.0", | ||
"eslint-plugin-jsdoc": "39.3.3", | ||
"eslint-plugin-node": "11.1.0", | ||
"eslint-plugin-unicorn": "42.0.0", | ||
"globby": "13.1.2", | ||
"eslint-plugin-jsdoc": "39.6.4", | ||
"eslint-plugin-n": "15.6.0", | ||
"eslint-plugin-regexp": "1.11.0", | ||
"eslint-plugin-unicorn": "45.0.2", | ||
"globby": "13.1.3", | ||
"js-yaml": "4.1.0", | ||
"markdown-it-footnote": "3.0.3", | ||
"markdown-it-for-inline": "0.1.1", | ||
@@ -78,12 +88,12 @@ "markdown-it-sub": "1.0.0", | ||
"markdown-it-texmath": "1.0.0", | ||
"markdownlint-rule-github-internal-links": "0.1.0", | ||
"markdownlint-rule-helpers": "0.16.0", | ||
"markdownlint-rule-helpers": "0.17.2", | ||
"npm-run-all": "4.1.5", | ||
"strip-json-comments": "4.0.0", | ||
"strip-json-comments": "5.0.0", | ||
"terser-webpack-plugin": "5.3.6", | ||
"toml": "3.0.0", | ||
"ts-loader": "9.3.0", | ||
"ts-loader": "9.4.2", | ||
"tv4": "1.3.0", | ||
"typescript": "4.7.4", | ||
"webpack": "5.73.0", | ||
"webpack-cli": "4.10.0" | ||
"typescript": "4.9.4", | ||
"webpack": "5.75.0", | ||
"webpack-cli": "5.0.1" | ||
}, | ||
@@ -90,0 +100,0 @@ "keywords": [ |
727
README.md
@@ -10,3 +10,3 @@ # markdownlint | ||
```shell | ||
```bash | ||
npm install markdownlint --save-dev | ||
@@ -36,22 +36,40 @@ ``` | ||
* CLI | ||
* [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli) | ||
command-line interface for Node.js ([works with pre-commit](https://github.com/igorshubovych/markdownlint-cli#use-with-pre-commit)) | ||
* [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) | ||
command-line interface for Node.js ([works with pre-commit](https://github.com/DavidAnson/markdownlint-cli2#pre-commit)) | ||
* GitHub | ||
* [GitHub Super-Linter Action](https://github.com/github/super-linter) | ||
* [GitHub Actions problem matcher for markdownlint-cli](https://github.com/xt0rted/markdownlint-problem-matcher) | ||
* Editor | ||
* [vscode-markdownlint extension for VS Code](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) | ||
* [Sublime Text markdownlint for Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint) | ||
* [coc-markdownlint extension for Vim/Neovim](https://github.com/fannheyward/coc-markdownlint) | ||
* Tooling | ||
* [eslint-plugin-markdownlint for the ESLint analyzer](https://github.com/paweldrozd/eslint-plugin-markdownlint) | ||
* [grunt-markdownlint for the Grunt task runner](https://github.com/sagiegurari/grunt-markdownlint) | ||
* [Cake.Markdownlint addin for Cake build automation system](https://github.com/cake-contrib/Cake.Markdownlint) | ||
* [Lombiq Node.js Extensions for MSBuild (.NET builds)](https://github.com/Lombiq/NodeJs-Extensions) | ||
* Ruby | ||
* [markdownlint/mdl gem for Ruby](https://rubygems.org/gems/mdl) | ||
- CLI | ||
- [markdownlint-cli][markdownlint-cli] command-line interface for Node.js | ||
([works with pre-commit][markdownlint-cli-precommit]) | ||
- [markdownlint-cli2][markdownlint-cli2] command-line interface for Node.js | ||
([works with pre-commit][markdownlint-cli2-precommit]) | ||
- GitHub | ||
- [GitHub Action for markdownlint-cli2][markdownlint-cli2-action] | ||
- [GitHub Super-Linter Action][super-linter] | ||
- [GitHub Actions problem matcher for | ||
markdownlint-cli][markdownlint-problem-matcher] | ||
- Editor | ||
- [vscode-markdownlint extension for VS Code][vscode-markdownlint] | ||
- [Sublime Text markdownlint for Sublime Text][sublimelinter] | ||
- [coc-markdownlint extension for Vim/Neovim][coc] | ||
- Tooling | ||
- [eslint-plugin-markdownlint for the ESLint analyzer][eslint-plugin] | ||
- [grunt-markdownlint for the Grunt task runner][grunt-markdownlint] | ||
- [Cake.Markdownlint addin for Cake build automation system][cake] | ||
- [Lombiq Node.js Extensions for MSBuild (.NET builds)][nodejs-extensions] | ||
- Ruby | ||
- [markdownlint/mdl gem for Ruby][rubygems-mdl] | ||
[cake]: https://github.com/cake-contrib/Cake.Markdownlint | ||
[coc]: https://github.com/fannheyward/coc-markdownlint | ||
[eslint-plugin]: https://github.com/paweldrozd/eslint-plugin-markdownlint | ||
[grunt-markdownlint]: https://github.com/sagiegurari/grunt-markdownlint | ||
[markdownlint-cli]: https://github.com/igorshubovych/markdownlint-cli | ||
[markdownlint-cli-precommit]: https://github.com/igorshubovych/markdownlint-cli#use-with-pre-commit | ||
[markdownlint-cli2]: https://github.com/DavidAnson/markdownlint-cli2 | ||
[markdownlint-cli2-action]: https://github.com/marketplace/actions/markdownlint-cli2-action | ||
[markdownlint-cli2-precommit]: https://github.com/DavidAnson/markdownlint-cli2#pre-commit | ||
[markdownlint-problem-matcher]: https://github.com/xt0rted/markdownlint-problem-matcher | ||
[nodejs-extensions]: https://github.com/Lombiq/NodeJs-Extensions | ||
[rubygems-mdl]: https://rubygems.org/gems/mdl | ||
[sublimelinter]: https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint | ||
[super-linter]: https://github.com/github/super-linter | ||
[vscode-markdownlint]: https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint | ||
## Demonstration | ||
@@ -66,51 +84,51 @@ | ||
* **[MD001](doc/Rules.md#md001)** *heading-increment/header-increment* - Heading levels should only increment by one level at a time | ||
* ~~**[MD002](doc/Rules.md#md002)** *first-heading-h1/first-header-h1* - First heading should be a top-level heading~~ | ||
* **[MD003](doc/Rules.md#md003)** *heading-style/header-style* - Heading 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 heading | ||
* **[MD019](doc/Rules.md#md019)** *no-multiple-space-atx* - Multiple spaces after hash on atx style heading | ||
* **[MD020](doc/Rules.md#md020)** *no-missing-space-closed-atx* - No space inside hashes on closed atx style heading | ||
* **[MD021](doc/Rules.md#md021)** *no-multiple-space-closed-atx* - Multiple spaces inside hashes on closed atx style heading | ||
* **[MD022](doc/Rules.md#md022)** *blanks-around-headings/blanks-around-headers* - Headings should be surrounded by blank lines | ||
* **[MD023](doc/Rules.md#md023)** *heading-start-left/header-start-left* - Headings must start at the beginning of the line | ||
* **[MD024](doc/Rules.md#md024)** *no-duplicate-heading/no-duplicate-header* - Multiple headings with the same content | ||
* **[MD025](doc/Rules.md#md025)** *single-title/single-h1* - Multiple top-level headings in the same document | ||
* **[MD026](doc/Rules.md#md026)** *no-trailing-punctuation* - Trailing punctuation in heading | ||
* **[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-heading/no-emphasis-as-header* - Emphasis used instead of a heading | ||
* **[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-heading/first-line-h1* - First line in a file should be a top-level heading | ||
* **[MD042](doc/Rules.md#md042)** *no-empty-links* - No empty links | ||
* **[MD043](doc/Rules.md#md043)** *required-headings/required-headers* - Required heading structure | ||
* **[MD044](doc/Rules.md#md044)** *proper-names* - Proper names should have the correct capitalization | ||
* **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have alternate text (alt text) | ||
* **[MD046](doc/Rules.md#md046)** *code-block-style* - Code block style | ||
* **[MD047](doc/Rules.md#md047)** *single-trailing-newline* - Files should end with a single newline character | ||
* **[MD048](doc/Rules.md#md048)** *code-fence-style* - Code fence style | ||
* **[MD049](doc/Rules.md#md049)** *emphasis-style* - Emphasis style should be consistent | ||
* **[MD050](doc/Rules.md#md050)** *strong-style* - Strong style should be consistent | ||
* **[MD051](doc/Rules.md#md051)** *link-fragments* - Link fragments should be valid | ||
* **[MD052](doc/Rules.md#md052)** *reference-links-images* - Reference links and images should use a label that is defined | ||
* **[MD053](doc/Rules.md#md053)** *link-image-reference-definitions* - Link and image reference definitions should be needed | ||
- **[MD001](doc/md001.md)** *heading-increment/header-increment* - Heading levels should only increment by one level at a time | ||
- ~~**[MD002](doc/md002.md)** *first-heading-h1/first-header-h1* - First heading should be a top-level heading~~ | ||
- **[MD003](doc/md003.md)** *heading-style/header-style* - Heading style | ||
- **[MD004](doc/md004.md)** *ul-style* - Unordered list style | ||
- **[MD005](doc/md005.md)** *list-indent* - Inconsistent indentation for list items at the same level | ||
- ~~**[MD006](doc/md006.md)** *ul-start-left* - Consider starting bulleted lists at the beginning of the line~~ | ||
- **[MD007](doc/md007.md)** *ul-indent* - Unordered list indentation | ||
- **[MD009](doc/md009.md)** *no-trailing-spaces* - Trailing spaces | ||
- **[MD010](doc/md010.md)** *no-hard-tabs* - Hard tabs | ||
- **[MD011](doc/md011.md)** *no-reversed-links* - Reversed link syntax | ||
- **[MD012](doc/md012.md)** *no-multiple-blanks* - Multiple consecutive blank lines | ||
- **[MD013](doc/md013.md)** *line-length* - Line length | ||
- **[MD014](doc/md014.md)** *commands-show-output* - Dollar signs used before commands without showing output | ||
- **[MD018](doc/md018.md)** *no-missing-space-atx* - No space after hash on atx style heading | ||
- **[MD019](doc/md019.md)** *no-multiple-space-atx* - Multiple spaces after hash on atx style heading | ||
- **[MD020](doc/md020.md)** *no-missing-space-closed-atx* - No space inside hashes on closed atx style heading | ||
- **[MD021](doc/md021.md)** *no-multiple-space-closed-atx* - Multiple spaces inside hashes on closed atx style heading | ||
- **[MD022](doc/md022.md)** *blanks-around-headings/blanks-around-headers* - Headings should be surrounded by blank lines | ||
- **[MD023](doc/md023.md)** *heading-start-left/header-start-left* - Headings must start at the beginning of the line | ||
- **[MD024](doc/md024.md)** *no-duplicate-heading/no-duplicate-header* - Multiple headings with the same content | ||
- **[MD025](doc/md025.md)** *single-title/single-h1* - Multiple top-level headings in the same document | ||
- **[MD026](doc/md026.md)** *no-trailing-punctuation* - Trailing punctuation in heading | ||
- **[MD027](doc/md027.md)** *no-multiple-space-blockquote* - Multiple spaces after blockquote symbol | ||
- **[MD028](doc/md028.md)** *no-blanks-blockquote* - Blank line inside blockquote | ||
- **[MD029](doc/md029.md)** *ol-prefix* - Ordered list item prefix | ||
- **[MD030](doc/md030.md)** *list-marker-space* - Spaces after list markers | ||
- **[MD031](doc/md031.md)** *blanks-around-fences* - Fenced code blocks should be surrounded by blank lines | ||
- **[MD032](doc/md032.md)** *blanks-around-lists* - Lists should be surrounded by blank lines | ||
- **[MD033](doc/md033.md)** *no-inline-html* - Inline HTML | ||
- **[MD034](doc/md034.md)** *no-bare-urls* - Bare URL used | ||
- **[MD035](doc/md035.md)** *hr-style* - Horizontal rule style | ||
- **[MD036](doc/md036.md)** *no-emphasis-as-heading/no-emphasis-as-header* - Emphasis used instead of a heading | ||
- **[MD037](doc/md037.md)** *no-space-in-emphasis* - Spaces inside emphasis markers | ||
- **[MD038](doc/md038.md)** *no-space-in-code* - Spaces inside code span elements | ||
- **[MD039](doc/md039.md)** *no-space-in-links* - Spaces inside link text | ||
- **[MD040](doc/md040.md)** *fenced-code-language* - Fenced code blocks should have a language specified | ||
- **[MD041](doc/md041.md)** *first-line-heading/first-line-h1* - First line in a file should be a top-level heading | ||
- **[MD042](doc/md042.md)** *no-empty-links* - No empty links | ||
- **[MD043](doc/md043.md)** *required-headings/required-headers* - Required heading structure | ||
- **[MD044](doc/md044.md)** *proper-names* - Proper names should have the correct capitalization | ||
- **[MD045](doc/md045.md)** *no-alt-text* - Images should have alternate text (alt text) | ||
- **[MD046](doc/md046.md)** *code-block-style* - Code block style | ||
- **[MD047](doc/md047.md)** *single-trailing-newline* - Files should end with a single newline character | ||
- **[MD048](doc/md048.md)** *code-fence-style* - Code fence style | ||
- **[MD049](doc/md049.md)** *emphasis-style* - Emphasis style should be consistent | ||
- **[MD050](doc/md050.md)** *strong-style* - Strong style should be consistent | ||
- **[MD051](doc/md051.md)** *link-fragments* - Link fragments should be valid | ||
- **[MD052](doc/md052.md)** *reference-links-images* - Reference links and images should use a label that is defined | ||
- **[MD053](doc/md053.md)** *link-image-reference-definitions* - Link and image reference definitions should be needed | ||
@@ -121,8 +139,17 @@ <!-- markdownlint-restore --> | ||
~~Struck through~~ rules are deprecated, and provided for backward-compatibility. | ||
~~Struck through~~ rules are deprecated and provided for backward-compatibility. | ||
> All rules with `heading` as part of their name are also available as | ||
> `header` aliases (e.g. `heading-increment` is also available as `header-increment`). | ||
> All rules with `heading` as part of their name are also available as `header` | ||
> aliases (e.g. `heading-increment` is also available as `header-increment`). | ||
> The use of `header` is deprecated and provided for backward-compatibility. | ||
### Custom Rules | ||
In addition to built-in rules, custom rules can be used to address | ||
project-specific requirements. To find community-developed rules use | ||
[keyword `markdownlint-rule` on npm][markdownlint-rule]. | ||
To implement your own rules, refer to [CustomRules.md](doc/CustomRules.md). | ||
[markdownlint-rule]: https://www.npmjs.com/search?q=keywords:markdownlint-rule | ||
## Tags | ||
@@ -133,29 +160,30 @@ | ||
* **accessibility** - MD045 | ||
* **atx** - MD018, MD019 | ||
* **atx_closed** - MD020, MD021 | ||
* **blank_lines** - MD012, MD022, MD031, MD032, MD047 | ||
* **blockquote** - MD027, MD028 | ||
* **bullet** - MD004, MD005, MD006, MD007, MD032 | ||
* **code** - MD014, MD031, MD038, MD040, MD046, MD048 | ||
* **emphasis** - MD036, MD037, MD049, MD050 | ||
* **hard_tab** - MD010 | ||
* **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, | ||
MD023, MD024, MD025, MD026, MD036, MD041, MD043 | ||
* **headings** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, | ||
MD023, MD024, MD025, MD026, MD036, MD041, MD043 | ||
* **hr** - MD035 | ||
* **html** - MD033 | ||
* **images** - MD045, MD052, MD053 | ||
* **indentation** - MD005, MD006, MD007, MD027 | ||
* **language** - MD040 | ||
* **line_length** - MD013 | ||
* **links** - MD011, MD034, MD039, MD042, MD051, MD052, MD053 | ||
* **ol** - MD029, MD030, MD032 | ||
* **spaces** - MD018, MD019, MD020, MD021, MD023 | ||
* **spelling** - MD044 | ||
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032 | ||
* **url** - MD034 | ||
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037, | ||
MD038, MD039 | ||
- **`accessibility`** - `MD045` | ||
- **`atx`** - `MD018`, `MD019` | ||
- **`atx_closed`** - `MD020`, `MD021` | ||
- **`blank_lines`** - `MD012`, `MD022`, `MD031`, `MD032`, `MD047` | ||
- **`blockquote`** - `MD027`, `MD028` | ||
- **`bullet`** - `MD004`, `MD005`, `MD006`, `MD007`, `MD032` | ||
- **`code`** - `MD014`, `MD031`, `MD038`, `MD040`, `MD046`, `MD048` | ||
- **`emphasis`** - `MD036`, `MD037`, `MD049`, `MD050` | ||
- **`hard_tab`** - `MD010` | ||
- **`headers`** - `MD001`, `MD002`, `MD003`, `MD018`, `MD019`, `MD020`, `MD021`, | ||
`MD022`, `MD023`, `MD024`, `MD025`, `MD026`, `MD036`, `MD041`, `MD043` | ||
- **`headings`** - `MD001`, `MD002`, `MD003`, `MD018`, `MD019`, `MD020`, | ||
`MD021`, `MD022`, `MD023`, `MD024`, `MD025`, `MD026`, `MD036`, `MD041`, | ||
`MD043` | ||
- **`hr`** - `MD035` | ||
- **`html`** - `MD033` | ||
- **`images`** - `MD045`, `MD052`, `MD053` | ||
- **`indentation`** - `MD005`, `MD006`, `MD007`, `MD027` | ||
- **`language`** - `MD040` | ||
- **`line_length`** - `MD013` | ||
- **`links`** - `MD011`, `MD034`, `MD039`, `MD042`, `MD051`, `MD052`, `MD053` | ||
- **`ol`** - `MD029`, `MD030`, `MD032` | ||
- **`spaces`** - `MD018`, `MD019`, `MD020`, `MD021`, `MD023` | ||
- **`spelling`** - `MD044` | ||
- **`ul`** - `MD004`, `MD005`, `MD006`, `MD007`, `MD030`, `MD032` | ||
- **`url`** - `MD034` | ||
- **`whitespace`** - `MD009`, `MD010`, `MD012`, `MD027`, `MD028`, `MD030`, | ||
`MD037`, `MD038`, `MD039` | ||
@@ -167,4 +195,4 @@ ## Configuration | ||
* [HTML comments](https://www.w3.org/TR/html5/syntax.html#comments) | ||
* [Front matter](https://jekyllrb.com/docs/frontmatter/) (see | ||
- [HTML comments](https://www.w3.org/TR/html5/syntax.html#comments) | ||
- [Front matter](https://jekyllrb.com/docs/frontmatter/) (see | ||
`options.frontMatter` below) | ||
@@ -178,14 +206,14 @@ | ||
* Disable all rules: `<!-- markdownlint-disable -->` | ||
* Enable all rules: `<!-- markdownlint-enable -->` | ||
* Disable all rules for the current line: `<!-- markdownlint-disable-line -->` | ||
* Disable all rules for the next line: `<!-- markdownlint-disable-next-line -->` | ||
* Disable one or more rules by name: `<!-- markdownlint-disable MD001 MD005 -->` | ||
* Enable one or more rules by name: `<!-- markdownlint-enable MD001 MD005 -->` | ||
* Disable one or more rules by name for the current line: | ||
- Disable all rules: `<!-- markdownlint-disable -->` | ||
- Enable all rules: `<!-- markdownlint-enable -->` | ||
- Disable all rules for the current line: `<!-- markdownlint-disable-line -->` | ||
- Disable all rules for the next line: `<!-- markdownlint-disable-next-line -->` | ||
- Disable one or more rules by name: `<!-- markdownlint-disable MD001 MD005 -->` | ||
- Enable one or more rules by name: `<!-- markdownlint-enable MD001 MD005 -->` | ||
- Disable one or more rules by name for the current line: | ||
`<!-- markdownlint-disable-line MD001 MD005 -->` | ||
* Disable one or more rules by name for the next line: | ||
- Disable one or more rules by name for the next line: | ||
`<!-- markdownlint-disable-next-line MD001 MD005 -->` | ||
* Capture the current rule configuration: `<!-- markdownlint-capture -->` | ||
* Restore the captured rule configuration: `<!-- markdownlint-restore -->` | ||
- Capture the current rule configuration: `<!-- markdownlint-capture -->` | ||
- Restore the captured rule configuration: `<!-- markdownlint-restore -->` | ||
@@ -196,3 +224,3 @@ For example: | ||
<!-- markdownlint-disable-next-line no-space-in-emphasis --> | ||
deliberate space * in * emphasis | ||
space * in * emphasis | ||
``` | ||
@@ -203,3 +231,3 @@ | ||
```markdown | ||
deliberate space * in * emphasis <!-- markdownlint-disable-line no-space-in-emphasis --> | ||
space * in * emphasis <!-- markdownlint-disable-line no-space-in-emphasis --> | ||
``` | ||
@@ -211,3 +239,3 @@ | ||
<!-- markdownlint-disable no-space-in-emphasis --> | ||
deliberate space * in * emphasis | ||
space * in * emphasis | ||
<!-- markdownlint-enable no-space-in-emphasis --> | ||
@@ -245,6 +273,6 @@ ``` | ||
* Disable all rules: `<!-- markdownlint-disable-file -->` | ||
* Enable all rules: `<!-- markdownlint-enable-file -->` | ||
* Disable one or more rules by name: `<!-- markdownlint-disable-file MD001 -->` | ||
* Enable one or more rules by name: `<!-- markdownlint-enable-file MD001 -->` | ||
- Disable all rules: `<!-- markdownlint-disable-file -->` | ||
- Enable all rules: `<!-- markdownlint-enable-file -->` | ||
- Disable one or more rules by name: `<!-- markdownlint-disable-file MD001 -->` | ||
- Enable one or more rules by name: `<!-- markdownlint-enable-file MD001 -->` | ||
@@ -256,3 +284,3 @@ This can be used to "hide" `markdownlint` comments at the bottom of a file. | ||
* Configure: `<!-- markdownlint-configure-file { options.config JSON } -->` | ||
- Configure: `<!-- markdownlint-configure-file { options.config JSON } -->` | ||
@@ -262,3 +290,3 @@ For example: | ||
```markdown | ||
<!-- markdownlint-configure-file { "MD013": { "code_blocks": false } } --> | ||
<!-- markdownlint-configure-file { "hr-style": { "style": "---" } } --> | ||
``` | ||
@@ -291,3 +319,3 @@ | ||
```js | ||
```javascript | ||
/** | ||
@@ -305,3 +333,3 @@ * Lint specified Markdown files. | ||
```js | ||
```javascript | ||
/** | ||
@@ -319,3 +347,3 @@ * Lint specified Markdown files synchronously. | ||
```js | ||
```javascript | ||
/** | ||
@@ -373,5 +401,5 @@ * Lint specified Markdown files. | ||
Example: | ||
Example of referencing a built-in style from JavaScript: | ||
```js | ||
```javascript | ||
const options = { | ||
@@ -383,2 +411,10 @@ "files": [ "..." ], | ||
Example doing so from `.markdownlint.json` via `extends` (more on this below): | ||
```json | ||
{ | ||
"extends": "markdownlint/style/relaxed" | ||
} | ||
``` | ||
See the [style](style) directory for more samples. | ||
@@ -413,3 +449,3 @@ | ||
```js | ||
```javascript | ||
const options = { | ||
@@ -422,3 +458,3 @@ "config": markdownlint.readConfigSync("./custom.json") | ||
```js | ||
```javascript | ||
const options = { | ||
@@ -441,8 +477,9 @@ "config": { | ||
default, the `JSON.parse` built-in is used, but custom parsers can be specified. | ||
Content is passed to each parser function until one returns a value (vs. throwing | ||
an exception). As such, strict parsers should come before flexible ones. | ||
Content is passed to each parser function until one returns a value (vs. | ||
throwing an exception). As such, strict parsers should come before flexible | ||
ones. | ||
For example: | ||
```js | ||
```javascript | ||
[ JSON.parse, require("toml").parse, require("js-yaml").load ] | ||
@@ -458,9 +495,7 @@ ``` | ||
Each array element should define a rule. Rules are typically exported | ||
by another package, but can be defined locally. Custom rules are | ||
identified by the | ||
[keyword `markdownlint-rule` on npm](https://www.npmjs.com/search?q=keywords:markdownlint-rule). | ||
by another package, but can be defined locally. | ||
Example: | ||
```js | ||
```javascript | ||
const extraRules = require("extraRules"); | ||
@@ -500,4 +535,4 @@ const options = { | ||
```js | ||
/((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$)|(^\{\s*$[^]*?^\}\s*$))(\r\n|\r|\n|$)/m | ||
```javascript | ||
/((^---\s*$[\s\S]*?^---\s*)|(^\+\+\+\s*$[\s\S]*?^(\+\+\+|\.\.\.)\s*)|(^\{\s*$[\s\S]*?^\}\s*))(\r\n|\r|\n|$)/m | ||
``` | ||
@@ -520,10 +555,12 @@ | ||
Type: `Object` implementing the [file system API](https://nodejs.org/api/fs.html) | ||
Type: `Object` implementing the [file system API][node-fs-api] | ||
In advanced scenarios, it may be desirable to bypass the default file system API. | ||
If a custom file system implementation is provided, `markdownlint` will use that | ||
instead of invoking `require("fs")`. | ||
In advanced scenarios, it may be desirable to bypass the default file system | ||
API. If a custom file system implementation is provided, `markdownlint` will use | ||
that instead of invoking `require("fs")`. | ||
Note: The only methods called are `readFile` and `readFileSync`. | ||
[node-fs-api]: https://nodejs.org/api/fs.html | ||
##### options.handleRuleFailures | ||
@@ -548,9 +585,11 @@ | ||
Specifies additional [markdown-it plugins](https://www.npmjs.com/search?q=keywords:markdown-it-plugin) | ||
to use when parsing input. Plugins can be used to support additional syntax and | ||
features for advanced scenarios. | ||
Specifies additional [markdown-it plugins][markdown-it-plugin] to use when | ||
parsing input. Plugins can be used to support additional syntax and features for | ||
advanced scenarios. | ||
[markdown-it-plugin]: https://www.npmjs.com/search?q=keywords:markdown-it-plugin | ||
Each item in the top-level `Array` should be of the form: | ||
```js | ||
```javascript | ||
[ require("markdown-it-plugin"), plugin_param_0, plugin_param_1, ... ] | ||
@@ -563,3 +602,3 @@ ``` | ||
Disables the use of HTML comments like `<!-- markdownlint-disable -->` to toggle | ||
Disables the use of HTML comments like `<!-- markdownlint-enable -->` to toggle | ||
rules within the body of Markdown content. | ||
@@ -575,20 +614,23 @@ | ||
Specifies which version of the `result` object to return (see the "Usage" section | ||
below for examples). | ||
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 | ||
each error is identified by rule name and line number. *This is deprecated.* | ||
Passing a `resultVersion` of `0` corresponds to the original, simple format | ||
where each error is identified by rule name and line number. *This is | ||
deprecated.* | ||
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 deprecated.* | ||
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 | ||
deprecated.* | ||
Passing a `resultVersion` of `2` corresponds to a detailed format where each error | ||
includes information about the line number, rule names, description, as well as any | ||
additional detail or context that is available. *This is deprecated.* | ||
Passing a `resultVersion` of `2` corresponds to a detailed format where each | ||
error includes information about the line number, rule names, description, as | ||
well as any additional detail or context that is available. *This is | ||
deprecated.* | ||
Passing a `resultVersion` of `3` corresponds to the detailed version `2` format | ||
with additional information about how to fix automatically-fixable errors. In this | ||
mode, all errors that occur on each line are reported (other versions report only | ||
the first error for each rule). *This is the default.* | ||
with additional information about how to fix automatically-fixable errors. In | ||
this mode, all errors that occur on each line are reported (other versions | ||
report only the first error for each rule). *This is the default.* | ||
@@ -635,8 +677,9 @@ ##### options.strings | ||
By default, configuration files are parsed as JSON (and named `.markdownlint.json`). | ||
Custom parsers can be provided to handle other formats like JSONC, YAML, and TOML. | ||
By default, configuration files are parsed as JSON (and named | ||
`.markdownlint.json`). Custom parsers can be provided to handle other formats | ||
like JSONC, YAML, and TOML. | ||
Asynchronous API: | ||
```js | ||
```javascript | ||
/** | ||
@@ -646,3 +689,3 @@ * Read specified configuration file. | ||
* @param {string} file Configuration file name. | ||
* @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing function(s). | ||
* @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing function. | ||
* @param {Object} [fs] File system implementation. | ||
@@ -657,3 +700,3 @@ * @param {ReadConfigCallback} [callback] Callback (err, result) function. | ||
```js | ||
```javascript | ||
/** | ||
@@ -673,3 +716,3 @@ * Read specified configuration file synchronously. | ||
```js | ||
```javascript | ||
/** | ||
@@ -692,8 +735,9 @@ * Read specified configuration file. | ||
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). If either the `file` or `extends` path begins | ||
with the `~` directory, it will act as a placeholder for the home directory. | ||
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). If either the `file` or | ||
`extends` path begins with the `~` directory, it will act as a placeholder for | ||
the home directory. | ||
@@ -706,9 +750,9 @@ #### parsers | ||
The contents of a configuration file are passed to each parser function until one | ||
of them returns a value (vs. throwing an exception). Consequently, strict parsers | ||
should come before flexible parsers. | ||
The contents of a configuration file are passed to each parser function until | ||
one of them returns a value (vs. throwing an exception). Consequently, strict | ||
parsers should come before flexible parsers. | ||
For example: | ||
```js | ||
```javascript | ||
[ JSON.parse, require("toml").parse, require("js-yaml").load ] | ||
@@ -719,10 +763,13 @@ ``` | ||
Type: *Optional* `Object` implementing the [file system API](https://nodejs.org/api/fs.html) | ||
Type: *Optional* `Object` implementing the [file system API][file-system-api] | ||
In advanced scenarios, it may be desirable to bypass the default file system API. | ||
If a custom file system implementation is provided, `markdownlint` will use that | ||
instead of invoking `require("fs")`. | ||
[file-system-api]: https://nodejs.org/api/fs.html | ||
Note: The only methods called are `readFile`, `readFileSync`, `access`, and `accessSync`. | ||
In advanced scenarios, it may be desirable to bypass the default file system | ||
API. If a custom file system implementation is provided, `markdownlint` will use | ||
that instead of invoking `require("fs")`. | ||
Note: The only methods called are `readFile`, `readFileSync`, `access`, and | ||
`accessSync`. | ||
#### callback | ||
@@ -744,3 +791,3 @@ | ||
```js | ||
```javascript | ||
const markdownlint = require("markdownlint"); | ||
@@ -778,3 +825,3 @@ | ||
```js | ||
```javascript | ||
const result = markdownlint.sync(options); | ||
@@ -786,3 +833,3 @@ console.log(result.toString()); | ||
```js | ||
```javascript | ||
markdownlint(options, function callback(err, result) { | ||
@@ -804,3 +851,3 @@ if (!err) { | ||
"ruleDescription": "Hard tabs", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md010", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md010.md", | ||
"errorDetail": "Column: 17", | ||
@@ -812,3 +859,3 @@ "errorContext": null, | ||
"ruleDescription": "No space after hash on atx style heading", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md018.md", | ||
"errorDetail": null, | ||
@@ -820,3 +867,3 @@ "errorContext": "#bad.md", | ||
"ruleDescription": "No space after hash on atx style heading", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md018.md", | ||
"errorDetail": null, | ||
@@ -828,3 +875,3 @@ "errorContext": "#This file fails\tsome rules.", | ||
"ruleDescription": "First line in a file should be a top-level heading", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md041", | ||
"ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/md041.md", | ||
"errorDetail": null, | ||
@@ -837,5 +884,6 @@ "errorContext": "#bad.md", | ||
Integration with the [gulp](https://gulpjs.com/) build system is straightforward: | ||
Integration with the [gulp](https://gulpjs.com/) build system is | ||
straightforward: | ||
```js | ||
```javascript | ||
const gulp = require("gulp"); | ||
@@ -874,3 +922,3 @@ const through2 = require("through2"); | ||
```js | ||
```javascript | ||
const markdownlint = require("markdownlint"); | ||
@@ -914,2 +962,10 @@ | ||
### Fixing | ||
Rules that can be fixed automatically include a `fixInfo` property which is | ||
outlined in the [documentation for custom rules](doc/CustomRules.md#authoring). | ||
To apply those fixes more easily, the `applyFixes` method in | ||
[markdownlint-rule-helpers](helpers/README.md#applying-recommended-fixes) may | ||
be used. | ||
## Browser | ||
@@ -921,3 +977,3 @@ | ||
```shell | ||
```bash | ||
npm run build-demo | ||
@@ -935,3 +991,3 @@ ``` | ||
```js | ||
```javascript | ||
const options = { | ||
@@ -950,20 +1006,55 @@ "strings": { | ||
* [.NET Documentation](https://docs.microsoft.com/en-us/dotnet/) ([Search repository](https://github.com/dotnet/docs/search?q=markdownlint)) | ||
* [ally.js](https://allyjs.io/) ([Search repository](https://github.com/medialize/ally.js/search?q=markdownlint)) | ||
* [Boostnote](https://boostnote.io/) ([Search repository](https://github.com/BoostIO/Boostnote/search?q=markdownlint)) | ||
* [CodiMD](https://github.com/hackmdio/codimd) ([Search repository](https://github.com/hackmdio/codimd/search?q=markdownlint)) | ||
* [ESLint](https://eslint.org/) ([Search repository](https://github.com/eslint/eslint/search?q=markdownlint)) | ||
* [Garden React Components](https://zendeskgarden.github.io/react-components/) ([Search repository](https://github.com/zendeskgarden/react-components/search?q=markdownlint)) | ||
* [MDN Web Docs](https://developer.mozilla.org/) ([Search repository](https://github.com/mdn/content/search?q=markdownlint)) | ||
* [MkDocs](https://www.mkdocs.org/) ([Search repository](https://github.com/mkdocs/mkdocs/search?q=markdownlint)) | ||
* [Mocha](https://mochajs.org/) ([Search repository](https://github.com/mochajs/mocha/search?q=markdownlint)) | ||
* [Pi-hole documentation](https://docs.pi-hole.net) ([Search repository](https://github.com/pi-hole/docs/search?q=markdownlint)) | ||
* [Reactable](https://glittershark.github.io/reactable/) ([Search repository](https://github.com/glittershark/reactable/search?q=markdownlint)) | ||
* [Sinon.JS](https://sinonjs.org/) ([Search repository](https://github.com/sinonjs/sinon/search?q=markdownlint)) | ||
* [TestCafe](https://devexpress.github.io/testcafe/) ([Search repository](https://github.com/DevExpress/testcafe/search?q=markdownlint)) | ||
* [V8](https://v8.dev/) ([Search repository](https://github.com/v8/v8.dev/search?q=markdownlint)) | ||
* [webhint](https://webhint.io/) ([Search repository](https://github.com/webhintio/hint/search?q=markdownlint)) | ||
* [webpack](https://webpack.js.org/) ([Search repository](https://github.com/webpack/webpack.js.org/search?q=markdownlint)) | ||
* [WordPress](https://wordpress.org/gutenberg/) ([Search repository](https://github.com/WordPress/gutenberg/search?q=markdownlint)) | ||
- [.NET Documentation][dot-net-doc] ([Search repository][dot-net-doc-search]) | ||
- [ally.js][ally-js] ([Search repository][ally-js-search]) | ||
- [Apache Airflow][airflow] ([Search repository][airflow-search]) | ||
- [Boostnote][boostnote] ([Search repository][boostnote-search]) | ||
- [CodiMD][codimd] ([Search repository][codimd-search]) | ||
- [Electron][electron] ([Search repository][electron-search]) | ||
- [ESLint][eslint] ([Search repository][eslint-search]) | ||
- [Garden React Components][garden] ([Search repository][garden-search]) | ||
- [MDN Web Docs][mdn] ([Search repository][mdn-search]) | ||
- [MkDocs][mkdocs] ([Search repository][mkdocs-search]) | ||
- [Mocha][mocha] ([Search repository][mocha-search]) | ||
- [Pi-hole documentation][pi-hole] ([Search repository][pi-hole-search]) | ||
- [Reactable][reactable] ([Search repository][reactable-search]) | ||
- [V8][v8] ([Search repository][v8-search]) | ||
- [webhint][webhint] ([Search repository][webhint-search]) | ||
- [webpack][webpack] ([Search repository][webpack-search]) | ||
- [WordPress][wordpress] ([Search repository][wordpress-search]) | ||
[ally-js]: https://allyjs.io/ | ||
[ally-js-search]: https://github.com/medialize/ally.js/search?q=markdownlint | ||
[airflow]: https://airflow.apache.org | ||
[airflow-search]: https://github.com/apache/airflow/search?q=markdownlint | ||
[boostnote]: https://boostnote.io/ | ||
[boostnote-search]: https://github.com/BoostIO/Boostnote/search?q=markdownlint | ||
[codimd]: https://github.com/hackmdio/codimd | ||
[codimd-search]: https://github.com/hackmdio/codimd/search?q=markdownlint | ||
[dot-net-doc]: https://docs.microsoft.com/en-us/dotnet/ | ||
[dot-net-doc-search]: https://github.com/dotnet/docs/search?q=markdownlint | ||
[electron]: https://www.electronjs.org | ||
[electron-search]: https://github.com/electron/electron/search?q=markdownlint | ||
[eslint]: https://eslint.org/ | ||
[eslint-search]: https://github.com/eslint/eslint/search?q=markdownlint | ||
[garden]: https://zendeskgarden.github.io/react-components/ | ||
[garden-search]: https://github.com/zendeskgarden/react-components/search?q=markdownlint | ||
[mdn]: https://developer.mozilla.org/ | ||
[mdn-search]: https://github.com/mdn/content/search?q=markdownlint | ||
[mkdocs]: https://www.mkdocs.org/ | ||
[mkdocs-search]: https://github.com/mkdocs/mkdocs/search?q=markdownlint | ||
[mocha]: https://mochajs.org/ | ||
[mocha-search]: https://github.com/mochajs/mocha/search?q=markdownlint | ||
[pi-hole]: https://docs.pi-hole.net | ||
[pi-hole-search]: https://github.com/pi-hole/docs/search?q=markdownlint | ||
[reactable]: https://glittershark.github.io/reactable/ | ||
[reactable-search]: https://github.com/glittershark/reactable/search?q=markdownlint | ||
[v8]: https://v8.dev/ | ||
[v8-search]: https://github.com/v8/v8.dev/search?q=markdownlint | ||
[webhint]: https://webhint.io/ | ||
[webhint-search]: https://github.com/webhintio/hint/search?q=markdownlint | ||
[webpack]: https://webpack.js.org/ | ||
[webpack-search]: https://github.com/webpack/webpack.js.org/search?q=markdownlint | ||
[wordpress]: https://wordpress.org/gutenberg/ | ||
[wordpress-search]: https://github.com/WordPress/gutenberg/search?q=markdownlint | ||
## Contributing | ||
@@ -973,101 +1064,131 @@ | ||
## Releasing | ||
See [ReleaseProcess.md](doc/ReleaseProcess.md) for more information. | ||
## History | ||
* 0.0.1 - Initial release, includes tests MD001-MD032. | ||
* 0.0.2 - Improve documentation, tests, and code. | ||
* 0.0.3 - Add synchronous API, improve documentation and code. | ||
* 0.0.4 - Add tests MD033-MD040, update dependencies. | ||
* 0.0.5 - Add `strings` option to enable file-less scenarios, add in-browser demo. | ||
* 0.0.6 - Improve performance, simplify in-browser, update dependencies. | ||
* 0.0.7 - Add MD041, improve MD003, ignore front matter, update dependencies. | ||
* 0.0.8 - Support disabling/enabling rules inline, improve code fence, dependencies. | ||
* 0.1.0 - Add aliases, exceptions for MD033, exclusions for MD013, dependencies. | ||
* 0.1.1 - Fix bug handling HTML in tables, reference markdownlint-cli. | ||
* 0.2.0 - Add MD042/MD043, enhance MD002/MD003/MD004/MD007/MD011/MD025/MD041, dependencies. | ||
* 0.3.0 - More detailed error reporting with `resultVersion`, enhance MD010/MD012/MD036, | ||
fixes for MD027/MD029/MD030, include JSON schema, dependencies. | ||
* 0.3.1 - Fix regressions in MD032/MD038, update dependencies. | ||
* 0.4.0 - Add MD044, enhance MD013/MD032/MD041/MD042/MD043, fix for MD038, dependencies. | ||
* 0.4.1 - Fixes for MD038/front matter, improvements to MD044, update dependencies. | ||
* 0.5.0 - Add shareable configuration, `noInlineConfig` option, README links, fix MD030, | ||
improve MD009/MD041, update dependencies. | ||
* 0.6.0 - `resultVersion` defaults to 1 (breaking change), ignore HTML comments, TOML | ||
front matter, fixes for MD044, update dependencies. | ||
* 0.6.1 - Update `markdown-it` versioning, exclude demo/test from publishing. | ||
* 0.6.2 - Improve MD013/MD027/MD034/MD037/MD038/MD041/MD044, update dependencies. | ||
* 0.6.3 - Improve highlighting for MD020. | ||
* 0.6.4 - Improve MD029/MD042, update dependencies. | ||
* 0.7.0 - `resultVersion` defaults to 2 (breaking change), add MD045, improve MD029, | ||
remove trimLeft/trimRight, split rules, refactor, update dependencies. | ||
* 0.8.0 - Add support for using and authoring custom rules, improve MD004/MD007/MD013, | ||
add `engines` to `package.json`, refactor, update dependencies. | ||
* 0.8.1 - Update item loop to be iterative, improve MD014, update dependencies. | ||
* 0.9.0 - Remove support for end-of-life Node versions 0.10/0.12/4, change "header" to | ||
"heading" per spec (non-breaking), improve MD003/MD009/MD041, handle uncommon | ||
line-break characters, refactor for ES6, update dependencies. | ||
* 0.10.0 - Add support for non-JSON configuration files, pass file/string name to custom | ||
rules, update dependencies. | ||
* 0.11.0 - Improve MD005/MD024/MD029/MD038, improve custom rule example, add CONTRIBUTING.md, | ||
- 0.0.1 - Initial release, includes tests MD001-MD032. | ||
- 0.0.2 - Improve documentation, tests, and code. | ||
- 0.0.3 - Add synchronous API, improve documentation and code. | ||
- 0.0.4 - Add tests MD033-MD040, update dependencies. | ||
- 0.0.5 - Add `strings` option to enable file-less scenarios, add in-browser | ||
demo. | ||
- 0.0.6 - Improve performance, simplify in-browser, update dependencies. | ||
- 0.0.7 - Add MD041, improve MD003, ignore front matter, update dependencies. | ||
- 0.0.8 - Support disabling/enabling rules inline, improve code fence, | ||
dependencies. | ||
- 0.1.0 - Add aliases, exceptions for MD033, exclusions for MD013, dependencies. | ||
- 0.1.1 - Fix bug handling HTML in tables, reference markdownlint-cli. | ||
- 0.2.0 - Add MD042/MD043, enhance MD002/MD003/MD004/MD007/MD011/MD025/MD041, | ||
dependencies. | ||
- 0.3.0 - More detailed error reporting with `resultVersion`, enhance | ||
MD010/MD012/MD036, fixes for MD027/MD029/MD030, include JSON schema, | ||
dependencies. | ||
- 0.3.1 - Fix regressions in MD032/MD038, update dependencies. | ||
- 0.4.0 - Add MD044, enhance MD013/MD032/MD041/MD042/MD043, fix for MD038, | ||
dependencies. | ||
- 0.4.1 - Fixes for MD038/front matter, improvements to MD044, update | ||
dependencies. | ||
- 0.5.0 - Add shareable configuration, `noInlineConfig` option, README links, | ||
fix MD030, improve MD009/MD041, update dependencies. | ||
- 0.6.0 - `resultVersion` defaults to 1 (breaking change), ignore HTML comments, | ||
TOML front matter, fixes for MD044, update dependencies. | ||
- 0.6.1 - Update `markdown-it` versioning, exclude demo/test from publishing. | ||
- 0.6.2 - Improve MD013/MD027/MD034/MD037/MD038/MD041/MD044, update | ||
dependencies. | ||
- 0.6.3 - Improve highlighting for MD020. | ||
- 0.6.4 - Improve MD029/MD042, update dependencies. | ||
- 0.7.0 - `resultVersion` defaults to 2 (breaking change), add MD045, improve | ||
MD029, remove trimLeft/trimRight, split rules, refactor, update | ||
dependencies. | ||
- 0.8.0 - Add support for using and authoring custom rules, improve | ||
MD004/MD007/MD013, add `engines` to `package.json`, refactor, update | ||
dependencies. | ||
- 0.8.1 - Update item loop to be iterative, improve MD014, update | ||
dependencies. | ||
- 0.9.0 - Remove support for end-of-life Node versions 0.10/0.12/4, change | ||
"header" to "heading" per spec (non-breaking), improve | ||
MD003/MD009/MD041, handle uncommon line-break characters, refactor for | ||
ES6, update dependencies. | ||
- 0.10.0 - Add support for non-JSON configuration files, pass file/string name | ||
to custom rules, update dependencies. | ||
- 0.11.0 - Improve MD005/MD024/MD029/MD038, improve custom rule example, add | ||
CONTRIBUTING.md, update dependencies. | ||
- 0.12.0 - Add `information` link for custom rules, `markdownItPlugins` for | ||
extensibility, improve MD023/MD032/MD038, update dependencies. | ||
- 0.13.0 - Improve MD013/MD022/MD025/MD029/MD031/MD032/MD037/MD041/, deprecate | ||
MD002, improve pandoc YAML support, update dependencies. | ||
- 0.14.0 - Remove support for end-of-life Node version 6, introduce | ||
`markdownlint-rule-helpers`, add MD046/MD047, improve | ||
MD033/MD034/MD039, improve custom rule validation and in-browser | ||
demo, update dependencies. | ||
- 0.14.1 - Improve MD033. | ||
- 0.14.2 - Improve MD047, add `handleRuleFailures` option. | ||
- 0.15.0 - Add `markdownlint-capture`/`markdownlint-restore` inline comments, | ||
improve MD009/MD013/MD026/MD033/MD036, update dependencies. | ||
- 0.16.0 - Add custom rule sample for linting code, improve | ||
MD026/MD031/MD033/MD038, update dependencies. | ||
- 0.17.0 - Add `resultVersion` 3 to support fix information for default and | ||
custom rules, add fix information for 24 rules, update newline | ||
handling to match latest CommonMark specification, improve | ||
MD014/MD037/MD039, update dependencies. | ||
- 0.17.1 - Fix handling of front matter by fix information. | ||
- 0.17.2 - Improve MD020/MD033/MD044. | ||
- 0.18.0 - Add MD048/code-fence-style, add fix information for MD007/ul-indent, | ||
add `markdownlint-disable-file`/`markdownlint-enable-file` inline | ||
comments, add type declaration file (.d.ts) for TypeScript | ||
dependents, update schema, improve MD006/MD007/MD009/MD013/MD030, | ||
update dependencies. | ||
* 0.12.0 - Add `information` link for custom rules, `markdownItPlugins` for extensibility, | ||
improve MD023/MD032/MD038, update dependencies. | ||
* 0.13.0 - Improve MD013/MD022/MD025/MD029/MD031/MD032/MD037/MD041/, deprecate MD002, | ||
improve pandoc YAML support, update dependencies. | ||
* 0.14.0 - Remove support for end-of-life Node version 6, introduce `markdownlint-rule-helpers`, | ||
add MD046/MD047, improve MD033/MD034/MD039, improve custom rule validation and | ||
in-browser demo, update dependencies. | ||
* 0.14.1 - Improve MD033. | ||
* 0.14.2 - Improve MD047, add `handleRuleFailures` option. | ||
* 0.15.0 - Add `markdownlint-capture`/`markdownlint-restore` inline comments, improve | ||
MD009/MD013/MD026/MD033/MD036, update dependencies. | ||
* 0.16.0 - Add custom rule sample for linting code, improve MD026/MD031/MD033/MD038, | ||
update dependencies. | ||
* 0.17.0 - Add `resultVersion` 3 to support fix information for default and custom rules, | ||
add fix information for 24 rules, update newline handling to match latest | ||
CommonMark specification, improve MD014/MD037/MD039, update dependencies. | ||
* 0.17.1 - Fix handling of front matter by fix information. | ||
* 0.17.2 - Improve MD020/MD033/MD044. | ||
* 0.18.0 - Add MD048/code-fence-style, add fix information for MD007/ul-indent, add | ||
`markdownlint-disable-file`/`markdownlint-enable-file` inline comments, add | ||
type declaration file (.d.ts) for TypeScript dependents, update schema, improve | ||
MD006/MD007/MD009/MD013/MD030, update dependencies. | ||
* 0.19.0 - Remove support for end-of-life Node version 8, add fix information for | ||
MD005/list-indent, improve MD007/MD013/MD014, deprecate MD006/ul-start-left, add | ||
rationale for every rule, update test runner and code coverage, add more JSDoc | ||
comments, update dependencies. | ||
* 0.20.0 - Add `markdownlint-configure-file` inline comment, reimplement MD037, | ||
improve MD005/MD007/MD013/MD018/MD029/MD031/MD034/MD038/MD039, improve HTML | ||
comment handling, update dependencies. | ||
* 0.20.1 - Fix regression in MD037. | ||
* 0.20.2 - Fix regression in MD037, improve MD038. | ||
* 0.20.3 - Fix regression in MD037, improve MD044, add automatic regression testing. | ||
* 0.20.4 - Fix regression in MD037, improve MD034/MD044, improve documentation. | ||
* 0.21.0 - Lint concurrently for better performance (async only), add Promise-based APIs, | ||
update TypeScript declaration file, hide `toString` on `LintResults`, add ability | ||
to fix in browser demo, allow custom rules in `.markdownlint.json` schema, improve | ||
- 0.19.0 - Remove support for end-of-life Node version 8, add fix information | ||
for MD005/list-indent, improve MD007/MD013/MD014, deprecate | ||
MD006/ul-start-left, add rationale for every rule, update test runner | ||
and code coverage, add more JSDoc comments, update dependencies. | ||
- 0.20.0 - Add `markdownlint-configure-file` inline comment, reimplement MD037, | ||
improve MD005/MD007/MD013/MD018/MD029/MD031/MD034/MD038/MD039, | ||
improve HTML comment handling, update dependencies. | ||
- 0.20.1 - Fix regression in MD037. | ||
- 0.20.2 - Fix regression in MD037, improve MD038. | ||
- 0.20.3 - Fix regression in MD037, improve MD044, add automatic regression | ||
testing. | ||
- 0.20.4 - Fix regression in MD037, improve MD034/MD044, improve | ||
documentation. | ||
- 0.21.0 - Lint concurrently for better performance (async only), add | ||
Promise-based APIs, update TypeScript declaration file, hide | ||
`toString` on `LintResults`, add ability to fix in browser demo, | ||
allow custom rules in `.markdownlint.json` schema, improve | ||
MD042/MD044, improve documentation, update dependencies. | ||
* 0.21.1 - Improve MD011/MD031, export `getVersion` API. | ||
* 0.22.0 - Allow `extends` in config to reference installed packages by name, add | ||
`markdownlint-disable-next-line` inline comment, support JSON front matter, improve | ||
MD009/MD026/MD028/MD043, update dependencies (including `markdown-it` to v12). | ||
* 0.23.0 - Add comprehensive example `.markdownlint.jsonc`/`.markdownlint.yaml` files, add fix | ||
information for MD004/ul-style, improve MD018/MD019/MD020/MD021/MD037/MD041, improve | ||
HTML comment handling, update test runner and test suite, update dependencies. | ||
* 0.23.1 - Work around lack of webpack support for dynamic calls to `require` (`.resolve`). | ||
* 0.24.0 - Remove support for end-of-life Node version 10, add support for custom file system | ||
module, improve MD010/MD011/MD037/MD043/MD044, improve TypeScript declaration file | ||
and JSON schema, update dependencies. | ||
* 0.25.0 - Add MD049/MD050 for consistent emphasis/strong style (both auto-fixable), improve | ||
MD007/MD010/MD032/MD033/MD035/MD037/MD039, support asynchronous custom rules, | ||
improve performance, improve CI process, reduce dependencies, update dependencies. | ||
* 0.25.1 - Update dependencies for CVE-2022-21670. | ||
* 0.26.0 - Add MD051/MD052/MD053 for validating link fragments & reference links/images & | ||
link/image reference definitions (MD053 is auto-fixable), improve | ||
MD010/MD031/MD035/MD039/MD042/MD044/MD049/MD050, add `markdownlint-disable-line` | ||
inline comment, support `~` paths in `readConfig/Sync`, add `configParsers` option, | ||
remove support for end-of-life Node version 12, default `resultVersion` to 3, update | ||
browser script to use ES2015, simplify JSON schema, address remaining CodeQL issues, | ||
improve performance, update dependencies. | ||
* 0.26.1 - Improve MD051. | ||
* 0.26.2 - Improve MD037/MD051/MD053. | ||
- 0.21.1 - Improve MD011/MD031, export `getVersion` API. | ||
- 0.22.0 - Allow `extends` in config to reference installed packages by name, | ||
add `markdownlint-disable-next-line` inline comment, support JSON | ||
front matter, improve MD009/MD026/MD028/MD043, update dependencies | ||
(including `markdown-it` to v12). | ||
- 0.23.0 - Add comprehensive example `.markdownlint.jsonc`/`.markdownlint.yaml` | ||
files, add fix information for MD004/ul-style, improve | ||
MD018/MD019/MD020/MD021/MD037/MD041, improve HTML comment handling, | ||
update test runner and test suite, update dependencies. | ||
- 0.23.1 - Work around lack of webpack support for dynamic calls to | ||
`require`(`.resolve`). | ||
- 0.24.0 - Remove support for end-of-life Node version 10, add support for | ||
custom file system module, improve MD010/MD011/MD037/MD043/MD044, | ||
improve TypeScript declaration file and JSON schema, update | ||
dependencies. | ||
- 0.25.0 - Add MD049/MD050 for consistent emphasis/strong style (both | ||
auto-fixable), improve MD007/MD010/MD032/MD033/MD035/MD037/MD039, | ||
support asynchronous custom rules, improve performance, improve CI | ||
process, reduce dependencies, update dependencies. | ||
- 0.25.1 - Update dependencies for CVE-2022-21670. | ||
- 0.26.0 - Add MD051/MD052/MD053 for validating link fragments & reference | ||
links/images & link/image reference definitions (MD053 auto-fixable), | ||
improve MD010/MD031/MD035/MD039/MD042/MD044/MD049/MD050, add | ||
`markdownlint-disable-line` inline comment, support `~` paths in | ||
`readConfig/Sync`, add `configParsers` option, remove support for | ||
end-of-life Node version 12, default `resultVersion` to 3, update | ||
browser script to use ES2015, simplify JSON schema, address remaining | ||
CodeQL issues, improve performance, update dependencies. | ||
- 0.26.1 - Improve MD051. | ||
- 0.26.2 - Improve MD037/MD051/MD053. | ||
- 0.27.0 - Improve MD011/MD013/MD022/MD031/MD032/MD033/MD034/MD040/MD043/MD051/ | ||
MD053, generate/separate documentation, improve documentation, update | ||
dependencies. | ||
@@ -1074,0 +1195,0 @@ [npm-image]: https://img.shields.io/npm/v/markdownlint.svg |
@@ -459,3 +459,3 @@ { | ||
"punctuation": { | ||
"description": "Punctuation characters", | ||
"description": "Punctuation characters not allowed at end of headings", | ||
"type": "string", | ||
@@ -673,4 +673,23 @@ "default": ".,;:!。,;:!" | ||
"description": "MD040/fenced-code-language - Fenced code blocks should have a language specified", | ||
"type": "boolean", | ||
"default": true | ||
"type": [ | ||
"boolean", | ||
"object" | ||
], | ||
"default": true, | ||
"properties": { | ||
"allowed_languages": { | ||
"description": "List of languages", | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
}, | ||
"default": [] | ||
}, | ||
"language_only": { | ||
"description": "Require language only", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
}, | ||
"additionalProperties": false | ||
}, | ||
@@ -742,2 +761,7 @@ "fenced-code-language": { | ||
"default": [] | ||
}, | ||
"match_case": { | ||
"description": "Match case of headings", | ||
"type": "boolean", | ||
"default": false | ||
} | ||
@@ -744,0 +768,0 @@ }, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
601930
122
11481
1151
2
25