markdownlint 0.38.0 → 0.40.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 +15 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +144 -75
- package/doc/Rules.md +174 -18
- package/doc/md001.md +14 -0
- package/doc/md009.md +8 -9
- package/doc/md010.md +6 -0
- package/doc/md029.md +2 -0
- package/doc/md033.md +7 -1
- package/doc/md051.md +10 -5
- package/doc/md055.md +1 -1
- package/doc/md056.md +1 -1
- package/doc/md059.md +4 -1
- package/doc/md060.md +118 -0
- package/helpers/README.md +2 -2
- package/helpers/helpers.cjs +171 -15
- package/helpers/micromark-helpers.cjs +11 -7
- package/helpers/package.json +1 -1
- package/lib/cache.mjs +6 -2
- package/lib/configuration-strict.d.ts +1351 -205
- package/lib/constants.mjs +6 -5
- package/lib/defer-require.cjs +2 -0
- package/lib/exports.d.mts +1 -2
- package/lib/exports.mjs +1 -2
- package/lib/markdownit.cjs +2 -1
- package/lib/markdownlint.d.mts +101 -51
- package/lib/markdownlint.mjs +217 -181
- package/lib/md001.mjs +6 -2
- package/lib/md004.mjs +7 -18
- package/lib/md007.mjs +2 -1
- package/lib/md009.mjs +9 -5
- package/lib/md010.mjs +1 -1
- package/lib/md011.mjs +8 -6
- package/lib/md013.mjs +14 -27
- package/lib/md022.mjs +5 -2
- package/lib/md029.mjs +25 -14
- package/lib/md031.mjs +0 -1
- package/lib/md032.mjs +3 -1
- package/lib/md033.mjs +28 -20
- package/lib/md034.mjs +2 -1
- package/lib/md036.mjs +5 -3
- package/lib/md037.mjs +10 -7
- package/lib/md042.mjs +4 -2
- package/lib/md043.mjs +2 -2
- package/lib/md044.mjs +1 -1
- package/lib/md046.mjs +6 -6
- package/lib/md053.mjs +1 -1
- package/lib/md054.mjs +7 -5
- package/lib/md055.mjs +7 -6
- package/lib/md056.mjs +1 -1
- package/lib/md060.mjs +170 -0
- package/lib/micromark-parse.mjs +5 -3
- package/lib/node-imports-browser.mjs +2 -0
- package/lib/parse-configuration.mjs +5 -4
- package/lib/rules.mjs +3 -1
- package/package.json +18 -18
- package/schema/.markdownlint.jsonc +69 -54
- package/schema/.markdownlint.yaml +66 -53
- package/schema/markdownlint-config-schema-strict.json +4709 -1537
- package/schema/markdownlint-config-schema.json +4709 -1537
package/lib/markdownlint.mjs
CHANGED
|
@@ -24,15 +24,17 @@ function validateRuleList(ruleList, synchronous) {
|
|
|
24
24
|
// No need to validate if only using built-in rules
|
|
25
25
|
return result;
|
|
26
26
|
}
|
|
27
|
+
/** @type {Object.<string, boolean>} */
|
|
27
28
|
const allIds = {};
|
|
28
29
|
for (const [ index, rule ] of ruleList.entries()) {
|
|
29
30
|
const customIndex = index - rules.length;
|
|
30
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
31
|
-
function newError(property, value) {
|
|
31
|
+
// eslint-disable-next-line jsdoc/reject-any-type, jsdoc/require-jsdoc
|
|
32
|
+
function newError(/** @type {string} */ property, /** @type {any} */ value) {
|
|
32
33
|
return new Error(
|
|
33
34
|
`Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`);
|
|
34
35
|
}
|
|
35
36
|
for (const property of [ "names", "tags" ]) {
|
|
37
|
+
// @ts-ignore
|
|
36
38
|
const value = rule[property];
|
|
37
39
|
if (!result &&
|
|
38
40
|
(!value || !Array.isArray(value) || (value.length === 0) ||
|
|
@@ -45,6 +47,7 @@ function validateRuleList(ruleList, synchronous) {
|
|
|
45
47
|
[ "function", "function" ]
|
|
46
48
|
]) {
|
|
47
49
|
const property = propertyInfo[0];
|
|
50
|
+
// @ts-ignore
|
|
48
51
|
const value = rule[property];
|
|
49
52
|
if (!result && (!value || (typeof value !== propertyInfo[1]))) {
|
|
50
53
|
result = newError(property, value);
|
|
@@ -108,9 +111,17 @@ function validateRuleList(ruleList, synchronous) {
|
|
|
108
111
|
* @returns {LintResults} New LintResults instance.
|
|
109
112
|
*/
|
|
110
113
|
function newResults(ruleList) {
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Returns the string representation of a LintResults instance.
|
|
116
|
+
*
|
|
117
|
+
* @param {boolean} useAlias True if rule alias should be used instead of name.
|
|
118
|
+
* @returns {string} String representation of the instance.
|
|
119
|
+
* @this {LintResults}
|
|
120
|
+
*/
|
|
113
121
|
function toString(useAlias) {
|
|
122
|
+
// eslint-disable-next-line consistent-this, unicorn/no-this-assignment
|
|
123
|
+
const lintResults = this;
|
|
124
|
+
/** @type {Object.<string, Rule> | null} */
|
|
114
125
|
let ruleNameToRule = null;
|
|
115
126
|
const results = [];
|
|
116
127
|
const keys = Object.keys(lintResults);
|
|
@@ -121,6 +132,7 @@ function newResults(ruleList) {
|
|
|
121
132
|
for (const result of fileResults) {
|
|
122
133
|
const ruleMoniker = result.ruleNames ?
|
|
123
134
|
result.ruleNames.join("/") :
|
|
135
|
+
// @ts-ignore
|
|
124
136
|
(result.ruleName + "/" + result.ruleAlias);
|
|
125
137
|
results.push(
|
|
126
138
|
file + ": " +
|
|
@@ -161,19 +173,29 @@ function newResults(ruleList) {
|
|
|
161
173
|
}
|
|
162
174
|
return results.join("\n");
|
|
163
175
|
}
|
|
176
|
+
const lintResults = {};
|
|
164
177
|
Object.defineProperty(lintResults, "toString", { "value": toString });
|
|
165
178
|
// @ts-ignore
|
|
166
179
|
return lintResults;
|
|
167
180
|
}
|
|
168
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Result object for removeFrontMatter.
|
|
184
|
+
*
|
|
185
|
+
* @typedef {Object} RemoveFrontMatterResult
|
|
186
|
+
* @property {string} content Markdown content.
|
|
187
|
+
* @property {string[]} frontMatterLines Front matter lines.
|
|
188
|
+
*/
|
|
189
|
+
|
|
169
190
|
/**
|
|
170
191
|
* Remove front matter (if present at beginning of content).
|
|
171
192
|
*
|
|
172
193
|
* @param {string} content Markdown content.
|
|
173
194
|
* @param {RegExp | null} frontMatter Regular expression to match front matter.
|
|
174
|
-
* @returns {
|
|
195
|
+
* @returns {RemoveFrontMatterResult} Trimmed content and front matter lines.
|
|
175
196
|
*/
|
|
176
197
|
function removeFrontMatter(content, frontMatter) {
|
|
198
|
+
/** @type {string[]} */
|
|
177
199
|
let frontMatterLines = [];
|
|
178
200
|
if (frontMatter) {
|
|
179
201
|
const frontMatterMatch = content.match(frontMatter);
|
|
@@ -200,6 +222,7 @@ function removeFrontMatter(content, frontMatter) {
|
|
|
200
222
|
* @returns {Object.<string, string[]>} Map of alias to rule name.
|
|
201
223
|
*/
|
|
202
224
|
function mapAliasToRuleNames(ruleList) {
|
|
225
|
+
/** @type {Object.<string, string[]>} */
|
|
203
226
|
const aliasToRuleNames = {};
|
|
204
227
|
// const tagToRuleNames = {};
|
|
205
228
|
for (const rule of ruleList) {
|
|
@@ -229,44 +252,87 @@ function mapAliasToRuleNames(ruleList) {
|
|
|
229
252
|
return aliasToRuleNames;
|
|
230
253
|
}
|
|
231
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Result object for getEffectiveConfig.
|
|
257
|
+
*
|
|
258
|
+
* @typedef {Object} GetEffectiveConfigResult
|
|
259
|
+
* @property {Configuration} effectiveConfig Effective configuration.
|
|
260
|
+
* @property {Map<string, boolean>} rulesEnabled Rules enabled.
|
|
261
|
+
* @property {Map<string, "error" | "warning">} rulesSeverity Rules severity.
|
|
262
|
+
*/
|
|
263
|
+
|
|
232
264
|
/**
|
|
233
265
|
* Apply (and normalize) configuration object.
|
|
234
266
|
*
|
|
235
267
|
* @param {Rule[]} ruleList List of rules.
|
|
236
268
|
* @param {Configuration} config Configuration object.
|
|
237
|
-
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
|
238
|
-
*
|
|
239
|
-
* @returns {Configuration} Effective configuration.
|
|
269
|
+
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
|
|
270
|
+
* @returns {GetEffectiveConfigResult} Effective configuration and rule severities.
|
|
240
271
|
*/
|
|
241
272
|
function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
273
|
+
let ruleDefaultEnable = true;
|
|
274
|
+
/** @type {"error" | "warning"} */
|
|
275
|
+
let ruleDefaultSeverity = "error";
|
|
276
|
+
Object.entries(config).every(([ key, value ]) => {
|
|
277
|
+
if (key.toUpperCase() === "DEFAULT") {
|
|
278
|
+
ruleDefaultEnable = !!value;
|
|
279
|
+
if (value === "warning") {
|
|
280
|
+
ruleDefaultSeverity = "warning";
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
return true;
|
|
285
|
+
});
|
|
246
286
|
/** @type {Configuration} */
|
|
247
287
|
const effectiveConfig = {};
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
288
|
+
/** @type {Map<string, boolean>} */
|
|
289
|
+
const rulesEnabled = new Map();
|
|
290
|
+
/** @type {Map<string, "error" | "warning">} */
|
|
291
|
+
const rulesSeverity = new Map();
|
|
292
|
+
const emptyObject = Object.freeze({});
|
|
293
|
+
for (const ruleName of ruleList.map((rule) => rule.names[0].toUpperCase())) {
|
|
294
|
+
effectiveConfig[ruleName] = emptyObject;
|
|
295
|
+
rulesEnabled.set(ruleName, ruleDefaultEnable);
|
|
296
|
+
rulesSeverity.set(ruleName, ruleDefaultSeverity);
|
|
251
297
|
}
|
|
252
298
|
// for (const ruleName of deprecatedRuleNames) {
|
|
253
299
|
// effectiveConfig[ruleName] = false;
|
|
254
300
|
// }
|
|
255
|
-
for (const key of Object.
|
|
256
|
-
|
|
301
|
+
for (const [ key, value ] of Object.entries(config)) {
|
|
302
|
+
const keyUpper = key.toUpperCase();
|
|
303
|
+
/** @type {boolean} */
|
|
304
|
+
let enabled = false;
|
|
305
|
+
/** @type {"error" | "warning"} */
|
|
306
|
+
let severity = "error";
|
|
307
|
+
let effectiveValue = {};
|
|
257
308
|
if (value) {
|
|
258
|
-
if (
|
|
259
|
-
|
|
309
|
+
if (value instanceof Object) {
|
|
310
|
+
/** @type {{ enabled?: boolean, severity?: "error" | "warning" }} */
|
|
311
|
+
const valueObject = value;
|
|
312
|
+
enabled = (valueObject.enabled === undefined) ? true : !!valueObject.enabled;
|
|
313
|
+
severity = (valueObject.severity === "warning") ? "warning" : "error";
|
|
314
|
+
effectiveValue = Object.fromEntries(
|
|
315
|
+
Object.entries(value).filter(
|
|
316
|
+
([ k ]) => (k !== "enabled") && (k !== "severity")
|
|
317
|
+
)
|
|
318
|
+
);
|
|
319
|
+
} else {
|
|
320
|
+
enabled = true;
|
|
321
|
+
severity = (value === "warning") ? "warning" : "error";
|
|
260
322
|
}
|
|
261
|
-
} else {
|
|
262
|
-
value = false;
|
|
263
323
|
}
|
|
264
|
-
const keyUpper = key.toUpperCase();
|
|
265
324
|
for (const ruleName of (aliasToRuleNames[keyUpper] || [])) {
|
|
266
|
-
|
|
325
|
+
Object.freeze(effectiveValue);
|
|
326
|
+
effectiveConfig[ruleName] = effectiveValue;
|
|
327
|
+
rulesEnabled.set(ruleName, enabled);
|
|
328
|
+
rulesSeverity.set(ruleName, severity);
|
|
267
329
|
}
|
|
268
330
|
}
|
|
269
|
-
return
|
|
331
|
+
return {
|
|
332
|
+
effectiveConfig,
|
|
333
|
+
rulesEnabled,
|
|
334
|
+
rulesSeverity
|
|
335
|
+
};
|
|
270
336
|
}
|
|
271
337
|
|
|
272
338
|
/**
|
|
@@ -274,8 +340,9 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
|
|
|
274
340
|
*
|
|
275
341
|
* @typedef {Object} EnabledRulesPerLineNumberResult
|
|
276
342
|
* @property {Configuration} effectiveConfig Effective configuration.
|
|
277
|
-
* @property {
|
|
343
|
+
* @property {Map<string, boolean>[]} enabledRulesPerLineNumber Enabled rules per line number.
|
|
278
344
|
* @property {Rule[]} enabledRuleList Enabled rule list.
|
|
345
|
+
* @property {Map<string, "error" | "warning">} rulesSeverity Rules severity.
|
|
279
346
|
*/
|
|
280
347
|
|
|
281
348
|
/**
|
|
@@ -287,8 +354,7 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
|
|
|
287
354
|
* @param {boolean} noInlineConfig Whether to allow inline configuration.
|
|
288
355
|
* @param {Configuration} config Configuration object.
|
|
289
356
|
* @param {ConfigurationParser[] | undefined} configParsers Configuration parsers.
|
|
290
|
-
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
|
|
291
|
-
* names.
|
|
357
|
+
* @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule names.
|
|
292
358
|
* @returns {EnabledRulesPerLineNumberResult} Effective configuration and enabled rules per line number.
|
|
293
359
|
*/
|
|
294
360
|
function getEnabledRulesPerLineNumber(
|
|
@@ -300,13 +366,14 @@ function getEnabledRulesPerLineNumber(
|
|
|
300
366
|
configParsers,
|
|
301
367
|
aliasToRuleNames) {
|
|
302
368
|
// Shared variables
|
|
303
|
-
|
|
304
|
-
let
|
|
305
|
-
|
|
369
|
+
/** @type {Map<string, boolean>} */
|
|
370
|
+
let enabledRules = new Map();
|
|
371
|
+
/** @type {Map<string, boolean>} */
|
|
372
|
+
let capturedRules = enabledRules;
|
|
306
373
|
const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length);
|
|
307
374
|
// Helper functions
|
|
308
375
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
309
|
-
function handleInlineConfig(input, forEachMatch, forEachLine) {
|
|
376
|
+
function handleInlineConfig(/** @type {string[]} */ input, /** @type {(act: string, par: string, ind: number) => void} */ forEachMatch, /** @type {(() => void)|undefined} */ forEachLine = undefined) {
|
|
310
377
|
for (const [ lineIndex, line ] of input.entries()) {
|
|
311
378
|
if (!noInlineConfig) {
|
|
312
379
|
let match = null;
|
|
@@ -327,7 +394,7 @@ function getEnabledRulesPerLineNumber(
|
|
|
327
394
|
}
|
|
328
395
|
}
|
|
329
396
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
330
|
-
function configureFile(action, parameter) {
|
|
397
|
+
function configureFile(/** @type {string} */ action, /** @type {string} */ parameter) {
|
|
331
398
|
if (action === "CONFIGURE-FILE") {
|
|
332
399
|
const { "config": parsed } = parseConfiguration(
|
|
333
400
|
"CONFIGURE-FILE", parameter, configParsers
|
|
@@ -341,26 +408,27 @@ function getEnabledRulesPerLineNumber(
|
|
|
341
408
|
}
|
|
342
409
|
}
|
|
343
410
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
344
|
-
function applyEnableDisable(action, parameter, state) {
|
|
345
|
-
state =
|
|
411
|
+
function applyEnableDisable(/** @type {string} */ action, /** @type {string} */ parameter, /** @type {Map<string, boolean>} */ state) {
|
|
412
|
+
state = new Map(state);
|
|
346
413
|
const enabled = (action.startsWith("ENABLE"));
|
|
347
414
|
const trimmed = parameter && parameter.trim();
|
|
415
|
+
// eslint-disable-next-line no-use-before-define
|
|
348
416
|
const items = trimmed ? trimmed.toUpperCase().split(/\s+/) : allRuleNames;
|
|
349
417
|
for (const nameUpper of items) {
|
|
350
418
|
for (const ruleName of (aliasToRuleNames[nameUpper] || [])) {
|
|
351
|
-
state
|
|
419
|
+
state.set(ruleName, enabled);
|
|
352
420
|
}
|
|
353
421
|
}
|
|
354
422
|
return state;
|
|
355
423
|
}
|
|
356
424
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
357
|
-
function enableDisableFile(action, parameter) {
|
|
425
|
+
function enableDisableFile(/** @type {string} */ action, /** @type {string} */ parameter) {
|
|
358
426
|
if ((action === "ENABLE-FILE") || (action === "DISABLE-FILE")) {
|
|
359
427
|
enabledRules = applyEnableDisable(action, parameter, enabledRules);
|
|
360
428
|
}
|
|
361
429
|
}
|
|
362
430
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
363
|
-
function captureRestoreEnableDisable(action, parameter) {
|
|
431
|
+
function captureRestoreEnableDisable(/** @type {string} */ action, /** @type {string} */ parameter) {
|
|
364
432
|
if (action === "CAPTURE") {
|
|
365
433
|
capturedRules = enabledRules;
|
|
366
434
|
} else if (action === "RESTORE") {
|
|
@@ -374,7 +442,7 @@ function getEnabledRulesPerLineNumber(
|
|
|
374
442
|
enabledRulesPerLineNumber.push(enabledRules);
|
|
375
443
|
}
|
|
376
444
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
377
|
-
function disableLineNextLine(action, parameter, lineNumber) {
|
|
445
|
+
function disableLineNextLine(/** @type {string} */ action, /** @type {string} */ parameter, /** @type {number} */ lineNumber) {
|
|
378
446
|
const disableLine = (action === "DISABLE-LINE");
|
|
379
447
|
const disableNextLine = (action === "DISABLE-NEXT-LINE");
|
|
380
448
|
if (disableLine || disableNextLine) {
|
|
@@ -390,29 +458,24 @@ function getEnabledRulesPerLineNumber(
|
|
|
390
458
|
}
|
|
391
459
|
// Handle inline comments
|
|
392
460
|
handleInlineConfig([ lines.join("\n") ], configureFile);
|
|
393
|
-
const effectiveConfig = getEffectiveConfig(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const ruleName = rule.names[0].toUpperCase();
|
|
397
|
-
allRuleNames.push(ruleName);
|
|
398
|
-
enabledRules[ruleName] = !!effectiveConfig[ruleName];
|
|
399
|
-
}
|
|
461
|
+
const { effectiveConfig, rulesEnabled, rulesSeverity } = getEffectiveConfig(ruleList, config, aliasToRuleNames);
|
|
462
|
+
const allRuleNames = [ ...rulesEnabled.keys() ];
|
|
463
|
+
enabledRules = new Map(rulesEnabled);
|
|
400
464
|
capturedRules = enabledRules;
|
|
401
465
|
handleInlineConfig(lines, enableDisableFile);
|
|
402
466
|
handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState);
|
|
403
467
|
handleInlineConfig(lines, disableLineNextLine);
|
|
404
468
|
// Create the list of rules that are used at least once
|
|
405
|
-
const enabledRuleList =
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
}
|
|
469
|
+
const enabledRuleList = ruleList.filter((rule) => {
|
|
470
|
+
const ruleName = rule.names[0].toUpperCase();
|
|
471
|
+
return enabledRulesPerLineNumber.some((enabledRulesForLine) => enabledRulesForLine.get(ruleName));
|
|
472
|
+
});
|
|
411
473
|
// Return results
|
|
412
474
|
return {
|
|
413
475
|
effectiveConfig,
|
|
414
476
|
enabledRulesPerLineNumber,
|
|
415
|
-
enabledRuleList
|
|
477
|
+
enabledRuleList,
|
|
478
|
+
rulesSeverity
|
|
416
479
|
};
|
|
417
480
|
}
|
|
418
481
|
|
|
@@ -429,7 +492,6 @@ function getEnabledRulesPerLineNumber(
|
|
|
429
492
|
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
|
430
493
|
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
|
|
431
494
|
* @param {boolean} noInlineConfig Whether to allow inline configuration.
|
|
432
|
-
* @param {number} resultVersion Version of the LintResults object to return.
|
|
433
495
|
* @param {boolean} synchronous Whether to execute synchronously.
|
|
434
496
|
* @param {LintContentCallback} callback Callback (err, result) function.
|
|
435
497
|
* @returns {void}
|
|
@@ -445,11 +507,11 @@ function lintContent(
|
|
|
445
507
|
frontMatter,
|
|
446
508
|
handleRuleFailures,
|
|
447
509
|
noInlineConfig,
|
|
448
|
-
resultVersion,
|
|
449
510
|
synchronous,
|
|
450
511
|
callback) {
|
|
451
512
|
// Provide a consistent error-reporting callback
|
|
452
|
-
|
|
513
|
+
// eslint-disable-next-line jsdoc/reject-any-type
|
|
514
|
+
const callbackError = (/** @type {any} */ error) => callback(error instanceof Error ? error : new Error(error));
|
|
453
515
|
// Remove UTF-8 byte order marker (if present)
|
|
454
516
|
content = content.replace(/^\uFEFF/, "");
|
|
455
517
|
// Remove front matter
|
|
@@ -457,7 +519,7 @@ function lintContent(
|
|
|
457
519
|
const { frontMatterLines } = removeFrontMatterResult;
|
|
458
520
|
content = removeFrontMatterResult.content;
|
|
459
521
|
// Get enabled rules per line (with HTML comments present)
|
|
460
|
-
const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList } =
|
|
522
|
+
const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList, rulesSeverity } =
|
|
461
523
|
getEnabledRulesPerLineNumber(
|
|
462
524
|
ruleList,
|
|
463
525
|
content.split(helpers.newLineRe),
|
|
@@ -484,7 +546,7 @@ function lintContent(
|
|
|
484
546
|
// Parse content into lines and get markdown-it tokens
|
|
485
547
|
const lines = content.split(helpers.newLineRe);
|
|
486
548
|
// Function to run after fetching markdown-it tokens (when needed)
|
|
487
|
-
const lintContentInternal = (markdownitTokens) => {
|
|
549
|
+
const lintContentInternal = (/** @type {MarkdownItToken[]} */ markdownitTokens) => {
|
|
488
550
|
// Create (frozen) parameters for rules
|
|
489
551
|
/** @type {MarkdownParsers} */
|
|
490
552
|
// @ts-ignore
|
|
@@ -515,7 +577,8 @@ function lintContent(
|
|
|
515
577
|
"config": null
|
|
516
578
|
});
|
|
517
579
|
// Function to run for each rule
|
|
518
|
-
|
|
580
|
+
/** @type {LintError[]} */
|
|
581
|
+
const results = [];
|
|
519
582
|
/**
|
|
520
583
|
* @param {Rule} rule Rule.
|
|
521
584
|
* @returns {Promise<void> | null} Promise.
|
|
@@ -533,19 +596,21 @@ function lintContent(
|
|
|
533
596
|
} else if (rule.parser === "micromark") {
|
|
534
597
|
parsers = parsersMicromark;
|
|
535
598
|
}
|
|
536
|
-
const params = {
|
|
599
|
+
const params = Object.freeze({
|
|
537
600
|
...paramsBase,
|
|
538
601
|
...tokens,
|
|
539
602
|
parsers,
|
|
603
|
+
/** @type {RuleConfiguration} */
|
|
604
|
+
// @ts-ignore
|
|
540
605
|
"config": effectiveConfig[ruleName]
|
|
541
|
-
};
|
|
606
|
+
});
|
|
542
607
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
543
|
-
function throwError(property) {
|
|
608
|
+
function throwError(/** @type {string} */ property) {
|
|
544
609
|
throw new Error(
|
|
545
610
|
`Value of '${property}' passed to onError by '${ruleName}' is incorrect for '${name}'.`);
|
|
546
611
|
}
|
|
547
612
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
548
|
-
function onError(errorInfo) {
|
|
613
|
+
function onError(/** @type {RuleOnErrorInfo} */ errorInfo) {
|
|
549
614
|
if (!errorInfo ||
|
|
550
615
|
!helpers.isNumber(errorInfo.lineNumber) ||
|
|
551
616
|
(errorInfo.lineNumber < 1) ||
|
|
@@ -553,7 +618,7 @@ function lintContent(
|
|
|
553
618
|
throwError("lineNumber");
|
|
554
619
|
}
|
|
555
620
|
const lineNumber = errorInfo.lineNumber + frontMatterLines.length;
|
|
556
|
-
if (!enabledRulesPerLineNumber[lineNumber]
|
|
621
|
+
if (!enabledRulesPerLineNumber[lineNumber].get(ruleName)) {
|
|
557
622
|
return;
|
|
558
623
|
}
|
|
559
624
|
if (errorInfo.detail &&
|
|
@@ -623,17 +688,19 @@ function lintContent(
|
|
|
623
688
|
const information = errorInfo.information || rule.information;
|
|
624
689
|
results.push({
|
|
625
690
|
lineNumber,
|
|
626
|
-
"ruleName": rule.names[0],
|
|
627
691
|
"ruleNames": rule.names,
|
|
628
692
|
"ruleDescription": rule.description,
|
|
629
693
|
"ruleInformation": information ? information.href : null,
|
|
630
|
-
"errorDetail": errorInfo.detail || null,
|
|
631
|
-
"errorContext": errorInfo.context || null,
|
|
694
|
+
"errorDetail": errorInfo.detail?.replace(helpers.newLineRe, " ") || null,
|
|
695
|
+
"errorContext": errorInfo.context?.replace(helpers.newLineRe, " ") || null,
|
|
632
696
|
"errorRange": errorInfo.range ? [ ...errorInfo.range ] : null,
|
|
633
|
-
"fixInfo": fixInfo ? cleanFixInfo : null
|
|
697
|
+
"fixInfo": fixInfo ? cleanFixInfo : null,
|
|
698
|
+
// @ts-ignore
|
|
699
|
+
"severity": rulesSeverity.get(ruleName)
|
|
634
700
|
});
|
|
635
701
|
}
|
|
636
702
|
// Call (possibly external) rule function to report errors
|
|
703
|
+
// @ts-ignore
|
|
637
704
|
const catchCallsOnError = (error) => onError({
|
|
638
705
|
"lineNumber": 1,
|
|
639
706
|
"detail": `This rule threw an exception: ${error.message || error}`
|
|
@@ -650,7 +717,7 @@ function lintContent(
|
|
|
650
717
|
// Synchronous rule
|
|
651
718
|
try {
|
|
652
719
|
invokeRuleFunction();
|
|
653
|
-
} catch
|
|
720
|
+
} catch(error) {
|
|
654
721
|
if (handleRuleFailures) {
|
|
655
722
|
catchCallsOnError(error);
|
|
656
723
|
} else {
|
|
@@ -662,46 +729,9 @@ function lintContent(
|
|
|
662
729
|
const formatResults = () => {
|
|
663
730
|
// Sort results by rule name by line number
|
|
664
731
|
results.sort((a, b) => (
|
|
665
|
-
a.
|
|
732
|
+
a.ruleNames[0].localeCompare(b.ruleNames[0]) ||
|
|
666
733
|
a.lineNumber - b.lineNumber
|
|
667
734
|
));
|
|
668
|
-
if (resultVersion < 3) {
|
|
669
|
-
// Remove fixInfo and multiple errors for the same rule and line number
|
|
670
|
-
const noPrevious = {
|
|
671
|
-
"ruleName": null,
|
|
672
|
-
"lineNumber": -1
|
|
673
|
-
};
|
|
674
|
-
results = results.filter((error, index, array) => {
|
|
675
|
-
delete error.fixInfo;
|
|
676
|
-
const previous = array[index - 1] || noPrevious;
|
|
677
|
-
return (
|
|
678
|
-
(error.ruleName !== previous.ruleName) ||
|
|
679
|
-
(error.lineNumber !== previous.lineNumber)
|
|
680
|
-
);
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
if (resultVersion === 0) {
|
|
684
|
-
// Return a dictionary of rule->[line numbers]
|
|
685
|
-
const dictionary = {};
|
|
686
|
-
for (const error of results) {
|
|
687
|
-
const ruleLines = dictionary[error.ruleName] || [];
|
|
688
|
-
ruleLines.push(error.lineNumber);
|
|
689
|
-
dictionary[error.ruleName] = ruleLines;
|
|
690
|
-
}
|
|
691
|
-
// @ts-ignore
|
|
692
|
-
results = dictionary;
|
|
693
|
-
} else if (resultVersion === 1) {
|
|
694
|
-
// Use ruleAlias instead of ruleNames
|
|
695
|
-
for (const error of results) {
|
|
696
|
-
error.ruleAlias = error.ruleNames[1] || error.ruleName;
|
|
697
|
-
delete error.ruleNames;
|
|
698
|
-
}
|
|
699
|
-
} else {
|
|
700
|
-
// resultVersion 2 or 3: Remove unwanted ruleName
|
|
701
|
-
for (const error of results) {
|
|
702
|
-
delete error.ruleName;
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
735
|
return results;
|
|
706
736
|
};
|
|
707
737
|
// Run all rules
|
|
@@ -721,7 +751,7 @@ function lintContent(
|
|
|
721
751
|
} else {
|
|
722
752
|
callbackSuccess();
|
|
723
753
|
}
|
|
724
|
-
} catch
|
|
754
|
+
} catch(error) {
|
|
725
755
|
callbackError(error);
|
|
726
756
|
} finally {
|
|
727
757
|
cacheInitialize();
|
|
@@ -759,8 +789,7 @@ function lintContent(
|
|
|
759
789
|
* @param {RegExp | null} frontMatter Regular expression for front matter.
|
|
760
790
|
* @param {boolean} handleRuleFailures Whether to handle exceptions in rules.
|
|
761
791
|
* @param {boolean} noInlineConfig Whether to allow inline configuration.
|
|
762
|
-
* @param {
|
|
763
|
-
* @param {Object} fs File system implementation.
|
|
792
|
+
* @param {FsLike} fs File system implementation.
|
|
764
793
|
* @param {boolean} synchronous Whether to execute synchronously.
|
|
765
794
|
* @param {LintContentCallback} callback Callback (err, result) function.
|
|
766
795
|
* @returns {void}
|
|
@@ -775,12 +804,11 @@ function lintFile(
|
|
|
775
804
|
frontMatter,
|
|
776
805
|
handleRuleFailures,
|
|
777
806
|
noInlineConfig,
|
|
778
|
-
resultVersion,
|
|
779
807
|
fs,
|
|
780
808
|
synchronous,
|
|
781
809
|
callback) {
|
|
782
810
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
783
|
-
function lintContentWrapper(err, content) {
|
|
811
|
+
function lintContentWrapper(/** @type {Error | null} */ err, /** @type {string} */ content) {
|
|
784
812
|
if (err) {
|
|
785
813
|
return callback(err);
|
|
786
814
|
}
|
|
@@ -795,7 +823,6 @@ function lintFile(
|
|
|
795
823
|
frontMatter,
|
|
796
824
|
handleRuleFailures,
|
|
797
825
|
noInlineConfig,
|
|
798
|
-
resultVersion,
|
|
799
826
|
synchronous,
|
|
800
827
|
callback
|
|
801
828
|
);
|
|
@@ -820,6 +847,8 @@ function lintInput(options, synchronous, callback) {
|
|
|
820
847
|
// Normalize inputs
|
|
821
848
|
options = options || {};
|
|
822
849
|
callback = callback || function noop() {};
|
|
850
|
+
/** @type {Rule[]} */
|
|
851
|
+
// @ts-ignore
|
|
823
852
|
const customRuleList =
|
|
824
853
|
[ options.customRules || [] ]
|
|
825
854
|
.flat()
|
|
@@ -839,6 +868,7 @@ function lintInput(options, synchronous, callback) {
|
|
|
839
868
|
callback(ruleErr);
|
|
840
869
|
return;
|
|
841
870
|
}
|
|
871
|
+
/** @type {string[]} */
|
|
842
872
|
let files = [];
|
|
843
873
|
if (Array.isArray(options.files)) {
|
|
844
874
|
files = [ ...options.files ];
|
|
@@ -854,12 +884,14 @@ function lintInput(options, synchronous, callback) {
|
|
|
854
884
|
options.frontMatter;
|
|
855
885
|
const handleRuleFailures = !!options.handleRuleFailures;
|
|
856
886
|
const noInlineConfig = !!options.noInlineConfig;
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
887
|
+
// @ts-ignore
|
|
888
|
+
// eslint-disable-next-line dot-notation
|
|
889
|
+
const resultVersion = (options["resultVersion"] === undefined) ? 3 : options["resultVersion"];
|
|
860
890
|
const markdownItFactory =
|
|
861
891
|
options.markdownItFactory ||
|
|
862
892
|
(() => { throw new Error("The option 'markdownItFactory' was required (due to the option 'customRules' including a rule requiring the 'markdown-it' parser), but 'markdownItFactory' was not set."); });
|
|
893
|
+
/** @type {FsLike} */
|
|
894
|
+
// @ts-ignore
|
|
863
895
|
const fs = options.fs || nodeFs;
|
|
864
896
|
const aliasToRuleNames = mapAliasToRuleNames(ruleList);
|
|
865
897
|
const results = newResults(ruleList);
|
|
@@ -867,14 +899,16 @@ function lintInput(options, synchronous, callback) {
|
|
|
867
899
|
let concurrency = 0;
|
|
868
900
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
869
901
|
function lintWorker() {
|
|
870
|
-
|
|
902
|
+
/** @type {string | undefined} */
|
|
903
|
+
let currentItem = undefined;
|
|
871
904
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
872
|
-
function lintWorkerCallback(err, result) {
|
|
905
|
+
function lintWorkerCallback(/** @type {Error | null} */ err, /** @type {LintError[] | undefined} */ result) {
|
|
873
906
|
concurrency--;
|
|
874
907
|
if (err) {
|
|
875
908
|
done = true;
|
|
876
909
|
return callback(err);
|
|
877
910
|
}
|
|
911
|
+
// @ts-ignore
|
|
878
912
|
results[currentItem] = result;
|
|
879
913
|
if (!synchronous) {
|
|
880
914
|
lintWorker();
|
|
@@ -883,10 +917,9 @@ function lintInput(options, synchronous, callback) {
|
|
|
883
917
|
}
|
|
884
918
|
if (done) {
|
|
885
919
|
// Abort for error or nothing left to do
|
|
886
|
-
} else if (files.
|
|
920
|
+
} else if ((currentItem = files.shift())) {
|
|
887
921
|
// Lint next file
|
|
888
922
|
concurrency++;
|
|
889
|
-
currentItem = files.shift();
|
|
890
923
|
lintFile(
|
|
891
924
|
ruleList,
|
|
892
925
|
aliasToRuleNames,
|
|
@@ -897,7 +930,6 @@ function lintInput(options, synchronous, callback) {
|
|
|
897
930
|
frontMatter,
|
|
898
931
|
handleRuleFailures,
|
|
899
932
|
noInlineConfig,
|
|
900
|
-
resultVersion,
|
|
901
933
|
fs,
|
|
902
934
|
synchronous,
|
|
903
935
|
lintWorkerCallback
|
|
@@ -916,14 +948,22 @@ function lintInput(options, synchronous, callback) {
|
|
|
916
948
|
frontMatter,
|
|
917
949
|
handleRuleFailures,
|
|
918
950
|
noInlineConfig,
|
|
919
|
-
resultVersion,
|
|
920
951
|
synchronous,
|
|
921
952
|
lintWorkerCallback
|
|
922
953
|
);
|
|
923
954
|
} else if (concurrency === 0) {
|
|
924
955
|
// Finish
|
|
925
956
|
done = true;
|
|
926
|
-
|
|
957
|
+
// Deprecated: Convert results to specified resultVersion
|
|
958
|
+
let convertedResults = results;
|
|
959
|
+
if (resultVersion === 0) {
|
|
960
|
+
convertedResults = helpers.convertToResultVersion0(results);
|
|
961
|
+
} else if (resultVersion === 1) {
|
|
962
|
+
convertedResults = helpers.convertToResultVersion1(results);
|
|
963
|
+
} else if (resultVersion === 2) {
|
|
964
|
+
convertedResults = helpers.convertToResultVersion2(results);
|
|
965
|
+
}
|
|
966
|
+
return callback(null, convertedResults);
|
|
927
967
|
}
|
|
928
968
|
return null;
|
|
929
969
|
}
|
|
@@ -993,15 +1033,24 @@ export function lintSync(options) {
|
|
|
993
1033
|
return results;
|
|
994
1034
|
}
|
|
995
1035
|
|
|
1036
|
+
/**
|
|
1037
|
+
* Node fs instance (or compatible object).
|
|
1038
|
+
*
|
|
1039
|
+
* @typedef FsLike
|
|
1040
|
+
* @property {(path: string, callback: (err: Error) => void) => void} access access method.
|
|
1041
|
+
* @property {(path: string) => void} accessSync accessSync method.
|
|
1042
|
+
* @property {(path: string, encoding: string, callback: (err: Error, data: string) => void) => void} readFile readFile method.
|
|
1043
|
+
* @property {(path: string, encoding: string) => string} readFileSync readFileSync method.
|
|
1044
|
+
*/
|
|
1045
|
+
|
|
996
1046
|
/**
|
|
997
1047
|
* Resolve referenced "extends" path in a configuration file
|
|
998
1048
|
* using path.resolve() with require.resolve() as a fallback.
|
|
999
1049
|
*
|
|
1000
1050
|
* @param {string} configFile Configuration file name.
|
|
1001
1051
|
* @param {string} referenceId Referenced identifier to resolve.
|
|
1002
|
-
* @param {
|
|
1003
|
-
* @param {ResolveConfigExtendsCallback} callback Callback (err, result)
|
|
1004
|
-
* function.
|
|
1052
|
+
* @param {FsLike} fs File system implementation.
|
|
1053
|
+
* @param {ResolveConfigExtendsCallback} callback Callback (err, result) function.
|
|
1005
1054
|
* @returns {void}
|
|
1006
1055
|
*/
|
|
1007
1056
|
function resolveConfigExtends(configFile, referenceId, fs, callback) {
|
|
@@ -1029,7 +1078,7 @@ function resolveConfigExtends(configFile, referenceId, fs, callback) {
|
|
|
1029
1078
|
*
|
|
1030
1079
|
* @param {string} configFile Configuration file name.
|
|
1031
1080
|
* @param {string} referenceId Referenced identifier to resolve.
|
|
1032
|
-
* @param {
|
|
1081
|
+
* @param {FsLike} fs File system implementation.
|
|
1033
1082
|
* @returns {string} Resolved path to file.
|
|
1034
1083
|
*/
|
|
1035
1084
|
function resolveConfigExtendsSync(configFile, referenceId, fs) {
|
|
@@ -1054,9 +1103,8 @@ function resolveConfigExtendsSync(configFile, referenceId, fs) {
|
|
|
1054
1103
|
*
|
|
1055
1104
|
* @param {Configuration} config Configuration object.
|
|
1056
1105
|
* @param {string} file Configuration file name.
|
|
1057
|
-
* @param {ConfigurationParser[] | undefined} parsers Parsing
|
|
1058
|
-
*
|
|
1059
|
-
* @param {Object} fs File system implementation.
|
|
1106
|
+
* @param {ConfigurationParser[] | undefined} parsers Parsing function(s).
|
|
1107
|
+
* @param {FsLike} fs File system implementation.
|
|
1060
1108
|
* @param {ReadConfigCallback} callback Callback (err, result) function.
|
|
1061
1109
|
* @returns {void}
|
|
1062
1110
|
*/
|
|
@@ -1096,7 +1144,7 @@ function extendConfig(config, file, parsers, fs, callback) {
|
|
|
1096
1144
|
* @param {Configuration} config Configuration object.
|
|
1097
1145
|
* @param {string} file Configuration file name.
|
|
1098
1146
|
* @param {ConfigurationParser[] | undefined} parsers Parsing function(s).
|
|
1099
|
-
* @param {
|
|
1147
|
+
* @param {FsLike} fs File system implementation.
|
|
1100
1148
|
* @returns {Promise<Configuration>} Configuration object.
|
|
1101
1149
|
*/
|
|
1102
1150
|
export function extendConfigPromise(config, file, parsers, fs) {
|
|
@@ -1115,16 +1163,17 @@ export function extendConfigPromise(config, file, parsers, fs) {
|
|
|
1115
1163
|
* Read specified configuration file.
|
|
1116
1164
|
*
|
|
1117
1165
|
* @param {string} file Configuration file name.
|
|
1118
|
-
* @param {ConfigurationParser[] | ReadConfigCallback} [parsers] Parsing
|
|
1119
|
-
*
|
|
1120
|
-
* @param {Object} [fs] File system implementation.
|
|
1166
|
+
* @param {ConfigurationParser[] | ReadConfigCallback} [parsers] Parsing function(s).
|
|
1167
|
+
* @param {FsLike | ReadConfigCallback} [fs] File system implementation.
|
|
1121
1168
|
* @param {ReadConfigCallback} [callback] Callback (err, result) function.
|
|
1122
1169
|
* @returns {void}
|
|
1123
1170
|
*/
|
|
1124
1171
|
export function readConfigAsync(file, parsers, fs, callback) {
|
|
1125
1172
|
if (!callback) {
|
|
1126
1173
|
if (fs) {
|
|
1174
|
+
// @ts-ignore
|
|
1127
1175
|
callback = fs;
|
|
1176
|
+
// @ts-ignore
|
|
1128
1177
|
fs = null;
|
|
1129
1178
|
} else {
|
|
1130
1179
|
// @ts-ignore
|
|
@@ -1133,12 +1182,12 @@ export function readConfigAsync(file, parsers, fs, callback) {
|
|
|
1133
1182
|
parsers = null;
|
|
1134
1183
|
}
|
|
1135
1184
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1185
|
+
/** @type {FsLike} */
|
|
1186
|
+
// @ts-ignore
|
|
1187
|
+
const fsLike = fs || nodeFs;
|
|
1139
1188
|
// Read file
|
|
1140
1189
|
file = helpers.expandTildePath(file, os);
|
|
1141
|
-
|
|
1190
|
+
fsLike.readFile(file, "utf8", (err, content) => {
|
|
1142
1191
|
if (err) {
|
|
1143
1192
|
// @ts-ignore
|
|
1144
1193
|
return callback(err);
|
|
@@ -1152,7 +1201,7 @@ export function readConfigAsync(file, parsers, fs, callback) {
|
|
|
1152
1201
|
}
|
|
1153
1202
|
// Extend configuration
|
|
1154
1203
|
// @ts-ignore
|
|
1155
|
-
return extendConfig(config, file, parsers,
|
|
1204
|
+
return extendConfig(config, file, parsers, fsLike, callback);
|
|
1156
1205
|
});
|
|
1157
1206
|
}
|
|
1158
1207
|
|
|
@@ -1161,7 +1210,7 @@ export function readConfigAsync(file, parsers, fs, callback) {
|
|
|
1161
1210
|
*
|
|
1162
1211
|
* @param {string} file Configuration file name.
|
|
1163
1212
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
|
1164
|
-
* @param {
|
|
1213
|
+
* @param {FsLike} [fs] File system implementation.
|
|
1165
1214
|
* @returns {Promise<Configuration>} Configuration object.
|
|
1166
1215
|
*/
|
|
1167
1216
|
export function readConfigPromise(file, parsers, fs) {
|
|
@@ -1181,16 +1230,16 @@ export function readConfigPromise(file, parsers, fs) {
|
|
|
1181
1230
|
*
|
|
1182
1231
|
* @param {string} file Configuration file name.
|
|
1183
1232
|
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
|
|
1184
|
-
* @param {
|
|
1233
|
+
* @param {FsLike} [fs] File system implementation.
|
|
1185
1234
|
* @returns {Configuration} Configuration object.
|
|
1186
1235
|
*/
|
|
1187
1236
|
export function readConfigSync(file, parsers, fs) {
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1237
|
+
/** @type {FsLike} */
|
|
1238
|
+
// @ts-ignore
|
|
1239
|
+
const fsLike = fs || nodeFs;
|
|
1191
1240
|
// Read file
|
|
1192
1241
|
file = helpers.expandTildePath(file, os);
|
|
1193
|
-
const content =
|
|
1242
|
+
const content = fsLike.readFileSync(file, "utf8");
|
|
1194
1243
|
// Try to parse file
|
|
1195
1244
|
const { config, message } = parseConfiguration(file, content, parsers);
|
|
1196
1245
|
if (!config) {
|
|
@@ -1204,7 +1253,7 @@ export function readConfigSync(file, parsers, fs) {
|
|
|
1204
1253
|
const resolvedExtends = resolveConfigExtendsSync(
|
|
1205
1254
|
file,
|
|
1206
1255
|
helpers.expandTildePath(configExtends, os),
|
|
1207
|
-
|
|
1256
|
+
fsLike
|
|
1208
1257
|
);
|
|
1209
1258
|
return {
|
|
1210
1259
|
...readConfigSync(resolvedExtends, parsers, fs),
|
|
@@ -1217,9 +1266,9 @@ export function readConfigSync(file, parsers, fs) {
|
|
|
1217
1266
|
/**
|
|
1218
1267
|
* Normalizes the fields of a RuleOnErrorFixInfo instance.
|
|
1219
1268
|
*
|
|
1220
|
-
* @param {
|
|
1269
|
+
* @param {FixInfo} fixInfo RuleOnErrorFixInfo instance.
|
|
1221
1270
|
* @param {number} [lineNumber] Line number.
|
|
1222
|
-
* @returns {
|
|
1271
|
+
* @returns {FixInfoNormalized} Normalized RuleOnErrorFixInfo instance.
|
|
1223
1272
|
*/
|
|
1224
1273
|
function normalizeFixInfo(fixInfo, lineNumber = 0) {
|
|
1225
1274
|
return {
|
|
@@ -1234,7 +1283,7 @@ function normalizeFixInfo(fixInfo, lineNumber = 0) {
|
|
|
1234
1283
|
* Applies the specified fix to a Markdown content line.
|
|
1235
1284
|
*
|
|
1236
1285
|
* @param {string} line Line of Markdown content.
|
|
1237
|
-
* @param {
|
|
1286
|
+
* @param {FixInfo} fixInfo FixInfo instance.
|
|
1238
1287
|
* @param {string} [lineEnding] Line ending to use.
|
|
1239
1288
|
* @returns {string | null} Fixed content or null if deleted.
|
|
1240
1289
|
*/
|
|
@@ -1250,7 +1299,7 @@ export function applyFix(line, fixInfo, lineEnding = "\n") {
|
|
|
1250
1299
|
* Applies as many of the specified fixes as possible to Markdown content.
|
|
1251
1300
|
*
|
|
1252
1301
|
* @param {string} input Lines of Markdown content.
|
|
1253
|
-
* @param {
|
|
1302
|
+
* @param {LintError[]} errors LintError instances.
|
|
1254
1303
|
* @returns {string} Fixed content.
|
|
1255
1304
|
*/
|
|
1256
1305
|
export function applyFixes(input, errors) {
|
|
@@ -1346,8 +1395,6 @@ export function getVersion() {
|
|
|
1346
1395
|
* @returns {void}
|
|
1347
1396
|
*/
|
|
1348
1397
|
|
|
1349
|
-
/* eslint-disable jsdoc/valid-types */
|
|
1350
|
-
|
|
1351
1398
|
/**
|
|
1352
1399
|
* Rule parameters.
|
|
1353
1400
|
*
|
|
@@ -1360,8 +1407,6 @@ export function getVersion() {
|
|
|
1360
1407
|
* @property {string} version Version of the markdownlint library.
|
|
1361
1408
|
*/
|
|
1362
1409
|
|
|
1363
|
-
/* eslint-enable jsdoc/valid-types */
|
|
1364
|
-
|
|
1365
1410
|
/**
|
|
1366
1411
|
* Markdown parser data.
|
|
1367
1412
|
*
|
|
@@ -1451,16 +1496,6 @@ export function getVersion() {
|
|
|
1451
1496
|
* @property {string} [insertText] Text to insert (after deleting).
|
|
1452
1497
|
*/
|
|
1453
1498
|
|
|
1454
|
-
/**
|
|
1455
|
-
* RuleOnErrorInfo with all optional properties present.
|
|
1456
|
-
*
|
|
1457
|
-
* @typedef {Object} RuleOnErrorFixInfoNormalized
|
|
1458
|
-
* @property {number} lineNumber Line number (1-based).
|
|
1459
|
-
* @property {number} editColumn Column of the fix (1-based).
|
|
1460
|
-
* @property {number} deleteCount Count of characters to delete.
|
|
1461
|
-
* @property {string} insertText Text to insert (after deleting).
|
|
1462
|
-
*/
|
|
1463
|
-
|
|
1464
1499
|
/**
|
|
1465
1500
|
* Rule definition.
|
|
1466
1501
|
*
|
|
@@ -1506,33 +1541,23 @@ export function getVersion() {
|
|
|
1506
1541
|
* @property {Rule[] | Rule} [customRules] Custom rules.
|
|
1507
1542
|
* @property {string[] | string} [files] Files to lint.
|
|
1508
1543
|
* @property {RegExp | null} [frontMatter] Front matter pattern.
|
|
1509
|
-
* @property {
|
|
1544
|
+
* @property {FsLike} [fs] File system implementation.
|
|
1510
1545
|
* @property {boolean} [handleRuleFailures] True to catch exceptions.
|
|
1511
1546
|
* @property {MarkdownItFactory} [markdownItFactory] Function to create a markdown-it parser.
|
|
1512
1547
|
* @property {boolean} [noInlineConfig] True to ignore HTML directives.
|
|
1513
|
-
* @property {number} [resultVersion] Results object version.
|
|
1514
1548
|
* @property {Object.<string, string>} [strings] Strings to lint.
|
|
1515
1549
|
*/
|
|
1516
1550
|
|
|
1517
1551
|
/**
|
|
1518
1552
|
* A markdown-it plugin.
|
|
1519
1553
|
*
|
|
1520
|
-
* @typedef {
|
|
1554
|
+
* @typedef {Object[]} Plugin
|
|
1521
1555
|
*/
|
|
1522
1556
|
|
|
1523
1557
|
/**
|
|
1524
|
-
*
|
|
1525
|
-
*
|
|
1526
|
-
* @callback ToStringCallback
|
|
1527
|
-
* @param {boolean} [ruleAliases] True to use rule aliases.
|
|
1528
|
-
* @returns {string} Pretty-printed results.
|
|
1529
|
-
*/
|
|
1530
|
-
|
|
1531
|
-
/**
|
|
1532
|
-
* Lint results (for resultVersion 3).
|
|
1558
|
+
* Lint results.
|
|
1533
1559
|
*
|
|
1534
1560
|
* @typedef {Object.<string, LintError[]>} LintResults
|
|
1535
|
-
* @property {ToStringCallback} toString String representation.
|
|
1536
1561
|
*/
|
|
1537
1562
|
|
|
1538
1563
|
/**
|
|
@@ -1542,11 +1567,12 @@ export function getVersion() {
|
|
|
1542
1567
|
* @property {number} lineNumber Line number (1-based).
|
|
1543
1568
|
* @property {string[]} ruleNames Rule name(s).
|
|
1544
1569
|
* @property {string} ruleDescription Rule description.
|
|
1545
|
-
* @property {string} ruleInformation Link to more information.
|
|
1546
|
-
* @property {string} errorDetail Detail about the error.
|
|
1547
|
-
* @property {string} errorContext Context for the error.
|
|
1548
|
-
* @property {number[]} errorRange Column number (1-based) and length.
|
|
1549
|
-
* @property {FixInfo}
|
|
1570
|
+
* @property {string | null} ruleInformation Link to more information.
|
|
1571
|
+
* @property {string | null} errorDetail Detail about the error.
|
|
1572
|
+
* @property {string | null} errorContext Context for the error.
|
|
1573
|
+
* @property {number[] | null} errorRange Column number (1-based) and length.
|
|
1574
|
+
* @property {FixInfo | null} fixInfo Fix information.
|
|
1575
|
+
* @property {"error" | "warning"} severity Severity of the error.
|
|
1550
1576
|
*/
|
|
1551
1577
|
|
|
1552
1578
|
/**
|
|
@@ -1559,6 +1585,16 @@ export function getVersion() {
|
|
|
1559
1585
|
* @property {string} [insertText] Text to insert (after deleting).
|
|
1560
1586
|
*/
|
|
1561
1587
|
|
|
1588
|
+
/**
|
|
1589
|
+
* FixInfo with all optional properties present.
|
|
1590
|
+
*
|
|
1591
|
+
* @typedef {Object} FixInfoNormalized
|
|
1592
|
+
* @property {number} lineNumber Line number (1-based).
|
|
1593
|
+
* @property {number} editColumn Column of the fix (1-based).
|
|
1594
|
+
* @property {number} deleteCount Count of characters to delete.
|
|
1595
|
+
* @property {string} insertText Text to insert (after deleting).
|
|
1596
|
+
*/
|
|
1597
|
+
|
|
1562
1598
|
/**
|
|
1563
1599
|
* Called with the result of linting a string or document.
|
|
1564
1600
|
*
|