markdownlint 0.30.0 → 0.31.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 +11 -0
- package/demo/markdownlint-browser.js +477 -390
- package/doc/Rules.md +45 -23
- package/doc/md007.md +1 -3
- package/doc/md032.md +31 -14
- package/doc/md052.md +13 -6
- package/helpers/helpers.js +67 -9
- package/helpers/micromark.cjs +94 -66
- package/helpers/package.json +2 -2
- package/lib/constants.js +1 -1
- package/lib/markdownlint.d.ts +6 -2
- package/lib/markdownlint.js +16 -6
- package/lib/md032.js +9 -4
- package/lib/md033.js +3 -2
- package/lib/md034.js +29 -31
- package/lib/md037.js +41 -48
- package/lib/md043.js +42 -40
- package/lib/md044.js +15 -41
- package/lib/md049-md050.js +6 -3
- package/lib/md051.js +51 -22
- package/lib/md052.js +7 -3
- package/package.json +11 -11
- package/schema/.markdownlint.jsonc +4 -1
- package/schema/.markdownlint.yaml +3 -1
- package/schema/markdownlint-config-schema.json +13 -2
package/lib/md051.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
5
|
const { addError, addErrorDetailIf } = require("../helpers");
|
|
6
|
-
const {
|
|
6
|
+
const { filterByPredicate, filterByTypes, getHtmlTagInfo } =
|
|
7
7
|
require("../helpers/micromark.cjs");
|
|
8
8
|
|
|
9
9
|
// Regular expression for identifying HTML anchor names
|
|
@@ -11,16 +11,28 @@ const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
|
|
|
11
11
|
const nameRe = /\sname\s*=\s*['"]?([^'"\s>]+)/iu;
|
|
12
12
|
const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
|
|
13
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
|
+
*/
|
|
21
|
+
|
|
14
22
|
/**
|
|
15
23
|
* Converts a Markdown heading into an HTML fragment according to the rules
|
|
16
24
|
* used by GitHub.
|
|
17
25
|
*
|
|
18
|
-
* @param {
|
|
26
|
+
* @param {Token} headingText Heading text token.
|
|
19
27
|
* @returns {string} Fragment string for heading.
|
|
20
28
|
*/
|
|
21
29
|
function convertHeadingToHTMLFragment(headingText) {
|
|
22
30
|
const inlineText =
|
|
23
|
-
|
|
31
|
+
filterByPredicate(
|
|
32
|
+
headingText.children,
|
|
33
|
+
(token) => tokensInclude.has(token.type),
|
|
34
|
+
(token) => (childrenExclude.has(token.type) ? [] : token.children)
|
|
35
|
+
)
|
|
24
36
|
.map((token) => token.text)
|
|
25
37
|
.join("");
|
|
26
38
|
return "#" + encodeURIComponent(
|
|
@@ -38,6 +50,18 @@ function convertHeadingToHTMLFragment(headingText) {
|
|
|
38
50
|
);
|
|
39
51
|
}
|
|
40
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
|
+
|
|
41
65
|
module.exports = {
|
|
42
66
|
"names": [ "MD051", "link-fragments" ],
|
|
43
67
|
"description": "Link fragments should be valid",
|
|
@@ -53,22 +77,24 @@ module.exports = {
|
|
|
53
77
|
);
|
|
54
78
|
for (const headingText of headingTexts) {
|
|
55
79
|
const fragment = convertHeadingToHTMLFragment(headingText);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
fragments.
|
|
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
|
+
}
|
|
66
92
|
}
|
|
67
93
|
}
|
|
68
94
|
}
|
|
69
95
|
|
|
70
96
|
// Process HTML anchors
|
|
71
|
-
for (const token of
|
|
97
|
+
for (const token of filterByTypes(tokens, [ "htmlText" ])) {
|
|
72
98
|
const htmlTagInfo = getHtmlTagInfo(token);
|
|
73
99
|
if (htmlTagInfo && !htmlTagInfo.close) {
|
|
74
100
|
const anchorMatch = idRe.exec(token.text) ||
|
|
@@ -89,10 +115,13 @@ module.exports = {
|
|
|
89
115
|
for (const link of links) {
|
|
90
116
|
const definitions = filterByTypes(link.children, [ definitionType ]);
|
|
91
117
|
for (const definition of definitions) {
|
|
118
|
+
const { endColumn, startColumn } = definition;
|
|
119
|
+
const text = unescapeStringTokenText(definition);
|
|
92
120
|
if (
|
|
93
|
-
(
|
|
94
|
-
|
|
95
|
-
!fragments.has(
|
|
121
|
+
(text.length > 1) &&
|
|
122
|
+
text.startsWith("#") &&
|
|
123
|
+
!fragments.has(text) &&
|
|
124
|
+
!fragments.has(`#${encodeURIComponent(text.slice(1))}`)
|
|
96
125
|
) {
|
|
97
126
|
// eslint-disable-next-line no-undef-init
|
|
98
127
|
let context = undefined;
|
|
@@ -104,13 +133,13 @@ module.exports = {
|
|
|
104
133
|
context = link.text;
|
|
105
134
|
range = [ link.startColumn, link.endColumn - link.startColumn ];
|
|
106
135
|
fixInfo = {
|
|
107
|
-
"editColumn":
|
|
108
|
-
"deleteCount":
|
|
136
|
+
"editColumn": startColumn,
|
|
137
|
+
"deleteCount": endColumn - startColumn
|
|
109
138
|
};
|
|
110
139
|
}
|
|
111
|
-
const
|
|
140
|
+
const textLower = text.toLowerCase();
|
|
112
141
|
const mixedCaseKey = [ ...fragments.keys() ]
|
|
113
|
-
.find((key) =>
|
|
142
|
+
.find((key) => textLower === key.toLowerCase());
|
|
114
143
|
if (mixedCaseKey) {
|
|
115
144
|
// @ts-ignore
|
|
116
145
|
(fixInfo || {}).insertText = mixedCaseKey;
|
|
@@ -118,7 +147,7 @@ module.exports = {
|
|
|
118
147
|
onError,
|
|
119
148
|
link.startLine,
|
|
120
149
|
mixedCaseKey,
|
|
121
|
-
|
|
150
|
+
text,
|
|
122
151
|
undefined,
|
|
123
152
|
context,
|
|
124
153
|
range,
|
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.1",
|
|
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",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"homepage": "https://github.com/DavidAnson/markdownlint",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "https://github.com/DavidAnson/markdownlint.git"
|
|
21
|
+
"url": "git+https://github.com/DavidAnson/markdownlint.git"
|
|
22
22
|
},
|
|
23
23
|
"bugs": "https://github.com/DavidAnson/markdownlint/issues",
|
|
24
24
|
"scripts": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos.js",
|
|
53
53
|
"serial-config-docs": "npm run build-config && npm run build-docs",
|
|
54
54
|
"serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration",
|
|
55
|
-
"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",
|
|
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
56
|
"test-cover": "c8 --100 npm test",
|
|
57
57
|
"test-declaration": "cd example/typescript && tsc && node type-check.js",
|
|
58
58
|
"test-extra": "ava --timeout=5m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js",
|
|
@@ -68,16 +68,16 @@
|
|
|
68
68
|
"markdownlint-micromark": "0.1.7"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@babel/core": "7.22.
|
|
72
|
-
"@babel/preset-env": "7.22.
|
|
71
|
+
"@babel/core": "7.22.19",
|
|
72
|
+
"@babel/preset-env": "7.22.15",
|
|
73
73
|
"ava": "5.3.1",
|
|
74
74
|
"babel-loader": "9.1.3",
|
|
75
75
|
"c8": "8.0.1",
|
|
76
76
|
"character-entities": "2.0.2",
|
|
77
|
-
"eslint": "8.
|
|
77
|
+
"eslint": "8.49.0",
|
|
78
78
|
"eslint-plugin-es": "4.1.0",
|
|
79
|
-
"eslint-plugin-jsdoc": "46.
|
|
80
|
-
"eslint-plugin-n": "16.0
|
|
79
|
+
"eslint-plugin-jsdoc": "46.8.0",
|
|
80
|
+
"eslint-plugin-n": "16.1.0",
|
|
81
81
|
"eslint-plugin-regexp": "1.15.0",
|
|
82
82
|
"eslint-plugin-unicorn": "48.0.1",
|
|
83
83
|
"gemoji": "8.1.0",
|
|
@@ -86,16 +86,16 @@
|
|
|
86
86
|
"markdown-it-for-inline": "0.1.1",
|
|
87
87
|
"markdown-it-sub": "1.0.0",
|
|
88
88
|
"markdown-it-sup": "1.0.0",
|
|
89
|
-
"markdownlint-rule-helpers": "0.
|
|
89
|
+
"markdownlint-rule-helpers": "0.22.0",
|
|
90
90
|
"npm-run-all": "4.1.5",
|
|
91
91
|
"strip-json-comments": "5.0.1",
|
|
92
92
|
"terser-webpack-plugin": "5.3.9",
|
|
93
93
|
"toml": "3.0.0",
|
|
94
94
|
"tv4": "1.3.0",
|
|
95
|
-
"typescript": "5.
|
|
95
|
+
"typescript": "5.2.2",
|
|
96
96
|
"webpack": "5.88.2",
|
|
97
97
|
"webpack-cli": "5.1.4",
|
|
98
|
-
"yaml": "2.3.
|
|
98
|
+
"yaml": "2.3.2"
|
|
99
99
|
},
|
|
100
100
|
"keywords": [
|
|
101
101
|
"markdown",
|
|
@@ -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": {
|
|
@@ -252,7 +252,9 @@ MD050:
|
|
|
252
252
|
MD051: true
|
|
253
253
|
|
|
254
254
|
# MD052/reference-links-images - Reference links and images should use a label that is defined
|
|
255
|
-
MD052:
|
|
255
|
+
MD052:
|
|
256
|
+
# Include shortcut syntax
|
|
257
|
+
shortcut_syntax: false
|
|
256
258
|
|
|
257
259
|
# MD053/link-image-reference-definitions - Link and image reference definitions should be needed
|
|
258
260
|
MD053:
|
|
@@ -937,8 +937,19 @@
|
|
|
937
937
|
},
|
|
938
938
|
"MD052": {
|
|
939
939
|
"description": "MD052/reference-links-images - Reference links and images should use a label that is defined",
|
|
940
|
-
"type":
|
|
941
|
-
|
|
940
|
+
"type": [
|
|
941
|
+
"boolean",
|
|
942
|
+
"object"
|
|
943
|
+
],
|
|
944
|
+
"default": true,
|
|
945
|
+
"properties": {
|
|
946
|
+
"shortcut_syntax": {
|
|
947
|
+
"description": "Include shortcut syntax",
|
|
948
|
+
"type": "boolean",
|
|
949
|
+
"default": false
|
|
950
|
+
}
|
|
951
|
+
},
|
|
952
|
+
"additionalProperties": false
|
|
942
953
|
},
|
|
943
954
|
"reference-links-images": {
|
|
944
955
|
"$ref": "#/properties/MD052"
|