markdownlint 0.32.0 → 0.33.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/lib/constants.js CHANGED
@@ -11,4 +11,4 @@ module.exports.fixableRuleNames = [
11
11
  "MD047", "MD049", "MD050", "MD051", "MD053", "MD054"
12
12
  ];
13
13
  module.exports.homepage = "https://github.com/DavidAnson/markdownlint";
14
- module.exports.version = "0.32.0";
14
+ module.exports.version = "0.33.0";
@@ -1177,7 +1177,6 @@ function readConfig(file, parsers, fs, callback) {
1177
1177
  }
1178
1178
  // Read file
1179
1179
  file = helpers.expandTildePath(file, require("node:os"));
1180
- // eslint-disable-next-line n/prefer-promises/fs
1181
1180
  fs.readFile(file, "utf8", (err, content) => {
1182
1181
  if (err) {
1183
1182
  // @ts-ignore
package/lib/md005.js CHANGED
@@ -23,8 +23,7 @@ module.exports = {
23
23
  for (const listItemPrefix of listItemPrefixes) {
24
24
  const lineNumber = listItemPrefix.startLine;
25
25
  const actualIndent = listItemPrefix.startColumn - 1;
26
- const markerLength = listItemPrefix.text.trim().length;
27
- const range = [ 1, listItemPrefix.startColumn + markerLength ];
26
+ const range = [ 1, listItemPrefix.endColumn - 1 ];
28
27
  if (list.type === "listUnordered") {
29
28
  addErrorDetailIf(
30
29
  onError,
@@ -37,7 +36,8 @@ module.exports = {
37
36
  // No fixInfo; MD007 handles this scenario better
38
37
  );
39
38
  } else {
40
- const actualEnd = range[1] - 1;
39
+ const markerLength = listItemPrefix.text.trim().length;
40
+ const actualEnd = listItemPrefix.startColumn + markerLength - 1;
41
41
  expectedEnd = expectedEnd || actualEnd;
42
42
  if ((expectedIndent !== actualIndent) || endMatching) {
43
43
  if (expectedEnd === actualEnd) {
package/lib/md007.js CHANGED
@@ -30,7 +30,7 @@ module.exports = {
30
30
  unorderedListTypes
31
31
  );
32
32
  for (const token of tokens) {
33
- const { parent, startColumn, startLine, type } = token;
33
+ const { endColumn, parent, startColumn, startLine, type } = token;
34
34
  if (type === "blockQuotePrefix") {
35
35
  lastBlockQuotePrefix = token;
36
36
  } else if (type === "listUnordered") {
@@ -42,6 +42,7 @@ module.exports = {
42
42
  ) {
43
43
  if (current.type === "listUnordered") {
44
44
  nesting++;
45
+ // eslint-disable-next-line no-continue
45
46
  continue;
46
47
  } else if (current.type === "listOrdered") {
47
48
  nesting = -1;
@@ -63,7 +64,7 @@ module.exports = {
63
64
  (lastBlockQuotePrefix.endColumn - 1) :
64
65
  0;
65
66
  const actualIndent = startColumn - 1 - blockQuoteAdjustment;
66
- const range = [ 1, startColumn + 1 ];
67
+ const range = [ 1, endColumn - 1 ];
67
68
  const fixInfo = {
68
69
  "editColumn": startColumn - actualIndent,
69
70
  "deleteCount": Math.max(actualIndent - expectedIndent, 0),
package/lib/md024.js CHANGED
@@ -9,8 +9,7 @@ module.exports = {
9
9
  "description": "Multiple headings with the same content",
10
10
  "tags": [ "headings" ],
11
11
  "function": function MD024(params, onError) {
12
- const siblingsOnly = !!params.config.siblings_only ||
13
- !!params.config.allow_different_nesting || false;
12
+ const siblingsOnly = !!params.config.siblings_only || false;
14
13
  const knownContents = [ null, [] ];
15
14
  let lastLevel = 1;
16
15
  let knownContent = knownContents[lastLevel];
@@ -27,10 +26,15 @@ module.exports = {
27
26
  }
28
27
  knownContent = knownContents[newLevel];
29
28
  }
29
+ // @ts-ignore
30
30
  if (knownContent.includes(content)) {
31
- addErrorContext(onError, heading.lineNumber,
32
- heading.line.trim());
31
+ addErrorContext(
32
+ onError,
33
+ heading.lineNumber,
34
+ heading.line.trim()
35
+ );
33
36
  } else {
37
+ // @ts-ignore
34
38
  knownContent.push(content);
35
39
  }
36
40
  });
package/lib/md026.js CHANGED
@@ -23,7 +23,7 @@ module.exports = {
23
23
  [ "atxHeadingText", "setextHeadingText" ]
24
24
  );
25
25
  for (const heading of headings) {
26
- const { endLine, startColumn, text } = heading;
26
+ const { endColumn, endLine, text } = heading;
27
27
  const match = trailingPunctuationRe.exec(text);
28
28
  if (
29
29
  match &&
@@ -31,8 +31,8 @@ module.exports = {
31
31
  !endOfLineGemojiCodeRe.test(text)
32
32
  ) {
33
33
  const fullMatch = match[0];
34
- const column = startColumn + match.index;
35
34
  const length = fullMatch.length;
35
+ const column = endColumn - length;
36
36
  addError(
37
37
  onError,
38
38
  endLine,
package/lib/md038.js CHANGED
@@ -41,7 +41,7 @@ module.exports = {
41
41
  tokenIfType(children[last - 2], "codeTextData");
42
42
  if (startSequence && endSequence && startData && endData) {
43
43
  const spaceLeft = leftSpaceRe.test(startData.text);
44
- const spaceRight = !spaceLeft && rightSpaceRe.test(endData.text);
44
+ const spaceRight = rightSpaceRe.test(endData.text);
45
45
  if (spaceLeft || spaceRight) {
46
46
  let lineNumber = startSequence.startLine;
47
47
  let range = null;
@@ -56,7 +56,7 @@ module.exports = {
56
56
  "deleteCount": endSequence.startColumn - startSequence.endColumn,
57
57
  "insertText": trimCodeText(startData.text, true, true)
58
58
  };
59
- } else if (spaceLeft) {
59
+ } else if (spaceLeft && (startSequence.endLine === startData.startLine)) {
60
60
  range = [
61
61
  startSequence.startColumn,
62
62
  startData.endColumn - startSequence.startColumn
@@ -66,7 +66,7 @@ module.exports = {
66
66
  "deleteCount": startData.endColumn - startData.startColumn,
67
67
  "insertText": trimCodeText(startData.text, true, false)
68
68
  };
69
- } else {
69
+ } else if (spaceRight && (endData.text.trim().length > 0)) {
70
70
  lineNumber = endSequence.endLine;
71
71
  range = [
72
72
  endData.startColumn,
@@ -78,18 +78,20 @@ module.exports = {
78
78
  "insertText": trimCodeText(endData.text, false, true)
79
79
  };
80
80
  }
81
- const context = params
82
- .lines[lineNumber - 1]
83
- .substring(range[0] - 1, range[0] - 1 + range[1]);
84
- addErrorContext(
85
- onError,
86
- lineNumber,
87
- context,
88
- spaceLeft,
89
- spaceRight,
90
- range,
91
- fixInfo
92
- );
81
+ if (range) {
82
+ const context = params
83
+ .lines[lineNumber - 1]
84
+ .substring(range[0] - 1, range[0] - 1 + range[1]);
85
+ addErrorContext(
86
+ onError,
87
+ lineNumber,
88
+ context,
89
+ spaceLeft,
90
+ spaceRight,
91
+ range,
92
+ fixInfo
93
+ );
94
+ }
93
95
  }
94
96
  }
95
97
  }
package/lib/md054.js CHANGED
@@ -64,7 +64,14 @@ module.exports = {
64
64
  if (destination) {
65
65
  // link kind is an inline link
66
66
  const title = getTokenTextByType(descendents, "resourceTitleString");
67
- isError = !inline || (!urlInline && autolink && !title && !image);
67
+ isError = !inline || (
68
+ !urlInline &&
69
+ autolink &&
70
+ !image &&
71
+ !title &&
72
+ (label === destination) &&
73
+ autolinkAble(destination)
74
+ );
68
75
  } else {
69
76
  // link kind is a full/collapsed/shortcut reference link
70
77
  const isShortcut = !children.some((t) => t.type === "reference");
package/lib/md055.js ADDED
@@ -0,0 +1,72 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes } = require("../helpers/micromark.cjs");
7
+
8
+ const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
9
+ const ignoreWhitespace = (tokens) => tokens.filter(
10
+ (token) => !whitespaceTypes.has(token.type)
11
+ );
12
+ const firstOrNothing = (items) => items[0];
13
+ const lastOrNothing = (items) => items[items.length - 1];
14
+ const makeRange = (start, end) => [ start, end - start + 1 ];
15
+
16
+ module.exports = {
17
+ "names": [ "MD055", "table-pipe-style" ],
18
+ "description": "Table pipe style",
19
+ "tags": [ "table" ],
20
+ "function": function MD055(params, onError) {
21
+ const style = String(params.config.style || "consistent");
22
+ let expectedStyle = style;
23
+ let expectedLeadingPipe =
24
+ ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
25
+ let expectedTrailingPipe =
26
+ ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
27
+ const tables = filterByTypes(params.parsers.micromark.tokens, [ "table" ]);
28
+ for (const table of tables) {
29
+ const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]);
30
+ for (const row of rows) {
31
+ // The following uses of first/lastOrNothing lack fallback handling
32
+ // because it seems not to be possible (i.e., 0% coverage)
33
+ const firstCell = firstOrNothing(row.children);
34
+ const leadingToken = firstOrNothing(ignoreWhitespace(firstCell.children));
35
+ const actualLeadingPipe = (leadingToken.type === "tableCellDivider");
36
+ const lastCell = lastOrNothing(row.children);
37
+ const trailingToken = lastOrNothing(ignoreWhitespace(lastCell.children));
38
+ const actualTrailingPipe = (trailingToken.type === "tableCellDivider");
39
+ const actualStyle = actualLeadingPipe ?
40
+ (actualTrailingPipe ? "leading_and_trailing" : "leading_only") :
41
+ (actualTrailingPipe ? "trailing_only" : "no_leading_or_trailing");
42
+ if (expectedStyle === "consistent") {
43
+ expectedStyle = actualStyle;
44
+ expectedLeadingPipe = actualLeadingPipe;
45
+ expectedTrailingPipe = actualTrailingPipe;
46
+ }
47
+ if (actualLeadingPipe !== expectedLeadingPipe) {
48
+ addErrorDetailIf(
49
+ onError,
50
+ firstCell.startLine,
51
+ expectedStyle,
52
+ actualStyle,
53
+ `${expectedLeadingPipe ? "Missing" : "Unexpected"} leading pipe`,
54
+ undefined,
55
+ makeRange(row.startColumn, firstCell.startColumn)
56
+ );
57
+ }
58
+ if (actualTrailingPipe !== expectedTrailingPipe) {
59
+ addErrorDetailIf(
60
+ onError,
61
+ lastCell.endLine,
62
+ expectedStyle,
63
+ actualStyle,
64
+ `${expectedTrailingPipe ? "Missing" : "Unexpected"} trailing pipe`,
65
+ undefined,
66
+ makeRange(lastCell.endColumn - 1, row.endColumn - 1)
67
+ );
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
package/lib/md056.js ADDED
@@ -0,0 +1,44 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes } = require("../helpers/micromark.cjs");
7
+
8
+ const makeRange = (start, end) => [ start, end - start + 1 ];
9
+
10
+ module.exports = {
11
+ "names": [ "MD056", "table-column-count" ],
12
+ "description": "Table column count",
13
+ "tags": [ "table" ],
14
+ "function": function MD056(params, onError) {
15
+ const tables = filterByTypes(params.parsers.micromark.tokens, [ "table" ]);
16
+ for (const table of tables) {
17
+ const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]);
18
+ let expectedCount = 0;
19
+ for (const row of rows) {
20
+ const cells = filterByTypes(row.children, [ "tableData", "tableDelimiter", "tableHeader" ]);
21
+ const actualCount = cells.length;
22
+ expectedCount ||= actualCount;
23
+ let detail = null;
24
+ let range = null;
25
+ if (actualCount < expectedCount) {
26
+ detail = "Too few cells, row will be missing data";
27
+ range = [ row.endColumn - 1, 1 ];
28
+ } else if (expectedCount < actualCount) {
29
+ detail = "Too many cells, extra data will be missing";
30
+ range = makeRange(cells[expectedCount].startColumn, row.endColumn - 1);
31
+ }
32
+ addErrorDetailIf(
33
+ onError,
34
+ row.endLine,
35
+ expectedCount,
36
+ actualCount,
37
+ detail,
38
+ null,
39
+ range
40
+ );
41
+ }
42
+ }
43
+ }
44
+ }
package/lib/rules.js CHANGED
@@ -6,9 +6,11 @@ const { homepage, version } = require("./constants");
6
6
 
7
7
  const rules = [
8
8
  require("./md001"),
9
+ // md002: Deprecated and removed
9
10
  require("./md003"),
10
11
  require("./md004"),
11
12
  require("./md005"),
13
+ // md006: Deprecated and removed
12
14
  require("./md007"),
13
15
  require("./md009"),
14
16
  require("./md010"),
@@ -51,9 +53,9 @@ const rules = [
51
53
  require("./md051"),
52
54
  require("./md052"),
53
55
  require("./md053"),
54
- require("./md054")
55
- // md055: See https://github.com/markdownlint/markdownlint
56
- // md056: See https://github.com/markdownlint/markdownlint
56
+ require("./md054"),
57
+ require("./md055"),
58
+ require("./md056")
57
59
  // md057: See https://github.com/markdownlint/markdownlint
58
60
  ];
59
61
  for (const rule of rules) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdownlint",
3
- "version": "0.32.0",
3
+ "version": "0.33.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",
@@ -48,53 +48,52 @@
48
48
  "example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint",
49
49
  "docker-npm-install": "docker run --rm --tty --name npm-install --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm install",
50
50
  "docker-npm-run-upgrade": "docker run --rm --tty --name npm-run-upgrade --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm run upgrade",
51
- "install-micromark": "cd micromark && npm install --no-package-lock",
51
+ "install-micromark": "cd micromark && npm install",
52
52
  "lint": "eslint --ext .js,.cjs,.mjs --max-warnings 0 .",
53
- "lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos.js",
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
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",
57
57
  "test-cover": "c8 --100 npm test",
58
58
  "test-declaration": "cd example/typescript && tsc && node type-check.js",
59
- "test-extra": "ava --timeout=5m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js",
59
+ "test-extra": "ava --timeout=10m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js",
60
60
  "update-snapshots": "ava --update-snapshots test/markdownlint-test-micromark.mjs test/markdownlint-test-scenarios.js",
61
- "update-snapshots-test-repos": "ava --timeout=10m --update-snapshots test/markdownlint-test-repos.js",
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
  },
64
64
  "engines": {
65
65
  "node": ">=18"
66
66
  },
67
67
  "dependencies": {
68
- "markdown-it": "13.0.2",
69
- "markdownlint-micromark": "0.1.7"
68
+ "markdown-it": "14.0.0",
69
+ "markdownlint-micromark": "0.1.8"
70
70
  },
71
71
  "devDependencies": {
72
- "@babel/core": "7.23.3",
73
- "@babel/preset-env": "7.23.3",
74
- "@hyperjump/json-schema": "1.6.5",
75
- "ava": "5.3.1",
72
+ "@babel/core": "7.23.7",
73
+ "@babel/preset-env": "7.23.7",
74
+ "ajv": "8.12.0",
75
+ "ava": "6.0.1",
76
76
  "babel-loader": "9.1.3",
77
- "c8": "8.0.1",
77
+ "c8": "9.0.0",
78
78
  "character-entities": "2.0.2",
79
- "eslint": "8.53.0",
80
- "eslint-plugin-es": "4.1.0",
81
- "eslint-plugin-jsdoc": "46.9.0",
82
- "eslint-plugin-n": "16.3.1",
83
- "eslint-plugin-regexp": "2.1.1",
84
- "eslint-plugin-unicorn": "49.0.0",
79
+ "eslint": "8.56.0",
80
+ "eslint-plugin-jsdoc": "48.0.2",
81
+ "eslint-plugin-n": "16.6.1",
82
+ "eslint-plugin-regexp": "2.1.2",
83
+ "eslint-plugin-unicorn": "50.0.1",
85
84
  "gemoji": "8.1.0",
86
85
  "globby": "14.0.0",
87
86
  "js-yaml": "4.1.0",
88
87
  "json-schema-to-typescript": "13.1.1",
89
- "markdown-it-for-inline": "0.1.1",
90
- "markdown-it-sub": "1.0.0",
91
- "markdown-it-sup": "1.0.0",
92
- "markdownlint-rule-helpers": "0.22.0",
88
+ "markdown-it-for-inline": "2.0.1",
89
+ "markdown-it-sub": "2.0.0",
90
+ "markdown-it-sup": "2.0.0",
91
+ "markdownlint-rule-helpers": "0.23.0",
93
92
  "npm-run-all": "4.1.5",
94
93
  "strip-json-comments": "5.0.1",
95
- "terser-webpack-plugin": "5.3.9",
94
+ "terser-webpack-plugin": "5.3.10",
96
95
  "toml": "3.0.0",
97
- "typescript": "5.2.2",
96
+ "typescript": "5.3.3",
98
97
  "webpack": "5.89.0",
99
98
  "webpack-cli": "5.1.4",
100
99
  "yaml": "2.3.4"