markdownlint 0.35.0 → 0.36.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 (73) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +72 -35
  3. package/demo/markdownlint-browser.js +1258 -1214
  4. package/doc/CustomRules.md +55 -249
  5. package/doc/Rules.md +36 -29
  6. package/doc/md003.md +2 -2
  7. package/doc/md004.md +4 -3
  8. package/doc/md035.md +3 -8
  9. package/doc/md046.md +2 -2
  10. package/doc/md048.md +3 -2
  11. package/doc/md049.md +4 -3
  12. package/doc/md050.md +4 -4
  13. package/doc/md051.md +11 -3
  14. package/doc/md055.md +3 -2
  15. package/helpers/README.md +2 -19
  16. package/helpers/helpers.js +87 -347
  17. package/helpers/micromark-helpers.cjs +296 -0
  18. package/helpers/micromark-parse.cjs +313 -0
  19. package/helpers/package.json +5 -2
  20. package/helpers/shared.js +6 -0
  21. package/helpers/test.cjs +28 -0
  22. package/lib/cache.js +3 -3
  23. package/lib/configuration-strict.d.ts +120 -106
  24. package/lib/constants.js +1 -1
  25. package/lib/markdownit.cjs +172 -0
  26. package/lib/markdownlint.d.ts +41 -3
  27. package/lib/markdownlint.js +153 -115
  28. package/lib/md001.js +1 -1
  29. package/lib/md003.js +1 -1
  30. package/lib/md004.js +3 -3
  31. package/lib/md007.js +3 -3
  32. package/lib/md009.js +1 -1
  33. package/lib/md010.js +18 -14
  34. package/lib/md011.js +24 -23
  35. package/lib/md012.js +1 -1
  36. package/lib/md013.js +1 -1
  37. package/lib/md014.js +5 -9
  38. package/lib/md018.js +1 -1
  39. package/lib/md019-md021.js +1 -1
  40. package/lib/md020.js +2 -2
  41. package/lib/md022.js +9 -15
  42. package/lib/md024.js +1 -1
  43. package/lib/md025.js +1 -1
  44. package/lib/md027.js +2 -2
  45. package/lib/md029.js +3 -3
  46. package/lib/md031.js +8 -6
  47. package/lib/md032.js +27 -15
  48. package/lib/md033.js +1 -1
  49. package/lib/md034.js +21 -29
  50. package/lib/md036.js +18 -24
  51. package/lib/md037.js +1 -1
  52. package/lib/md038.js +9 -14
  53. package/lib/md039.js +13 -15
  54. package/lib/md040.js +11 -13
  55. package/lib/md041.js +4 -4
  56. package/lib/md042.js +2 -6
  57. package/lib/md043.js +1 -1
  58. package/lib/md044.js +31 -28
  59. package/lib/md045.js +2 -2
  60. package/lib/md048.js +28 -17
  61. package/lib/md049-md050.js +20 -5
  62. package/lib/md051.js +16 -18
  63. package/lib/md053.js +5 -4
  64. package/lib/md054.js +10 -12
  65. package/lib/md055.js +39 -46
  66. package/lib/md056.js +31 -36
  67. package/lib/md058.js +29 -14
  68. package/package.json +14 -13
  69. package/schema/.markdownlint.jsonc +55 -52
  70. package/schema/.markdownlint.yaml +54 -52
  71. package/schema/markdownlint-config-schema-strict.json +132 -110
  72. package/schema/markdownlint-config-schema.json +132 -110
  73. package/helpers/micromark.cjs +0 -544
package/lib/md055.js CHANGED
@@ -3,7 +3,6 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorDetailIf } = require("../helpers");
6
- const { filterByTypes } = require("../helpers/micromark.cjs");
7
6
  const { filterByTypesCached } = require("./cache");
8
7
 
9
8
  const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
@@ -28,51 +27,45 @@ module.exports = {
28
27
  ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
29
28
  let expectedTrailingPipe =
30
29
  ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
31
- const tables = filterByTypesCached([ "table" ]);
32
- for (const table of tables) {
33
- const rows = filterByTypes(
34
- table.children,
35
- [ "tableDelimiterRow", "tableRow" ]
36
- );
37
- for (const row of rows) {
38
- // The following uses of first/lastOrNothing lack fallback handling
39
- // because it seems not to be possible (i.e., 0% coverage)
40
- const firstCell = firstOrNothing(row.children);
41
- const leadingToken = firstOrNothing(ignoreWhitespace(firstCell.children));
42
- const actualLeadingPipe = (leadingToken.type === "tableCellDivider");
43
- const lastCell = lastOrNothing(row.children);
44
- const trailingToken = lastOrNothing(ignoreWhitespace(lastCell.children));
45
- const actualTrailingPipe = (trailingToken.type === "tableCellDivider");
46
- const actualStyle = actualLeadingPipe ?
47
- (actualTrailingPipe ? "leading_and_trailing" : "leading_only") :
48
- (actualTrailingPipe ? "trailing_only" : "no_leading_or_trailing");
49
- if (expectedStyle === "consistent") {
50
- expectedStyle = actualStyle;
51
- expectedLeadingPipe = actualLeadingPipe;
52
- expectedTrailingPipe = actualTrailingPipe;
53
- }
54
- if (actualLeadingPipe !== expectedLeadingPipe) {
55
- addErrorDetailIf(
56
- onError,
57
- firstCell.startLine,
58
- expectedStyle,
59
- actualStyle,
60
- `${expectedLeadingPipe ? "Missing" : "Unexpected"} leading pipe`,
61
- undefined,
62
- makeRange(row.startColumn, firstCell.startColumn)
63
- );
64
- }
65
- if (actualTrailingPipe !== expectedTrailingPipe) {
66
- addErrorDetailIf(
67
- onError,
68
- lastCell.endLine,
69
- expectedStyle,
70
- actualStyle,
71
- `${expectedTrailingPipe ? "Missing" : "Unexpected"} trailing pipe`,
72
- undefined,
73
- makeRange(lastCell.endColumn - 1, row.endColumn - 1)
74
- );
75
- }
30
+ const rows = filterByTypesCached([ "tableDelimiterRow", "tableRow" ]);
31
+ for (const row of rows) {
32
+ // The following uses of first/lastOrNothing lack fallback handling
33
+ // because it seems not to be possible (i.e., 0% coverage)
34
+ const firstCell = firstOrNothing(row.children);
35
+ const leadingToken = firstOrNothing(ignoreWhitespace(firstCell.children));
36
+ const actualLeadingPipe = (leadingToken.type === "tableCellDivider");
37
+ const lastCell = lastOrNothing(row.children);
38
+ const trailingToken = lastOrNothing(ignoreWhitespace(lastCell.children));
39
+ const actualTrailingPipe = (trailingToken.type === "tableCellDivider");
40
+ const actualStyle = actualLeadingPipe ?
41
+ (actualTrailingPipe ? "leading_and_trailing" : "leading_only") :
42
+ (actualTrailingPipe ? "trailing_only" : "no_leading_or_trailing");
43
+ if (expectedStyle === "consistent") {
44
+ expectedStyle = actualStyle;
45
+ expectedLeadingPipe = actualLeadingPipe;
46
+ expectedTrailingPipe = actualTrailingPipe;
47
+ }
48
+ if (actualLeadingPipe !== expectedLeadingPipe) {
49
+ addErrorDetailIf(
50
+ onError,
51
+ firstCell.startLine,
52
+ expectedStyle,
53
+ actualStyle,
54
+ `${expectedLeadingPipe ? "Missing" : "Unexpected"} leading pipe`,
55
+ undefined,
56
+ makeRange(row.startColumn, firstCell.startColumn)
57
+ );
58
+ }
59
+ if (actualTrailingPipe !== expectedTrailingPipe) {
60
+ addErrorDetailIf(
61
+ onError,
62
+ lastCell.endLine,
63
+ expectedStyle,
64
+ actualStyle,
65
+ `${expectedTrailingPipe ? "Missing" : "Unexpected"} trailing pipe`,
66
+ undefined,
67
+ makeRange(lastCell.endColumn - 1, row.endColumn - 1)
68
+ );
76
69
  }
77
70
  }
78
71
  }
package/lib/md056.js CHANGED
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorDetailIf } = require("../helpers");
6
- const { filterByTypes } = require("../helpers/micromark.cjs");
6
+ const { getParentOfType } = require("../helpers/micromark-helpers.cjs");
7
7
  const { filterByTypesCached } = require("./cache");
8
8
 
9
9
  const makeRange = (start, end) => [ start, end - start + 1 ];
@@ -16,41 +16,36 @@ module.exports = {
16
16
  "tags": [ "table" ],
17
17
  "parser": "micromark",
18
18
  "function": function MD056(params, onError) {
19
- const tables = filterByTypesCached([ "table" ]);
20
- for (const table of tables) {
21
- const rows = filterByTypes(
22
- table.children,
23
- [ "tableDelimiterRow", "tableRow" ]
24
- );
25
- let expectedCount = 0;
26
- for (const row of rows) {
27
- const cells = filterByTypes(
28
- row.children,
29
- [ "tableData", "tableDelimiter", "tableHeader" ]
30
- );
31
- const actualCount = cells.length;
32
- expectedCount ||= actualCount;
33
- // eslint-disable-next-line no-undef-init
34
- let detail = undefined;
35
- // eslint-disable-next-line no-undef-init
36
- let range = undefined;
37
- if (actualCount < expectedCount) {
38
- detail = "Too few cells, row will be missing data";
39
- range = [ row.endColumn - 1, 1 ];
40
- } else if (expectedCount < actualCount) {
41
- detail = "Too many cells, extra data will be missing";
42
- range = makeRange(cells[expectedCount].startColumn, row.endColumn - 1);
43
- }
44
- addErrorDetailIf(
45
- onError,
46
- row.endLine,
47
- expectedCount,
48
- actualCount,
49
- detail,
50
- undefined,
51
- range
52
- );
19
+ const rows = filterByTypesCached([ "tableDelimiterRow", "tableRow" ]);
20
+ let expectedCount = 0;
21
+ let currentTable = null;
22
+ for (const row of rows) {
23
+ const table = getParentOfType(row, [ "table" ]);
24
+ if (currentTable !== table) {
25
+ expectedCount = 0;
26
+ currentTable = table;
27
+ }
28
+ const cells = row.children.filter((child) => [ "tableData", "tableDelimiter", "tableHeader" ].includes(child.type));
29
+ const actualCount = cells.length;
30
+ expectedCount ||= actualCount;
31
+ let detail = undefined;
32
+ let range = undefined;
33
+ if (actualCount < expectedCount) {
34
+ detail = "Too few cells, row will be missing data";
35
+ range = [ row.endColumn - 1, 1 ];
36
+ } else if (expectedCount < actualCount) {
37
+ detail = "Too many cells, extra data will be missing";
38
+ range = makeRange(cells[expectedCount].startColumn, row.endColumn - 1);
53
39
  }
40
+ addErrorDetailIf(
41
+ onError,
42
+ row.endLine,
43
+ expectedCount,
44
+ actualCount,
45
+ detail,
46
+ undefined,
47
+ range
48
+ );
54
49
  }
55
50
  }
56
- }
51
+ };
package/lib/md058.js CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- const { addErrorContextForLine, isBlankLine } = require("../helpers");
5
+ const { addErrorContext, isBlankLine } = require("../helpers");
6
+ const { getBlockQuotePrefixText } = require("../helpers/micromark-helpers.cjs");
6
7
  const { filterByTypesCached } = require("./cache");
7
8
 
8
9
  // eslint-disable-next-line jsdoc/valid-types
@@ -14,28 +15,42 @@ module.exports = {
14
15
  "parser": "micromark",
15
16
  "function": function MD058(params, onError) {
16
17
  const { lines } = params;
18
+ const blockQuotePrefixes = filterByTypesCached([ "blockQuotePrefix", "linePrefix" ]);
19
+
17
20
  // For every table...
18
21
  const tables = filterByTypesCached([ "table" ]);
19
22
  for (const table of tables) {
23
+
20
24
  // Look for a blank line above the table
21
- const firstIndex = table.startLine - 1;
22
- if (!isBlankLine(lines[firstIndex - 1])) {
23
- addErrorContextForLine(
25
+ const firstLineNumber = table.startLine;
26
+ if (!isBlankLine(lines[firstLineNumber - 2])) {
27
+ addErrorContext(
24
28
  onError,
25
- // @ts-ignore
26
- lines,
27
- firstIndex
29
+ firstLineNumber,
30
+ lines[firstLineNumber - 1].trim(),
31
+ undefined,
32
+ undefined,
33
+ undefined,
34
+ {
35
+ "insertText": getBlockQuotePrefixText(blockQuotePrefixes, firstLineNumber)
36
+ }
28
37
  );
29
38
  }
39
+
30
40
  // Look for a blank line below the table
31
- const lastIndex = table.endLine - 1;
32
- if (!isBlankLine(lines[lastIndex + 1])) {
33
- addErrorContextForLine(
41
+ const lastLineNumber = table.endLine;
42
+ if (!isBlankLine(lines[lastLineNumber])) {
43
+ addErrorContext(
34
44
  onError,
35
- // @ts-ignore
36
- lines,
37
- lastIndex,
38
- lastIndex + 2
45
+ lastLineNumber,
46
+ lines[lastLineNumber - 1].trim(),
47
+ undefined,
48
+ undefined,
49
+ undefined,
50
+ {
51
+ "lineNumber": lastLineNumber + 1,
52
+ "insertText": getBlockQuotePrefixText(blockQuotePrefixes, lastLineNumber)
53
+ }
39
54
  );
40
55
  }
41
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdownlint",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "description": "A Node.js style checker and lint tool for Markdown/CommonMark files.",
5
5
  "type": "commonjs",
6
6
  "main": "./lib/markdownlint.js",
@@ -27,7 +27,7 @@
27
27
  "build-config-example": "node schema/build-config-example.js",
28
28
  "build-config-schema": "node schema/build-config-schema.js",
29
29
  "build-declaration": "tsc --allowJs --declaration --emitDeclarationOnly --module commonjs --outDir dts --resolveJsonModule --target es2015 lib/markdownlint.js && node scripts copy dts/lib/markdownlint.d.ts lib/markdownlint.d.ts && node scripts remove dts",
30
- "build-demo": "node scripts copy node_modules/markdown-it/dist/markdown-it.min.js demo/markdown-it.min.js && node scripts copy node_modules/markdownlint-micromark/micromark-browser.js demo/micromark-browser.js && node scripts copy node_modules/markdownlint-micromark/micromark-html-browser.js demo/micromark-html-browser.js && cd demo && webpack --no-stats",
30
+ "build-demo": "node scripts copy node_modules/markdownlint-micromark/micromark-browser.js demo/micromark-browser.js && node scripts copy node_modules/markdownlint-micromark/micromark-html-browser.js demo/micromark-html-browser.js && cd demo && webpack --no-stats",
31
31
  "build-docs": "node doc-build/build-rules.mjs",
32
32
  "build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2",
33
33
  "build-micromark": "cd micromark && npm run build",
@@ -53,11 +53,11 @@
53
53
  "lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos-*.js",
54
54
  "serial-config-docs": "npm run build-config && npm run build-docs",
55
55
  "serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration",
56
- "test": "ava --timeout=30s test/markdownlint-test.js test/markdownlint-test-config.js test/markdownlint-test-custom-rules.js test/markdownlint-test-helpers.js test/markdownlint-test-micromark.mjs test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js",
56
+ "test": "ava --timeout=30s test/markdownlint-test.js test/markdownlint-test-config.js test/markdownlint-test-custom-rules.js test/markdownlint-test-fixes.js test/markdownlint-test-helpers.js test/markdownlint-test-micromark.mjs test/markdownlint-test-result-object.js test/markdownlint-test-scenarios.js helpers/test.cjs",
57
57
  "test-cover": "c8 --100 npm test",
58
58
  "test-declaration": "cd example/typescript && tsc --module nodenext && tsc --module commonjs && node type-check.js",
59
59
  "test-extra": "ava --timeout=10m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js",
60
- "update-snapshots": "ava --update-snapshots test/markdownlint-test-micromark.mjs test/markdownlint-test-scenarios.js",
60
+ "update-snapshots": "ava --update-snapshots test/markdownlint-test-custom-rules.js test/markdownlint-test-micromark.mjs test/markdownlint-test-scenarios.js",
61
61
  "update-snapshots-test-repos": "ava --timeout=10m --update-snapshots test/markdownlint-test-repos-*.js",
62
62
  "upgrade": "npx --yes npm-check-updates --upgrade"
63
63
  },
@@ -66,23 +66,24 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "markdown-it": "14.1.0",
69
- "markdownlint-micromark": "0.1.10"
69
+ "markdownlint-micromark": "0.1.12"
70
70
  },
71
71
  "devDependencies": {
72
- "@eslint/js": "9.9.1",
72
+ "@eslint/js": "9.13.0",
73
+ "@stylistic/eslint-plugin": "2.9.0",
73
74
  "ajv": "8.17.1",
74
75
  "ava": "6.1.3",
75
76
  "c8": "10.1.2",
76
77
  "character-entities": "2.0.2",
77
- "eslint": "9.9.1",
78
- "eslint-plugin-jsdoc": "50.2.2",
79
- "eslint-plugin-n": "17.10.2",
78
+ "eslint": "9.13.0",
79
+ "eslint-plugin-jsdoc": "50.4.3",
80
+ "eslint-plugin-n": "17.11.1",
80
81
  "eslint-plugin-regexp": "2.6.0",
81
- "eslint-plugin-unicorn": "55.0.0",
82
+ "eslint-plugin-unicorn": "56.0.0",
82
83
  "gemoji": "8.1.0",
83
84
  "globby": "14.0.2",
84
85
  "js-yaml": "4.1.0",
85
- "json-schema-to-typescript": "15.0.1",
86
+ "json-schema-to-typescript": "15.0.2",
86
87
  "jsonc-parser": "3.3.1",
87
88
  "markdown-it-for-inline": "2.0.1",
88
89
  "markdown-it-sub": "2.0.0",
@@ -91,8 +92,8 @@
91
92
  "npm-run-all": "4.1.5",
92
93
  "terser-webpack-plugin": "5.3.10",
93
94
  "toml": "3.0.0",
94
- "typescript": "5.5.4",
95
- "webpack": "5.94.0",
95
+ "typescript": "5.6.3",
96
+ "webpack": "5.95.0",
96
97
  "webpack-cli": "5.1.4"
97
98
  },
98
99
  "keywords": [