markdownlint 0.29.0 → 0.31.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 +13 -0
- package/demo/markdownlint-browser.js +997 -891
- package/doc/CustomRules.md +2 -0
- package/doc/Rules.md +46 -23
- package/doc/md022.md +12 -6
- package/doc/md026.md +1 -2
- package/doc/md049.md +2 -2
- package/doc/md050.md +2 -2
- package/doc/md051.md +17 -6
- package/doc/md052.md +13 -6
- package/helpers/helpers.js +146 -235
- package/helpers/micromark.cjs +192 -53
- package/helpers/package.json +2 -2
- package/helpers/shared.js +7 -0
- package/lib/cache.js +0 -2
- package/lib/constants.js +1 -1
- package/lib/markdownlint.d.ts +10 -2
- package/lib/markdownlint.js +37 -13
- package/lib/md022.js +80 -40
- package/lib/md026.js +19 -12
- package/lib/md032.js +62 -31
- package/lib/md033.js +20 -45
- package/lib/md037.js +70 -164
- package/lib/md043.js +42 -40
- package/lib/md044.js +15 -41
- package/lib/md045.js +17 -5
- package/lib/md049-md050.js +6 -3
- package/lib/md051.js +123 -72
- package/lib/md052.js +7 -3
- package/package.json +25 -24
- package/schema/.markdownlint.jsonc +7 -4
- package/schema/.markdownlint.yaml +6 -4
- package/schema/markdownlint-config-schema.json +32 -9
package/lib/md043.js
CHANGED
|
@@ -11,52 +11,54 @@ module.exports = {
|
|
|
11
11
|
"tags": [ "headings", "headers" ],
|
|
12
12
|
"function": function MD043(params, onError) {
|
|
13
13
|
const requiredHeadings = params.config.headings || params.config.headers;
|
|
14
|
+
if (!Array.isArray(requiredHeadings)) {
|
|
15
|
+
// Nothing to check; avoid doing any work
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
14
18
|
const matchCase = params.config.match_case || false;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (handleCase(nextExpected) !== handleCase(actual)) {
|
|
34
|
-
matchAny = true;
|
|
35
|
-
i--;
|
|
36
|
-
}
|
|
37
|
-
} else if (expected === "+") {
|
|
19
|
+
const levels = {};
|
|
20
|
+
for (const level of [ 1, 2, 3, 4, 5, 6 ]) {
|
|
21
|
+
levels["h" + level] = "######".substr(-level);
|
|
22
|
+
}
|
|
23
|
+
let i = 0;
|
|
24
|
+
let matchAny = false;
|
|
25
|
+
let hasError = false;
|
|
26
|
+
let anyHeadings = false;
|
|
27
|
+
const getExpected = () => requiredHeadings[i++] || "[None]";
|
|
28
|
+
const handleCase = (str) => (matchCase ? str : str.toLowerCase());
|
|
29
|
+
forEachHeading(params, (heading, content) => {
|
|
30
|
+
if (!hasError) {
|
|
31
|
+
anyHeadings = true;
|
|
32
|
+
const actual = levels[heading.tag] + " " + content;
|
|
33
|
+
const expected = getExpected();
|
|
34
|
+
if (expected === "*") {
|
|
35
|
+
const nextExpected = getExpected();
|
|
36
|
+
if (handleCase(nextExpected) !== handleCase(actual)) {
|
|
38
37
|
matchAny = true;
|
|
39
|
-
} else if (handleCase(expected) === handleCase(actual)) {
|
|
40
|
-
matchAny = false;
|
|
41
|
-
} else if (matchAny) {
|
|
42
38
|
i--;
|
|
43
|
-
} else {
|
|
44
|
-
addErrorDetailIf(onError, heading.lineNumber,
|
|
45
|
-
expected, actual);
|
|
46
|
-
hasError = true;
|
|
47
39
|
}
|
|
40
|
+
} else if (expected === "+") {
|
|
41
|
+
matchAny = true;
|
|
42
|
+
} else if (handleCase(expected) === handleCase(actual)) {
|
|
43
|
+
matchAny = false;
|
|
44
|
+
} else if (matchAny) {
|
|
45
|
+
i--;
|
|
46
|
+
} else {
|
|
47
|
+
addErrorDetailIf(onError, heading.lineNumber,
|
|
48
|
+
expected, actual);
|
|
49
|
+
hasError = true;
|
|
48
50
|
}
|
|
49
|
-
});
|
|
50
|
-
const extraHeadings = requiredHeadings.length - i;
|
|
51
|
-
if (
|
|
52
|
-
!hasError &&
|
|
53
|
-
((extraHeadings > 1) ||
|
|
54
|
-
((extraHeadings === 1) && (requiredHeadings[i] !== "*"))) &&
|
|
55
|
-
(anyHeadings || !requiredHeadings.every((heading) => heading === "*"))
|
|
56
|
-
) {
|
|
57
|
-
addErrorContext(onError, params.lines.length,
|
|
58
|
-
requiredHeadings[i]);
|
|
59
51
|
}
|
|
52
|
+
});
|
|
53
|
+
const extraHeadings = requiredHeadings.length - i;
|
|
54
|
+
if (
|
|
55
|
+
!hasError &&
|
|
56
|
+
((extraHeadings > 1) ||
|
|
57
|
+
((extraHeadings === 1) && (requiredHeadings[i] !== "*"))) &&
|
|
58
|
+
(anyHeadings || !requiredHeadings.every((heading) => heading === "*"))
|
|
59
|
+
) {
|
|
60
|
+
addErrorContext(onError, params.lines.length,
|
|
61
|
+
requiredHeadings[i]);
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
};
|
package/lib/md044.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addErrorDetailIf, escapeForRegExp,
|
|
5
|
+
const { addErrorDetailIf, escapeForRegExp, withinAnyRange } =
|
|
6
6
|
require("../helpers");
|
|
7
7
|
const { filterByPredicate, filterByTypes, parse } =
|
|
8
8
|
require("../helpers/micromark.cjs");
|
|
@@ -19,46 +19,32 @@ module.exports = {
|
|
|
19
19
|
let names = params.config.names;
|
|
20
20
|
names = Array.isArray(names) ? names : [];
|
|
21
21
|
names.sort((a, b) => (b.length - a.length) || a.localeCompare(b));
|
|
22
|
+
if (names.length === 0) {
|
|
23
|
+
// Nothing to check; avoid doing any work
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
22
26
|
const codeBlocks = params.config.code_blocks;
|
|
23
27
|
const includeCodeBlocks =
|
|
24
28
|
(codeBlocks === undefined) ? true : !!codeBlocks;
|
|
25
29
|
const htmlElements = params.config.html_elements;
|
|
26
30
|
const includeHtmlElements =
|
|
27
31
|
(htmlElements === undefined) ? true : !!htmlElements;
|
|
28
|
-
const scannedTypes = new Set([ "data"
|
|
32
|
+
const scannedTypes = new Set([ "data" ]);
|
|
29
33
|
if (includeCodeBlocks) {
|
|
30
34
|
scannedTypes.add("codeFlowValue");
|
|
31
35
|
scannedTypes.add("codeTextData");
|
|
32
36
|
}
|
|
33
|
-
|
|
37
|
+
if (includeHtmlElements) {
|
|
38
|
+
scannedTypes.add("htmlFlowData");
|
|
39
|
+
scannedTypes.add("htmlTextData");
|
|
40
|
+
}
|
|
34
41
|
const contentTokens =
|
|
35
42
|
filterByPredicate(
|
|
36
43
|
params.parsers.micromark.tokens,
|
|
37
44
|
(token) => scannedTypes.has(token.type),
|
|
38
|
-
(token) =>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (!includeHtmlElements && (token.type === "htmlFlow")) {
|
|
42
|
-
if (text.startsWith("<!--")) {
|
|
43
|
-
// Remove comment content
|
|
44
|
-
children = [];
|
|
45
|
-
} else {
|
|
46
|
-
// Re-parse to get htmlText elements for detailed tokenization
|
|
47
|
-
const htmlTextLines =
|
|
48
|
-
`<md044>\n${text}\n</md044>`.split(newLineRe);
|
|
49
|
-
children = parse(htmlTextLines.join(""));
|
|
50
|
-
const reTokens = [ ...children ];
|
|
51
|
-
for (const reToken of reTokens) {
|
|
52
|
-
tokenAdjustments.set(reToken, {
|
|
53
|
-
htmlTextLines,
|
|
54
|
-
startLine
|
|
55
|
-
});
|
|
56
|
-
reTokens.push(...reToken.children);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return children.filter((t) => !ignoredChildTypes.has(t.type));
|
|
61
|
-
}
|
|
45
|
+
(token) => (
|
|
46
|
+
token.children.filter((t) => !ignoredChildTypes.has(t.type))
|
|
47
|
+
)
|
|
62
48
|
);
|
|
63
49
|
const exclusions = [];
|
|
64
50
|
const autoLinked = new Set();
|
|
@@ -96,22 +82,10 @@ module.exports = {
|
|
|
96
82
|
autoLinked.add(token);
|
|
97
83
|
}
|
|
98
84
|
if (!withinAnyRange(urlRanges, lineIndex, index, length)) {
|
|
99
|
-
|
|
100
|
-
let column = index;
|
|
101
|
-
if (tokenAdjustments.has(token)) {
|
|
102
|
-
const { htmlTextLines, startLine } =
|
|
103
|
-
tokenAdjustments.get(token);
|
|
104
|
-
let lineDelta = 0;
|
|
105
|
-
while (htmlTextLines[lineDelta].length <= column) {
|
|
106
|
-
column -= htmlTextLines[lineDelta].length;
|
|
107
|
-
lineDelta++;
|
|
108
|
-
}
|
|
109
|
-
lineNumber = startLine + lineDelta - 1;
|
|
110
|
-
}
|
|
111
|
-
column++;
|
|
85
|
+
const column = index + 1;
|
|
112
86
|
addErrorDetailIf(
|
|
113
87
|
onError,
|
|
114
|
-
|
|
88
|
+
token.startLine,
|
|
115
89
|
name,
|
|
116
90
|
nameMatch,
|
|
117
91
|
null,
|
package/lib/md045.js
CHANGED
|
@@ -2,17 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError
|
|
5
|
+
const { addError } = require("../helpers");
|
|
6
|
+
const { filterByTypes } = require("../helpers/micromark.cjs");
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
"names": [ "MD045", "no-alt-text" ],
|
|
9
10
|
"description": "Images should have alternate text (alt text)",
|
|
10
11
|
"tags": [ "accessibility", "images" ],
|
|
11
12
|
"function": function MD045(params, onError) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const images = filterByTypes(params.parsers.micromark.tokens, [ "image" ]);
|
|
14
|
+
for (const image of images) {
|
|
15
|
+
const labelTexts = filterByTypes(image.children, [ "labelText" ]);
|
|
16
|
+
if (labelTexts.some((labelText) => labelText.text.length === 0)) {
|
|
17
|
+
const range = (image.startLine === image.endLine) ?
|
|
18
|
+
[ image.startColumn, image.endColumn - image.startColumn ] :
|
|
19
|
+
undefined;
|
|
20
|
+
addError(
|
|
21
|
+
onError,
|
|
22
|
+
image.startLine,
|
|
23
|
+
undefined,
|
|
24
|
+
undefined,
|
|
25
|
+
range
|
|
26
|
+
);
|
|
15
27
|
}
|
|
16
|
-
}
|
|
28
|
+
}
|
|
17
29
|
}
|
|
18
30
|
};
|
package/lib/md049-md050.js
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
5
|
const { addError, emphasisOrStrongStyleFor } = require("../helpers");
|
|
6
|
-
const {
|
|
6
|
+
const { filterByPredicate, tokenIfType } = require("../helpers/micromark.cjs");
|
|
7
7
|
|
|
8
8
|
const intrawordRe = /\w/;
|
|
9
9
|
|
|
10
10
|
const impl =
|
|
11
11
|
(params, onError, type, asterisk, underline, style = "consistent") => {
|
|
12
12
|
const { lines, parsers } = params;
|
|
13
|
-
const emphasisTokens =
|
|
14
|
-
|
|
13
|
+
const emphasisTokens = filterByPredicate(
|
|
14
|
+
parsers.micromark.tokens,
|
|
15
|
+
(token) => token.type === type,
|
|
16
|
+
(token) => ((token.type === "htmlFlow") ? [] : token.children)
|
|
17
|
+
);
|
|
15
18
|
for (const token of emphasisTokens) {
|
|
16
19
|
const { children } = token;
|
|
17
20
|
const childType = `${type}Sequence`;
|
package/lib/md051.js
CHANGED
|
@@ -2,25 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
const { addError, addErrorDetailIf
|
|
6
|
-
|
|
5
|
+
const { addError, addErrorDetailIf } = require("../helpers");
|
|
6
|
+
const { filterByPredicate, filterByTypes, getHtmlTagInfo } =
|
|
7
|
+
require("../helpers/micromark.cjs");
|
|
7
8
|
|
|
8
9
|
// Regular expression for identifying HTML anchor names
|
|
9
10
|
const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
|
|
10
11
|
const nameRe = /\sname\s*=\s*['"]?([^'"\s>]+)/iu;
|
|
12
|
+
const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
|
|
13
|
+
|
|
14
|
+
// Sets for filtering heading tokens during conversion
|
|
15
|
+
const childrenExclude = new Set([ "image", "reference", "resource" ]);
|
|
16
|
+
const tokensInclude = new Set([ "codeTextData", "data" ]);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {import("../helpers/micromark.cjs").Token} Token
|
|
20
|
+
*/
|
|
11
21
|
|
|
12
22
|
/**
|
|
13
23
|
* Converts a Markdown heading into an HTML fragment according to the rules
|
|
14
24
|
* used by GitHub.
|
|
15
25
|
*
|
|
16
|
-
* @param {
|
|
26
|
+
* @param {Token} headingText Heading text token.
|
|
17
27
|
* @returns {string} Fragment string for heading.
|
|
18
28
|
*/
|
|
19
|
-
function convertHeadingToHTMLFragment(
|
|
20
|
-
const inlineText =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
function convertHeadingToHTMLFragment(headingText) {
|
|
30
|
+
const inlineText =
|
|
31
|
+
filterByPredicate(
|
|
32
|
+
headingText.children,
|
|
33
|
+
(token) => tokensInclude.has(token.type),
|
|
34
|
+
(token) => (childrenExclude.has(token.type) ? [] : token.children)
|
|
35
|
+
)
|
|
36
|
+
.map((token) => token.text)
|
|
37
|
+
.join("");
|
|
24
38
|
return "#" + encodeURIComponent(
|
|
25
39
|
inlineText
|
|
26
40
|
.toLowerCase()
|
|
@@ -36,84 +50,121 @@ function convertHeadingToHTMLFragment(inline) {
|
|
|
36
50
|
);
|
|
37
51
|
}
|
|
38
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Unescapes the text of a String-type micromark Token.
|
|
55
|
+
*
|
|
56
|
+
* @param {Token} token String-type micromark Token.
|
|
57
|
+
* @returns {string} Unescaped token text.
|
|
58
|
+
*/
|
|
59
|
+
function unescapeStringTokenText(token) {
|
|
60
|
+
return filterByTypes(token.children, [ "characterEscapeValue", "data" ])
|
|
61
|
+
.map((child) => child.text)
|
|
62
|
+
.join("");
|
|
63
|
+
}
|
|
64
|
+
|
|
39
65
|
module.exports = {
|
|
40
66
|
"names": [ "MD051", "link-fragments" ],
|
|
41
67
|
"description": "Link fragments should be valid",
|
|
42
68
|
"tags": [ "links" ],
|
|
43
69
|
"function": function MD051(params, onError) {
|
|
70
|
+
const { tokens } = params.parsers.micromark;
|
|
44
71
|
const fragments = new Map();
|
|
72
|
+
|
|
45
73
|
// Process headings
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
const headingTexts = filterByTypes(
|
|
75
|
+
tokens,
|
|
76
|
+
[ "atxHeadingText", "setextHeadingText" ]
|
|
77
|
+
);
|
|
78
|
+
for (const headingText of headingTexts) {
|
|
79
|
+
const fragment = convertHeadingToHTMLFragment(headingText);
|
|
80
|
+
if (fragment !== "#") {
|
|
81
|
+
const count = fragments.get(fragment) || 0;
|
|
82
|
+
if (count) {
|
|
83
|
+
fragments.set(`${fragment}-${count}`, 0);
|
|
84
|
+
}
|
|
85
|
+
fragments.set(fragment, count + 1);
|
|
86
|
+
let match = null;
|
|
87
|
+
while ((match = anchorRe.exec(headingText.text)) !== null) {
|
|
88
|
+
const [ , anchor ] = match;
|
|
89
|
+
if (!fragments.has(anchor)) {
|
|
90
|
+
fragments.set(anchor, 1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
51
93
|
}
|
|
52
|
-
|
|
53
|
-
|
|
94
|
+
}
|
|
95
|
+
|
|
54
96
|
// Process HTML anchors
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
(element.toLowerCase() === "a" && nameRe.exec(tag));
|
|
97
|
+
for (const token of filterByTypes(tokens, [ "htmlText" ])) {
|
|
98
|
+
const htmlTagInfo = getHtmlTagInfo(token);
|
|
99
|
+
if (htmlTagInfo && !htmlTagInfo.close) {
|
|
100
|
+
const anchorMatch = idRe.exec(token.text) ||
|
|
101
|
+
(htmlTagInfo.name.toLowerCase() === "a" && nameRe.exec(token.text));
|
|
61
102
|
if (anchorMatch) {
|
|
62
103
|
fragments.set(`#${anchorMatch[1]}`, 0);
|
|
63
104
|
}
|
|
64
105
|
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Process link and definition fragments
|
|
109
|
+
const parentChilds = [
|
|
110
|
+
[ "link", "resourceDestinationString" ],
|
|
111
|
+
[ "definition", "definitionDestinationString" ]
|
|
112
|
+
];
|
|
113
|
+
for (const [ parentType, definitionType ] of parentChilds) {
|
|
114
|
+
const links = filterByTypes(tokens, [ parentType ]);
|
|
115
|
+
for (const link of links) {
|
|
116
|
+
const definitions = filterByTypes(link.children, [ definitionType ]);
|
|
117
|
+
for (const definition of definitions) {
|
|
118
|
+
const { endColumn, startColumn } = definition;
|
|
119
|
+
const text = unescapeStringTokenText(definition);
|
|
120
|
+
if (
|
|
121
|
+
(text.length > 1) &&
|
|
122
|
+
text.startsWith("#") &&
|
|
123
|
+
!fragments.has(text) &&
|
|
124
|
+
!fragments.has(`#${encodeURIComponent(text.slice(1))}`)
|
|
125
|
+
) {
|
|
126
|
+
// eslint-disable-next-line no-undef-init
|
|
127
|
+
let context = undefined;
|
|
128
|
+
// eslint-disable-next-line no-undef-init
|
|
129
|
+
let range = undefined;
|
|
130
|
+
// eslint-disable-next-line no-undef-init
|
|
131
|
+
let fixInfo = undefined;
|
|
132
|
+
if (link.startLine === link.endLine) {
|
|
133
|
+
context = link.text;
|
|
134
|
+
range = [ link.startColumn, link.endColumn - link.startColumn ];
|
|
135
|
+
fixInfo = {
|
|
136
|
+
"editColumn": startColumn,
|
|
137
|
+
"deleteCount": endColumn - startColumn
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const textLower = text.toLowerCase();
|
|
141
|
+
const mixedCaseKey = [ ...fragments.keys() ]
|
|
142
|
+
.find((key) => textLower === key.toLowerCase());
|
|
143
|
+
if (mixedCaseKey) {
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
(fixInfo || {}).insertText = mixedCaseKey;
|
|
146
|
+
addErrorDetailIf(
|
|
147
|
+
onError,
|
|
148
|
+
link.startLine,
|
|
149
|
+
mixedCaseKey,
|
|
150
|
+
text,
|
|
151
|
+
undefined,
|
|
152
|
+
context,
|
|
153
|
+
range,
|
|
154
|
+
fixInfo
|
|
155
|
+
);
|
|
156
|
+
} else {
|
|
157
|
+
addError(
|
|
158
|
+
onError,
|
|
159
|
+
link.startLine,
|
|
160
|
+
undefined,
|
|
161
|
+
context,
|
|
162
|
+
range
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
115
166
|
}
|
|
116
167
|
}
|
|
117
|
-
}
|
|
168
|
+
}
|
|
118
169
|
}
|
|
119
170
|
};
|
package/lib/md052.js
CHANGED
|
@@ -11,10 +11,14 @@ module.exports = {
|
|
|
11
11
|
"Reference links and images should use a label that is defined",
|
|
12
12
|
"tags": [ "images", "links" ],
|
|
13
13
|
"function": function MD052(params, onError) {
|
|
14
|
-
const { lines } = params;
|
|
15
|
-
const
|
|
14
|
+
const { config, lines } = params;
|
|
15
|
+
const shortcutSyntax = config.shortcut_syntax || false;
|
|
16
|
+
const { definitions, references, shortcuts } = referenceLinkImageData();
|
|
17
|
+
const entries = shortcutSyntax ?
|
|
18
|
+
[ ...references.entries(), ...shortcuts.entries() ] :
|
|
19
|
+
references.entries();
|
|
16
20
|
// Look for links/images that use an undefined link reference
|
|
17
|
-
for (const reference of
|
|
21
|
+
for (const reference of entries) {
|
|
18
22
|
const [ label, datas ] = reference;
|
|
19
23
|
if (!definitions.has(label)) {
|
|
20
24
|
for (const data of datas) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdownlint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./lib/markdownlint.js",
|
|
@@ -33,17 +33,16 @@
|
|
|
33
33
|
"ci": "npm-run-all --continue-on-error --parallel lint serial-config-docs serial-declaration-demo test-cover && git diff --exit-code",
|
|
34
34
|
"clone-test-repos-apache-airflow": "cd test-repos && git clone https://github.com/apache/airflow apache-airflow --depth 1 --no-tags --quiet",
|
|
35
35
|
"clone-test-repos-dotnet-docs": "cd test-repos && git clone https://github.com/dotnet/docs dotnet-docs --depth 1 --no-tags --quiet",
|
|
36
|
-
"clone-test-repos-electron-electron": "cd test-repos && git clone https://github.com/electron/electron electron-electron --depth 1 --no-tags --quiet && cd electron-electron && npm install --ignore-scripts @electron/lint-roller",
|
|
36
|
+
"clone-test-repos-electron-electron": "cd test-repos && git clone https://github.com/electron/electron electron-electron --depth 1 --no-tags --quiet && cd electron-electron && npm install --ignore-scripts @electron/lint-roller typescript@4",
|
|
37
37
|
"clone-test-repos-eslint-eslint": "cd test-repos && git clone https://github.com/eslint/eslint eslint-eslint --depth 1 --no-tags --quiet",
|
|
38
38
|
"clone-test-repos-mdn-content": "cd test-repos && git clone https://github.com/mdn/content mdn-content --depth 1 --no-tags --quiet",
|
|
39
|
-
"clone-test-repos-mdn-translated-content": "cd test-repos && git clone https://github.com/mdn/translated-content mdn-translated-content --depth 1 --no-tags --quiet",
|
|
40
39
|
"clone-test-repos-mkdocs-mkdocs": "cd test-repos && git clone https://github.com/mkdocs/mkdocs mkdocs-mkdocs --depth 1 --no-tags --quiet",
|
|
41
40
|
"clone-test-repos-mochajs-mocha": "cd test-repos && git clone https://github.com/mochajs/mocha mochajs-mocha --depth 1 --no-tags --quiet",
|
|
42
41
|
"clone-test-repos-pi-hole-docs": "cd test-repos && git clone https://github.com/pi-hole/docs pi-hole-docs --depth 1 --no-tags --quiet",
|
|
43
42
|
"clone-test-repos-v8-v8-dev": "cd test-repos && git clone https://github.com/v8/v8.dev v8-v8-dev --depth 1 --no-tags --quiet",
|
|
44
43
|
"clone-test-repos-webhintio-hint": "cd test-repos && git clone https://github.com/webhintio/hint webhintio-hint --depth 1 --no-tags --quiet",
|
|
45
44
|
"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",
|
|
46
|
-
"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-
|
|
45
|
+
"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",
|
|
47
46
|
"declaration": "npm run build-declaration && npm run test-declaration",
|
|
48
47
|
"example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint",
|
|
49
48
|
"docker-npm-install": "docker run --rm --tty --name npm-install --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm install",
|
|
@@ -53,11 +52,12 @@
|
|
|
53
52
|
"lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos.js",
|
|
54
53
|
"serial-config-docs": "npm run build-config && npm run build-docs",
|
|
55
54
|
"serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration",
|
|
56
|
-
"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-micromark.mjs test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js",
|
|
57
|
-
"test-cover": "c8 --
|
|
55
|
+
"test": "ava --timeout=30s test/markdownlint-test.js test/markdownlint-test-config.js test/markdownlint-test-custom-rules.js test/markdownlint-test-helpers.js test/markdownlint-test-micromark.mjs test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js",
|
|
56
|
+
"test-cover": "c8 --100 npm test",
|
|
58
57
|
"test-declaration": "cd example/typescript && tsc && node type-check.js",
|
|
59
58
|
"test-extra": "ava --timeout=5m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js",
|
|
60
59
|
"update-snapshots": "ava --update-snapshots test/markdownlint-test-micromark.mjs test/markdownlint-test-scenarios.js",
|
|
60
|
+
"update-snapshots-test-repos": "ava --timeout=10m --update-snapshots test/markdownlint-test-repos.js",
|
|
61
61
|
"upgrade": "npx --yes npm-check-updates --upgrade"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
@@ -65,36 +65,37 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"markdown-it": "13.0.1",
|
|
68
|
-
"markdownlint-micromark": "0.1.
|
|
68
|
+
"markdownlint-micromark": "0.1.7"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@babel/core": "7.22.
|
|
72
|
-
"@babel/preset-env": "7.22.
|
|
73
|
-
"ava": "5.3.
|
|
74
|
-
"babel-loader": "9.1.
|
|
75
|
-
"c8": "
|
|
76
|
-
"
|
|
71
|
+
"@babel/core": "7.22.15",
|
|
72
|
+
"@babel/preset-env": "7.22.15",
|
|
73
|
+
"ava": "5.3.1",
|
|
74
|
+
"babel-loader": "9.1.3",
|
|
75
|
+
"c8": "8.0.1",
|
|
76
|
+
"character-entities": "2.0.2",
|
|
77
|
+
"eslint": "8.48.0",
|
|
77
78
|
"eslint-plugin-es": "4.1.0",
|
|
78
|
-
"eslint-plugin-jsdoc": "46.1
|
|
79
|
-
"eslint-plugin-n": "16.0.
|
|
79
|
+
"eslint-plugin-jsdoc": "46.5.1",
|
|
80
|
+
"eslint-plugin-n": "16.0.2",
|
|
80
81
|
"eslint-plugin-regexp": "1.15.0",
|
|
81
|
-
"eslint-plugin-unicorn": "
|
|
82
|
-
"
|
|
82
|
+
"eslint-plugin-unicorn": "48.0.1",
|
|
83
|
+
"gemoji": "8.1.0",
|
|
84
|
+
"globby": "13.2.2",
|
|
83
85
|
"js-yaml": "4.1.0",
|
|
84
86
|
"markdown-it-for-inline": "0.1.1",
|
|
85
87
|
"markdown-it-sub": "1.0.0",
|
|
86
88
|
"markdown-it-sup": "1.0.0",
|
|
87
|
-
"
|
|
88
|
-
"markdownlint-rule-helpers": "0.19.0",
|
|
89
|
+
"markdownlint-rule-helpers": "0.21.0",
|
|
89
90
|
"npm-run-all": "4.1.5",
|
|
90
|
-
"strip-json-comments": "5.0.
|
|
91
|
+
"strip-json-comments": "5.0.1",
|
|
91
92
|
"terser-webpack-plugin": "5.3.9",
|
|
92
93
|
"toml": "3.0.0",
|
|
93
94
|
"tv4": "1.3.0",
|
|
94
|
-
"typescript": "5.
|
|
95
|
-
"webpack": "5.
|
|
96
|
-
"webpack-cli": "5.1.
|
|
97
|
-
"yaml": "2.3.
|
|
95
|
+
"typescript": "5.2.2",
|
|
96
|
+
"webpack": "5.88.2",
|
|
97
|
+
"webpack-cli": "5.1.4",
|
|
98
|
+
"yaml": "2.3.2"
|
|
98
99
|
},
|
|
99
100
|
"keywords": [
|
|
100
101
|
"markdown",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
|
|
140
140
|
// MD026/no-trailing-punctuation - Trailing punctuation in heading
|
|
141
141
|
"MD026": {
|
|
142
|
-
// Punctuation characters
|
|
142
|
+
// Punctuation characters
|
|
143
143
|
"punctuation": ".,;:!。,;:!"
|
|
144
144
|
},
|
|
145
145
|
|
|
@@ -265,13 +265,13 @@
|
|
|
265
265
|
|
|
266
266
|
// MD049/emphasis-style - Emphasis style should be consistent
|
|
267
267
|
"MD049": {
|
|
268
|
-
// Emphasis style
|
|
268
|
+
// Emphasis style
|
|
269
269
|
"style": "consistent"
|
|
270
270
|
},
|
|
271
271
|
|
|
272
272
|
// MD050/strong-style - Strong style should be consistent
|
|
273
273
|
"MD050": {
|
|
274
|
-
// Strong style
|
|
274
|
+
// Strong style
|
|
275
275
|
"style": "consistent"
|
|
276
276
|
},
|
|
277
277
|
|
|
@@ -279,7 +279,10 @@
|
|
|
279
279
|
"MD051": true,
|
|
280
280
|
|
|
281
281
|
// MD052/reference-links-images - Reference links and images should use a label that is defined
|
|
282
|
-
"MD052":
|
|
282
|
+
"MD052": {
|
|
283
|
+
// Include shortcut syntax
|
|
284
|
+
"shortcut_syntax": false
|
|
285
|
+
},
|
|
283
286
|
|
|
284
287
|
// MD053/link-image-reference-definitions - Link and image reference definitions should be needed
|
|
285
288
|
"MD053": {
|