markdownlint 0.33.0 → 0.35.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/CONTRIBUTING.md +4 -3
  3. package/README.md +25 -10
  4. package/demo/markdownlint-browser.js +3286 -2119
  5. package/doc/CustomRules.md +25 -13
  6. package/doc/Rules.md +106 -7
  7. package/doc/md013.md +8 -7
  8. package/doc/md034.md +5 -0
  9. package/doc/md044.md +10 -0
  10. package/doc/md049.md +3 -0
  11. package/doc/md050.md +3 -0
  12. package/doc/md051.md +26 -0
  13. package/doc/md058.md +48 -0
  14. package/helpers/README.md +3 -27
  15. package/helpers/helpers.js +60 -292
  16. package/helpers/micromark.cjs +153 -36
  17. package/helpers/package.json +2 -2
  18. package/lib/cache.js +62 -13
  19. package/lib/configuration-strict.d.ts +1185 -0
  20. package/lib/configuration.d.ts +3 -1173
  21. package/lib/constants.js +3 -2
  22. package/lib/markdownlint.d.ts +143 -61
  23. package/lib/markdownlint.js +151 -54
  24. package/lib/md001.js +17 -8
  25. package/lib/md003.js +16 -8
  26. package/lib/md004.js +57 -47
  27. package/lib/md005.js +7 -8
  28. package/lib/md007.js +13 -12
  29. package/lib/md009.js +52 -43
  30. package/lib/md010.js +50 -32
  31. package/lib/md011.js +18 -7
  32. package/lib/md012.js +19 -8
  33. package/lib/md013.js +46 -37
  34. package/lib/md014.js +37 -36
  35. package/lib/md018.js +20 -8
  36. package/lib/md019-md021.js +80 -0
  37. package/lib/md020.js +15 -6
  38. package/lib/md022.js +10 -12
  39. package/lib/md023.js +24 -22
  40. package/lib/md024.js +14 -8
  41. package/lib/md025.js +17 -9
  42. package/lib/md026.js +5 -6
  43. package/lib/md027.js +24 -43
  44. package/lib/md028.js +26 -14
  45. package/lib/md029.js +42 -33
  46. package/lib/md030.js +7 -8
  47. package/lib/md031.js +45 -22
  48. package/lib/md032.js +18 -30
  49. package/lib/md033.js +6 -4
  50. package/lib/md034.js +30 -9
  51. package/lib/md035.js +5 -3
  52. package/lib/md036.js +34 -39
  53. package/lib/md037.js +3 -0
  54. package/lib/md038.js +6 -5
  55. package/lib/md039.js +68 -52
  56. package/lib/md040.js +21 -21
  57. package/lib/md041.js +21 -26
  58. package/lib/md042.js +50 -36
  59. package/lib/md043.js +22 -13
  60. package/lib/md044.js +5 -2
  61. package/lib/md045.js +6 -4
  62. package/lib/md046.js +9 -8
  63. package/lib/md047.js +5 -2
  64. package/lib/md048.js +22 -13
  65. package/lib/md049-md050.js +19 -5
  66. package/lib/md051.js +18 -20
  67. package/lib/md052.js +5 -2
  68. package/lib/md053.js +5 -2
  69. package/lib/md054.js +12 -12
  70. package/lib/md055.js +10 -3
  71. package/lib/md056.js +18 -6
  72. package/lib/md058.js +43 -0
  73. package/lib/rules.js +11 -4
  74. package/package.json +22 -25
  75. package/schema/.markdownlint.jsonc +54 -51
  76. package/schema/.markdownlint.yaml +53 -50
  77. package/schema/ValidatingConfiguration.md +6 -8
  78. package/schema/markdownlint-config-schema-strict.json +1819 -0
  79. package/schema/markdownlint-config-schema.json +115 -105
  80. package/style/prettier.json +1 -0
  81. package/lib/md019.js +0 -39
  82. package/lib/md021.js +0 -62
package/lib/constants.js CHANGED
@@ -8,7 +8,8 @@ module.exports.fixableRuleNames = [
8
8
  "MD012", "MD014", "MD018", "MD019", "MD020", "MD021",
9
9
  "MD022", "MD023", "MD026", "MD027", "MD030", "MD031",
10
10
  "MD032", "MD034", "MD037", "MD038", "MD039", "MD044",
11
- "MD047", "MD049", "MD050", "MD051", "MD053", "MD054"
11
+ "MD047", "MD049", "MD050", "MD051", "MD053", "MD054",
12
+ "MD058"
12
13
  ];
13
14
  module.exports.homepage = "https://github.com/DavidAnson/markdownlint";
14
- module.exports.version = "0.33.0";
15
+ module.exports.version = "0.35.0";
@@ -8,63 +8,8 @@ export = markdownlint;
8
8
  */
9
9
  declare function markdownlint(options: Options | null, callback: LintCallback): void;
10
10
  declare namespace markdownlint {
11
- export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
11
+ export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, GetMarkdownIt, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, ConfigurationStrict, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
12
12
  }
13
- /**
14
- * Configuration options.
15
- */
16
- type Options = {
17
- /**
18
- * Configuration object.
19
- */
20
- config?: Configuration;
21
- /**
22
- * Configuration parsers.
23
- */
24
- configParsers?: ConfigurationParser[];
25
- /**
26
- * Custom rules.
27
- */
28
- customRules?: Rule[] | Rule;
29
- /**
30
- * Files to lint.
31
- */
32
- files?: string[] | string;
33
- /**
34
- * Front matter pattern.
35
- */
36
- frontMatter?: RegExp | null;
37
- /**
38
- * File system implementation.
39
- */
40
- fs?: any;
41
- /**
42
- * True to catch exceptions.
43
- */
44
- handleRuleFailures?: boolean;
45
- /**
46
- * Additional plugins.
47
- */
48
- markdownItPlugins?: Plugin[];
49
- /**
50
- * True to ignore HTML directives.
51
- */
52
- noInlineConfig?: boolean;
53
- /**
54
- * Results object version.
55
- */
56
- resultVersion?: number;
57
- /**
58
- * Strings to lint.
59
- */
60
- strings?: {
61
- [x: string]: string;
62
- };
63
- };
64
- /**
65
- * Called with the result of the lint function.
66
- */
67
- type LintCallback = (error: Error | null, results?: LintResults) => void;
68
13
  /**
69
14
  * Lint specified Markdown files synchronously.
70
15
  *
@@ -104,6 +49,10 @@ declare namespace promises {
104
49
  export { extendConfigPromise as extendConfig };
105
50
  export { readConfigPromise as readConfig };
106
51
  }
52
+ /**
53
+ * Function to get an instance of the markdown-it parser.
54
+ */
55
+ type GetMarkdownIt = () => any;
107
56
  /**
108
57
  * Function to implement rule logic.
109
58
  */
@@ -117,24 +66,55 @@ type RuleParams = {
117
66
  */
118
67
  name: string;
119
68
  /**
120
- * Token objects from markdown-it.
69
+ * Markdown parser data.
121
70
  */
122
- tokens: MarkdownItToken[];
71
+ parsers: MarkdownParsers;
123
72
  /**
124
73
  * File/string lines.
125
74
  */
126
- lines: string[];
75
+ lines: readonly string[];
127
76
  /**
128
77
  * Front matter lines.
129
78
  */
130
- frontMatterLines: string[];
79
+ frontMatterLines: readonly string[];
131
80
  /**
132
81
  * Rule configuration.
133
82
  */
134
83
  config: RuleConfiguration;
135
84
  };
136
85
  /**
137
- * Markdown-It token.
86
+ * Markdown parser data.
87
+ */
88
+ type MarkdownParsers = {
89
+ /**
90
+ * Markdown parser data from markdown-it (only present when Rule.parser is "markdownit").
91
+ */
92
+ markdownit: ParserMarkdownIt;
93
+ /**
94
+ * Markdown parser data from micromark (only present when Rule.parser is "micromark").
95
+ */
96
+ micromark: ParserMicromark;
97
+ };
98
+ /**
99
+ * Markdown parser data from markdown-it.
100
+ */
101
+ type ParserMarkdownIt = {
102
+ /**
103
+ * Token objects from markdown-it.
104
+ */
105
+ tokens: MarkdownItToken[];
106
+ };
107
+ /**
108
+ * Markdown parser data from micromark.
109
+ */
110
+ type ParserMicromark = {
111
+ /**
112
+ * Token objects from micromark.
113
+ */
114
+ tokens: MicromarkToken[];
115
+ };
116
+ /**
117
+ * markdown-it token.
138
118
  */
139
119
  type MarkdownItToken = {
140
120
  /**
@@ -198,6 +178,44 @@ type MarkdownItToken = {
198
178
  */
199
179
  line: string;
200
180
  };
181
+ type MicromarkTokenType = import("markdownlint-micromark").TokenType;
182
+ /**
183
+ * micromark token.
184
+ */
185
+ type MicromarkToken = {
186
+ /**
187
+ * Token type.
188
+ */
189
+ type: MicromarkTokenType;
190
+ /**
191
+ * Start line (1-based).
192
+ */
193
+ startLine: number;
194
+ /**
195
+ * Start column (1-based).
196
+ */
197
+ startColumn: number;
198
+ /**
199
+ * End line (1-based).
200
+ */
201
+ endLine: number;
202
+ /**
203
+ * End column (1-based).
204
+ */
205
+ endColumn: number;
206
+ /**
207
+ * Token text.
208
+ */
209
+ text: string;
210
+ /**
211
+ * Child tokens.
212
+ */
213
+ children: MicromarkToken[];
214
+ /**
215
+ * Parent token.
216
+ */
217
+ parent: MicromarkToken | null;
218
+ };
201
219
  /**
202
220
  * Error-reporting callback.
203
221
  */
@@ -272,6 +290,10 @@ type Rule = {
272
290
  * Rule tag(s).
273
291
  */
274
292
  tags: string[];
293
+ /**
294
+ * Parser used.
295
+ */
296
+ parser: "markdownit" | "micromark" | "none";
275
297
  /**
276
298
  * True if asynchronous.
277
299
  */
@@ -281,6 +303,57 @@ type Rule = {
281
303
  */
282
304
  function: RuleFunction;
283
305
  };
306
+ /**
307
+ * Configuration options.
308
+ */
309
+ type Options = {
310
+ /**
311
+ * Configuration object.
312
+ */
313
+ config?: Configuration;
314
+ /**
315
+ * Configuration parsers.
316
+ */
317
+ configParsers?: ConfigurationParser[];
318
+ /**
319
+ * Custom rules.
320
+ */
321
+ customRules?: Rule[] | Rule;
322
+ /**
323
+ * Files to lint.
324
+ */
325
+ files?: string[] | string;
326
+ /**
327
+ * Front matter pattern.
328
+ */
329
+ frontMatter?: RegExp | null;
330
+ /**
331
+ * File system implementation.
332
+ */
333
+ fs?: any;
334
+ /**
335
+ * True to catch exceptions.
336
+ */
337
+ handleRuleFailures?: boolean;
338
+ /**
339
+ * Additional plugins.
340
+ */
341
+ markdownItPlugins?: Plugin[];
342
+ /**
343
+ * True to ignore HTML directives.
344
+ */
345
+ noInlineConfig?: boolean;
346
+ /**
347
+ * Results object version.
348
+ */
349
+ resultVersion?: number;
350
+ /**
351
+ * Strings to lint.
352
+ */
353
+ strings?: {
354
+ [x: string]: string;
355
+ };
356
+ };
284
357
  /**
285
358
  * A markdown-it plugin.
286
359
  */
@@ -357,11 +430,20 @@ type FixInfo = {
357
430
  * Called with the result of linting a string or document.
358
431
  */
359
432
  type LintContentCallback = (error: Error | null, result?: LintError[]) => void;
433
+ /**
434
+ * Called with the result of the lint function.
435
+ */
436
+ type LintCallback = (error: Error | null, results?: LintResults) => void;
360
437
  /**
361
438
  * Configuration object for linting rules. For the JSON schema, see
362
439
  * {@link ../schema/markdownlint-config-schema.json}.
363
440
  */
364
441
  type Configuration = import("./configuration").Configuration;
442
+ /**
443
+ * Configuration object for linting rules strictly. For the JSON schema, see
444
+ * {@link ../schema/markdownlint-config-schema-strict.json}.
445
+ */
446
+ type ConfigurationStrict = import("./configuration-strict").ConfigurationStrict;
365
447
  /**
366
448
  * Rule configuration.
367
449
  */
@@ -4,7 +4,6 @@
4
4
 
5
5
  const path = require("node:path");
6
6
  const { promisify } = require("node:util");
7
- const markdownit = require("markdown-it");
8
7
  const micromark = require("../helpers/micromark.cjs");
9
8
  // const { deprecatedRuleNames } = require("./constants");
10
9
  const rules = require("./rules");
@@ -32,18 +31,17 @@ function validateRuleList(ruleList, synchronous) {
32
31
  const allIds = {};
33
32
  for (const [ index, rule ] of ruleList.entries()) {
34
33
  const customIndex = index - rules.length;
35
- // eslint-disable-next-line no-inner-declarations, jsdoc/require-jsdoc
36
- function newError(property) {
34
+ // eslint-disable-next-line jsdoc/require-jsdoc
35
+ function newError(property, value) {
37
36
  return new Error(
38
- "Property '" + property + "' of custom rule at index " +
39
- customIndex + " is incorrect.");
37
+ `Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`);
40
38
  }
41
39
  for (const property of [ "names", "tags" ]) {
42
40
  const value = rule[property];
43
41
  if (!result &&
44
42
  (!value || !Array.isArray(value) || (value.length === 0) ||
45
43
  !value.every(helpers.isString) || value.some(helpers.isEmptyString))) {
46
- result = newError(property);
44
+ result = newError(property, value);
47
45
  }
48
46
  }
49
47
  for (const propertyInfo of [
@@ -53,22 +51,31 @@ function validateRuleList(ruleList, synchronous) {
53
51
  const property = propertyInfo[0];
54
52
  const value = rule[property];
55
53
  if (!result && (!value || (typeof value !== propertyInfo[1]))) {
56
- result = newError(property);
54
+ result = newError(property, value);
57
55
  }
58
56
  }
57
+ if (
58
+ !result &&
59
+ (rule.parser !== undefined) &&
60
+ (rule.parser !== "markdownit") &&
61
+ !((customIndex < 0) && (rule.parser === "micromark")) &&
62
+ (rule.parser !== "none")
63
+ ) {
64
+ result = newError("parser", rule.parser);
65
+ }
59
66
  if (
60
67
  !result &&
61
68
  rule.information &&
62
69
  !helpers.isUrl(rule.information)
63
70
  ) {
64
- result = newError("information");
71
+ result = newError("information", rule.information);
65
72
  }
66
73
  if (
67
74
  !result &&
68
75
  (rule.asynchronous !== undefined) &&
69
76
  (typeof rule.asynchronous !== "boolean")
70
77
  ) {
71
- result = newError("asynchronous");
78
+ result = newError("asynchronous", rule.asynchronous);
72
79
  }
73
80
  if (!result && rule.asynchronous && synchronous) {
74
81
  result = new Error(
@@ -218,13 +225,17 @@ function freezeToken(token) {
218
225
  /**
219
226
  * Annotate tokens with line/lineNumber and freeze them.
220
227
  *
221
- * @param {MarkdownItToken[]} tokens Array of markdown-it tokens.
228
+ * @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens.
222
229
  * @param {string[]} lines Lines of Markdown content.
223
230
  * @returns {void}
224
231
  */
225
232
  function annotateAndFreezeTokens(tokens, lines) {
226
233
  let trMap = null;
227
- for (const token of tokens) {
234
+ // eslint-disable-next-line jsdoc/valid-types
235
+ /** @type MarkdownItToken[] */
236
+ // @ts-ignore
237
+ const markdownItTokens = tokens;
238
+ for (const token of markdownItTokens) {
228
239
  // Provide missing maps for table content
229
240
  if (token.type === "tr_open") {
230
241
  trMap = token.map;
@@ -499,10 +510,18 @@ function getEnabledRulesPerLineNumber(
499
510
  handleInlineConfig(lines, enableDisableFile);
500
511
  handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState);
501
512
  handleInlineConfig(lines, disableLineNextLine);
513
+ // Create the list of rules that are used at least once
514
+ const enabledRuleList = [];
515
+ for (const [ index, ruleName ] of allRuleNames.entries()) {
516
+ if (enabledRulesPerLineNumber.some((enabledRulesForLine) => enabledRulesForLine[ruleName])) {
517
+ enabledRuleList.push(ruleList[index]);
518
+ }
519
+ }
502
520
  // Return results
503
521
  return {
504
522
  effectiveConfig,
505
- enabledRulesPerLineNumber
523
+ enabledRulesPerLineNumber,
524
+ enabledRuleList
506
525
  };
507
526
  }
508
527
 
@@ -514,7 +533,7 @@ function getEnabledRulesPerLineNumber(
514
533
  * names.
515
534
  * @param {string} name Identifier for the content.
516
535
  * @param {string} content Markdown content.
517
- * @param {Object} md Instance of markdown-it.
536
+ * @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it.
518
537
  * @param {Configuration} config Configuration object.
519
538
  * @param {ConfigurationParser[] | null} configParsers Configuration parsers.
520
539
  * @param {RegExp | null} frontMatter Regular expression for front matter.
@@ -529,7 +548,7 @@ function lintContent(
529
548
  aliasToRuleNames,
530
549
  name,
531
550
  content,
532
- md,
551
+ getMarkdownIt,
533
552
  config,
534
553
  configParsers,
535
554
  frontMatter,
@@ -544,7 +563,7 @@ function lintContent(
544
563
  const { frontMatterLines } = removeFrontMatterResult;
545
564
  content = removeFrontMatterResult.content;
546
565
  // Get enabled rules per line (with HTML comments present)
547
- const { effectiveConfig, enabledRulesPerLineNumber } =
566
+ const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList } =
548
567
  getEnabledRulesPerLineNumber(
549
568
  ruleList,
550
569
  content.split(helpers.newLineRe),
@@ -554,8 +573,11 @@ function lintContent(
554
573
  configParsers,
555
574
  aliasToRuleNames
556
575
  );
576
+ const needMarkdownItTokens = enabledRuleList.some(
577
+ (rule) => (rule.parser === "markdownit") || (rule.parser === undefined)
578
+ );
557
579
  // Parse content into parser tokens
558
- const markdownitTokens = md.parse(content, {});
580
+ const markdownitTokens = needMarkdownItTokens ? getMarkdownIt().parse(content, {}) : [];
559
581
  const micromarkTokens = micromark.parse(content);
560
582
  // Hide the content of HTML comments from rules
561
583
  content = helpers.clearHtmlCommentText(content);
@@ -563,43 +585,56 @@ function lintContent(
563
585
  const lines = content.split(helpers.newLineRe);
564
586
  annotateAndFreezeTokens(markdownitTokens, lines);
565
587
  // Create (frozen) parameters for rules
566
- const parsers = Object.freeze({
588
+ /** @type {MarkdownParsers} */
589
+ // @ts-ignore
590
+ const parsersMarkdownIt = Object.freeze({
567
591
  "markdownit": Object.freeze({
568
592
  "tokens": markdownitTokens
569
- }),
593
+ })
594
+ });
595
+ /** @type {MarkdownParsers} */
596
+ // @ts-ignore
597
+ const parsersMicromark = Object.freeze({
570
598
  "micromark": Object.freeze({
571
599
  "tokens": micromarkTokens
572
600
  })
573
601
  });
602
+ /** @type {MarkdownParsers} */
603
+ // @ts-ignore
604
+ const parsersNone = Object.freeze({});
574
605
  const paramsBase = {
575
606
  name,
576
- parsers,
577
- "tokens": markdownitTokens,
578
607
  "lines": Object.freeze(lines),
579
608
  "frontMatterLines": Object.freeze(frontMatterLines)
580
609
  };
581
- const lineMetadata =
582
- helpers.getLineMetadata(paramsBase);
583
- const codeBlockAndSpanRanges =
584
- helpers.codeBlockAndSpanRanges(paramsBase, lineMetadata);
585
- const flattenedLists =
586
- helpers.flattenLists(paramsBase.parsers.markdownit.tokens);
587
- const referenceLinkImageData =
588
- helpers.getReferenceLinkImageData(paramsBase);
589
- cache.set({
590
- codeBlockAndSpanRanges,
591
- flattenedLists,
592
- lineMetadata,
593
- referenceLinkImageData
610
+ cache.initialize({
611
+ ...paramsBase,
612
+ "parsers": parsersMicromark,
613
+ "config": null
594
614
  });
595
615
  // Function to run for each rule
596
616
  let results = [];
597
- // eslint-disable-next-line jsdoc/require-jsdoc
598
- function forRule(rule) {
617
+ /**
618
+ * @param {Rule} rule Rule.
619
+ * @returns {Promise<void> | null} Promise.
620
+ */
621
+ const forRule = (rule) => {
599
622
  // Configure rule
600
623
  const ruleName = rule.names[0].toUpperCase();
624
+ const tokens = {};
625
+ let parsers = parsersNone;
626
+ if (rule.parser === undefined) {
627
+ tokens.tokens = markdownitTokens;
628
+ parsers = parsersMarkdownIt;
629
+ } else if (rule.parser === "markdownit") {
630
+ parsers = parsersMarkdownIt;
631
+ } else if (rule.parser === "micromark") {
632
+ parsers = parsersMicromark;
633
+ }
601
634
  const params = {
602
635
  ...paramsBase,
636
+ ...tokens,
637
+ parsers,
603
638
  "config": effectiveConfig[ruleName]
604
639
  };
605
640
  // eslint-disable-next-line jsdoc/require-jsdoc
@@ -721,7 +756,7 @@ function lintContent(
721
756
  }
722
757
  }
723
758
  return null;
724
- }
759
+ };
725
760
  // eslint-disable-next-line jsdoc/require-jsdoc
726
761
  function formatResults() {
727
762
  // Sort results by rule name by line number
@@ -769,8 +804,8 @@ function lintContent(
769
804
  return results;
770
805
  }
771
806
  // Run all rules
772
- const ruleListAsync = ruleList.filter((rule) => rule.asynchronous);
773
- const ruleListSync = ruleList.filter((rule) => !rule.asynchronous);
807
+ const ruleListAsync = enabledRuleList.filter((rule) => rule.asynchronous);
808
+ const ruleListSync = enabledRuleList.filter((rule) => !rule.asynchronous);
774
809
  const ruleListAsyncFirst = [
775
810
  ...ruleListAsync,
776
811
  ...ruleListSync
@@ -790,7 +825,7 @@ function lintContent(
790
825
  } catch (error) {
791
826
  callbackError(error);
792
827
  } finally {
793
- cache.clear();
828
+ cache.initialize();
794
829
  }
795
830
  }
796
831
 
@@ -801,7 +836,7 @@ function lintContent(
801
836
  * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule
802
837
  * names.
803
838
  * @param {string} file Path of file to lint.
804
- * @param {Object} md Instance of markdown-it.
839
+ * @param {GetMarkdownIt} getMarkdownIt Getter for instance of markdown-it.
805
840
  * @param {Configuration} config Configuration object.
806
841
  * @param {ConfigurationParser[] | null} configParsers Configuration parsers.
807
842
  * @param {RegExp | null} frontMatter Regular expression for front matter.
@@ -817,7 +852,7 @@ function lintFile(
817
852
  ruleList,
818
853
  aliasToRuleNames,
819
854
  file,
820
- md,
855
+ getMarkdownIt,
821
856
  config,
822
857
  configParsers,
823
858
  frontMatter,
@@ -837,7 +872,7 @@ function lintFile(
837
872
  aliasToRuleNames,
838
873
  file,
839
874
  content,
840
- md,
875
+ getMarkdownIt,
841
876
  config,
842
877
  configParsers,
843
878
  frontMatter,
@@ -875,6 +910,7 @@ function lintInput(options, synchronous, callback) {
875
910
  "description": rule.description,
876
911
  "information": helpers.cloneIfUrl(rule.information),
877
912
  "tags": helpers.cloneIfArray(rule.tags),
913
+ "parser": rule.parser,
878
914
  "asynchronous": rule.asynchronous,
879
915
  "function": rule.function
880
916
  }));
@@ -901,12 +937,16 @@ function lintInput(options, synchronous, callback) {
901
937
  const noInlineConfig = !!options.noInlineConfig;
902
938
  const resultVersion = (options.resultVersion === undefined) ?
903
939
  3 : options.resultVersion;
904
- const md = markdownit({ "html": true });
905
- const markdownItPlugins = options.markdownItPlugins || [];
906
- for (const plugin of markdownItPlugins) {
907
- // @ts-ignore
908
- md.use(...plugin);
909
- }
940
+ const getMarkdownIt = () => {
941
+ const markdownit = require("markdown-it");
942
+ const md = markdownit({ "html": true });
943
+ const markdownItPlugins = options.markdownItPlugins || [];
944
+ for (const plugin of markdownItPlugins) {
945
+ // @ts-ignore
946
+ md.use(...plugin);
947
+ }
948
+ return md;
949
+ };
910
950
  const fs = options.fs || require("node:fs");
911
951
  const aliasToRuleNames = mapAliasToRuleNames(ruleList);
912
952
  const results = newResults(ruleList);
@@ -938,7 +978,7 @@ function lintInput(options, synchronous, callback) {
938
978
  ruleList,
939
979
  aliasToRuleNames,
940
980
  currentItem,
941
- md,
981
+ getMarkdownIt,
942
982
  config,
943
983
  configParsers,
944
984
  frontMatter,
@@ -957,7 +997,7 @@ function lintInput(options, synchronous, callback) {
957
997
  aliasToRuleNames,
958
998
  currentItem,
959
999
  strings[currentItem] || "",
960
- md,
1000
+ getMarkdownIt,
961
1001
  config,
962
1002
  configParsers,
963
1003
  frontMatter,
@@ -1272,6 +1312,13 @@ module.exports = markdownlint;
1272
1312
 
1273
1313
  // Type declarations
1274
1314
 
1315
+ /**
1316
+ * Function to get an instance of the markdown-it parser.
1317
+ *
1318
+ * @callback GetMarkdownIt
1319
+ * @returns {import("markdown-it")}
1320
+ */
1321
+
1275
1322
  /**
1276
1323
  * Function to implement rule logic.
1277
1324
  *
@@ -1281,19 +1328,45 @@ module.exports = markdownlint;
1281
1328
  * @returns {void}
1282
1329
  */
1283
1330
 
1331
+ /* eslint-disable jsdoc/valid-types */
1332
+
1284
1333
  /**
1285
1334
  * Rule parameters.
1286
1335
  *
1287
1336
  * @typedef {Object} RuleParams
1288
1337
  * @property {string} name File/string name.
1289
- * @property {MarkdownItToken[]} tokens Token objects from markdown-it.
1290
- * @property {string[]} lines File/string lines.
1291
- * @property {string[]} frontMatterLines Front matter lines.
1338
+ * @property {MarkdownParsers} parsers Markdown parser data.
1339
+ * @property {readonly string[]} lines File/string lines.
1340
+ * @property {readonly string[]} frontMatterLines Front matter lines.
1292
1341
  * @property {RuleConfiguration} config Rule configuration.
1293
1342
  */
1294
1343
 
1344
+ /* eslint-enable jsdoc/valid-types */
1345
+
1346
+ /**
1347
+ * Markdown parser data.
1348
+ *
1349
+ * @typedef {Object} MarkdownParsers
1350
+ * @property {ParserMarkdownIt} markdownit Markdown parser data from markdown-it (only present when Rule.parser is "markdownit").
1351
+ * @property {ParserMicromark} micromark Markdown parser data from micromark (only present when Rule.parser is "micromark").
1352
+ */
1353
+
1354
+ /**
1355
+ * Markdown parser data from markdown-it.
1356
+ *
1357
+ * @typedef {Object} ParserMarkdownIt
1358
+ * @property {MarkdownItToken[]} tokens Token objects from markdown-it.
1359
+ */
1360
+
1295
1361
  /**
1296
- * Markdown-It token.
1362
+ * Markdown parser data from micromark.
1363
+ *
1364
+ * @typedef {Object} ParserMicromark
1365
+ * @property {MicromarkToken[]} tokens Token objects from micromark.
1366
+ */
1367
+
1368
+ /**
1369
+ * markdown-it token.
1297
1370
  *
1298
1371
  * @typedef {Object} MarkdownItToken
1299
1372
  * @property {string[][]} attrs HTML attributes.
@@ -1313,6 +1386,22 @@ module.exports = markdownlint;
1313
1386
  * @property {string} line Line content.
1314
1387
  */
1315
1388
 
1389
+ /** @typedef {import("markdownlint-micromark").TokenType} MicromarkTokenType */
1390
+
1391
+ /**
1392
+ * micromark token.
1393
+ *
1394
+ * @typedef {Object} MicromarkToken
1395
+ * @property {MicromarkTokenType} type Token type.
1396
+ * @property {number} startLine Start line (1-based).
1397
+ * @property {number} startColumn Start column (1-based).
1398
+ * @property {number} endLine End line (1-based).
1399
+ * @property {number} endColumn End column (1-based).
1400
+ * @property {string} text Token text.
1401
+ * @property {MicromarkToken[]} children Child tokens.
1402
+ * @property {MicromarkToken | null} parent Parent token.
1403
+ */
1404
+
1316
1405
  /**
1317
1406
  * Error-reporting callback.
1318
1407
  *
@@ -1351,6 +1440,7 @@ module.exports = markdownlint;
1351
1440
  * @property {string} description Rule description.
1352
1441
  * @property {URL} [information] Link to more information.
1353
1442
  * @property {string[]} tags Rule tag(s).
1443
+ * @property {"markdownit" | "micromark" | "none"} parser Parser used.
1354
1444
  * @property {boolean} [asynchronous] True if asynchronous.
1355
1445
  * @property {RuleFunction} function Rule implementation.
1356
1446
  */
@@ -1442,6 +1532,13 @@ module.exports = markdownlint;
1442
1532
  * @typedef {import("./configuration").Configuration} Configuration
1443
1533
  */
1444
1534
 
1535
+ /**
1536
+ * Configuration object for linting rules strictly. For the JSON schema, see
1537
+ * {@link ../schema/markdownlint-config-schema-strict.json}.
1538
+ *
1539
+ * @typedef {import("./configuration-strict").ConfigurationStrict} ConfigurationStrict
1540
+ */
1541
+
1445
1542
  /**
1446
1543
  * Rule configuration object.
1447
1544
  *