markdownlint 0.41.0 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/constants.mjs CHANGED
@@ -11,4 +11,4 @@ export const fixableRuleNames = [
11
11
  "MD054", "MD058", "MD060"
12
12
  ];
13
13
  export const homepage = "https://github.com/DavidAnson/markdownlint";
14
- export const version = "0.41.0";
14
+ export const version = "0.41.1";
@@ -93,6 +93,7 @@ function validateRuleList(ruleList, synchronous) {
93
93
  }
94
94
  for (const tag of rule.tags) {
95
95
  const tagUpper = tag.toUpperCase();
96
+ // eslint-disable-next-line unicorn/no-computed-property-existence-check
96
97
  if (!result && allIds[tagUpper]) {
97
98
  result = new Error("Tag '" + tag + "' of custom rule at index " +
98
99
  customIndex + " is already used as a name.");
@@ -439,6 +440,7 @@ function lintContent(
439
440
  // eslint-disable-next-line jsdoc/reject-any-type
440
441
  const callbackError = (/** @type {any} */ error) => callback(error instanceof Error ? error : new Error(error));
441
442
  // Remove UTF-8 byte order marker (if present)
443
+ // eslint-disable-next-line unicorn/prefer-unicode-code-point-escapes
442
444
  content = content.replace(/^\uFEFF/, "");
443
445
  // Remove front matter
444
446
  const removeFrontMatterResult = removeFrontMatter(content, frontMatter);
@@ -771,8 +773,8 @@ function lintFile(
771
773
  */
772
774
  function lintInput(options, synchronous, callback) {
773
775
  // Normalize inputs
774
- options = options || {};
775
- callback = callback || function noop() {};
776
+ options ||= {};
777
+ callback ||= () => {};
776
778
  /** @type {Rule[]} */
777
779
  // @ts-ignore
778
780
  const customRuleList =
@@ -1209,6 +1211,7 @@ export function applyFix(line, fixInfo, lineEnding = "\n") {
1209
1211
  const editIndex = editColumn - 1;
1210
1212
  return (deleteCount === -1) ?
1211
1213
  null :
1214
+ // eslint-disable-next-line unicorn/no-unsafe-string-replacement
1212
1215
  line.slice(0, editIndex) + insertText.replace(/\n/g, lineEnding) + line.slice(editIndex + deleteCount);
1213
1216
  }
1214
1217
 
package/lib/md004.mjs CHANGED
@@ -40,6 +40,7 @@ export default {
40
40
  for (const listItemMarker of listItemMarkers) {
41
41
  const itemStyle = markerToStyle(listItemMarker.text);
42
42
  if (style === "sublist") {
43
+ // eslint-disable-next-line unicorn/no-computed-property-existence-check
43
44
  if (!nestingStyles[nesting]) {
44
45
  nestingStyles[nesting] =
45
46
  (itemStyle === nestingStyles[nesting - 1]) ?
package/lib/md005.mjs CHANGED
@@ -34,7 +34,7 @@ export default {
34
34
  } else {
35
35
  const markerLength = listItemPrefix.text.trim().length;
36
36
  const actualEnd = listItemPrefix.startColumn + markerLength - 1;
37
- expectedEnd = expectedEnd || actualEnd;
37
+ expectedEnd ||= actualEnd;
38
38
  if ((expectedIndent !== actualIndent) || endMatching) {
39
39
  if (expectedEnd === actualEnd) {
40
40
  endMatching = true;
@@ -16,6 +16,7 @@ function validateHeadingSpaces(onError, heading, delta) {
16
16
  const { children, startLine, text } = heading;
17
17
  let index = (delta > 0) ? 0 : (children.length - 1);
18
18
  while (
19
+ // eslint-disable-next-line unicorn/no-computed-property-existence-check
19
20
  children[index] &&
20
21
  (children[index].type !== "atxHeadingSequence")
21
22
  ) {
package/lib/md022.mjs CHANGED
@@ -11,6 +11,7 @@ const defaultLines = 1;
11
11
  // eslint-disable-next-line jsdoc/reject-any-type
12
12
  const getLinesFunction = (/** @type {any} */ linesParam) => {
13
13
  if (Array.isArray(linesParam)) {
14
+ // eslint-disable-next-line unicorn/no-unreadable-new-expression
14
15
  const linesArray = new Array(6).fill(defaultLines);
15
16
  for (const [ index, value ] of [ ...linesParam.entries() ].slice(0, 6)) {
16
17
  linesArray[index] = value;
package/lib/md024.mjs CHANGED
@@ -11,7 +11,7 @@ export default {
11
11
  "tags": [ "headings" ],
12
12
  "parser": "micromark",
13
13
  "function": function MD024(params, onError) {
14
- const siblingsOnly = !!params.config.siblings_only || false;
14
+ const siblingsOnly = !!params.config.siblings_only;
15
15
  const knownContents = [ null, [] ];
16
16
  let lastLevel = 1;
17
17
  let knownContent = knownContents[lastLevel];
package/lib/md029.mjs CHANGED
@@ -15,13 +15,16 @@ const listStyles = Object.keys(listStyleExamples);
15
15
  * Gets the column and text of an ordered list item prefix token.
16
16
  *
17
17
  * @param {import("markdownlint").MicromarkToken} listItemPrefix List item prefix token.
18
- * @returns {{column: number, value: number}} List item value column and text.
18
+ * @returns {{startColumn: number, endColumn: number, text: string, number: number}} List item value column and text.
19
19
  */
20
20
  function getOrderedListItemValue(listItemPrefix) {
21
21
  const listItemValue = getDescendantsByType(listItemPrefix, [ "listItemValue" ])[0];
22
+ const { startColumn, endColumn, text } = listItemValue;
22
23
  return {
23
- "column": listItemValue.startColumn,
24
- "value": Number(listItemValue.text)
24
+ startColumn,
25
+ endColumn,
26
+ text,
27
+ "number": Number(text)
25
28
  };
26
29
  }
27
30
 
@@ -35,40 +38,49 @@ export default {
35
38
  const style = String(params.config.style);
36
39
  for (const listOrdered of filterByTypesCached([ "listOrdered" ])) {
37
40
  const listItemPrefixes = getDescendantsByType(listOrdered, [ "listItemPrefix" ]);
38
- let expected = 1;
41
+ let expectedNumber = 1;
39
42
  let incrementing = false;
40
- // Check for incrementing number pattern 1/2/3 or 0/1/2
41
- if (listItemPrefixes.length >= 2) {
42
- const first = getOrderedListItemValue(listItemPrefixes[0]);
43
- const second = getOrderedListItemValue(listItemPrefixes[1]);
44
- if ((second.value !== 1) || (first.value === 0)) {
45
- incrementing = true;
46
- if (first.value === 0) {
47
- expected = 0;
43
+ let rightAligned = false;
44
+ let zeroPrefixed = false;
45
+ if (listItemPrefixes.length > 0) {
46
+ // Check for right alignment
47
+ const firstPrefixEndColumn = listItemPrefixes[0].endColumn;
48
+ rightAligned = listItemPrefixes.every((prefix) => prefix.endColumn === firstPrefixEndColumn);
49
+ if (listItemPrefixes.length > 1) {
50
+ // Check for incrementing number pattern 1/2/3 or 0/1/2
51
+ const firstValue = getOrderedListItemValue(listItemPrefixes[0]);
52
+ const secondValue = getOrderedListItemValue(listItemPrefixes[1]);
53
+ if ((secondValue.number !== 1) || (firstValue.number === 0)) {
54
+ incrementing = true;
55
+ if (firstValue.number === 0) {
56
+ expectedNumber = 0;
57
+ }
48
58
  }
59
+ zeroPrefixed = firstValue.text.startsWith("0");
49
60
  }
50
61
  }
51
62
  // Determine effective style
52
63
  const listStyle = listStyles.includes(style) ? style : (incrementing ? "ordered" : "one");
53
64
  if (listStyle === "zero") {
54
- expected = 0;
65
+ expectedNumber = 0;
55
66
  } else if (listStyle === "one") {
56
- expected = 1;
67
+ expectedNumber = 1;
57
68
  }
58
69
  // Validate each list item marker
59
70
  for (const listItemPrefix of listItemPrefixes) {
60
- const orderedListItemValue = getOrderedListItemValue(listItemPrefix);
61
- const actual = orderedListItemValue.value;
71
+ const expectedText = expectedNumber.toString();
72
+ const { endColumn, startColumn, "number": actualNumber } = getOrderedListItemValue(listItemPrefix);
73
+ const length = endColumn - startColumn;
62
74
  const fixInfo = {
63
- "editColumn": orderedListItemValue.column,
64
- "deleteCount": orderedListItemValue.value.toString().length,
65
- "insertText": expected.toString()
75
+ "editColumn": startColumn,
76
+ "deleteCount": length,
77
+ "insertText": rightAligned ? expectedText.padStart(length, (zeroPrefixed ? "0" : " ")) : expectedText
66
78
  };
67
79
  addErrorDetailIf(
68
80
  onError,
69
81
  listItemPrefix.startLine,
70
- expected,
71
- actual,
82
+ expectedNumber,
83
+ actualNumber,
72
84
  // @ts-ignore
73
85
  "Style: " + listStyleExamples[listStyle],
74
86
  undefined,
@@ -76,7 +88,7 @@ export default {
76
88
  fixInfo
77
89
  );
78
90
  if (listStyle === "ordered") {
79
- expected++;
91
+ expectedNumber++;
80
92
  }
81
93
  }
82
94
  }
package/lib/md032.mjs CHANGED
@@ -52,10 +52,11 @@ export default {
52
52
  (token) => !nonContentTokens.has(token.type),
53
53
  (token) => nonContentTokens.has(token.type) ? [] : token.children
54
54
  );
55
- let endLine = list.endLine;
56
- if (flattenedChildren.length > 0) {
57
- endLine = flattenedChildren[flattenedChildren.length - 1].endLine;
58
- }
55
+ const endLine = (
56
+ (flattenedChildren.length > 0) ?
57
+ flattenedChildren[flattenedChildren.length - 1] :
58
+ list
59
+ ).endLine;
59
60
 
60
61
  // Look for a blank line below the list
61
62
  const lastLineNumber = endLine;
package/lib/md037.mjs CHANGED
@@ -38,8 +38,7 @@ export default {
38
38
  }
39
39
 
40
40
  // Process bare tokens for each emphasis marker type
41
- for (const entry of emphasisTokensByMarker.entries()) {
42
- const [ marker, emphasisTokens ] = entry;
41
+ for (const [ marker, emphasisTokens ] of emphasisTokensByMarker) {
43
42
  for (let i = 0; i + 1 < emphasisTokens.length; i += 2) {
44
43
 
45
44
  // Process start token of start/end pair
package/lib/md051.mjs CHANGED
@@ -141,6 +141,7 @@ export default {
141
141
  };
142
142
  }
143
143
  const textLower = text.toLowerCase();
144
+ // eslint-disable-next-line unicorn/prefer-iterator-helpers
144
145
  const mixedCaseKey = [ ...fragments.keys() ]
145
146
  .find((key) => textLower === key.toLowerCase());
146
147
  if (mixedCaseKey) {
@@ -297,9 +297,10 @@ function parseInternal(
297
297
  current
298
298
  );
299
299
  current.children = tokens;
300
+ // eslint-disable-next-line unicorn/comment-content
300
301
  // Avoid stack overflow of Array.push(...spread)
301
302
  // @ts-ignore
302
- // eslint-disable-next-line unicorn/prefer-spread
303
+ // eslint-disable-next-line unicorn/no-array-concat-in-loop
303
304
  flatTokens = flatTokens.concat(tokens[flatTokensSymbol]);
304
305
  }
305
306
  } else if (kind === "exit") {
@@ -3,9 +3,10 @@
3
3
  "use strict";
4
4
 
5
5
  // Captures the native require implementation (even under webpack).
6
+ /* node:coverage ignore next 3 */
6
7
  // @ts-ignore
7
- // eslint-disable-next-line no-underscore-dangle
8
- const nativeRequire = globalThis.__non_webpack_require__ ?? require;
8
+ // eslint-disable-next-line camelcase, no-undef
9
+ const nativeRequire = (typeof __non_webpack_require__ === "undefined") ? require : __non_webpack_require__;
9
10
 
10
11
  /**
11
12
  * @typedef RequireResolveOptions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdownlint",
3
- "version": "0.41.0",
3
+ "version": "0.41.1",
4
4
  "description": "A Node.js style checker and lint tool for Markdown/CommonMark files.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -39,7 +39,7 @@
39
39
  "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
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",
41
41
  "build-docs": "node doc-build/build-rules.mjs",
42
- "ci": "concurrently npm:build-demo npm:lint npm:serial-config-docs npm:serial-declaration npm:test && git diff --exit-code && echo PASS",
42
+ "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
43
  "clone-test-repos-apache-airflow": "cd test-repos && git clone https://github.com/apache/airflow apache-airflow --depth 1 --no-tags --quiet",
44
44
  "clone-test-repos-dotnet-docs": "cd test-repos && git clone https://github.com/dotnet/docs dotnet-docs --depth 1 --no-tags --quiet",
45
45
  "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",
@@ -62,6 +62,7 @@
62
62
  "test-declaration-cts": "cd example/typescript && node ../../scripts/index.mjs copy type-check.ts type-check-commonjs.cts && tsc --project tsconfig.cts.json",
63
63
  "test-declaration-mts": "cd example/typescript && node ../../scripts/index.mjs copy type-check.ts type-check-nodenext.mts && tsc --project tsconfig.mts.json && node type-check-nodenext.mjs",
64
64
  "test-extra": "node --test test/markdownlint-test-extra-parse.mjs test/markdownlint-test-extra-type.mjs",
65
+ "test-webpack": "cd test && node resolve-module-webpack.mjs && webpack --entry ./resolve-module-webpack.mjs --output-path . --output-filename resolve-module-webpack.cjs --stats errors-only && node resolve-module-webpack.cjs",
65
66
  "update-snapshots": "node --test --test-update-snapshots test/markdownlint-test-custom-rules.mjs test/markdownlint-test-exports.mjs test/markdownlint-test-micromark.mjs test/markdownlint-test-result-object.mjs test/markdownlint-test-scenarios.mjs",
66
67
  "update-snapshots-test-repos": "node --test --test-update-snapshots test/markdownlint-test-repos-*.mjs",
67
68
  "update-test-repos": "node scripts/index.mjs remove ./test-repos && npm run clone-test-repos && npm run update-snapshots-test-repos"
@@ -87,28 +88,29 @@
87
88
  "ajv": "8.20.0",
88
89
  "character-entities": "2.0.2",
89
90
  "concurrently": "10.0.3",
90
- "eslint": "10.4.1",
91
- "eslint-plugin-jsdoc": "63.0.2",
92
- "eslint-plugin-n": "18.1.0",
93
- "eslint-plugin-regexp": "3.1.0",
94
- "eslint-plugin-unicorn": "65.0.1",
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",
95
97
  "gemoji": "8.1.0",
96
98
  "globby": "16.2.0",
97
- "js-yaml": "4.2.0",
99
+ "js-yaml": "5.2.1",
98
100
  "json-schema-to-typescript": "15.0.4",
99
101
  "json-stringify-safe": "5.0.1",
100
102
  "jsonc-parser": "3.3.1",
101
- "markdown-it": "14.2.0",
103
+ "markdown-it": "14.3.0",
102
104
  "markdown-it-for-inline": "2.0.1",
103
105
  "markdown-it-sub": "2.0.0",
104
106
  "markdown-it-sup": "2.0.0",
105
107
  "markdownlint-rule-extended-ascii": "0.2.1",
106
108
  "nano-spawn": "2.1.0",
107
109
  "terser-webpack-plugin": "5.6.1",
108
- "toml": "4.1.1",
110
+ "toml": "4.1.2",
109
111
  "typescript": "6.0.3",
110
- "webpack": "5.107.2",
111
- "webpack-cli": "7.0.3"
112
+ "webpack": "5.108.3",
113
+ "webpack-cli": "7.1.0"
112
114
  },
113
115
  "keywords": [
114
116
  "markdown",