markdownlint 0.27.0 → 0.28.1
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 +382 -0
- package/CONTRIBUTING.md +4 -3
- package/LICENSE +1 -1
- package/README.md +1 -123
- package/demo/markdownlint-browser.js +4978 -3583
- package/doc/CustomRules.md +1 -4
- package/doc/Rules.md +22 -16
- package/doc/md034.md +21 -15
- package/doc/md051.md +1 -1
- package/helpers/LICENSE +1 -1
- package/helpers/helpers.js +106 -248
- package/helpers/micromark.cjs +209 -0
- package/helpers/package.json +4 -1
- package/lib/constants.js +1 -1
- package/lib/markdownlint.d.ts +16 -5
- package/lib/markdownlint.js +99 -46
- package/lib/md002.js +1 -1
- package/lib/md027.js +1 -1
- package/lib/md028.js +1 -1
- package/lib/md033.js +47 -40
- package/lib/md034.js +54 -72
- package/lib/md035.js +9 -11
- package/lib/md036.js +1 -1
- package/lib/md038.js +80 -55
- package/lib/md041.js +1 -1
- package/lib/md044.js +58 -44
- package/lib/md046.js +1 -1
- package/lib/md048.js +3 -1
- package/package.json +29 -24
- package/schema/.markdownlint.jsonc +1 -1
- package/schema/.markdownlint.yaml +3 -4
package/lib/md033.js
CHANGED
|
@@ -2,17 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const { codeBlockAndSpanRanges, lineMetadata, referenceLinkImageData } =
|
|
9
|
-
require("./cache");
|
|
5
|
+
const { addError } = require("../helpers");
|
|
6
|
+
const { filterByTypes, getHtmlTagInfo, parse } =
|
|
7
|
+
require("../helpers/micromark.cjs");
|
|
10
8
|
|
|
11
|
-
const
|
|
12
|
-
// See https://spec.commonmark.org/0.29/#autolinks
|
|
13
|
-
const emailAddressRe =
|
|
14
|
-
// eslint-disable-next-line max-len
|
|
15
|
-
/^[\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])?)*$/;
|
|
9
|
+
const nextLinesRe = /[\r\n][\s\S]*$/;
|
|
16
10
|
|
|
17
11
|
module.exports = {
|
|
18
12
|
"names": [ "MD033", "no-inline-html" ],
|
|
@@ -22,38 +16,51 @@ module.exports = {
|
|
|
22
16
|
let allowedElements = params.config.allowed_elements;
|
|
23
17
|
allowedElements = Array.isArray(allowedElements) ? allowedElements : [];
|
|
24
18
|
allowedElements = allowedElements.map((element) => element.toLowerCase());
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (!linkDestinationRe.test(prefix)) {
|
|
49
|
-
const unescaped = unescapeMarkdown(prefix + "<", "_");
|
|
50
|
-
if (!unescaped.endsWith("_")) {
|
|
51
|
-
addError(onError, lineIndex + 1, "Element: " + element,
|
|
52
|
-
undefined, [ match.index + 1, tag.length ]);
|
|
53
|
-
}
|
|
19
|
+
const pending = [ [ 0, params.parsers.micromark.tokens ] ];
|
|
20
|
+
let current = null;
|
|
21
|
+
while ((current = pending.shift())) {
|
|
22
|
+
const [ offset, tokens ] = current;
|
|
23
|
+
for (const token of filterByTypes(tokens, [ "htmlFlow", "htmlText" ])) {
|
|
24
|
+
if (token.type === "htmlText") {
|
|
25
|
+
const htmlTagInfo = getHtmlTagInfo(token);
|
|
26
|
+
if (
|
|
27
|
+
htmlTagInfo &&
|
|
28
|
+
!htmlTagInfo.close &&
|
|
29
|
+
!allowedElements.includes(htmlTagInfo.name.toLowerCase())
|
|
30
|
+
) {
|
|
31
|
+
const range = [
|
|
32
|
+
token.startColumn,
|
|
33
|
+
token.text.replace(nextLinesRe, "").length
|
|
34
|
+
];
|
|
35
|
+
addError(
|
|
36
|
+
onError,
|
|
37
|
+
token.startLine + offset,
|
|
38
|
+
"Element: " + htmlTagInfo.name,
|
|
39
|
+
undefined,
|
|
40
|
+
range
|
|
41
|
+
);
|
|
54
42
|
}
|
|
43
|
+
} else {
|
|
44
|
+
// token.type === "htmlFlow"
|
|
45
|
+
// Re-parse without "htmlFlow" to get only "htmlText" tokens
|
|
46
|
+
const options = {
|
|
47
|
+
"extensions": [
|
|
48
|
+
{
|
|
49
|
+
"disable": {
|
|
50
|
+
"null": [ "codeIndented", "htmlFlow" ]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
};
|
|
55
|
+
// Use lines instead of token.text for accurate columns
|
|
56
|
+
const lines =
|
|
57
|
+
params.lines.slice(token.startLine - 1, token.endLine).join("\n");
|
|
58
|
+
const flowTokens = parse(lines, options);
|
|
59
|
+
pending.push(
|
|
60
|
+
[ token.startLine - 1, flowTokens ]
|
|
61
|
+
);
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
|
-
}
|
|
64
|
+
}
|
|
58
65
|
}
|
|
59
66
|
};
|
package/lib/md034.js
CHANGED
|
@@ -2,85 +2,67 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorContext
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
require("./cache");
|
|
9
|
-
|
|
10
|
-
const htmlLinkRe = /<a(?:\s[^>]*)?>[^<>]*<\/a\s*>/gi;
|
|
5
|
+
const { addErrorContext } = require("../helpers");
|
|
6
|
+
const { filterByPredicate, getHtmlTagInfo } =
|
|
7
|
+
require("../helpers/micromark.cjs");
|
|
11
8
|
|
|
12
9
|
module.exports = {
|
|
13
10
|
"names": [ "MD034", "no-bare-urls" ],
|
|
14
11
|
"description": "Bare URL used",
|
|
15
12
|
"tags": [ "links", "url" ],
|
|
16
13
|
"function": function MD034(params, onError) {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// Allow >...</ to avoid reporting <code>...</code>
|
|
48
|
-
!(prefix.endsWith(">") && postfix.startsWith("</")) &&
|
|
49
|
-
// Allow "..." and '...' to allow quoting a bare link
|
|
50
|
-
!(prefix.endsWith("\"") && postfix.startsWith("\"")) &&
|
|
51
|
-
!(prefix.endsWith("'") && postfix.startsWith("'")) &&
|
|
52
|
-
// Allow ](... to avoid reporting Markdown-style links
|
|
53
|
-
!(/\]\(\s*$/.test(prefix)) &&
|
|
54
|
-
// Allow [...] to avoid MD011/no-reversed-links and nested links
|
|
55
|
-
!(/\[[^\]]*$/.test(prefix) && /^[^[]*\]/.test(postfix)) &&
|
|
56
|
-
!withinAnyRange(
|
|
57
|
-
lineExclusions, lineIndex, matchIndex, bareUrlLength
|
|
58
|
-
) &&
|
|
59
|
-
!withinAnyRange(
|
|
60
|
-
codeExclusions, lineIndex, matchIndex, bareUrlLength
|
|
61
|
-
)
|
|
62
|
-
) {
|
|
63
|
-
const range = [
|
|
64
|
-
matchIndex + 1,
|
|
65
|
-
bareUrlLength
|
|
66
|
-
];
|
|
67
|
-
const fixInfo = {
|
|
68
|
-
"editColumn": range[0],
|
|
69
|
-
"deleteCount": range[1],
|
|
70
|
-
"insertText": `<${bareUrl}>`
|
|
71
|
-
};
|
|
72
|
-
addErrorContext(
|
|
73
|
-
onError,
|
|
74
|
-
lineIndex + 1,
|
|
75
|
-
bareUrl,
|
|
76
|
-
null,
|
|
77
|
-
null,
|
|
78
|
-
range,
|
|
79
|
-
fixInfo
|
|
80
|
-
);
|
|
14
|
+
const literalAutolinks =
|
|
15
|
+
filterByPredicate(
|
|
16
|
+
params.parsers.micromark.tokens,
|
|
17
|
+
(token) => token.type === "literalAutolink",
|
|
18
|
+
(token) => {
|
|
19
|
+
const { children } = token;
|
|
20
|
+
const result = [];
|
|
21
|
+
for (let i = 0; i < children.length; i++) {
|
|
22
|
+
const openToken = children[i];
|
|
23
|
+
const openTagInfo = getHtmlTagInfo(openToken);
|
|
24
|
+
if (openTagInfo && !openTagInfo.close) {
|
|
25
|
+
let count = 1;
|
|
26
|
+
for (let j = i + 1; j < children.length; j++) {
|
|
27
|
+
const closeToken = children[j];
|
|
28
|
+
const closeTagInfo = getHtmlTagInfo(closeToken);
|
|
29
|
+
if (closeTagInfo && (openTagInfo.name === closeTagInfo.name)) {
|
|
30
|
+
if (closeTagInfo.close) {
|
|
31
|
+
count--;
|
|
32
|
+
if (count === 0) {
|
|
33
|
+
i = j;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
count++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
result.push(openToken);
|
|
43
|
+
}
|
|
81
44
|
}
|
|
82
|
-
|
|
83
|
-
|
|
45
|
+
return result;
|
|
46
|
+
});
|
|
47
|
+
for (const token of literalAutolinks) {
|
|
48
|
+
const range = [
|
|
49
|
+
token.startColumn,
|
|
50
|
+
token.endColumn - token.startColumn
|
|
51
|
+
];
|
|
52
|
+
const fixInfo = {
|
|
53
|
+
"editColumn": range[0],
|
|
54
|
+
"deleteCount": range[1],
|
|
55
|
+
"insertText": `<${token.text}>`
|
|
56
|
+
};
|
|
57
|
+
addErrorContext(
|
|
58
|
+
onError,
|
|
59
|
+
token.startLine,
|
|
60
|
+
token.text,
|
|
61
|
+
null,
|
|
62
|
+
null,
|
|
63
|
+
range,
|
|
64
|
+
fixInfo
|
|
65
|
+
);
|
|
84
66
|
}
|
|
85
67
|
}
|
|
86
68
|
};
|
package/lib/md035.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorDetailIf
|
|
5
|
+
const { addErrorDetailIf } = require("../helpers");
|
|
6
|
+
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
"names": [ "MD035", "hr-style" ],
|
|
@@ -10,17 +11,14 @@ module.exports = {
|
|
|
10
11
|
"tags": [ "hr" ],
|
|
11
12
|
"function": function MD035(params, onError) {
|
|
12
13
|
let style = String(params.config.style || "consistent").trim();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
if (match) {
|
|
18
|
-
markup = match[0].trim();
|
|
19
|
-
}
|
|
14
|
+
const thematicBreaks =
|
|
15
|
+
filterByTypes(params.parsers.micromark.tokens, [ "thematicBreak" ]);
|
|
16
|
+
for (const token of thematicBreaks) {
|
|
17
|
+
const { startLine, text } = token;
|
|
20
18
|
if (style === "consistent") {
|
|
21
|
-
style =
|
|
19
|
+
style = text;
|
|
22
20
|
}
|
|
23
|
-
addErrorDetailIf(onError,
|
|
24
|
-
}
|
|
21
|
+
addErrorDetailIf(onError, startLine, style, text);
|
|
22
|
+
}
|
|
25
23
|
}
|
|
26
24
|
};
|
package/lib/md036.js
CHANGED
package/lib/md038.js
CHANGED
|
@@ -2,70 +2,95 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorContext
|
|
6
|
-
|
|
5
|
+
const { addErrorContext } = require("../helpers");
|
|
6
|
+
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
7
7
|
|
|
8
8
|
const leftSpaceRe = /^\s(?:[^`]|$)/;
|
|
9
9
|
const rightSpaceRe = /[^`]\s$/;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
(
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const trimCodeText = (text, start, end) => {
|
|
11
|
+
text = text.replace(/^\s+$/, "");
|
|
12
|
+
if (start) {
|
|
13
|
+
text = text.replace(/^\s+?(\s`|\S)/, "$1");
|
|
14
|
+
}
|
|
15
|
+
if (end) {
|
|
16
|
+
text = text.replace(/(`\s|\S)\s+$/, "$1");
|
|
17
|
+
}
|
|
18
|
+
return text;
|
|
19
|
+
};
|
|
20
|
+
const tokenIfType = (token, type) => token && (token.type === type) && token;
|
|
15
21
|
|
|
16
22
|
module.exports = {
|
|
17
23
|
"names": [ "MD038", "no-space-in-code" ],
|
|
18
24
|
"description": "Spaces inside code span elements",
|
|
19
25
|
"tags": [ "whitespace", "code" ],
|
|
20
26
|
"function": function MD038(params, onError) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
27
|
+
const codeTextTokens =
|
|
28
|
+
filterByTypes(params.parsers.micromark.tokens, [ "codeText" ]);
|
|
29
|
+
for (const token of codeTextTokens) {
|
|
30
|
+
const { children } = token;
|
|
31
|
+
const first = 0;
|
|
32
|
+
const last = children.length - 1;
|
|
33
|
+
const startSequence = tokenIfType(children[first], "codeTextSequence");
|
|
34
|
+
const endSequence = tokenIfType(children[last], "codeTextSequence");
|
|
35
|
+
const startData =
|
|
36
|
+
tokenIfType(children[first + 1], "codeTextData") ||
|
|
37
|
+
tokenIfType(children[first + 2], "codeTextData");
|
|
38
|
+
const endData =
|
|
39
|
+
tokenIfType(children[last - 1], "codeTextData") ||
|
|
40
|
+
tokenIfType(children[last - 2], "codeTextData");
|
|
41
|
+
if (startSequence && endSequence && startData && endData) {
|
|
42
|
+
const spaceLeft = leftSpaceRe.test(startData.text);
|
|
43
|
+
const spaceRight = !spaceLeft && rightSpaceRe.test(endData.text);
|
|
44
|
+
if (spaceLeft || spaceRight) {
|
|
45
|
+
let lineNumber = startSequence.startLine;
|
|
46
|
+
let range = null;
|
|
47
|
+
let fixInfo = null;
|
|
48
|
+
if (startSequence.startLine === endSequence.endLine) {
|
|
49
|
+
range = [
|
|
50
|
+
startSequence.startColumn,
|
|
51
|
+
endSequence.endColumn - startSequence.startColumn
|
|
52
|
+
];
|
|
53
|
+
fixInfo = {
|
|
54
|
+
"editColumn": startSequence.endColumn,
|
|
55
|
+
"deleteCount": endSequence.startColumn - startSequence.endColumn,
|
|
56
|
+
"insertText": trimCodeText(startData.text, true, true)
|
|
57
|
+
};
|
|
58
|
+
} else if (spaceLeft) {
|
|
59
|
+
range = [
|
|
60
|
+
startSequence.startColumn,
|
|
61
|
+
startData.endColumn - startSequence.startColumn
|
|
62
|
+
];
|
|
63
|
+
fixInfo = {
|
|
64
|
+
"editColumn": startSequence.endColumn,
|
|
65
|
+
"deleteCount": startData.endColumn - startData.startColumn,
|
|
66
|
+
"insertText": trimCodeText(startData.text, true, false)
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
lineNumber = endSequence.endLine;
|
|
70
|
+
range = [
|
|
71
|
+
endData.startColumn,
|
|
72
|
+
endSequence.endColumn - endData.startColumn
|
|
73
|
+
];
|
|
74
|
+
fixInfo = {
|
|
75
|
+
"editColumn": endData.startColumn,
|
|
76
|
+
"deleteCount": endData.endColumn - endData.startColumn,
|
|
77
|
+
"insertText": trimCodeText(endData.text, false, true)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const context = params
|
|
81
|
+
.lines[lineNumber - 1]
|
|
82
|
+
.substring(range[0] - 1, range[0] - 1 + range[1]);
|
|
83
|
+
addErrorContext(
|
|
84
|
+
onError,
|
|
85
|
+
lineNumber,
|
|
86
|
+
context,
|
|
87
|
+
spaceLeft,
|
|
88
|
+
spaceRight,
|
|
89
|
+
range,
|
|
90
|
+
fixInfo
|
|
91
|
+
);
|
|
92
|
+
}
|
|
68
93
|
}
|
|
69
|
-
}
|
|
94
|
+
}
|
|
70
95
|
}
|
|
71
96
|
};
|
package/lib/md041.js
CHANGED
|
@@ -18,7 +18,7 @@ module.exports = {
|
|
|
18
18
|
);
|
|
19
19
|
if (!foundFrontMatterTitle) {
|
|
20
20
|
const htmlHeadingRe = new RegExp(`^<h${level}[ />]`, "i");
|
|
21
|
-
params.tokens.every((token) => {
|
|
21
|
+
params.parsers.markdownit.tokens.every((token) => {
|
|
22
22
|
let isError = false;
|
|
23
23
|
if (token.type === "html_block") {
|
|
24
24
|
if (token.content.startsWith("<!--")) {
|
package/lib/md044.js
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorDetailIf, escapeForRegExp,
|
|
6
|
-
funcExpExec, linkReferenceDefinitionRe, urlFe, withinAnyRange } =
|
|
5
|
+
const { addErrorDetailIf, escapeForRegExp, withinAnyRange } =
|
|
7
6
|
require("../helpers");
|
|
8
|
-
const {
|
|
9
|
-
require("
|
|
7
|
+
const { filterByPredicate, filterByTypes, parse } =
|
|
8
|
+
require("../helpers/micromark.cjs");
|
|
9
|
+
|
|
10
|
+
const ignoredChildTypes = new Set(
|
|
11
|
+
[ "codeFencedFence", "definition", "reference", "resource" ]
|
|
12
|
+
);
|
|
10
13
|
|
|
11
14
|
module.exports = {
|
|
12
15
|
"names": [ "MD044", "proper-names" ],
|
|
@@ -22,31 +25,25 @@ module.exports = {
|
|
|
22
25
|
const htmlElements = params.config.html_elements;
|
|
23
26
|
const includeHtmlElements =
|
|
24
27
|
(htmlElements === undefined) ? true : !!htmlElements;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} else {
|
|
30
|
-
let match = null;
|
|
31
|
-
while ((match = funcExpExec(urlFe, line)) !== null) {
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
exclusions.push([ lineIndex, match.index, match[0].length ]);
|
|
34
|
-
}
|
|
35
|
-
forEachLink(line, (index, _, text, destination) => {
|
|
36
|
-
if (destination) {
|
|
37
|
-
exclusions.push(
|
|
38
|
-
[ lineIndex, index + text.length, destination.length ]
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
if (!includeCodeBlocks) {
|
|
45
|
-
exclusions.push(...codeBlockAndSpanRanges());
|
|
46
|
-
}
|
|
47
|
-
if (!includeHtmlElements) {
|
|
48
|
-
exclusions.push(...htmlElementRanges());
|
|
28
|
+
const scannedTypes = new Set([ "data", "htmlFlowData" ]);
|
|
29
|
+
if (includeCodeBlocks) {
|
|
30
|
+
scannedTypes.add("codeFlowValue");
|
|
31
|
+
scannedTypes.add("codeTextData");
|
|
49
32
|
}
|
|
33
|
+
const contentTokens =
|
|
34
|
+
filterByPredicate(
|
|
35
|
+
params.parsers.micromark.tokens,
|
|
36
|
+
(token) => scannedTypes.has(token.type),
|
|
37
|
+
(token) => {
|
|
38
|
+
let { children } = token;
|
|
39
|
+
if (!includeHtmlElements && (token.type === "htmlFlow")) {
|
|
40
|
+
children = children.slice(1, -1);
|
|
41
|
+
}
|
|
42
|
+
return children.filter((t) => !ignoredChildTypes.has(t.type));
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
const exclusions = [];
|
|
46
|
+
const autoLinked = new Set();
|
|
50
47
|
for (const name of names) {
|
|
51
48
|
const escapedName = escapeForRegExp(name);
|
|
52
49
|
const startNamePattern = /^\W/.test(name) ? "" : "\\b_*";
|
|
@@ -54,36 +51,53 @@ module.exports = {
|
|
|
54
51
|
const namePattern =
|
|
55
52
|
`(${startNamePattern})(${escapedName})${endNamePattern}`;
|
|
56
53
|
const nameRe = new RegExp(namePattern, "gi");
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
for (const token of contentTokens) {
|
|
55
|
+
let match = null;
|
|
56
|
+
while ((match = nameRe.exec(token.text)) !== null) {
|
|
57
|
+
const [ , leftMatch, nameMatch ] = match;
|
|
58
|
+
const index = token.startColumn - 1 + match.index + leftMatch.length;
|
|
59
|
+
const length = nameMatch.length;
|
|
60
|
+
const lineIndex = token.startLine - 1;
|
|
61
|
+
if (
|
|
62
|
+
!withinAnyRange(exclusions, lineIndex, index, length) &&
|
|
63
|
+
!names.includes(nameMatch)
|
|
64
|
+
) {
|
|
65
|
+
let urlRanges = [];
|
|
66
|
+
if (!autoLinked.has(token)) {
|
|
67
|
+
urlRanges = filterByTypes(
|
|
68
|
+
parse(token.text),
|
|
69
|
+
[ "literalAutolink" ]
|
|
70
|
+
).map(
|
|
71
|
+
(t) => [
|
|
72
|
+
lineIndex,
|
|
73
|
+
token.startColumn - 1 + t.startColumn - 1,
|
|
74
|
+
t.endColumn - t.startColumn
|
|
75
|
+
]
|
|
76
|
+
);
|
|
77
|
+
exclusions.push(...urlRanges);
|
|
78
|
+
autoLinked.add(token);
|
|
79
|
+
}
|
|
80
|
+
if (!withinAnyRange(urlRanges, lineIndex, index, length)) {
|
|
81
|
+
const column = index + 1;
|
|
68
82
|
addErrorDetailIf(
|
|
69
83
|
onError,
|
|
70
|
-
|
|
84
|
+
token.startLine,
|
|
71
85
|
name,
|
|
72
86
|
nameMatch,
|
|
73
87
|
null,
|
|
74
88
|
null,
|
|
75
|
-
[
|
|
89
|
+
[ column, length ],
|
|
76
90
|
{
|
|
77
|
-
"editColumn":
|
|
91
|
+
"editColumn": column,
|
|
78
92
|
"deleteCount": length,
|
|
79
93
|
"insertText": name
|
|
80
94
|
}
|
|
81
95
|
);
|
|
82
96
|
}
|
|
83
|
-
exclusions.push([ lineIndex, index, length ]);
|
|
84
97
|
}
|
|
98
|
+
exclusions.push([ lineIndex, index, length ]);
|
|
85
99
|
}
|
|
86
|
-
}
|
|
100
|
+
}
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
};
|
package/lib/md046.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
"tags": [ "code" ],
|
|
16
16
|
"function": function MD046(params, onError) {
|
|
17
17
|
let expectedStyle = String(params.config.style || "consistent");
|
|
18
|
-
const codeBlocksAndFences = params.tokens.filter(
|
|
18
|
+
const codeBlocksAndFences = params.parsers.markdownit.tokens.filter(
|
|
19
19
|
(token) => (token.type === "code_block") || (token.type === "fence")
|
|
20
20
|
);
|
|
21
21
|
for (const token of codeBlocksAndFences) {
|
package/lib/md048.js
CHANGED
|
@@ -11,7 +11,9 @@ module.exports = {
|
|
|
11
11
|
"function": function MD048(params, onError) {
|
|
12
12
|
const style = String(params.config.style || "consistent");
|
|
13
13
|
let expectedStyle = style;
|
|
14
|
-
const fenceTokens = params.tokens.filter(
|
|
14
|
+
const fenceTokens = params.parsers.markdownit.tokens.filter(
|
|
15
|
+
(token) => token.type === "fence"
|
|
16
|
+
);
|
|
15
17
|
for (const fenceToken of fenceTokens) {
|
|
16
18
|
const { lineNumber, markup } = fenceToken;
|
|
17
19
|
if (expectedStyle === "consistent") {
|