markdownlint 0.41.1 → 0.42.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 (56) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/CONTRIBUTING.md +62 -77
  3. package/README.md +7 -7
  4. package/doc/CustomRules.md +6 -4
  5. package/doc/Rules.md +76 -35
  6. package/doc/md010.md +0 -1
  7. package/doc/md024.md +1 -1
  8. package/doc/md043.md +47 -9
  9. package/doc/md051.md +19 -19
  10. package/doc/md055.md +6 -3
  11. package/doc/md060.md +3 -2
  12. package/helpers/README.md +2 -2
  13. package/helpers/helpers.cjs +16 -7
  14. package/helpers/micromark-helpers.cjs +7 -10
  15. package/helpers/package.json +1 -5
  16. package/lib/configuration-strict.d.ts +124 -112
  17. package/lib/constants.mjs +1 -1
  18. package/lib/defer-require.cjs +1 -0
  19. package/lib/exports.d.mts +29 -1
  20. package/lib/markdownit.cjs +8 -1
  21. package/lib/markdownlint.d.mts +337 -195
  22. package/lib/markdownlint.mjs +78 -85
  23. package/lib/md007.mjs +2 -2
  24. package/lib/md009.mjs +2 -3
  25. package/lib/md010.mjs +1 -1
  26. package/lib/md011.mjs +10 -7
  27. package/lib/md012.mjs +1 -1
  28. package/lib/md013.mjs +13 -9
  29. package/lib/md018.mjs +1 -1
  30. package/lib/md020.mjs +1 -1
  31. package/lib/md022.mjs +5 -6
  32. package/lib/md025.mjs +1 -1
  33. package/lib/md027.mjs +1 -1
  34. package/lib/md028.mjs +1 -2
  35. package/lib/md029.mjs +1 -2
  36. package/lib/md030.mjs +4 -4
  37. package/lib/md031.mjs +1 -1
  38. package/lib/md033.mjs +1 -1
  39. package/lib/md034.mjs +1 -1
  40. package/lib/md039.mjs +5 -1
  41. package/lib/md041.mjs +1 -1
  42. package/lib/md043.mjs +98 -44
  43. package/lib/md044.mjs +2 -2
  44. package/lib/md048.mjs +1 -3
  45. package/lib/md051.mjs +2 -3
  46. package/lib/md055.mjs +11 -1
  47. package/lib/md056.mjs +1 -1
  48. package/lib/md058.mjs +1 -1
  49. package/lib/md060.mjs +24 -4
  50. package/lib/micromark-parse.mjs +1 -1
  51. package/lib/resolve-module.d.cts +15 -10
  52. package/package.json +31 -34
  53. package/schema/.markdownlint.jsonc +54 -54
  54. package/schema/.markdownlint.yaml +54 -54
  55. package/schema/markdownlint-config-schema-strict.json +126 -118
  56. package/schema/markdownlint-config-schema.json +126 -118
package/lib/md030.mjs CHANGED
@@ -10,10 +10,10 @@ export default {
10
10
  "tags": [ "ol", "ul", "whitespace" ],
11
11
  "parser": "micromark",
12
12
  "function": function MD030(params, onError) {
13
- const ulSingle = Number(params.config.ul_single || 1);
14
- const olSingle = Number(params.config.ol_single || 1);
15
- const ulMulti = Number(params.config.ul_multi || 1);
16
- const olMulti = Number(params.config.ol_multi || 1);
13
+ const ulSingle = Number(params.config.ul_single ?? 1);
14
+ const olSingle = Number(params.config.ol_single ?? 1);
15
+ const ulMulti = Number(params.config.ul_multi ?? 1);
16
+ const olMulti = Number(params.config.ol_multi ?? 1);
17
17
  for (const list of filterByTypesCached([ "listOrdered", "listUnordered" ])) {
18
18
  const ordered = (list.type === "listOrdered");
19
19
  const listItemPrefixes =
package/lib/md031.mjs CHANGED
@@ -45,7 +45,7 @@ export default {
45
45
  "parser": "micromark",
46
46
  "function": function MD031(params, onError) {
47
47
  const listItems = params.config.list_items;
48
- const includeListItems = (listItems === undefined) ? true : !!listItems;
48
+ const includeListItems = (listItems === undefined) || !!listItems;
49
49
  const { lines } = params;
50
50
  for (const codeBlock of filterByTypesCached([ "codeFenced" ])) {
51
51
  if (includeListItems || !(getParentOfType(codeBlock, [ "listOrdered", "listUnordered" ]))) {
package/lib/md033.mjs CHANGED
@@ -4,7 +4,7 @@ import { addError, nextLinesRe } from "../helpers/helpers.cjs";
4
4
  import { getHtmlTagInfo, getParentOfType } from "../helpers/micromark-helpers.cjs";
5
5
  import { filterByTypesCached } from "./cache.mjs";
6
6
 
7
- /** @typedef {import("micromark-extension-gfm-table")} */
7
+ /** @typedef {typeof import("micromark-extension-gfm-table")} _ambient_ */
8
8
 
9
9
  // eslint-disable-next-line jsdoc/reject-any-type
10
10
  const toLowerCaseStringArray = (/** @type {any} */ arr) => Array.isArray(arr) ? arr.map((elm) => String(elm).toLowerCase()) : [];
package/lib/md034.mjs CHANGED
@@ -4,7 +4,7 @@ import { addErrorContext } from "../helpers/helpers.cjs";
4
4
  import { filterByPredicate, getHtmlTagInfo, inHtmlFlow } from "../helpers/micromark-helpers.cjs";
5
5
 
6
6
  /** @typedef {import("markdownlint").MicromarkToken} MicromarkToken */
7
- /** @typedef {import("micromark-extension-gfm-autolink-literal")} */
7
+ /** @typedef {typeof import("micromark-extension-gfm-autolink-literal")} _ambient_ */
8
8
 
9
9
  /** @type {import("markdownlint").Rule} */
10
10
  export default {
package/lib/md039.mjs CHANGED
@@ -1,8 +1,12 @@
1
1
  // @ts-check
2
2
 
3
+ import { re } from "re2js";
3
4
  import { addErrorContext } from "../helpers/helpers.cjs";
4
5
  import { filterByTypesCached } from "./cache.mjs";
5
6
 
7
+ const startRe = re`^[^\S\r\n]+`;
8
+ const endRe = re`[^\S\r\n]+$`;
9
+
6
10
  /**
7
11
  * Adds an error for a label space issue.
8
12
  *
@@ -12,7 +16,7 @@ import { filterByTypesCached } from "./cache.mjs";
12
16
  * @param {boolean} isStart True iff error is at the start of the link.
13
17
  */
14
18
  function addLabelSpaceError(onError, label, labelText, isStart) {
15
- const match = labelText.text.match(isStart ? /^[^\S\r\n]+/ : /[^\S\r\n]+$/);
19
+ const match = (isStart ? startRe : endRe).exec(labelText.text);
16
20
  const range = match ?
17
21
  [
18
22
  (isStart ? (labelText.startColumn) : (labelText.endColumn - match[0].length)),
package/lib/md041.mjs CHANGED
@@ -31,7 +31,7 @@ export default {
31
31
  "parser": "micromark",
32
32
  "function": function MD041(params, onError) {
33
33
  const allowPreamble = !!params.config.allow_preamble;
34
- const level = Number(params.config.level || 1);
34
+ const level = Number(params.config.level ?? 1);
35
35
  const { tokens } = params.parsers.micromark;
36
36
  if (
37
37
  !frontMatterHasTitle(
package/lib/md043.mjs CHANGED
@@ -1,9 +1,32 @@
1
1
  // @ts-check
2
2
 
3
- import { addErrorContext, addErrorDetailIf } from "../helpers/helpers.cjs";
3
+ import { addError, addErrorDetailIf } from "../helpers/helpers.cjs";
4
4
  import { getHeadingLevel, getHeadingText } from "../helpers/micromark-helpers.cjs";
5
5
  import { filterByTypesCached } from "./cache.mjs";
6
6
 
7
+ export const headingsItemsRe = /^(?:[*+?]|\^+|[#%]{1,6}\s+\S.*)$/u;
8
+ const prefixedHeadingPartsRe = /^([#%]{1,6})\s+(\S.*)$/u;
9
+ const loopHeadingRe = /^\^+$/u;
10
+ const canMatchNothingHeadingsRe = /^(?:\*|\^+)$/u;
11
+ const maximumLoopsAllowed = 1000;
12
+
13
+ const headingIsExpected = (/** @type {string} */ actual, /** @type {string} */ expected, /** @type {boolean} */ matchCase) => {
14
+ if (expected.startsWith("%")) {
15
+ // Regular expression comparison
16
+ const [ , actualLevel, actualText ] = prefixedHeadingPartsRe.exec(actual) || [];
17
+ const [ , expectedLevel, expectedText ] = prefixedHeadingPartsRe.exec(expected) || [];
18
+ return (
19
+ (actualLevel.length === expectedLevel.length) &&
20
+ // eslint-disable-next-line unicorn/no-unreadable-new-expression
21
+ (new RegExp(expectedText, `${matchCase ? "" : "i"}u`)).test(actualText)
22
+ );
23
+ }
24
+ // Text comparison
25
+ const actualLower = matchCase ? actual : actual.toLowerCase();
26
+ const expectedLower = matchCase ? expected : expected.toLowerCase();
27
+ return actualLower === expectedLower;
28
+ };
29
+
7
30
  /** @type {import("markdownlint").Rule} */
8
31
  export default {
9
32
  "names": [ "MD043", "required-headings" ],
@@ -11,62 +34,93 @@ export default {
11
34
  "tags": [ "headings" ],
12
35
  "parser": "micromark",
13
36
  "function": function MD043(params, onError) {
14
- const requiredHeadings = params.config.headings;
15
- if (!Array.isArray(requiredHeadings)) {
16
- // Nothing to check; avoid doing any work
37
+ /** @type {string[] | null | undefined} */
38
+ const headings = params.config.headings;
39
+ if (!headings) {
17
40
  return;
18
41
  }
19
- const matchCase = params.config.match_case || false;
42
+ const requiredHeadings = headings.map((heading) => headingsItemsRe.test(heading) ? heading : "[Invalid syntax]");
43
+ const matchCase = Boolean(params.config.match_case);
20
44
  let i = 0;
21
- let matchAny = false;
45
+ let remainingLoopsAllowed = maximumLoopsAllowed;
46
+ let allowAnyMatchFallback = false;
22
47
  let hasError = false;
23
- let anyHeadings = false;
24
- const getExpected = () => String(requiredHeadings[i++] || "[None]");
25
- const handleCase = (/** @type {string} */ str) => (matchCase ? str : str.toLowerCase());
48
+ const getExpected = (/** @type {boolean} */ skipLoopHeadings) => {
49
+ let expected = null;
50
+ do {
51
+ expected = requiredHeadings[i++] || "[No heading]";
52
+ // eslint-disable-next-line no-unmodified-loop-condition
53
+ } while (skipLoopHeadings && loopHeadingRe.test(expected));
54
+ return expected;
55
+ };
26
56
  for (const heading of filterByTypesCached([ "atxHeading", "setextHeading" ])) {
27
- if (!hasError) {
28
- const headingText = getHeadingText(heading);
29
- const headingLevel = getHeadingLevel(heading);
30
- anyHeadings = true;
31
- const actual = `${"".padEnd(headingLevel, "#")} ${headingText}`;
32
- const expected = getExpected();
33
- if (expected === "*") {
34
- const nextExpected = getExpected();
35
- if (handleCase(nextExpected) !== handleCase(actual)) {
36
- matchAny = true;
37
- i--;
57
+ const headingText = getHeadingText(heading);
58
+ const headingLevel = getHeadingLevel(heading);
59
+ const actual = `${"".padEnd(headingLevel, "#")} ${headingText}`;
60
+ let expected = getExpected(false);
61
+ if (expected.startsWith("^")) {
62
+ // Handle loop
63
+ const current = i;
64
+ const nextExpected = getExpected(true);
65
+ if (headingIsExpected(actual, nextExpected, matchCase)) {
66
+ // No need to loop (again)
67
+ expected = nextExpected;
68
+ } else {
69
+ // Try to loop to previous matching marker
70
+ remainingLoopsAllowed--;
71
+ let j = current - 2;
72
+ for (; j >= 0; j--) {
73
+ if (requiredHeadings[j] === expected) {
74
+ // Perform loop
75
+ i = j + 1;
76
+ expected = getExpected(false);
77
+ break;
78
+ }
38
79
  }
39
- } else if (expected === "+") {
40
- matchAny = true;
41
- } else if (expected === "?") {
42
- // Allow current, match next
43
- } else if (handleCase(expected) === handleCase(actual)) {
44
- matchAny = false;
45
- } else if (matchAny) {
80
+ if (j < 0) {
81
+ // No matching loop marker
82
+ expected = nextExpected;
83
+ }
84
+ }
85
+ }
86
+ if (remainingLoopsAllowed < 0) {
87
+ // Too many loops performed
88
+ addError(onError, heading.startLine, "Too many loops", `Limit: ${maximumLoopsAllowed}`);
89
+ hasError = true;
90
+ break;
91
+ } else if (expected === "*") {
92
+ // Handle "zero or more of anything"
93
+ const nextExpected = getExpected(true);
94
+ if (!headingIsExpected(actual, nextExpected, matchCase)) {
95
+ allowAnyMatchFallback = true;
46
96
  i--;
47
- } else {
48
- addErrorDetailIf(
49
- onError,
50
- heading.startLine,
51
- expected,
52
- actual
53
- );
54
- hasError = true;
55
97
  }
98
+ } else if (expected === "+") {
99
+ // Handle "one or more of anything"
100
+ allowAnyMatchFallback = true;
101
+ } else if (expected === "?") {
102
+ // Handle "exactly one of anything"
103
+ // Nothing to do
104
+ } else if (headingIsExpected(actual, expected, matchCase)) {
105
+ // Handle successful match
106
+ allowAnyMatchFallback = false;
107
+ } else if (allowAnyMatchFallback) {
108
+ // Handle "anything" match by restoring index
109
+ i--;
110
+ } else {
111
+ // Report heading mismatch
112
+ addErrorDetailIf(onError, heading.startLine, expected, actual);
113
+ hasError = true;
114
+ break;
56
115
  }
57
116
  }
58
- const extraHeadings = requiredHeadings.length - i;
117
+ const remainingRequiredHeadings = requiredHeadings.slice(i).filter((heading) => !canMatchNothingHeadingsRe.test(heading));
59
118
  if (
60
119
  !hasError &&
61
- ((extraHeadings > 1) ||
62
- ((extraHeadings === 1) && (requiredHeadings[i] !== "*"))) &&
63
- (anyHeadings || !requiredHeadings.every((heading) => heading === "*"))
120
+ (remainingRequiredHeadings.length > 0)
64
121
  ) {
65
- addErrorContext(
66
- onError,
67
- params.lines.length,
68
- requiredHeadings[i]
69
- );
122
+ // Report unmatched heading(s)
123
+ addErrorDetailIf(onError, params.lines.length, remainingRequiredHeadings[0], "[End of file]");
70
124
  }
71
125
  }
72
126
  };
package/lib/md044.mjs CHANGED
@@ -24,10 +24,10 @@ export default {
24
24
  }
25
25
  const codeBlocks = params.config.code_blocks;
26
26
  const includeCodeBlocks =
27
- (codeBlocks === undefined) ? true : !!codeBlocks;
27
+ (codeBlocks === undefined) || !!codeBlocks;
28
28
  const htmlElements = params.config.html_elements;
29
29
  const includeHtmlElements =
30
- (htmlElements === undefined) ? true : !!htmlElements;
30
+ (htmlElements === undefined) || !!htmlElements;
31
31
  const scannedTypes = new Set([ "data" ]);
32
32
  if (includeCodeBlocks) {
33
33
  scannedTypes.add("codeFlowValue");
package/lib/md048.mjs CHANGED
@@ -30,9 +30,7 @@ export default {
30
30
  let expectedStyle = style;
31
31
  const codeFenceds = filterByTypesCached([ "codeFenced" ]);
32
32
  for (const codeFenced of codeFenceds) {
33
- const codeFencedFenceSequence =
34
- getDescendantsByType(codeFenced, [ "codeFencedFence", "codeFencedFenceSequence" ])[0];
35
- const { startLine, text } = codeFencedFenceSequence;
33
+ const { startLine, text } = getDescendantsByType(codeFenced, [ "codeFencedFence", "codeFencedFenceSequence" ])[0];
36
34
  if (expectedStyle === "consistent") {
37
35
  expectedStyle = fencedCodeBlockStyleFor(text);
38
36
  }
package/lib/md051.mjs CHANGED
@@ -7,7 +7,7 @@ import { filterByTypesCached } from "./cache.mjs";
7
7
  // Regular expression for identifying HTML anchor names
8
8
  const idRe = getHtmlAttributeRe("id");
9
9
  const nameRe = getHtmlAttributeRe("name");
10
- const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
10
+ const anchorRe = /\{(#[a-z\d]+(?:[-_]+[a-z\d]+)*)\}/gu;
11
11
  const lineFragmentRe = /^#(?:L\d+(?:C\d+)?-L\d+(?:C\d+)?|L\d+)$/;
12
12
 
13
13
  // Sets for filtering heading tokens during conversion
@@ -17,8 +17,7 @@ const tokensInclude = new Set(
17
17
  );
18
18
 
19
19
  /**
20
- * Converts a Markdown heading into an HTML fragment according to the rules
21
- * used by GitHub.
20
+ * Converts a Markdown heading into an HTML fragment according to the rules used by GitHub.
22
21
  *
23
22
  * @param {import("markdownlint").MicromarkToken} headingText Heading text token.
24
23
  * @returns {string} Fragment string for heading.
package/lib/md055.mjs CHANGED
@@ -1,10 +1,11 @@
1
1
  // @ts-check
2
2
 
3
3
  import { addErrorDetailIf } from "../helpers/helpers.cjs";
4
+ import { getParentOfType } from "../helpers/micromark-helpers.cjs";
4
5
  import { filterByTypesCached } from "./cache.mjs";
5
6
 
6
7
  /** @typedef {import("markdownlint").MicromarkToken} MicromarkToken */
7
- /** @typedef {import("micromark-extension-gfm-table")} */
8
+ /** @typedef {typeof import("micromark-extension-gfm-table")} _ambient_ */
8
9
 
9
10
  const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
10
11
  const ignoreWhitespace = (/** @type {MicromarkToken[]} */ tokens) => tokens.filter(
@@ -27,8 +28,17 @@ export default {
27
28
  ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
28
29
  let expectedTrailingPipe =
29
30
  ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
31
+ let currentTable = null;
30
32
  const rows = filterByTypesCached([ "tableDelimiterRow", "tableRow" ]);
31
33
  for (const row of rows) {
34
+ if (style === "per_table") {
35
+ // Reset style for each new table
36
+ const rowTable = getParentOfType(row, [ "table" ]);
37
+ if (rowTable !== currentTable) {
38
+ expectedStyle = "consistent";
39
+ currentTable = rowTable;
40
+ }
41
+ }
32
42
  // The following uses of first/lastOrNothing lack fallback handling
33
43
  // because it seems not to be possible (i.e., 0% coverage)
34
44
  const firstCell = firstOrNothing(row.children);
package/lib/md056.mjs CHANGED
@@ -6,7 +6,7 @@ import { filterByTypesCached } from "./cache.mjs";
6
6
 
7
7
  const makeRange = (/** @type {number} */ start, /** @type {number} */ end) => [ start, end - start + 1 ];
8
8
 
9
- /** @typedef {import("micromark-extension-gfm-table")} */
9
+ /** @typedef {typeof import("micromark-extension-gfm-table")} _ambient_ */
10
10
 
11
11
  /** @type {import("markdownlint").Rule} */
12
12
  export default {
package/lib/md058.mjs CHANGED
@@ -4,7 +4,7 @@ import { addErrorContext, isBlankLine } from "../helpers/helpers.cjs";
4
4
  import { getBlockQuotePrefixText } from "../helpers/micromark-helpers.cjs";
5
5
  import { filterByTypesCached } from "./cache.mjs";
6
6
 
7
- /** @typedef {import("micromark-extension-gfm-table")} */
7
+ /** @typedef {typeof import("micromark-extension-gfm-table")} _ambient_ */
8
8
 
9
9
  /** @type {import("markdownlint").Rule} */
10
10
  export default {
package/lib/md060.mjs CHANGED
@@ -4,21 +4,35 @@ import { filterByTypes } from "../helpers/micromark-helpers.cjs";
4
4
  import { filterByTypesCached } from "./cache.mjs";
5
5
  import stringWidth from "string-width";
6
6
 
7
- /** @typedef {import("micromark-extension-gfm-table")} */
7
+ /** @typedef {typeof import("micromark-extension-gfm-table")} _ambient_ */
8
8
  /** @typedef {import("markdownlint").MicromarkToken} MicromarkToken */
9
9
  /** @typedef {import("markdownlint").RuleOnErrorInfo} RuleOnErrorInfo */
10
10
  /** @typedef {import("markdownlint").RuleOnErrorFixInfo} RuleOnErrorFixInfo */
11
11
 
12
+ // Regular expression to match text that could represent an unordered list item prefix
13
+ const unorderedListPrefix = /^[>\s]*[-+*]$/;
14
+
12
15
  /**
13
16
  * Adds a RuleOnErrorInfo object to a list of RuleOnErrorInfo objects.
14
17
  *
15
18
  * @param {RuleOnErrorInfo[]} errors List of errors.
19
+ * @param {readonly string[]} lines File/string lines.
16
20
  * @param {number} lineNumber Line number.
17
21
  * @param {number} column Column number.
18
22
  * @param {string} detail Detail message.
19
23
  * @param {RuleOnErrorFixInfo} [fixInfo] Fix information.
24
+ * @returns {void}
20
25
  */
21
- function addError(errors, lineNumber, column, detail, fixInfo) {
26
+ function addError(errors, lines, lineNumber, column, detail, fixInfo) {
27
+ if (
28
+ fixInfo &&
29
+ (fixInfo.insertText === " ") &&
30
+ fixInfo.editColumn &&
31
+ unorderedListPrefix.test(lines[lineNumber - 1].slice(0, fixInfo.editColumn - 1))
32
+ ) {
33
+ // Do not apply edits that would change a table cell into an unordered list item
34
+ fixInfo = undefined;
35
+ }
22
36
  errors.push({
23
37
  lineNumber,
24
38
  detail,
@@ -70,7 +84,7 @@ function checkStyleAligned(lines, rows, detail) {
70
84
  const rowDividerColumns = getTableDividerColumns(lines, row);
71
85
  for (const dividerColumn of rowDividerColumns) {
72
86
  if ((remainingHeaderDividerColumns.size > 0) && !remainingHeaderDividerColumns.delete(dividerColumn.effective)) {
73
- addError(errorInfos, row.startLine, dividerColumn.actual, detail);
87
+ addError(errorInfos, lines, row.startLine, dividerColumn.actual, detail);
74
88
  }
75
89
  }
76
90
  }
@@ -128,6 +142,7 @@ export default {
128
142
  if (previous.text.length !== 1) {
129
143
  addError(
130
144
  errorsIfCompact,
145
+ lines,
131
146
  startLine,
132
147
  startColumn,
133
148
  "Table pipe has extra space to the left for style \"compact\"",
@@ -136,6 +151,7 @@ export default {
136
151
  }
137
152
  addError(
138
153
  errorsIfTight,
154
+ lines,
139
155
  startLine,
140
156
  startColumn,
141
157
  "Table pipe has space to the left for style \"tight\"",
@@ -144,6 +160,7 @@ export default {
144
160
  } else {
145
161
  addError(
146
162
  errorsIfCompact,
163
+ lines,
147
164
  startLine,
148
165
  startColumn,
149
166
  "Table pipe is missing space to the left for style \"compact\"",
@@ -158,6 +175,7 @@ export default {
158
175
  if (next.text.length !== 1) {
159
176
  addError(
160
177
  errorsIfCompact,
178
+ lines,
161
179
  startLine,
162
180
  startColumn,
163
181
  "Table pipe has extra space to the right for style \"compact\"",
@@ -166,6 +184,7 @@ export default {
166
184
  }
167
185
  addError(
168
186
  errorsIfTight,
187
+ lines,
169
188
  startLine,
170
189
  startColumn,
171
190
  "Table pipe has space to the right for style \"tight\"",
@@ -175,6 +194,7 @@ export default {
175
194
  } else {
176
195
  addError(
177
196
  errorsIfCompact,
197
+ lines,
178
198
  startLine,
179
199
  startColumn,
180
200
  "Table pipe is missing space to the right for style \"compact\"",
@@ -191,7 +211,7 @@ export default {
191
211
  let errorInfos = errorsIfAligned;
192
212
  if (
193
213
  styleCompactAllowed &&
194
- ((errorsIfCompact.length < errorInfos.length) || !styleAlignedAllowed)
214
+ (!styleAlignedAllowed || (errorsIfCompact.length < errorInfos.length))
195
215
  ) {
196
216
  errorInfos = errorsIfCompact;
197
217
  }
@@ -19,7 +19,7 @@ import { flatTokensSymbol, htmlFlowSymbol, newlineRe } from "../helpers/shared.c
19
19
  /** @typedef {import("micromark-util-types").Token} Token */
20
20
  /** @typedef {import("micromark-util-types").Tokenizer} Tokenizer */
21
21
  /** @typedef {import("markdownlint").MicromarkToken} MicromarkToken */
22
- /** @typedef {import("./micromark-types.d.mts")} */
22
+ /** @typedef {typeof import("./micromark-types.d.mts")} _ambient_ */
23
23
 
24
24
  /**
25
25
  * Gets a modified micromark-extension-directive without support for inline directives.
@@ -1,18 +1,15 @@
1
+ declare const _exports: {
2
+ resolveModule: typeof resolveModule;
3
+ resolveModuleCustomResolve: typeof resolveModuleCustomResolve;
4
+ };
5
+ export = _exports;
1
6
  export type RequireResolveOptions = {
2
7
  /**
3
8
  * Additional paths to resolve from.
4
9
  */
5
- paths?: string[] | undefined;
10
+ paths?: string[];
6
11
  };
7
12
  export type RequireResolve = (id: string, options: RequireResolveOptions) => string;
8
- /**
9
- * Resolves modules according to Node's resolution rules.
10
- *
11
- * @param {string} id Module name or path.
12
- * @param {string[]} [paths] Additional paths to resolve from.
13
- * @returns {string} Resolved module path.
14
- */
15
- export function resolveModule(id: string, paths?: string[]): string;
16
13
  /**
17
14
  * @typedef RequireResolveOptions
18
15
  * @property {string[]} [paths] Additional paths to resolve from.
@@ -31,4 +28,12 @@ export function resolveModule(id: string, paths?: string[]): string;
31
28
  * @param {string[]} [paths] Additional paths to resolve from.
32
29
  * @returns {string} Resolved module path.
33
30
  */
34
- export function resolveModuleCustomResolve(resolve: RequireResolve, id: string, paths?: string[]): string;
31
+ declare const resolveModuleCustomResolve: (resolve: RequireResolve, id: string, paths?: string[]) => string;
32
+ /**
33
+ * Resolves modules according to Node's resolution rules.
34
+ *
35
+ * @param {string} id Module name or path.
36
+ * @param {string[]} [paths] Additional paths to resolve from.
37
+ * @returns {string} Resolved module path.
38
+ */
39
+ declare const resolveModule: (id: string, paths?: string[]) => string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "markdownlint",
3
- "version": "0.41.1",
4
- "description": "A Node.js style checker and lint tool for Markdown/CommonMark files.",
3
+ "version": "0.42.0",
4
+ "description": "A Node.js style checker and lint tool for Markdown/CommonMark files",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./lib/exports.mjs",
@@ -26,21 +26,16 @@
26
26
  "author": "David Anson (https://dlaa.me/)",
27
27
  "license": "MIT",
28
28
  "homepage": "https://github.com/DavidAnson/markdownlint",
29
- "repository": {
30
- "type": "git",
31
- "url": "git+https://github.com/DavidAnson/markdownlint.git"
32
- },
33
- "bugs": "https://github.com/DavidAnson/markdownlint/issues",
29
+ "repository": "github:DavidAnson/markdownlint",
34
30
  "funding": "https://github.com/sponsors/DavidAnson",
35
31
  "scripts": {
36
32
  "build-config": "npm run build-config-schema && npm run build-config-example",
37
33
  "build-config-example": "node schema/build-config-example.mjs",
38
34
  "build-config-schema": "node schema/build-config-schema.mjs",
39
35
  "build-declaration": "tsc --project ./declaration/tsconfig.json && node scripts/index.mjs copy dts/lib/exports.d.mts lib/exports.d.mts && node scripts/index.mjs copy dts/lib/exports-async.d.mts lib/exports-async.d.mts && node scripts/index.mjs copy dts/lib/exports-promise.d.mts lib/exports-promise.d.mts && node scripts/index.mjs copy dts/lib/exports-sync.d.mts lib/exports-sync.d.mts && node scripts/index.mjs copy dts/lib/markdownlint.d.mts lib/markdownlint.d.mts && node scripts/index.mjs copy dts/lib/resolve-module.d.cts lib/resolve-module.d.cts && node scripts/index.mjs remove dts",
40
- "build-demo": "node scripts/index.mjs copy node_modules/markdown-it/dist/markdown-it.min.js demo/markdown-it.min.js && cd demo && webpack --no-stats",
36
+ "build-demo": "node scripts/index.mjs copy node_modules/markdown-it/dist/browser/markdown-it.umd.min.js demo/markdown-it.umd.min.js && cd demo && webpack --no-stats",
41
37
  "build-docs": "node doc-build/build-rules.mjs",
42
38
  "ci": "concurrently npm:build-demo npm:lint npm:serial-config-docs npm:serial-declaration npm:test npm:test-webpack && git diff --exit-code && echo PASS",
43
- "clone-test-repos-apache-airflow": "cd test-repos && git clone https://github.com/apache/airflow apache-airflow --depth 1 --no-tags --quiet",
44
39
  "clone-test-repos-dotnet-docs": "cd test-repos && git clone https://github.com/dotnet/docs dotnet-docs --depth 1 --no-tags --quiet",
45
40
  "clone-test-repos-electron-electron": "cd test-repos && git clone https://github.com/electron/electron electron-electron --depth 1 --no-tags --quiet && cd electron-electron && node ../../scripts/index.mjs delete package.json && npm install --no-save --ignore-scripts @electron/lint-roller",
46
41
  "clone-test-repos-eslint-eslint": "cd test-repos && git clone https://github.com/eslint/eslint eslint-eslint --depth 1 --no-tags --quiet",
@@ -51,9 +46,9 @@
51
46
  "clone-test-repos-v8-v8-dev": "cd test-repos && git clone https://github.com/v8/v8.dev v8-v8-dev --depth 1 --no-tags --quiet",
52
47
  "clone-test-repos-webhintio-hint": "cd test-repos && git clone https://github.com/webhintio/hint webhintio-hint --depth 1 --no-tags --quiet",
53
48
  "clone-test-repos-webpack-webpack-js-org": "cd test-repos && git clone https://github.com/webpack/webpack.js.org webpack-webpack-js-org --depth 1 --no-tags --quiet",
54
- "clone-test-repos": "mkdir test-repos && cd test-repos && npm run clone-test-repos-apache-airflow && npm run clone-test-repos-dotnet-docs && npm run clone-test-repos-electron-electron && npm run clone-test-repos-eslint-eslint && npm run clone-test-repos-mdn-content && npm run clone-test-repos-mkdocs-mkdocs && npm run clone-test-repos-mochajs-mocha && npm run clone-test-repos-pi-hole-docs && npm run clone-test-repos-v8-v8-dev && npm run clone-test-repos-webhintio-hint && npm run clone-test-repos-webpack-webpack-js-org",
49
+ "clone-test-repos": "mkdir test-repos && cd test-repos && npm run clone-test-repos-dotnet-docs && npm run clone-test-repos-electron-electron && npm run clone-test-repos-eslint-eslint && npm run clone-test-repos-mdn-content && npm run clone-test-repos-mkdocs-mkdocs && npm run clone-test-repos-mochajs-mocha && npm run clone-test-repos-pi-hole-docs && npm run clone-test-repos-v8-v8-dev && npm run clone-test-repos-webhintio-hint && npm run clone-test-repos-webpack-webpack-js-org",
55
50
  "example": "cd example && node standalone.mjs",
56
- "lint": "eslint --max-warnings 0",
51
+ "lint": "cross-env RECHECK_BACKEND=pure eslint --max-warnings 0",
57
52
  "lint-test-repos": "node --test test/markdownlint-test-repos-*.mjs",
58
53
  "serial-config-docs": "npm run build-config && npm run build-docs",
59
54
  "serial-declaration": "npm run build-declaration && npm run test-declaration",
@@ -71,52 +66,54 @@
71
66
  "node": ">=22"
72
67
  },
73
68
  "dependencies": {
74
- "micromark": "4.0.2",
75
- "micromark-core-commonmark": "2.0.3",
69
+ "micromark-core-commonmark": "2.0.4",
76
70
  "micromark-extension-directive": "4.0.0",
77
71
  "micromark-extension-gfm-autolink-literal": "2.1.0",
78
72
  "micromark-extension-gfm-footnote": "2.1.0",
79
- "micromark-extension-gfm-table": "2.1.1",
73
+ "micromark-extension-gfm-table": "2.1.2",
80
74
  "micromark-extension-math": "3.1.0",
81
- "micromark-util-types": "2.0.2",
82
- "string-width": "8.2.1"
75
+ "micromark-util-types": "2.0.3",
76
+ "micromark": "4.0.3",
77
+ "re2js": "2.8.6",
78
+ "string-width": "8.3.0"
83
79
  },
84
80
  "devDependencies": {
85
81
  "@eslint/js": "10.0.1",
86
82
  "@stylistic/eslint-plugin": "5.10.0",
87
- "@types/markdown-it": "14.1.2",
88
83
  "ajv": "8.20.0",
89
84
  "character-entities": "2.0.2",
90
- "concurrently": "10.0.3",
91
- "eslint": "10.6.0",
92
- "eslint-node-test": "0.1.0",
93
- "eslint-plugin-jsdoc": "63.0.10",
94
- "eslint-plugin-n": "18.2.1",
95
- "eslint-plugin-regexp": "3.1.1",
96
- "eslint-plugin-unicorn": "70.0.0",
85
+ "concurrently": "10.0.5",
86
+ "cross-env": "10.1.0",
87
+ "eslint-node-test": "1.0.1",
88
+ "eslint-package-json": "2.0.0",
89
+ "eslint-plugin-jsdoc": "65.1.0",
90
+ "eslint-plugin-n": "18.4.1",
91
+ "eslint-plugin-redos": "4.5.0",
92
+ "eslint-plugin-regexp": "3.3.1",
93
+ "eslint-plugin-unicorn": "77.0.0",
94
+ "eslint": "10.12.0",
97
95
  "gemoji": "8.1.0",
98
- "globby": "16.2.0",
99
- "js-yaml": "5.2.1",
100
- "json-schema-to-typescript": "15.0.4",
96
+ "globby": "16.2.4",
97
+ "js-yaml": "5.4.2",
98
+ "json-schema-to-typescript": "16.0.0",
101
99
  "json-stringify-safe": "5.0.1",
102
100
  "jsonc-parser": "3.3.1",
103
- "markdown-it": "14.3.0",
104
101
  "markdown-it-for-inline": "2.0.1",
105
102
  "markdown-it-sub": "2.0.0",
106
103
  "markdown-it-sup": "2.0.0",
104
+ "markdown-it": "15.0.2",
107
105
  "markdownlint-rule-extended-ascii": "0.2.1",
108
106
  "nano-spawn": "2.1.0",
107
+ "smol-toml": "1.9.0",
109
108
  "terser-webpack-plugin": "5.6.1",
110
- "toml": "4.1.2",
111
- "typescript": "6.0.3",
112
- "webpack": "5.108.3",
113
- "webpack-cli": "7.1.0"
109
+ "typescript": "7.0.2",
110
+ "webpack-cli": "7.2.3",
111
+ "webpack": "5.111.1"
114
112
  },
115
113
  "keywords": [
116
114
  "markdown",
117
115
  "lint",
118
116
  "md",
119
- "CommonMark",
120
- "markdownlint"
117
+ "commonmark"
121
118
  ]
122
119
  }