markdownlint 0.34.0 → 0.36.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 +21 -0
- package/README.md +97 -45
- package/demo/markdownlint-browser.js +2186 -2164
- package/doc/CustomRules.md +66 -255
- package/doc/Rules.md +102 -29
- package/doc/md003.md +2 -2
- package/doc/md004.md +4 -3
- package/doc/md034.md +5 -0
- package/doc/md035.md +3 -8
- package/doc/md044.md +10 -0
- package/doc/md046.md +2 -2
- package/doc/md048.md +3 -2
- package/doc/md049.md +4 -3
- package/doc/md050.md +4 -4
- package/doc/md051.md +11 -3
- package/doc/md055.md +3 -2
- package/doc/md058.md +48 -0
- package/helpers/README.md +2 -45
- package/helpers/helpers.js +115 -607
- package/helpers/micromark-helpers.cjs +296 -0
- package/helpers/micromark-parse.cjs +313 -0
- package/helpers/package.json +5 -2
- package/helpers/shared.js +6 -0
- package/helpers/test.cjs +28 -0
- package/lib/cache.js +62 -13
- package/lib/configuration-strict.d.ts +1199 -0
- package/lib/configuration.d.ts +3 -1173
- package/lib/constants.js +3 -2
- package/lib/markdownit.cjs +172 -0
- package/lib/markdownlint.d.ts +103 -56
- package/lib/markdownlint.js +180 -120
- package/lib/md001.js +15 -9
- package/lib/md003.js +14 -9
- package/lib/md004.js +55 -48
- package/lib/md005.js +4 -13
- package/lib/md007.js +7 -11
- package/lib/md009.js +50 -44
- package/lib/md010.js +52 -33
- package/lib/md011.js +32 -23
- package/lib/md012.js +17 -9
- package/lib/md013.js +44 -38
- package/lib/md014.js +31 -38
- package/lib/md018.js +17 -9
- package/lib/md019-md021.js +80 -0
- package/lib/md020.js +14 -8
- package/lib/md022.js +13 -29
- package/lib/md023.js +22 -23
- package/lib/md024.js +12 -9
- package/lib/md025.js +15 -10
- package/lib/md026.js +2 -7
- package/lib/md027.js +7 -12
- package/lib/md028.js +3 -8
- package/lib/md029.js +40 -34
- package/lib/md030.js +4 -10
- package/lib/md031.js +45 -23
- package/lib/md032.js +33 -31
- package/lib/md033.js +3 -8
- package/lib/md034.js +21 -34
- package/lib/md035.js +2 -7
- package/lib/md036.js +19 -24
- package/lib/md037.js +3 -8
- package/lib/md038.js +11 -22
- package/lib/md039.js +64 -54
- package/lib/md040.js +13 -20
- package/lib/md041.js +5 -5
- package/lib/md042.js +44 -38
- package/lib/md043.js +20 -14
- package/lib/md044.js +34 -36
- package/lib/md045.js +5 -10
- package/lib/md046.js +2 -8
- package/lib/md048.js +30 -23
- package/lib/md049-md050.js +22 -12
- package/lib/md051.js +20 -28
- package/lib/md052.js +2 -2
- package/lib/md053.js +7 -6
- package/lib/md054.js +16 -23
- package/lib/md055.js +41 -49
- package/lib/md056.js +32 -33
- package/lib/md058.js +58 -0
- package/lib/rules.js +11 -4
- package/package.json +23 -20
- package/schema/.markdownlint.jsonc +58 -52
- package/schema/.markdownlint.yaml +56 -51
- package/schema/ValidatingConfiguration.md +6 -8
- package/schema/markdownlint-config-schema-strict.json +1841 -0
- package/schema/markdownlint-config-schema.json +141 -109
- package/style/prettier.json +1 -0
- package/helpers/micromark.cjs +0 -445
- package/lib/md019.js +0 -42
- package/lib/md021.js +0 -65
package/lib/md005.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
5
|
const { addError, addErrorDetailIf } = require("../helpers");
|
|
6
|
-
const {
|
|
6
|
+
const { filterByTypesCached } = require("./cache");
|
|
7
7
|
|
|
8
8
|
// eslint-disable-next-line jsdoc/valid-types
|
|
9
9
|
/** @type import("./markdownlint").Rule */
|
|
@@ -13,16 +13,7 @@ module.exports = {
|
|
|
13
13
|
"tags": [ "bullet", "ul", "indentation" ],
|
|
14
14
|
"parser": "micromark",
|
|
15
15
|
"function": function MD005(params, onError) {
|
|
16
|
-
|
|
17
|
-
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
18
|
-
const micromarkTokens =
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
params.parsers.micromark.tokens;
|
|
21
|
-
const lists = filterByTypes(
|
|
22
|
-
micromarkTokens,
|
|
23
|
-
[ "listOrdered", "listUnordered" ]
|
|
24
|
-
).filter((list) => !inHtmlFlow(list));
|
|
25
|
-
for (const list of lists) {
|
|
16
|
+
for (const list of filterByTypesCached([ "listOrdered", "listUnordered" ])) {
|
|
26
17
|
const expectedIndent = list.startColumn - 1;
|
|
27
18
|
let expectedEnd = 0;
|
|
28
19
|
let endMatching = false;
|
|
@@ -38,8 +29,8 @@ module.exports = {
|
|
|
38
29
|
lineNumber,
|
|
39
30
|
expectedIndent,
|
|
40
31
|
actualIndent,
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
undefined,
|
|
33
|
+
undefined,
|
|
43
34
|
range
|
|
44
35
|
// No fixInfo; MD007 handles this scenario better
|
|
45
36
|
);
|
package/lib/md007.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
5
|
const { addErrorDetailIf } = require("../helpers");
|
|
6
|
-
const {
|
|
7
|
-
|
|
6
|
+
const { getParentOfType } = require("../helpers/micromark-helpers.cjs");
|
|
7
|
+
const { filterByTypesCached } = require("./cache");
|
|
8
8
|
|
|
9
9
|
// eslint-disable-next-line jsdoc/valid-types
|
|
10
10
|
/** @type import("markdownlint-micromark").TokenType[] */
|
|
@@ -26,24 +26,20 @@ module.exports = {
|
|
|
26
26
|
const indent = Number(params.config.indent || 2);
|
|
27
27
|
const startIndented = !!params.config.start_indented;
|
|
28
28
|
const startIndent = Number(params.config.start_indent || indent);
|
|
29
|
-
// eslint-disable-next-line jsdoc/valid-types
|
|
30
|
-
/** @type import("../helpers/micromark.cjs").Token[] */
|
|
31
|
-
const micromarkTokens =
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
params.parsers.micromark.tokens;
|
|
34
29
|
const unorderedListNesting = new Map();
|
|
35
30
|
let lastBlockQuotePrefix = null;
|
|
36
|
-
const tokens =
|
|
31
|
+
const tokens = filterByTypesCached(unorderedListTypes);
|
|
37
32
|
for (const token of tokens) {
|
|
38
33
|
const { endColumn, parent, startColumn, startLine, type } = token;
|
|
39
34
|
if (type === "blockQuotePrefix") {
|
|
40
35
|
lastBlockQuotePrefix = token;
|
|
41
36
|
} else if (type === "listUnordered") {
|
|
42
37
|
let nesting = 0;
|
|
43
|
-
/** @type {import("../helpers/micromark.cjs").Token | null} */
|
|
38
|
+
/** @type {import("../helpers/micromark-helpers.cjs").Token | null} */
|
|
44
39
|
let current = token;
|
|
45
40
|
while (
|
|
46
|
-
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
(current = getParentOfType(current, unorderedParentTypes))
|
|
47
43
|
) {
|
|
48
44
|
if (current.type === "listUnordered") {
|
|
49
45
|
nesting++;
|
|
@@ -57,7 +53,7 @@ module.exports = {
|
|
|
57
53
|
if (nesting >= 0) {
|
|
58
54
|
unorderedListNesting.set(token, nesting);
|
|
59
55
|
}
|
|
60
|
-
} else
|
|
56
|
+
} else {
|
|
61
57
|
// listItemPrefix
|
|
62
58
|
const nesting = unorderedListNesting.get(parent);
|
|
63
59
|
if (nesting !== undefined) {
|
package/lib/md009.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError
|
|
6
|
-
|
|
7
|
-
const {
|
|
5
|
+
const { addError } = require("../helpers");
|
|
6
|
+
const { addRangeToSet } = require("../helpers/micromark-helpers.cjs");
|
|
7
|
+
const { filterByTypesCached } = require("./cache");
|
|
8
8
|
|
|
9
9
|
// eslint-disable-next-line jsdoc/valid-types
|
|
10
10
|
/** @type import("./markdownlint").Rule */
|
|
@@ -12,63 +12,68 @@ module.exports = {
|
|
|
12
12
|
"names": [ "MD009", "no-trailing-spaces" ],
|
|
13
13
|
"description": "Trailing spaces",
|
|
14
14
|
"tags": [ "whitespace" ],
|
|
15
|
-
"parser": "
|
|
15
|
+
"parser": "micromark",
|
|
16
16
|
"function": function MD009(params, onError) {
|
|
17
17
|
let brSpaces = params.config.br_spaces;
|
|
18
18
|
brSpaces = Number((brSpaces === undefined) ? 2 : brSpaces);
|
|
19
19
|
const listItemEmptyLines = !!params.config.list_item_empty_lines;
|
|
20
20
|
const strict = !!params.config.strict;
|
|
21
|
-
const
|
|
21
|
+
const codeBlockLineNumbers = new Set();
|
|
22
|
+
for (const codeBlock of filterByTypesCached([ "codeFenced" ])) {
|
|
23
|
+
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine + 1, codeBlock.endLine - 1);
|
|
24
|
+
}
|
|
25
|
+
for (const codeBlock of filterByTypesCached([ "codeIndented" ])) {
|
|
26
|
+
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
|
27
|
+
}
|
|
28
|
+
const listItemLineNumbers = new Set();
|
|
22
29
|
if (listItemEmptyLines) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
for (const listBlock of filterByTypesCached([ "listOrdered", "listUnordered" ])) {
|
|
31
|
+
addRangeToSet(listItemLineNumbers, listBlock.startLine, listBlock.endLine);
|
|
32
|
+
let trailingIndent = true;
|
|
33
|
+
for (let i = listBlock.children.length - 1; i >= 0; i--) {
|
|
34
|
+
const child = listBlock.children[i];
|
|
35
|
+
switch (child.type) {
|
|
36
|
+
case "content":
|
|
37
|
+
trailingIndent = false;
|
|
38
|
+
break;
|
|
39
|
+
case "listItemIndent":
|
|
40
|
+
if (trailingIndent) {
|
|
41
|
+
listItemLineNumbers.delete(child.startLine);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case "listItemPrefix":
|
|
45
|
+
trailingIndent = true;
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
26
50
|
}
|
|
27
|
-
}
|
|
28
|
-
listItemLineNumbers.sort(numericSortAscending);
|
|
51
|
+
}
|
|
29
52
|
}
|
|
30
|
-
const paragraphLineNumbers =
|
|
31
|
-
const codeInlineLineNumbers =
|
|
53
|
+
const paragraphLineNumbers = new Set();
|
|
54
|
+
const codeInlineLineNumbers = new Set();
|
|
32
55
|
if (strict) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
for (let i = start; i < end; i++) {
|
|
40
|
-
codeInlineLineNumbers.push(i);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
filterTokens(params, "inline", (token) => {
|
|
44
|
-
let start = 0;
|
|
45
|
-
for (const child of token.children) {
|
|
46
|
-
if (start > 0) {
|
|
47
|
-
addLineNumberRange(start, child.lineNumber);
|
|
48
|
-
start = 0;
|
|
49
|
-
}
|
|
50
|
-
if (child.type === "code_inline") {
|
|
51
|
-
start = child.lineNumber;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (start > 0) {
|
|
55
|
-
addLineNumberRange(start, token.map[1]);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
56
|
+
for (const paragraph of filterByTypesCached([ "paragraph" ])) {
|
|
57
|
+
addRangeToSet(paragraphLineNumbers, paragraph.startLine, paragraph.endLine - 1);
|
|
58
|
+
}
|
|
59
|
+
for (const codeText of filterByTypesCached([ "codeText" ])) {
|
|
60
|
+
addRangeToSet(codeInlineLineNumbers, codeText.startLine, codeText.endLine - 1);
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
const expected = (brSpaces < 2) ? 0 : brSpaces;
|
|
60
|
-
|
|
64
|
+
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) {
|
|
65
|
+
const line = params.lines[lineIndex];
|
|
61
66
|
const lineNumber = lineIndex + 1;
|
|
62
67
|
const trailingSpaces = line.length - line.trimEnd().length;
|
|
63
68
|
if (
|
|
64
69
|
trailingSpaces &&
|
|
65
|
-
!
|
|
66
|
-
!
|
|
70
|
+
!codeBlockLineNumbers.has(lineNumber) &&
|
|
71
|
+
!listItemLineNumbers.has(lineNumber) &&
|
|
67
72
|
(
|
|
68
73
|
(expected !== trailingSpaces) ||
|
|
69
74
|
(strict &&
|
|
70
|
-
(!
|
|
71
|
-
|
|
75
|
+
(!paragraphLineNumbers.has(lineNumber) ||
|
|
76
|
+
codeInlineLineNumbers.has(lineNumber)))
|
|
72
77
|
)
|
|
73
78
|
) {
|
|
74
79
|
const column = line.length - trailingSpaces + 1;
|
|
@@ -82,8 +87,9 @@ module.exports = {
|
|
|
82
87
|
{
|
|
83
88
|
"editColumn": column,
|
|
84
89
|
"deleteCount": trailingSpaces
|
|
85
|
-
}
|
|
90
|
+
}
|
|
91
|
+
);
|
|
86
92
|
}
|
|
87
|
-
}
|
|
93
|
+
}
|
|
88
94
|
}
|
|
89
95
|
};
|
package/lib/md010.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError,
|
|
6
|
-
|
|
7
|
-
const {
|
|
5
|
+
const { addError, hasOverlap } = require("../helpers");
|
|
6
|
+
const { getDescendantsByType } = require("../helpers/micromark-helpers.cjs");
|
|
7
|
+
const { filterByTypesCached } = require("./cache");
|
|
8
8
|
|
|
9
9
|
const tabRe = /\t+/g;
|
|
10
10
|
|
|
@@ -14,7 +14,7 @@ module.exports = {
|
|
|
14
14
|
"names": [ "MD010", "no-hard-tabs" ],
|
|
15
15
|
"description": "Hard tabs",
|
|
16
16
|
"tags": [ "whitespace", "hard_tab" ],
|
|
17
|
-
"parser": "
|
|
17
|
+
"parser": "micromark",
|
|
18
18
|
"function": function MD010(params, onError) {
|
|
19
19
|
const codeBlocks = params.config.code_blocks;
|
|
20
20
|
const includeCode = (codeBlocks === undefined) ? true : !!codeBlocks;
|
|
@@ -26,38 +26,57 @@ module.exports = {
|
|
|
26
26
|
const spaceMultiplier = (spacesPerTab === undefined) ?
|
|
27
27
|
1 :
|
|
28
28
|
Math.max(0, Number(spacesPerTab));
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
// eslint-disable-next-line jsdoc/valid-types
|
|
30
|
+
/** @type import("../helpers/micromark-helpers.cjs").TokenType[] */
|
|
31
|
+
const exclusionTypes = [];
|
|
32
|
+
if (includeCode) {
|
|
33
|
+
if (ignoreCodeLanguages.size > 0) {
|
|
34
|
+
exclusionTypes.push("codeFenced");
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
exclusionTypes.push("codeFenced", "codeIndented", "codeText");
|
|
38
|
+
}
|
|
39
|
+
const codeTokens = filterByTypesCached(exclusionTypes).filter((token) => {
|
|
40
|
+
if ((token.type === "codeFenced") && (ignoreCodeLanguages.size > 0)) {
|
|
41
|
+
const fenceInfos = getDescendantsByType(token, [ "codeFencedFence", "codeFencedFenceInfo" ]);
|
|
42
|
+
return fenceInfos.every((fenceInfo) => ignoreCodeLanguages.has(fenceInfo.text.toLowerCase()));
|
|
36
43
|
}
|
|
44
|
+
return true;
|
|
37
45
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
const codeRanges = codeTokens.map((token) => {
|
|
47
|
+
const { type, startLine, startColumn, endLine, endColumn } = token;
|
|
48
|
+
const codeFenced = (type === "codeFenced");
|
|
49
|
+
return {
|
|
50
|
+
"startLine": startLine + (codeFenced ? 1 : 0),
|
|
51
|
+
"startColumn": codeFenced ? 0 : startColumn,
|
|
52
|
+
"endLine": endLine - (codeFenced ? 1 : 0),
|
|
53
|
+
"endColumn": codeFenced ? Number.MAX_SAFE_INTEGER : endColumn
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) {
|
|
57
|
+
const line = params.lines[lineIndex];
|
|
58
|
+
let match = null;
|
|
59
|
+
while ((match = tabRe.exec(line)) !== null) {
|
|
60
|
+
const lineNumber = lineIndex + 1;
|
|
61
|
+
const column = match.index + 1;
|
|
62
|
+
const length = match[0].length;
|
|
63
|
+
/** @type {import("../helpers").FileRange} */
|
|
64
|
+
const range = { "startLine": lineNumber, "startColumn": column, "endLine": lineNumber, "endColumn": column + length - 1 };
|
|
65
|
+
if (!codeRanges.some((codeRange) => hasOverlap(codeRange, range))) {
|
|
66
|
+
addError(
|
|
67
|
+
onError,
|
|
68
|
+
lineNumber,
|
|
69
|
+
"Column: " + column,
|
|
70
|
+
undefined,
|
|
71
|
+
[ column, length ],
|
|
72
|
+
{
|
|
73
|
+
"editColumn": column,
|
|
74
|
+
"deleteCount": length,
|
|
75
|
+
"insertText": "".padEnd(length * spaceMultiplier)
|
|
76
|
+
}
|
|
77
|
+
);
|
|
59
78
|
}
|
|
60
79
|
}
|
|
61
|
-
}
|
|
80
|
+
}
|
|
62
81
|
}
|
|
63
82
|
};
|
package/lib/md011.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError,
|
|
6
|
-
const {
|
|
5
|
+
const { addError, hasOverlap } = require("../helpers");
|
|
6
|
+
const { addRangeToSet } = require("../helpers/micromark-helpers.cjs");
|
|
7
|
+
const { filterByTypesCached } = require("./cache");
|
|
7
8
|
|
|
8
9
|
const reversedLinkRe =
|
|
9
10
|
/(^|[^\\])\(([^()]+)\)\[([^\]^][^\]]*)\](?!\()/g;
|
|
@@ -14,36 +15,44 @@ module.exports = {
|
|
|
14
15
|
"names": [ "MD011", "no-reversed-links" ],
|
|
15
16
|
"description": "Reversed link syntax",
|
|
16
17
|
"tags": [ "links" ],
|
|
17
|
-
"parser": "
|
|
18
|
+
"parser": "micromark",
|
|
18
19
|
"function": function MD011(params, onError) {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const codeBlockLineNumbers = new Set();
|
|
21
|
+
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
|
22
|
+
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
|
23
|
+
}
|
|
24
|
+
const codeTexts = filterByTypesCached([ "codeText" ]);
|
|
25
|
+
for (const [ lineIndex, line ] of params.lines.entries()) {
|
|
26
|
+
const lineNumber = lineIndex + 1;
|
|
27
|
+
if (!codeBlockLineNumbers.has(lineNumber)) {
|
|
22
28
|
let match = null;
|
|
23
29
|
while ((match = reversedLinkRe.exec(line)) !== null) {
|
|
24
30
|
const [ reversedLink, preChar, linkText, linkDestination ] = match;
|
|
25
|
-
const index = match.index + preChar.length;
|
|
26
|
-
const length = match[0].length - preChar.length;
|
|
27
31
|
if (
|
|
28
32
|
!linkText.endsWith("\\") &&
|
|
29
|
-
!linkDestination.endsWith("\\")
|
|
30
|
-
!withinAnyRange(exclusions, lineIndex, index, length)
|
|
33
|
+
!linkDestination.endsWith("\\")
|
|
31
34
|
) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
const column = match.index + preChar.length + 1;
|
|
36
|
+
const length = match[0].length - preChar.length;
|
|
37
|
+
/** @type {import("../helpers").FileRange} */
|
|
38
|
+
const range = { "startLine": lineNumber, "startColumn": column, "endLine": lineNumber, "endColumn": column + length - 1 };
|
|
39
|
+
if (!codeTexts.some((codeText) => hasOverlap(codeText, range))) {
|
|
40
|
+
addError(
|
|
41
|
+
onError,
|
|
42
|
+
lineNumber,
|
|
43
|
+
reversedLink.slice(preChar.length),
|
|
44
|
+
undefined,
|
|
45
|
+
[ column, length ],
|
|
46
|
+
{
|
|
47
|
+
"editColumn": column,
|
|
48
|
+
"deleteCount": length,
|
|
49
|
+
"insertText": `[${linkText}](${linkDestination})`
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
44
53
|
}
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
|
-
}
|
|
56
|
+
}
|
|
48
57
|
}
|
|
49
58
|
};
|
package/lib/md012.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorDetailIf
|
|
6
|
-
const {
|
|
5
|
+
const { addErrorDetailIf } = require("../helpers");
|
|
6
|
+
const { addRangeToSet } = require("../helpers/micromark-helpers.cjs");
|
|
7
|
+
const { filterByTypesCached } = require("./cache");
|
|
7
8
|
|
|
8
9
|
// eslint-disable-next-line jsdoc/valid-types
|
|
9
10
|
/** @type import("./markdownlint").Rule */
|
|
@@ -11,11 +12,17 @@ module.exports = {
|
|
|
11
12
|
"names": [ "MD012", "no-multiple-blanks" ],
|
|
12
13
|
"description": "Multiple consecutive blank lines",
|
|
13
14
|
"tags": [ "whitespace", "blank_lines" ],
|
|
14
|
-
"parser": "
|
|
15
|
+
"parser": "micromark",
|
|
15
16
|
"function": function MD012(params, onError) {
|
|
16
17
|
const maximum = Number(params.config.maximum || 1);
|
|
18
|
+
const { lines } = params;
|
|
19
|
+
const codeBlockLineNumbers = new Set();
|
|
20
|
+
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
|
21
|
+
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
|
22
|
+
}
|
|
17
23
|
let count = 0;
|
|
18
|
-
|
|
24
|
+
for (const [ lineIndex, line ] of lines.entries()) {
|
|
25
|
+
const inCode = codeBlockLineNumbers.has(lineIndex + 1);
|
|
19
26
|
count = (inCode || (line.trim().length > 0)) ? 0 : count + 1;
|
|
20
27
|
if (maximum < count) {
|
|
21
28
|
addErrorDetailIf(
|
|
@@ -23,13 +30,14 @@ module.exports = {
|
|
|
23
30
|
lineIndex + 1,
|
|
24
31
|
maximum,
|
|
25
32
|
count,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
undefined,
|
|
34
|
+
undefined,
|
|
35
|
+
undefined,
|
|
29
36
|
{
|
|
30
37
|
"deleteCount": -1
|
|
31
|
-
}
|
|
38
|
+
}
|
|
39
|
+
);
|
|
32
40
|
}
|
|
33
|
-
}
|
|
41
|
+
}
|
|
34
42
|
}
|
|
35
43
|
};
|
package/lib/md013.js
CHANGED
|
@@ -2,25 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorDetailIf
|
|
6
|
-
|
|
7
|
-
const {
|
|
5
|
+
const { addErrorDetailIf } = require("../helpers");
|
|
6
|
+
const { getReferenceLinkImageData } = require("./cache");
|
|
7
|
+
const { addRangeToSet, getDescendantsByType } = require("../helpers/micromark-helpers.cjs");
|
|
8
|
+
const { filterByTypesCached } = require("./cache");
|
|
8
9
|
|
|
9
10
|
const longLineRePrefix = "^.{";
|
|
10
11
|
const longLineRePostfixRelaxed = "}.*\\s.*$";
|
|
11
12
|
const longLineRePostfixStrict = "}.+$";
|
|
12
|
-
const linkOrImageOnlyLineRe = /^[es]*(?:lT?L|I)[ES]*$/;
|
|
13
13
|
const sternModeRe = /^(?:[#>\s]*\s)?\S*$/;
|
|
14
|
-
const tokenTypeMap = {
|
|
15
|
-
"em_open": "e",
|
|
16
|
-
"em_close": "E",
|
|
17
|
-
"image": "I",
|
|
18
|
-
"link_open": "l",
|
|
19
|
-
"link_close": "L",
|
|
20
|
-
"strong_open": "s",
|
|
21
|
-
"strong_close": "S",
|
|
22
|
-
"text": "T"
|
|
23
|
-
};
|
|
24
14
|
|
|
25
15
|
// eslint-disable-next-line jsdoc/valid-types
|
|
26
16
|
/** @type import("./markdownlint").Rule */
|
|
@@ -28,7 +18,7 @@ module.exports = {
|
|
|
28
18
|
"names": [ "MD013", "line-length" ],
|
|
29
19
|
"description": "Line length",
|
|
30
20
|
"tags": [ "line_length" ],
|
|
31
|
-
"parser": "
|
|
21
|
+
"parser": "micromark",
|
|
32
22
|
"function": function MD013(params, onError) {
|
|
33
23
|
const lineLength = Number(params.config.line_length || 80);
|
|
34
24
|
const headingLineLength =
|
|
@@ -51,26 +41,41 @@ module.exports = {
|
|
|
51
41
|
const includeTables = (tables === undefined) ? true : !!tables;
|
|
52
42
|
const headings = params.config.headings;
|
|
53
43
|
const includeHeadings = (headings === undefined) ? true : !!headings;
|
|
54
|
-
const headingLineNumbers =
|
|
55
|
-
|
|
56
|
-
headingLineNumbers.
|
|
57
|
-
}
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
44
|
+
const headingLineNumbers = new Set();
|
|
45
|
+
for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
|
|
46
|
+
addRangeToSet(headingLineNumbers, heading.startLine, heading.endLine);
|
|
47
|
+
}
|
|
48
|
+
const codeBlockLineNumbers = new Set();
|
|
49
|
+
for (const codeBlock of filterByTypesCached([ "codeFenced", "codeIndented" ])) {
|
|
50
|
+
addRangeToSet(codeBlockLineNumbers, codeBlock.startLine, codeBlock.endLine);
|
|
51
|
+
}
|
|
52
|
+
const tableLineNumbers = new Set();
|
|
53
|
+
for (const table of filterByTypesCached([ "table" ])) {
|
|
54
|
+
addRangeToSet(tableLineNumbers, table.startLine, table.endLine);
|
|
55
|
+
}
|
|
56
|
+
const linkLineNumbers = new Set();
|
|
57
|
+
for (const link of filterByTypesCached([ "autolink", "image", "link", "literalAutolink" ])) {
|
|
58
|
+
addRangeToSet(linkLineNumbers, link.startLine, link.endLine);
|
|
59
|
+
}
|
|
60
|
+
const paragraphDataLineNumbers = new Set();
|
|
61
|
+
for (const paragraph of filterByTypesCached([ "paragraph" ])) {
|
|
62
|
+
for (const data of getDescendantsByType(paragraph, [ "data" ])) {
|
|
63
|
+
addRangeToSet(paragraphDataLineNumbers, data.startLine, data.endLine);
|
|
65
64
|
}
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
}
|
|
66
|
+
const linkOnlyLineNumbers = new Set();
|
|
67
|
+
for (const lineNumber of linkLineNumbers) {
|
|
68
|
+
if (!paragraphDataLineNumbers.has(lineNumber)) {
|
|
69
|
+
linkOnlyLineNumbers.add(lineNumber);
|
|
68
70
|
}
|
|
69
|
-
}
|
|
70
|
-
const
|
|
71
|
-
|
|
71
|
+
}
|
|
72
|
+
const definitionLineIndices = new Set(getReferenceLinkImageData().definitionLineIndices);
|
|
73
|
+
for (let lineIndex = 0; lineIndex < params.lines.length; lineIndex++) {
|
|
74
|
+
const line = params.lines[lineIndex];
|
|
72
75
|
const lineNumber = lineIndex + 1;
|
|
73
|
-
const isHeading =
|
|
76
|
+
const isHeading = headingLineNumbers.has(lineNumber);
|
|
77
|
+
const inCode = codeBlockLineNumbers.has(lineNumber);
|
|
78
|
+
const inTable = tableLineNumbers.has(lineNumber);
|
|
74
79
|
const length = inCode ?
|
|
75
80
|
codeLineLength :
|
|
76
81
|
(isHeading ? headingLineLength : lineLength);
|
|
@@ -80,20 +85,21 @@ module.exports = {
|
|
|
80
85
|
if ((includeCodeBlocks || !inCode) &&
|
|
81
86
|
(includeTables || !inTable) &&
|
|
82
87
|
(includeHeadings || !isHeading) &&
|
|
83
|
-
!
|
|
88
|
+
!definitionLineIndices.has(lineIndex) &&
|
|
84
89
|
(strict ||
|
|
85
90
|
(!(stern && sternModeRe.test(line)) &&
|
|
86
|
-
!
|
|
91
|
+
!linkOnlyLineNumbers.has(lineNumber))) &&
|
|
87
92
|
lengthRe.test(line)) {
|
|
88
93
|
addErrorDetailIf(
|
|
89
94
|
onError,
|
|
90
95
|
lineNumber,
|
|
91
96
|
length,
|
|
92
97
|
line.length,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
[ length + 1, line.length - length ]
|
|
98
|
+
undefined,
|
|
99
|
+
undefined,
|
|
100
|
+
[ length + 1, line.length - length ]
|
|
101
|
+
);
|
|
96
102
|
}
|
|
97
|
-
}
|
|
103
|
+
}
|
|
98
104
|
}
|
|
99
105
|
};
|