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
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
const {
|
|
7
|
+
gfmAutolinkLiteral, gfmFootnote, gfmTable, parse, postprocess, preprocess
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
} = require("markdownlint-micromark");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Markdown token.
|
|
13
|
+
*
|
|
14
|
+
* @typedef {Object} Token
|
|
15
|
+
* @property {string} type Token type.
|
|
16
|
+
* @property {number} startLine Start line (1-based).
|
|
17
|
+
* @property {number} startColumn Start column (1-based).
|
|
18
|
+
* @property {number} endLine End line (1-based).
|
|
19
|
+
* @property {number} endColumn End column (1-based).
|
|
20
|
+
* @property {string} text Token text.
|
|
21
|
+
* @property {Token[]} children Child tokens.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parses a Markdown document and returns Micromark events.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} markdown Markdown document.
|
|
28
|
+
* @param {Object} [options] Options for micromark.
|
|
29
|
+
* @returns {Object[]} Micromark events.
|
|
30
|
+
*/
|
|
31
|
+
function getMicromarkEvents(markdown, options = {}) {
|
|
32
|
+
|
|
33
|
+
// Customize options object to add useful extensions
|
|
34
|
+
options.extensions = options.extensions || [];
|
|
35
|
+
options.extensions.push(gfmAutolinkLiteral, gfmFootnote(), gfmTable);
|
|
36
|
+
|
|
37
|
+
// Use micromark to parse document into Events
|
|
38
|
+
const encoding = undefined;
|
|
39
|
+
const eol = true;
|
|
40
|
+
const parseContext = parse(options);
|
|
41
|
+
// Customize ParseContext to treat all references as defined
|
|
42
|
+
parseContext.defined.includes = (searchElement) => searchElement.length > 0;
|
|
43
|
+
const chunks = preprocess()(markdown, encoding, eol);
|
|
44
|
+
const events = postprocess(parseContext.document().write(chunks));
|
|
45
|
+
return events;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Parses a Markdown document and returns (frozen) tokens.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} markdown Markdown document.
|
|
52
|
+
* @param {Object} [options] Options for micromark.
|
|
53
|
+
* @returns {Token[]} Micromark tokens (frozen).
|
|
54
|
+
*/
|
|
55
|
+
function micromarkParse(markdown, options = {}) {
|
|
56
|
+
|
|
57
|
+
// Use micromark to parse document into Events
|
|
58
|
+
const events = getMicromarkEvents(markdown, options);
|
|
59
|
+
|
|
60
|
+
// Create Token objects
|
|
61
|
+
const document = [];
|
|
62
|
+
let current = {
|
|
63
|
+
"children": document
|
|
64
|
+
};
|
|
65
|
+
const history = [ current ];
|
|
66
|
+
for (const event of events) {
|
|
67
|
+
const [ kind, token, context ] = event;
|
|
68
|
+
const { type, start, end } = token;
|
|
69
|
+
const { "column": startColumn, "line": startLine } = start;
|
|
70
|
+
const { "column": endColumn, "line": endLine } = end;
|
|
71
|
+
let text = null;
|
|
72
|
+
try {
|
|
73
|
+
text = context.sliceSerialize(token);
|
|
74
|
+
} catch {
|
|
75
|
+
// https://github.com/micromark/micromark/issues/131
|
|
76
|
+
}
|
|
77
|
+
if (kind === "enter") {
|
|
78
|
+
const previous = current;
|
|
79
|
+
history.push(previous);
|
|
80
|
+
current = {
|
|
81
|
+
type,
|
|
82
|
+
startLine,
|
|
83
|
+
startColumn,
|
|
84
|
+
endLine,
|
|
85
|
+
endColumn,
|
|
86
|
+
text,
|
|
87
|
+
"children": []
|
|
88
|
+
};
|
|
89
|
+
previous.children.push(current);
|
|
90
|
+
} else if (kind === "exit") {
|
|
91
|
+
Object.freeze(current.children);
|
|
92
|
+
Object.freeze(current);
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
current = history.pop();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Return document
|
|
99
|
+
Object.freeze(document);
|
|
100
|
+
return document;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Filter a list of Micromark tokens by predicate.
|
|
105
|
+
*
|
|
106
|
+
* @param {Token[]} tokens Micromark tokens.
|
|
107
|
+
* @param {Function} allowed Allowed token predicate.
|
|
108
|
+
* @param {Function} [transformChildren] Transform children predicate.
|
|
109
|
+
* @returns {Token[]} Filtered tokens.
|
|
110
|
+
*/
|
|
111
|
+
function filterByPredicate(tokens, allowed, transformChildren) {
|
|
112
|
+
const result = [];
|
|
113
|
+
const pending = [ ...tokens ];
|
|
114
|
+
let token = null;
|
|
115
|
+
while ((token = pending.shift())) {
|
|
116
|
+
if (allowed(token)) {
|
|
117
|
+
result.push(token);
|
|
118
|
+
}
|
|
119
|
+
if (token.children.length > 0) {
|
|
120
|
+
const transformed =
|
|
121
|
+
transformChildren ? transformChildren(token) : token.children;
|
|
122
|
+
pending.unshift(...transformed);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Filter a list of Micromark tokens by type.
|
|
130
|
+
*
|
|
131
|
+
* @param {Token[]} tokens Micromark tokens.
|
|
132
|
+
* @param {string[]} allowed Types to allow.
|
|
133
|
+
* @returns {Token[]} Filtered tokens.
|
|
134
|
+
*/
|
|
135
|
+
function filterByTypes(tokens, allowed) {
|
|
136
|
+
return filterByPredicate(
|
|
137
|
+
tokens,
|
|
138
|
+
(token) => allowed.includes(token.type)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Gets information about the tag in an HTML token.
|
|
144
|
+
*
|
|
145
|
+
* @param {Token} token Micromark token.
|
|
146
|
+
* @returns {Object | null} HTML tag information.
|
|
147
|
+
*/
|
|
148
|
+
function getHtmlTagInfo(token) {
|
|
149
|
+
const htmlTagNameRe = /^<([^!>][^/\s>]*)/;
|
|
150
|
+
if (token.type === "htmlText") {
|
|
151
|
+
const match = htmlTagNameRe.exec(token.text);
|
|
152
|
+
if (match) {
|
|
153
|
+
const name = match[1];
|
|
154
|
+
const close = name.startsWith("/");
|
|
155
|
+
return {
|
|
156
|
+
close,
|
|
157
|
+
"name": close ? name.slice(1) : name
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get the text of a single token from a list of Micromark tokens by type.
|
|
166
|
+
*
|
|
167
|
+
* @param {Token[]} tokens Micromark tokens.
|
|
168
|
+
* @param {string} type Types to match.
|
|
169
|
+
* @returns {string | null} Text of token.
|
|
170
|
+
*/
|
|
171
|
+
function getTokenTextByType(tokens, type) {
|
|
172
|
+
const filtered = tokens.filter((token) => token.type === type);
|
|
173
|
+
return (filtered.length === 1) ? filtered[0].text : null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Determines a list of Micromark tokens matches and returns a subset.
|
|
178
|
+
*
|
|
179
|
+
* @param {Token[]} tokens Micromark tokens.
|
|
180
|
+
* @param {string[]} matchTypes Types to match.
|
|
181
|
+
* @param {string[]} [resultTypes] Types to return.
|
|
182
|
+
* @returns {Token[] | null} Matching tokens.
|
|
183
|
+
*/
|
|
184
|
+
function matchAndGetTokensByType(tokens, matchTypes, resultTypes) {
|
|
185
|
+
if (tokens.length !== matchTypes.length) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
resultTypes = resultTypes || matchTypes;
|
|
189
|
+
const result = [];
|
|
190
|
+
// eslint-disable-next-line unicorn/no-for-loop
|
|
191
|
+
for (let i = 0; i < matchTypes.length; i++) {
|
|
192
|
+
if (tokens[i].type !== matchTypes[i]) {
|
|
193
|
+
return null;
|
|
194
|
+
} else if (resultTypes.includes(matchTypes[i])) {
|
|
195
|
+
result.push(tokens[i]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
module.exports = {
|
|
202
|
+
"parse": micromarkParse,
|
|
203
|
+
filterByPredicate,
|
|
204
|
+
filterByTypes,
|
|
205
|
+
getHtmlTagInfo,
|
|
206
|
+
getMicromarkEvents,
|
|
207
|
+
getTokenTextByType,
|
|
208
|
+
matchAndGetTokensByType
|
|
209
|
+
};
|
package/helpers/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdownlint-rule-helpers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "A collection of markdownlint helper functions for custom rules",
|
|
5
5
|
"main": "./helpers.js",
|
|
6
6
|
"exports": "./helpers.js",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"engines": {
|
|
16
16
|
"node": ">=14.18.0"
|
|
17
17
|
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"markdownlint-micromark": "0.1.2"
|
|
20
|
+
},
|
|
18
21
|
"keywords": [
|
|
19
22
|
"markdownlint",
|
|
20
23
|
"markdownlint-rule"
|
package/lib/constants.js
CHANGED
package/lib/markdownlint.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ export = markdownlint;
|
|
|
2
2
|
/**
|
|
3
3
|
* Lint specified Markdown files.
|
|
4
4
|
*
|
|
5
|
-
* @param {Options} options Configuration options.
|
|
5
|
+
* @param {Options | null} options Configuration options.
|
|
6
6
|
* @param {LintCallback} callback Callback (err, result) function.
|
|
7
7
|
* @returns {void}
|
|
8
8
|
*/
|
|
9
|
-
declare function markdownlint(options: Options, callback: LintCallback): void;
|
|
9
|
+
declare function markdownlint(options: Options | null, callback: LintCallback): void;
|
|
10
10
|
declare namespace markdownlint {
|
|
11
11
|
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
|
|
12
12
|
}
|
|
@@ -33,7 +33,7 @@ type Options = {
|
|
|
33
33
|
/**
|
|
34
34
|
* Front matter pattern.
|
|
35
35
|
*/
|
|
36
|
-
frontMatter?: RegExp;
|
|
36
|
+
frontMatter?: RegExp | null;
|
|
37
37
|
/**
|
|
38
38
|
* File system implementation.
|
|
39
39
|
*/
|
|
@@ -68,10 +68,10 @@ type LintCallback = (err: Error | null, results?: LintResults) => void;
|
|
|
68
68
|
/**
|
|
69
69
|
* Lint specified Markdown files synchronously.
|
|
70
70
|
*
|
|
71
|
-
* @param {Options} options Configuration options.
|
|
71
|
+
* @param {Options | null} options Configuration options.
|
|
72
72
|
* @returns {LintResults} Results object.
|
|
73
73
|
*/
|
|
74
|
-
declare function markdownlintSync(options: Options): LintResults;
|
|
74
|
+
declare function markdownlintSync(options: Options | null): LintResults;
|
|
75
75
|
/**
|
|
76
76
|
* Read specified configuration file.
|
|
77
77
|
*
|
|
@@ -101,6 +101,7 @@ declare function readConfigSync(file: string, parsers?: ConfigurationParser[], f
|
|
|
101
101
|
declare function getVersion(): string;
|
|
102
102
|
declare namespace promises {
|
|
103
103
|
export { markdownlintPromise as markdownlint };
|
|
104
|
+
export { extendConfigPromise as extendConfig };
|
|
104
105
|
export { readConfigPromise as readConfig };
|
|
105
106
|
}
|
|
106
107
|
/**
|
|
@@ -378,6 +379,16 @@ type ResolveConfigExtendsCallback = (err: Error | null, path?: string) => void;
|
|
|
378
379
|
* @returns {Promise<LintResults>} Results object.
|
|
379
380
|
*/
|
|
380
381
|
declare function markdownlintPromise(options: Options): Promise<LintResults>;
|
|
382
|
+
/**
|
|
383
|
+
* Extend specified configuration object.
|
|
384
|
+
*
|
|
385
|
+
* @param {Configuration} config Configuration object.
|
|
386
|
+
* @param {string} file Configuration file name.
|
|
387
|
+
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
|
388
|
+
* @param {Object} [fs] File system implementation.
|
|
389
|
+
* @returns {Promise<Configuration>} Configuration object.
|
|
390
|
+
*/
|
|
391
|
+
declare function extendConfigPromise(config: Configuration, file: string, parsers?: ConfigurationParser[], fs?: any): Promise<Configuration>;
|
|
381
392
|
/**
|
|
382
393
|
* Read specified configuration file.
|
|
383
394
|
*
|
package/lib/markdownlint.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
const path = require("node:path");
|
|
6
6
|
const { promisify } = require("node:util");
|
|
7
|
-
const
|
|
7
|
+
const markdownit = require("markdown-it");
|
|
8
|
+
const micromark = require("../helpers/micromark.cjs");
|
|
8
9
|
const { deprecatedRuleNames } = require("./constants");
|
|
9
10
|
const rules = require("./rules");
|
|
10
11
|
const helpers = require("../helpers");
|
|
@@ -166,7 +167,7 @@ function newResults(ruleList) {
|
|
|
166
167
|
* Remove front matter (if present at beginning of content).
|
|
167
168
|
*
|
|
168
169
|
* @param {string} content Markdown content.
|
|
169
|
-
* @param {RegExp} frontMatter Regular expression to match front matter.
|
|
170
|
+
* @param {RegExp | null} frontMatter Regular expression to match front matter.
|
|
170
171
|
* @returns {Object} Trimmed content and front matter lines.
|
|
171
172
|
*/
|
|
172
173
|
function removeFrontMatter(content, frontMatter) {
|
|
@@ -508,12 +509,14 @@ function getEnabledRulesPerLineNumber(
|
|
|
508
509
|
* Lints a string containing Markdown content.
|
|
509
510
|
*
|
|
510
511
|
* @param {Rule[]} ruleList List of rules.
|
|
512
|
+
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
|
513
|
+
* names.
|
|
511
514
|
* @param {string} name Identifier for the content.
|
|
512
515
|
* @param {string} content Markdown content.
|
|
513
516
|
* @param {Object} md Instance of markdown-it.
|
|
514
517
|
* @param {Configuration} config Configuration object.
|
|
515
518
|
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
|
516
|
-
* @param {RegExp} frontMatter Regular expression for front matter.
|
|
519
|
+
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
|
517
520
|
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
|
|
518
521
|
* @param {boolean} noInlineConfig Whether to allow inline configuration.
|
|
519
522
|
* @param {number} resultVersion Version of the LintResults object to return.
|
|
@@ -522,6 +525,7 @@ function getEnabledRulesPerLineNumber(
|
|
|
522
525
|
*/
|
|
523
526
|
function lintContent(
|
|
524
527
|
ruleList,
|
|
528
|
+
aliasToRuleNames,
|
|
525
529
|
name,
|
|
526
530
|
content,
|
|
527
531
|
md,
|
|
@@ -547,18 +551,29 @@ function lintContent(
|
|
|
547
551
|
noInlineConfig,
|
|
548
552
|
config,
|
|
549
553
|
configParsers,
|
|
550
|
-
|
|
554
|
+
aliasToRuleNames
|
|
551
555
|
);
|
|
552
|
-
//
|
|
556
|
+
// Parse content into parser tokens
|
|
557
|
+
const markdownitTokens = md.parse(content, {});
|
|
558
|
+
const micromarkTokens = micromark.parse(content);
|
|
559
|
+
// Hide the content of HTML comments from rules
|
|
553
560
|
content = helpers.clearHtmlCommentText(content);
|
|
554
|
-
// Parse content into
|
|
555
|
-
const tokens = md.parse(content, {});
|
|
561
|
+
// Parse content into lines and update markdown-it tokens
|
|
556
562
|
const lines = content.split(helpers.newLineRe);
|
|
557
|
-
annotateAndFreezeTokens(
|
|
563
|
+
annotateAndFreezeTokens(markdownitTokens, lines);
|
|
558
564
|
// Create (frozen) parameters for rules
|
|
565
|
+
const parsers = Object.freeze({
|
|
566
|
+
"markdownit": Object.freeze({
|
|
567
|
+
"tokens": markdownitTokens
|
|
568
|
+
}),
|
|
569
|
+
"micromark": Object.freeze({
|
|
570
|
+
"tokens": micromarkTokens
|
|
571
|
+
})
|
|
572
|
+
});
|
|
559
573
|
const paramsBase = {
|
|
560
574
|
name,
|
|
561
|
-
|
|
575
|
+
parsers,
|
|
576
|
+
"tokens": markdownitTokens,
|
|
562
577
|
"lines": Object.freeze(lines),
|
|
563
578
|
"frontMatterLines": Object.freeze(frontMatterLines)
|
|
564
579
|
};
|
|
@@ -567,11 +582,11 @@ function lintContent(
|
|
|
567
582
|
const codeBlockAndSpanRanges =
|
|
568
583
|
helpers.codeBlockAndSpanRanges(paramsBase, lineMetadata);
|
|
569
584
|
const flattenedLists =
|
|
570
|
-
helpers.flattenLists(paramsBase.tokens);
|
|
585
|
+
helpers.flattenLists(paramsBase.parsers.markdownit.tokens);
|
|
571
586
|
const htmlElementRanges =
|
|
572
587
|
helpers.htmlElementRanges(paramsBase, lineMetadata);
|
|
573
588
|
const referenceLinkImageData =
|
|
574
|
-
helpers.getReferenceLinkImageData(
|
|
589
|
+
helpers.getReferenceLinkImageData(paramsBase);
|
|
575
590
|
cache.set({
|
|
576
591
|
codeBlockAndSpanRanges,
|
|
577
592
|
flattenedLists,
|
|
@@ -780,11 +795,13 @@ function lintContent(
|
|
|
780
795
|
* Lints a file containing Markdown content.
|
|
781
796
|
*
|
|
782
797
|
* @param {Rule[]} ruleList List of rules.
|
|
798
|
+
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
|
799
|
+
* names.
|
|
783
800
|
* @param {string} file Path of file to lint.
|
|
784
801
|
* @param {Object} md Instance of markdown-it.
|
|
785
802
|
* @param {Configuration} config Configuration object.
|
|
786
803
|
* @param {ConfigurationParser[] | null} configParsers Configuration parsers.
|
|
787
|
-
* @param {RegExp} frontMatter Regular expression for front matter.
|
|
804
|
+
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
|
788
805
|
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
|
|
789
806
|
* @param {boolean} noInlineConfig Whether to allow inline configuration.
|
|
790
807
|
* @param {number} resultVersion Version of the LintResults object to return.
|
|
@@ -795,6 +812,7 @@ function lintContent(
|
|
|
795
812
|
*/
|
|
796
813
|
function lintFile(
|
|
797
814
|
ruleList,
|
|
815
|
+
aliasToRuleNames,
|
|
798
816
|
file,
|
|
799
817
|
md,
|
|
800
818
|
config,
|
|
@@ -813,6 +831,7 @@ function lintFile(
|
|
|
813
831
|
}
|
|
814
832
|
return lintContent(
|
|
815
833
|
ruleList,
|
|
834
|
+
aliasToRuleNames,
|
|
816
835
|
file,
|
|
817
836
|
content,
|
|
818
837
|
md,
|
|
@@ -836,7 +855,7 @@ function lintFile(
|
|
|
836
855
|
/**
|
|
837
856
|
* Lint files and strings specified in the Options object.
|
|
838
857
|
*
|
|
839
|
-
* @param {Options} options Options object.
|
|
858
|
+
* @param {Options | null} options Options object.
|
|
840
859
|
* @param {boolean} synchronous Whether to execute synchronously.
|
|
841
860
|
* @param {Function} callback Callback (err, result) function.
|
|
842
861
|
* @returns {void}
|
|
@@ -868,13 +887,14 @@ function lintInput(options, synchronous, callback) {
|
|
|
868
887
|
const noInlineConfig = !!options.noInlineConfig;
|
|
869
888
|
const resultVersion = (options.resultVersion === undefined) ?
|
|
870
889
|
3 : options.resultVersion;
|
|
871
|
-
const md =
|
|
890
|
+
const md = markdownit({ "html": true });
|
|
872
891
|
const markdownItPlugins = options.markdownItPlugins || [];
|
|
873
892
|
for (const plugin of markdownItPlugins) {
|
|
874
893
|
// @ts-ignore
|
|
875
894
|
md.use(...plugin);
|
|
876
895
|
}
|
|
877
896
|
const fs = options.fs || require("node:fs");
|
|
897
|
+
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
|
878
898
|
const results = newResults(ruleList);
|
|
879
899
|
let done = false;
|
|
880
900
|
let concurrency = 0;
|
|
@@ -902,6 +922,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
902
922
|
currentItem = files.shift();
|
|
903
923
|
lintFile(
|
|
904
924
|
ruleList,
|
|
925
|
+
aliasToRuleNames,
|
|
905
926
|
currentItem,
|
|
906
927
|
md,
|
|
907
928
|
config,
|
|
@@ -919,6 +940,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
919
940
|
concurrency++;
|
|
920
941
|
lintContent(
|
|
921
942
|
ruleList,
|
|
943
|
+
aliasToRuleNames,
|
|
922
944
|
currentItem,
|
|
923
945
|
strings[currentItem] || "",
|
|
924
946
|
md,
|
|
@@ -959,7 +981,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
959
981
|
/**
|
|
960
982
|
* Lint specified Markdown files.
|
|
961
983
|
*
|
|
962
|
-
* @param {Options} options Configuration options.
|
|
984
|
+
* @param {Options | null} options Configuration options.
|
|
963
985
|
* @param {LintCallback} callback Callback (err, result) function.
|
|
964
986
|
* @returns {void}
|
|
965
987
|
*/
|
|
@@ -983,7 +1005,7 @@ function markdownlintPromise(options) {
|
|
|
983
1005
|
/**
|
|
984
1006
|
* Lint specified Markdown files synchronously.
|
|
985
1007
|
*
|
|
986
|
-
* @param {Options} options Configuration options.
|
|
1008
|
+
* @param {Options | null} options Configuration options.
|
|
987
1009
|
* @returns {LintResults} Results object.
|
|
988
1010
|
*/
|
|
989
1011
|
function markdownlintSync(options) {
|
|
@@ -1057,6 +1079,63 @@ function resolveConfigExtendsSync(configFile, referenceId, fs) {
|
|
|
1057
1079
|
return resolvedExtendsFile;
|
|
1058
1080
|
}
|
|
1059
1081
|
|
|
1082
|
+
/**
|
|
1083
|
+
* Extend specified configuration object.
|
|
1084
|
+
*
|
|
1085
|
+
* @param {Configuration} config Configuration object.
|
|
1086
|
+
* @param {string} file Configuration file name.
|
|
1087
|
+
* @param {ConfigurationParser[]} parsers Parsing
|
|
1088
|
+
* function(s).
|
|
1089
|
+
* @param {Object} fs File system implementation.
|
|
1090
|
+
* @param {ReadConfigCallback} callback Callback (err, result) function.
|
|
1091
|
+
* @returns {void}
|
|
1092
|
+
*/
|
|
1093
|
+
function extendConfig(config, file, parsers, fs, callback) {
|
|
1094
|
+
const configExtends = config.extends;
|
|
1095
|
+
if (configExtends) {
|
|
1096
|
+
return resolveConfigExtends(
|
|
1097
|
+
file,
|
|
1098
|
+
helpers.expandTildePath(configExtends, require("node:os")),
|
|
1099
|
+
fs,
|
|
1100
|
+
// eslint-disable-next-line no-use-before-define
|
|
1101
|
+
(_, resolvedExtends) => readConfig(
|
|
1102
|
+
// @ts-ignore
|
|
1103
|
+
resolvedExtends,
|
|
1104
|
+
parsers,
|
|
1105
|
+
fs,
|
|
1106
|
+
(err, extendsConfig) => {
|
|
1107
|
+
if (err) {
|
|
1108
|
+
return callback(err);
|
|
1109
|
+
}
|
|
1110
|
+
const result = {
|
|
1111
|
+
...extendsConfig,
|
|
1112
|
+
...config
|
|
1113
|
+
};
|
|
1114
|
+
delete result.extends;
|
|
1115
|
+
return callback(null, result);
|
|
1116
|
+
}
|
|
1117
|
+
)
|
|
1118
|
+
);
|
|
1119
|
+
}
|
|
1120
|
+
return callback(null, config);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
const extendConfigPromisify = promisify && promisify(extendConfig);
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Extend specified configuration object.
|
|
1127
|
+
*
|
|
1128
|
+
* @param {Configuration} config Configuration object.
|
|
1129
|
+
* @param {string} file Configuration file name.
|
|
1130
|
+
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
|
1131
|
+
* @param {Object} [fs] File system implementation.
|
|
1132
|
+
* @returns {Promise<Configuration>} Configuration object.
|
|
1133
|
+
*/
|
|
1134
|
+
function extendConfigPromise(config, file, parsers, fs) {
|
|
1135
|
+
// @ts-ignore
|
|
1136
|
+
return extendConfigPromisify(config, file, parsers, fs);
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1060
1139
|
/**
|
|
1061
1140
|
* Read specified configuration file.
|
|
1062
1141
|
*
|
|
@@ -1083,8 +1162,7 @@ function readConfig(file, parsers, fs, callback) {
|
|
|
1083
1162
|
fs = require("node:fs");
|
|
1084
1163
|
}
|
|
1085
1164
|
// Read file
|
|
1086
|
-
|
|
1087
|
-
file = helpers.expandTildePath(file, os);
|
|
1165
|
+
file = helpers.expandTildePath(file, require("node:os"));
|
|
1088
1166
|
fs.readFile(file, "utf8", (err, content) => {
|
|
1089
1167
|
if (err) {
|
|
1090
1168
|
// @ts-ignore
|
|
@@ -1098,34 +1176,8 @@ function readConfig(file, parsers, fs, callback) {
|
|
|
1098
1176
|
return callback(new Error(message));
|
|
1099
1177
|
}
|
|
1100
1178
|
// Extend configuration
|
|
1101
|
-
const configExtends = config.extends;
|
|
1102
|
-
if (configExtends) {
|
|
1103
|
-
delete config.extends;
|
|
1104
|
-
return resolveConfigExtends(
|
|
1105
|
-
file,
|
|
1106
|
-
helpers.expandTildePath(configExtends, os),
|
|
1107
|
-
fs,
|
|
1108
|
-
(_, resolvedExtends) => readConfig(
|
|
1109
|
-
// @ts-ignore
|
|
1110
|
-
resolvedExtends,
|
|
1111
|
-
parsers,
|
|
1112
|
-
fs,
|
|
1113
|
-
(errr, extendsConfig) => {
|
|
1114
|
-
if (errr) {
|
|
1115
|
-
// @ts-ignore
|
|
1116
|
-
return callback(errr);
|
|
1117
|
-
}
|
|
1118
|
-
// @ts-ignore
|
|
1119
|
-
return callback(null, {
|
|
1120
|
-
...extendsConfig,
|
|
1121
|
-
...config
|
|
1122
|
-
});
|
|
1123
|
-
}
|
|
1124
|
-
)
|
|
1125
|
-
);
|
|
1126
|
-
}
|
|
1127
1179
|
// @ts-ignore
|
|
1128
|
-
return
|
|
1180
|
+
return extendConfig(config, file, parsers, fs, callback);
|
|
1129
1181
|
});
|
|
1130
1182
|
}
|
|
1131
1183
|
|
|
@@ -1199,6 +1251,7 @@ markdownlint.readConfigSync = readConfigSync;
|
|
|
1199
1251
|
markdownlint.getVersion = getVersion;
|
|
1200
1252
|
markdownlint.promises = {
|
|
1201
1253
|
"markdownlint": markdownlintPromise,
|
|
1254
|
+
"extendConfig": extendConfigPromise,
|
|
1202
1255
|
"readConfig": readConfigPromise
|
|
1203
1256
|
};
|
|
1204
1257
|
module.exports = markdownlint;
|
|
@@ -1295,7 +1348,7 @@ module.exports = markdownlint;
|
|
|
1295
1348
|
* @property {ConfigurationParser[]} [configParsers] Configuration parsers.
|
|
1296
1349
|
* @property {Rule[] | Rule} [customRules] Custom rules.
|
|
1297
1350
|
* @property {string[] | string} [files] Files to lint.
|
|
1298
|
-
* @property {RegExp} [frontMatter] Front matter pattern.
|
|
1351
|
+
* @property {RegExp | null} [frontMatter] Front matter pattern.
|
|
1299
1352
|
* @property {Object} [fs] File system implementation.
|
|
1300
1353
|
* @property {boolean} [handleRuleFailures] True to catch exceptions.
|
|
1301
1354
|
* @property {Plugin[]} [markdownItPlugins] Additional plugins.
|
package/lib/md002.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
"function": function MD002(params, onError) {
|
|
12
12
|
const level = Number(params.config.level || 1);
|
|
13
13
|
const tag = "h" + level;
|
|
14
|
-
params.tokens.every(function forToken(token) {
|
|
14
|
+
params.parsers.markdownit.tokens.every(function forToken(token) {
|
|
15
15
|
if (token.type === "heading_open") {
|
|
16
16
|
addErrorDetailIf(onError, token.lineNumber, tag, token.tag);
|
|
17
17
|
return false;
|
package/lib/md027.js
CHANGED
|
@@ -13,7 +13,7 @@ module.exports = {
|
|
|
13
13
|
"function": function MD027(params, onError) {
|
|
14
14
|
let blockquoteNesting = 0;
|
|
15
15
|
let listItemNesting = 0;
|
|
16
|
-
for (const token of params.tokens) {
|
|
16
|
+
for (const token of params.parsers.markdownit.tokens) {
|
|
17
17
|
const { content, lineNumber, type } = token;
|
|
18
18
|
if (type === "blockquote_open") {
|
|
19
19
|
blockquoteNesting++;
|
package/lib/md028.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
"function": function MD028(params, onError) {
|
|
12
12
|
let prevToken = {};
|
|
13
13
|
let prevLineNumber = null;
|
|
14
|
-
for (const token of params.tokens) {
|
|
14
|
+
for (const token of params.parsers.markdownit.tokens) {
|
|
15
15
|
if ((token.type === "blockquote_open") &&
|
|
16
16
|
(prevToken.type === "blockquote_close")) {
|
|
17
17
|
for (
|