markdownlint 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +4 -3
- package/demo/markdownlint-browser.js +2730 -1541
- package/doc/CustomRules.md +14 -7
- package/doc/Rules.md +40 -7
- package/doc/md013.md +8 -7
- package/doc/md049.md +3 -0
- package/doc/md050.md +3 -0
- package/doc/md051.md +26 -0
- package/helpers/README.md +5 -3
- package/helpers/helpers.js +5 -5
- package/helpers/micromark.cjs +45 -27
- package/helpers/package.json +2 -2
- package/lib/configuration.d.ts +102 -102
- package/lib/constants.js +1 -1
- package/lib/markdownlint.d.ts +79 -6
- package/lib/markdownlint.js +95 -20
- package/lib/md001.js +3 -0
- package/lib/md003.js +3 -0
- package/lib/md004.js +3 -0
- package/lib/md005.js +9 -1
- package/lib/md007.js +14 -9
- package/lib/md009.js +3 -0
- package/lib/md010.js +4 -1
- package/lib/md011.js +3 -0
- package/lib/md012.js +3 -0
- package/lib/md013.js +3 -0
- package/lib/md014.js +4 -0
- package/lib/md018.js +4 -0
- package/lib/md019.js +3 -0
- package/lib/md020.js +3 -0
- package/lib/md021.js +3 -0
- package/lib/md022.js +10 -2
- package/lib/md023.js +3 -0
- package/lib/md024.js +3 -0
- package/lib/md025.js +3 -0
- package/lib/md026.js +9 -5
- package/lib/md027.js +29 -43
- package/lib/md028.js +31 -14
- package/lib/md029.js +3 -0
- package/lib/md030.js +9 -4
- package/lib/md031.js +3 -0
- package/lib/md032.js +12 -14
- package/lib/md033.js +9 -2
- package/lib/md034.js +31 -5
- package/lib/md035.js +9 -2
- package/lib/md036.js +33 -39
- package/lib/md037.js +10 -2
- package/lib/md038.js +10 -3
- package/lib/md039.js +4 -0
- package/lib/md040.js +26 -21
- package/lib/md041.js +21 -26
- package/lib/md042.js +4 -0
- package/lib/md043.js +3 -0
- package/lib/md044.js +9 -1
- package/lib/md045.js +10 -3
- package/lib/md046.js +14 -7
- package/lib/md047.js +5 -2
- package/lib/md048.js +26 -13
- package/lib/md049-md050.js +26 -7
- package/lib/md051.js +20 -16
- package/lib/md052.js +3 -0
- package/lib/md053.js +3 -0
- package/lib/md054.js +10 -5
- package/lib/md055.js +9 -1
- package/lib/md056.js +9 -1
- package/package.json +17 -22
- package/schema/.markdownlint.jsonc +50 -50
- package/schema/.markdownlint.yaml +50 -50
- package/schema/markdownlint-config-schema.json +104 -104
package/lib/md022.js
CHANGED
|
@@ -31,16 +31,24 @@ const getBlockQuote = (str, count) => (
|
|
|
31
31
|
.repeat(count)
|
|
32
32
|
);
|
|
33
33
|
|
|
34
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
35
|
+
/** @type import("./markdownlint").Rule */
|
|
34
36
|
module.exports = {
|
|
35
37
|
"names": [ "MD022", "blanks-around-headings" ],
|
|
36
38
|
"description": "Headings should be surrounded by blank lines",
|
|
37
39
|
"tags": [ "headings", "blank_lines" ],
|
|
40
|
+
"parser": "micromark",
|
|
38
41
|
"function": function MD022(params, onError) {
|
|
39
42
|
const getLinesAbove = getLinesFunction(params.config.lines_above);
|
|
40
43
|
const getLinesBelow = getLinesFunction(params.config.lines_below);
|
|
41
|
-
|
|
44
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
45
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
46
|
+
const micromarkTokens =
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
params.parsers.micromark.tokens;
|
|
49
|
+
const { lines } = params;
|
|
42
50
|
const headings = filterByTypes(
|
|
43
|
-
|
|
51
|
+
micromarkTokens,
|
|
44
52
|
[ "atxHeading", "setextHeading" ]
|
|
45
53
|
).filter((heading) => !inHtmlFlow(heading));
|
|
46
54
|
for (const heading of headings) {
|
package/lib/md023.js
CHANGED
|
@@ -6,10 +6,13 @@ const { addErrorContext, filterTokens } = require("../helpers");
|
|
|
6
6
|
|
|
7
7
|
const spaceBeforeHeadingRe = /^(\s+|[>\s]+\s\s)[^>\s]/;
|
|
8
8
|
|
|
9
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
10
|
+
/** @type import("./markdownlint").Rule */
|
|
9
11
|
module.exports = {
|
|
10
12
|
"names": [ "MD023", "heading-start-left" ],
|
|
11
13
|
"description": "Headings must start at the beginning of the line",
|
|
12
14
|
"tags": [ "headings", "spaces" ],
|
|
15
|
+
"parser": "markdownit",
|
|
13
16
|
"function": function MD023(params, onError) {
|
|
14
17
|
filterTokens(params, "heading_open", function forToken(token) {
|
|
15
18
|
const { lineNumber, line } = token;
|
package/lib/md024.js
CHANGED
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
const { addErrorContext, forEachHeading } = require("../helpers");
|
|
6
6
|
|
|
7
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
8
|
+
/** @type import("./markdownlint").Rule */
|
|
7
9
|
module.exports = {
|
|
8
10
|
"names": [ "MD024", "no-duplicate-heading" ],
|
|
9
11
|
"description": "Multiple headings with the same content",
|
|
10
12
|
"tags": [ "headings" ],
|
|
13
|
+
"parser": "markdownit",
|
|
11
14
|
"function": function MD024(params, onError) {
|
|
12
15
|
const siblingsOnly = !!params.config.siblings_only || false;
|
|
13
16
|
const knownContents = [ null, [] ];
|
package/lib/md025.js
CHANGED
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
const { addErrorContext, filterTokens, frontMatterHasTitle } =
|
|
6
6
|
require("../helpers");
|
|
7
7
|
|
|
8
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
9
|
+
/** @type import("./markdownlint").Rule */
|
|
8
10
|
module.exports = {
|
|
9
11
|
"names": [ "MD025", "single-title", "single-h1" ],
|
|
10
12
|
"description": "Multiple top-level headings in the same document",
|
|
11
13
|
"tags": [ "headings" ],
|
|
14
|
+
"parser": "markdownit",
|
|
12
15
|
"function": function MD025(params, onError) {
|
|
13
16
|
const level = Number(params.config.level || 1);
|
|
14
17
|
const tag = "h" + level;
|
package/lib/md026.js
CHANGED
|
@@ -6,11 +6,13 @@ const { addError, allPunctuationNoQuestion, endOfLineGemojiCodeRe,
|
|
|
6
6
|
endOfLineHtmlEntityRe, escapeForRegExp } = require("../helpers");
|
|
7
7
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
10
|
+
/** @type import("./markdownlint").Rule */
|
|
10
11
|
module.exports = {
|
|
11
12
|
"names": [ "MD026", "no-trailing-punctuation" ],
|
|
12
13
|
"description": "Trailing punctuation in heading",
|
|
13
14
|
"tags": [ "headings" ],
|
|
15
|
+
"parser": "micromark",
|
|
14
16
|
"function": function MD026(params, onError) {
|
|
15
17
|
let punctuation = params.config.punctuation;
|
|
16
18
|
punctuation = String(
|
|
@@ -18,10 +20,12 @@ module.exports = {
|
|
|
18
20
|
);
|
|
19
21
|
const trailingPunctuationRe =
|
|
20
22
|
new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$");
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
24
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
25
|
+
const micromarkTokens =
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
params.parsers.micromark.tokens;
|
|
28
|
+
const headings = filterByTypes(micromarkTokens, [ "atxHeadingText", "setextHeadingText" ]);
|
|
25
29
|
for (const heading of headings) {
|
|
26
30
|
const { endColumn, endLine, text } = heading;
|
|
27
31
|
const match = trailingPunctuationRe.exec(text);
|
package/lib/md027.js
CHANGED
|
@@ -2,54 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorContext
|
|
6
|
-
|
|
7
|
-
const spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/;
|
|
5
|
+
const { addErrorContext } = require("../helpers");
|
|
6
|
+
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
8
7
|
|
|
8
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
9
|
+
/** @type import("./markdownlint").Rule */
|
|
9
10
|
module.exports = {
|
|
10
|
-
"names": [
|
|
11
|
+
"names": ["MD027", "no-multiple-space-blockquote"],
|
|
11
12
|
"description": "Multiple spaces after blockquote symbol",
|
|
12
|
-
"tags": [
|
|
13
|
+
"tags": ["blockquote", "whitespace", "indentation"],
|
|
14
|
+
"parser": "micromark",
|
|
13
15
|
"function": function MD027(params, onError) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
{ "length": spaceLength }
|
|
36
|
-
] = match;
|
|
37
|
-
if (!listItemNesting || (fullMatch[fullMatch.length - 1] === ">")) {
|
|
38
|
-
addErrorContext(
|
|
39
|
-
onError,
|
|
40
|
-
lineNumber + i,
|
|
41
|
-
line,
|
|
42
|
-
null,
|
|
43
|
-
null,
|
|
44
|
-
[ 1, fullMatch.length ],
|
|
45
|
-
{
|
|
46
|
-
"editColumn": blockquoteLength + 1,
|
|
47
|
-
"deleteCount": spaceLength - 1
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
}
|
|
16
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
17
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
18
|
+
const micromarkTokens =
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
params.parsers.micromark.tokens;
|
|
21
|
+
for (const token of filterByTypes(micromarkTokens, [ "linePrefix" ])) {
|
|
22
|
+
const siblings = token.parent?.children || micromarkTokens;
|
|
23
|
+
if (siblings[siblings.indexOf(token) - 1]?.type === "blockQuotePrefix") {
|
|
24
|
+
const { startColumn, startLine, text } = token;
|
|
25
|
+
const { length } = text;
|
|
26
|
+
const line = params.lines[startLine - 1];
|
|
27
|
+
addErrorContext(
|
|
28
|
+
onError,
|
|
29
|
+
startLine,
|
|
30
|
+
line,
|
|
31
|
+
null,
|
|
32
|
+
null,
|
|
33
|
+
[ startColumn, length ],
|
|
34
|
+
{
|
|
35
|
+
"editColumn": startColumn,
|
|
36
|
+
"deleteCount": length
|
|
51
37
|
}
|
|
52
|
-
|
|
38
|
+
);
|
|
53
39
|
}
|
|
54
40
|
}
|
|
55
41
|
}
|
package/lib/md028.js
CHANGED
|
@@ -3,28 +3,45 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
5
|
const { addError } = require("../helpers");
|
|
6
|
+
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
6
7
|
|
|
8
|
+
const ignoreTypes = new Set([ "lineEnding", "listItemIndent", "linePrefix" ]);
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
11
|
+
/** @type import("./markdownlint").Rule */
|
|
7
12
|
module.exports = {
|
|
8
13
|
"names": [ "MD028", "no-blanks-blockquote" ],
|
|
9
14
|
"description": "Blank line inside blockquote",
|
|
10
15
|
"tags": [ "blockquote", "whitespace" ],
|
|
16
|
+
"parser": "micromark",
|
|
11
17
|
"function": function MD028(params, onError) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
19
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
20
|
+
const micromarkTokens =
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
params.parsers.micromark.tokens;
|
|
23
|
+
for (const token of filterByTypes(micromarkTokens, [ "blockQuote" ])) {
|
|
24
|
+
const errorLineNumbers = [];
|
|
25
|
+
const siblings = token.parent?.children || micromarkTokens;
|
|
26
|
+
for (let i = siblings.indexOf(token) + 1; i < siblings.length; i++) {
|
|
27
|
+
const sibling = siblings[i];
|
|
28
|
+
const { startLine, type } = sibling;
|
|
29
|
+
if (type === "lineEndingBlank") {
|
|
30
|
+
// Possible blank between blockquotes
|
|
31
|
+
errorLineNumbers.push(startLine);
|
|
32
|
+
} else if (ignoreTypes.has(type)) {
|
|
33
|
+
// Ignore invisible formatting
|
|
34
|
+
} else if (type === "blockQuote") {
|
|
35
|
+
// Blockquote followed by blockquote
|
|
36
|
+
for (const lineNumber of errorLineNumbers) {
|
|
37
|
+
addError(onError, lineNumber);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
} else {
|
|
41
|
+
// Blockquote not followed by blockquote
|
|
42
|
+
break;
|
|
22
43
|
}
|
|
23
44
|
}
|
|
24
|
-
prevToken = token;
|
|
25
|
-
if (token.type === "blockquote_open") {
|
|
26
|
-
prevLineNumber = token.map[1] + 1;
|
|
27
|
-
}
|
|
28
45
|
}
|
|
29
46
|
}
|
|
30
47
|
};
|
package/lib/md029.js
CHANGED
|
@@ -12,10 +12,13 @@ const listStyleExamples = {
|
|
|
12
12
|
"zero": "0/0/0"
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
16
|
+
/** @type import("./markdownlint").Rule */
|
|
15
17
|
module.exports = {
|
|
16
18
|
"names": [ "MD029", "ol-prefix" ],
|
|
17
19
|
"description": "Ordered list item prefix",
|
|
18
20
|
"tags": [ "ol" ],
|
|
21
|
+
"parser": "none",
|
|
19
22
|
"function": function MD029(params, onError) {
|
|
20
23
|
const style = String(params.config.style || "one_or_ordered");
|
|
21
24
|
const filteredLists = flattenedLists().filter((list) => !list.unordered);
|
package/lib/md030.js
CHANGED
|
@@ -5,19 +5,24 @@
|
|
|
5
5
|
const { addErrorDetailIf } = require("../helpers");
|
|
6
6
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
7
7
|
|
|
8
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
9
|
+
/** @type import("./markdownlint").Rule */
|
|
8
10
|
module.exports = {
|
|
9
11
|
"names": [ "MD030", "list-marker-space" ],
|
|
10
12
|
"description": "Spaces after list markers",
|
|
11
13
|
"tags": [ "ol", "ul", "whitespace" ],
|
|
14
|
+
"parser": "micromark",
|
|
12
15
|
"function": function MD030(params, onError) {
|
|
13
16
|
const ulSingle = Number(params.config.ul_single || 1);
|
|
14
17
|
const olSingle = Number(params.config.ol_single || 1);
|
|
15
18
|
const ulMulti = Number(params.config.ul_multi || 1);
|
|
16
19
|
const olMulti = Number(params.config.ol_multi || 1);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
21
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
22
|
+
const micromarkTokens =
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
params.parsers.micromark.tokens;
|
|
25
|
+
const lists = filterByTypes(micromarkTokens, [ "listOrdered", "listUnordered" ]);
|
|
21
26
|
for (const list of lists) {
|
|
22
27
|
const ordered = (list.type === "listOrdered");
|
|
23
28
|
const listItemPrefixes =
|
package/lib/md031.js
CHANGED
|
@@ -7,10 +7,13 @@ const { lineMetadata } = require("./cache");
|
|
|
7
7
|
|
|
8
8
|
const codeFencePrefixRe = /^(.*?)[`~]/;
|
|
9
9
|
|
|
10
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
11
|
+
/** @type import("./markdownlint").Rule */
|
|
10
12
|
module.exports = {
|
|
11
13
|
"names": [ "MD031", "blanks-around-fences" ],
|
|
12
14
|
"description": "Fenced code blocks should be surrounded by blank lines",
|
|
13
15
|
"tags": [ "code", "blank_lines" ],
|
|
16
|
+
"parser": "none",
|
|
14
17
|
"function": function MD031(params, onError) {
|
|
15
18
|
const listItems = params.config.list_items;
|
|
16
19
|
const includeListItems = (listItems === undefined) ? true : !!listItems;
|
package/lib/md032.js
CHANGED
|
@@ -2,19 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorContext, blockquotePrefixRe, isBlankLine } =
|
|
6
|
-
|
|
7
|
-
const { filterByPredicate } = require("../helpers/micromark.cjs");
|
|
5
|
+
const { addErrorContext, blockquotePrefixRe, isBlankLine } = require("../helpers");
|
|
6
|
+
const { filterByPredicate, nonContentTokens } = require("../helpers/micromark.cjs");
|
|
8
7
|
|
|
9
|
-
const nonContentTokens = new Set([
|
|
10
|
-
"blockQuoteMarker",
|
|
11
|
-
"blockQuotePrefix",
|
|
12
|
-
"blockQuotePrefixWhitespace",
|
|
13
|
-
"lineEnding",
|
|
14
|
-
"lineEndingBlank",
|
|
15
|
-
"linePrefix",
|
|
16
|
-
"listItemIndent"
|
|
17
|
-
]);
|
|
18
8
|
const isList = (token) => (
|
|
19
9
|
(token.type === "listOrdered") || (token.type === "listUnordered")
|
|
20
10
|
);
|
|
@@ -35,16 +25,24 @@ const addBlankLineError = (onError, lines, lineIndex, lineNumber) => {
|
|
|
35
25
|
);
|
|
36
26
|
};
|
|
37
27
|
|
|
28
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
29
|
+
/** @type import("./markdownlint").Rule */
|
|
38
30
|
module.exports = {
|
|
39
31
|
"names": [ "MD032", "blanks-around-lists" ],
|
|
40
32
|
"description": "Lists should be surrounded by blank lines",
|
|
41
33
|
"tags": [ "bullet", "ul", "ol", "blank_lines" ],
|
|
34
|
+
"parser": "micromark",
|
|
42
35
|
"function": function MD032(params, onError) {
|
|
43
|
-
|
|
36
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
37
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
38
|
+
const micromarkTokens =
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
params.parsers.micromark.tokens;
|
|
41
|
+
const { lines } = params;
|
|
44
42
|
|
|
45
43
|
// For every top-level list...
|
|
46
44
|
const topLevelLists = filterByPredicate(
|
|
47
|
-
|
|
45
|
+
micromarkTokens,
|
|
48
46
|
isList,
|
|
49
47
|
(token) => (
|
|
50
48
|
(isList(token) || (token.type === "htmlFlow")) ? [] : token.children
|
package/lib/md033.js
CHANGED
|
@@ -6,16 +6,23 @@ const { addError, nextLinesRe } = require("../helpers");
|
|
|
6
6
|
const { filterByTypes, getHtmlTagInfo } =
|
|
7
7
|
require("../helpers/micromark.cjs");
|
|
8
8
|
|
|
9
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
10
|
+
/** @type import("./markdownlint").Rule */
|
|
9
11
|
module.exports = {
|
|
10
12
|
"names": [ "MD033", "no-inline-html" ],
|
|
11
13
|
"description": "Inline HTML",
|
|
12
14
|
"tags": [ "html" ],
|
|
15
|
+
"parser": "micromark",
|
|
13
16
|
"function": function MD033(params, onError) {
|
|
14
17
|
let allowedElements = params.config.allowed_elements;
|
|
15
18
|
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
|
|
16
19
|
allowedElements = allowedElements.map((element) => element.toLowerCase());
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
21
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
22
|
+
const micromarkTokens =
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
params.parsers.micromark.tokens;
|
|
25
|
+
for (const token of filterByTypes(micromarkTokens, [ "htmlText" ])) {
|
|
19
26
|
const htmlTagInfo = getHtmlTagInfo(token);
|
|
20
27
|
if (
|
|
21
28
|
htmlTagInfo &&
|
package/lib/md034.js
CHANGED
|
@@ -6,15 +6,44 @@ const { addErrorContext } = require("../helpers");
|
|
|
6
6
|
const { filterByPredicate, filterByTypes, getHtmlTagInfo, inHtmlFlow, parse } =
|
|
7
7
|
require("../helpers/micromark.cjs");
|
|
8
8
|
|
|
9
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
10
|
+
/** @type import("./markdownlint").Rule */
|
|
9
11
|
module.exports = {
|
|
10
12
|
"names": [ "MD034", "no-bare-urls" ],
|
|
11
13
|
"description": "Bare URL used",
|
|
12
14
|
"tags": [ "links", "url" ],
|
|
15
|
+
"parser": "micromark",
|
|
13
16
|
"function": function MD034(params, onError) {
|
|
17
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
18
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
19
|
+
const micromarkTokens =
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
params.parsers.micromark.tokens;
|
|
14
22
|
const literalAutolinks = (tokens) => (
|
|
15
23
|
filterByPredicate(
|
|
16
24
|
tokens,
|
|
17
|
-
(token) =>
|
|
25
|
+
(token) => {
|
|
26
|
+
if ((token.type === "literalAutolink") && !inHtmlFlow(token)) {
|
|
27
|
+
// Detect and ignore https://github.com/micromark/micromark/issues/164
|
|
28
|
+
const siblings = token.parent?.children;
|
|
29
|
+
// Commented-out due to not being able to exercise in test/code coverage
|
|
30
|
+
// || micromarkTokens;
|
|
31
|
+
const index = siblings?.indexOf(token);
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
const prev = siblings?.at(index - 1);
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
const next = siblings?.at(index + 1);
|
|
36
|
+
return !(
|
|
37
|
+
prev &&
|
|
38
|
+
next &&
|
|
39
|
+
(prev.type === "data") &&
|
|
40
|
+
(next.type === "data") &&
|
|
41
|
+
prev.text.endsWith("<") &&
|
|
42
|
+
next.text.startsWith(">")
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
},
|
|
18
47
|
(token) => {
|
|
19
48
|
const { children } = token;
|
|
20
49
|
const result = [];
|
|
@@ -46,10 +75,7 @@ module.exports = {
|
|
|
46
75
|
}
|
|
47
76
|
)
|
|
48
77
|
);
|
|
49
|
-
const autoLinks = filterByTypes(
|
|
50
|
-
params.parsers.micromark.tokens,
|
|
51
|
-
[ "literalAutolink" ]
|
|
52
|
-
);
|
|
78
|
+
const autoLinks = filterByTypes(micromarkTokens, [ "literalAutolink" ]);
|
|
53
79
|
if (autoLinks.length > 0) {
|
|
54
80
|
// Re-parse with correct link/image reference definition handling
|
|
55
81
|
const document = params.lines.join("\n");
|
package/lib/md035.js
CHANGED
|
@@ -5,14 +5,21 @@
|
|
|
5
5
|
const { addErrorDetailIf } = require("../helpers");
|
|
6
6
|
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
7
7
|
|
|
8
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
9
|
+
/** @type import("./markdownlint").Rule */
|
|
8
10
|
module.exports = {
|
|
9
11
|
"names": [ "MD035", "hr-style" ],
|
|
10
12
|
"description": "Horizontal rule style",
|
|
11
13
|
"tags": [ "hr" ],
|
|
14
|
+
"parser": "micromark",
|
|
12
15
|
"function": function MD035(params, onError) {
|
|
13
16
|
let style = String(params.config.style || "consistent").trim();
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
18
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
19
|
+
const micromarkTokens =
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
params.parsers.micromark.tokens;
|
|
22
|
+
const thematicBreaks = filterByTypes(micromarkTokens, [ "thematicBreak" ]);
|
|
16
23
|
for (const token of thematicBreaks) {
|
|
17
24
|
const { startLine, text } = token;
|
|
18
25
|
if (style === "consistent") {
|
package/lib/md036.js
CHANGED
|
@@ -3,54 +3,48 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
5
|
const { addErrorContext, allPunctuation } = require("../helpers");
|
|
6
|
+
const { filterByTypes, matchAndGetTokensByType } = require("../helpers/micromark.cjs");
|
|
6
7
|
|
|
8
|
+
/** @typedef {import("../helpers/micromark.cjs").TokenType} TokenType */
|
|
9
|
+
/** @type {Map<TokenType, TokenType[]>} */
|
|
10
|
+
const emphasisAndChildrenTypes = new Map([
|
|
11
|
+
[ "emphasis", [ "emphasisSequence", "emphasisText", "emphasisSequence" ] ],
|
|
12
|
+
[ "strong", [ "strongSequence", "strongText", "strongSequence" ] ]
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
16
|
+
/** @type import("./markdownlint").Rule */
|
|
7
17
|
module.exports = {
|
|
8
18
|
"names": [ "MD036", "no-emphasis-as-heading" ],
|
|
9
19
|
"description": "Emphasis used instead of a heading",
|
|
10
20
|
"tags": [ "headings", "emphasis" ],
|
|
21
|
+
"parser": "micromark",
|
|
11
22
|
"function": function MD036(params, onError) {
|
|
12
23
|
let punctuation = params.config.punctuation;
|
|
13
|
-
punctuation =
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} else if (token.type === "blockquote_open") {
|
|
35
|
-
return function inBlockquote(t) {
|
|
36
|
-
if (t.type !== "blockquote_close") {
|
|
37
|
-
return inBlockquote;
|
|
24
|
+
punctuation = String((punctuation === undefined) ? allPunctuation : punctuation);
|
|
25
|
+
const punctuationRe = new RegExp("[" + punctuation + "]$");
|
|
26
|
+
const paragraphTokens =
|
|
27
|
+
filterByTypes(params.parsers.micromark.tokens, [ "paragraph" ]).
|
|
28
|
+
filter((token) =>
|
|
29
|
+
(token.parent?.type === "content") && !token.parent?.parent && (token.children.length === 1)
|
|
30
|
+
);
|
|
31
|
+
for (const paragraphToken of paragraphTokens) {
|
|
32
|
+
const childToken = paragraphToken.children[0];
|
|
33
|
+
for (const [ emphasisType, emphasisChildrenTypes ] of emphasisAndChildrenTypes) {
|
|
34
|
+
if (childToken.type === emphasisType) {
|
|
35
|
+
const matchingTokens = matchAndGetTokensByType(childToken.children, emphasisChildrenTypes);
|
|
36
|
+
if (matchingTokens) {
|
|
37
|
+
const textToken = matchingTokens[1];
|
|
38
|
+
if (
|
|
39
|
+
(textToken.children.length === 1) &&
|
|
40
|
+
(textToken.children[0].type === "data") &&
|
|
41
|
+
!punctuationRe.test(textToken.text)
|
|
42
|
+
) {
|
|
43
|
+
addErrorContext(onError, textToken.startLine, textToken.text);
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
} else if (token.type === "list_item_open") {
|
|
42
|
-
return function inListItem(t) {
|
|
43
|
-
if (t.type !== "list_item_close") {
|
|
44
|
-
return inListItem;
|
|
45
|
-
}
|
|
46
|
-
return base;
|
|
47
|
-
};
|
|
46
|
+
}
|
|
48
47
|
}
|
|
49
|
-
return base;
|
|
50
|
-
}
|
|
51
|
-
let state = base;
|
|
52
|
-
for (const token of params.parsers.markdownit.tokens) {
|
|
53
|
-
state = state(token);
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
};
|
package/lib/md037.js
CHANGED
|
@@ -5,20 +5,28 @@
|
|
|
5
5
|
const { addError } = require("../helpers");
|
|
6
6
|
const { filterByPredicate, inHtmlFlow } = require("../helpers/micromark.cjs");
|
|
7
7
|
|
|
8
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
9
|
+
/** @type import("./markdownlint").Rule */
|
|
8
10
|
module.exports = {
|
|
9
11
|
"names": [ "MD037", "no-space-in-emphasis" ],
|
|
10
12
|
"description": "Spaces inside emphasis markers",
|
|
11
13
|
"tags": [ "whitespace", "emphasis" ],
|
|
14
|
+
"parser": "micromark",
|
|
12
15
|
"function": function MD037(params, onError) {
|
|
13
16
|
|
|
14
17
|
// Initialize variables
|
|
15
|
-
|
|
18
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
19
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
20
|
+
const micromarkTokens =
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
params.parsers.micromark.tokens;
|
|
23
|
+
const { lines } = params;
|
|
16
24
|
const emphasisTokensByMarker = new Map();
|
|
17
25
|
for (const marker of [ "_", "__", "___", "*", "**", "***" ]) {
|
|
18
26
|
emphasisTokensByMarker.set(marker, []);
|
|
19
27
|
}
|
|
20
28
|
const tokens = filterByPredicate(
|
|
21
|
-
|
|
29
|
+
micromarkTokens,
|
|
22
30
|
(token) => token.children.some((child) => child.type === "data")
|
|
23
31
|
);
|
|
24
32
|
for (const token of tokens) {
|
package/lib/md038.js
CHANGED
|
@@ -19,14 +19,21 @@ const trimCodeText = (text, start, end) => {
|
|
|
19
19
|
return text;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
23
|
+
/** @type import("./markdownlint").Rule */
|
|
22
24
|
module.exports = {
|
|
23
25
|
"names": [ "MD038", "no-space-in-code" ],
|
|
24
26
|
"description": "Spaces inside code span elements",
|
|
25
27
|
"tags": [ "whitespace", "code" ],
|
|
28
|
+
"parser": "micromark",
|
|
26
29
|
"function": function MD038(params, onError) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
31
|
+
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
32
|
+
const micromarkTokens =
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
params.parsers.micromark.tokens;
|
|
35
|
+
const codeTexts = filterByTypes(micromarkTokens, [ "codeText" ])
|
|
36
|
+
.filter((codeText) => !inHtmlFlow(codeText));
|
|
30
37
|
for (const codeText of codeTexts) {
|
|
31
38
|
const { children } = codeText;
|
|
32
39
|
const first = 0;
|
package/lib/md039.js
CHANGED
|
@@ -7,10 +7,13 @@ const { addErrorContext, filterTokens } = require("../helpers");
|
|
|
7
7
|
const spaceInLinkRe =
|
|
8
8
|
/\[(?:\s[^\]]*|[^\]]*?\s)\](?=(\([^)]*\)|\[[^\]]*\]))/;
|
|
9
9
|
|
|
10
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
11
|
+
/** @type import("./markdownlint").Rule */
|
|
10
12
|
module.exports = {
|
|
11
13
|
"names": [ "MD039", "no-space-in-links" ],
|
|
12
14
|
"description": "Spaces inside link text",
|
|
13
15
|
"tags": [ "whitespace", "links" ],
|
|
16
|
+
"parser": "markdownit",
|
|
14
17
|
"function": function MD039(params, onError) {
|
|
15
18
|
filterTokens(params, "inline", (token) => {
|
|
16
19
|
const { children } = token;
|
|
@@ -33,6 +36,7 @@ module.exports = {
|
|
|
33
36
|
let fixInfo = null;
|
|
34
37
|
const match = line.slice(lineIndex).match(spaceInLinkRe);
|
|
35
38
|
if (match) {
|
|
39
|
+
// @ts-ignore
|
|
36
40
|
const column = match.index + lineIndex + 1;
|
|
37
41
|
const length = match[0].length;
|
|
38
42
|
range = [ column, length ];
|