markdownlint 0.30.0 → 0.31.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/md051.js CHANGED
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
 
5
5
  const { addError, addErrorDetailIf } = require("../helpers");
6
- const { filterByHtmlTokens, filterByTypes, getHtmlTagInfo } =
6
+ const { filterByPredicate, filterByTypes, getHtmlTagInfo } =
7
7
  require("../helpers/micromark.cjs");
8
8
 
9
9
  // Regular expression for identifying HTML anchor names
@@ -11,16 +11,28 @@ const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
11
11
  const nameRe = /\sname\s*=\s*['"]?([^'"\s>]+)/iu;
12
12
  const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
13
13
 
14
+ // Sets for filtering heading tokens during conversion
15
+ const childrenExclude = new Set([ "image", "reference", "resource" ]);
16
+ const tokensInclude = new Set([ "codeTextData", "data" ]);
17
+
18
+ /**
19
+ * @typedef {import("../helpers/micromark.cjs").Token} Token
20
+ */
21
+
14
22
  /**
15
23
  * Converts a Markdown heading into an HTML fragment according to the rules
16
24
  * used by GitHub.
17
25
  *
18
- * @param {Object} headingText Heading text token.
26
+ * @param {Token} headingText Heading text token.
19
27
  * @returns {string} Fragment string for heading.
20
28
  */
21
29
  function convertHeadingToHTMLFragment(headingText) {
22
30
  const inlineText =
23
- filterByTypes(headingText.children, [ "codeTextData", "data" ])
31
+ filterByPredicate(
32
+ headingText.children,
33
+ (token) => tokensInclude.has(token.type),
34
+ (token) => (childrenExclude.has(token.type) ? [] : token.children)
35
+ )
24
36
  .map((token) => token.text)
25
37
  .join("");
26
38
  return "#" + encodeURIComponent(
@@ -38,6 +50,18 @@ function convertHeadingToHTMLFragment(headingText) {
38
50
  );
39
51
  }
40
52
 
53
+ /**
54
+ * Unescapes the text of a String-type micromark Token.
55
+ *
56
+ * @param {Token} token String-type micromark Token.
57
+ * @returns {string} Unescaped token text.
58
+ */
59
+ function unescapeStringTokenText(token) {
60
+ return filterByTypes(token.children, [ "characterEscapeValue", "data" ])
61
+ .map((child) => child.text)
62
+ .join("");
63
+ }
64
+
41
65
  module.exports = {
42
66
  "names": [ "MD051", "link-fragments" ],
43
67
  "description": "Link fragments should be valid",
@@ -53,22 +77,24 @@ module.exports = {
53
77
  );
54
78
  for (const headingText of headingTexts) {
55
79
  const fragment = convertHeadingToHTMLFragment(headingText);
56
- const count = fragments.get(fragment) || 0;
57
- if (count) {
58
- fragments.set(`${fragment}-${count}`, 0);
59
- }
60
- fragments.set(fragment, count + 1);
61
- let match = null;
62
- while ((match = anchorRe.exec(headingText.text)) !== null) {
63
- const [ , anchor ] = match;
64
- if (!fragments.has(anchor)) {
65
- fragments.set(anchor, 1);
80
+ if (fragment !== "#") {
81
+ const count = fragments.get(fragment) || 0;
82
+ if (count) {
83
+ fragments.set(`${fragment}-${count}`, 0);
84
+ }
85
+ fragments.set(fragment, count + 1);
86
+ let match = null;
87
+ while ((match = anchorRe.exec(headingText.text)) !== null) {
88
+ const [ , anchor ] = match;
89
+ if (!fragments.has(anchor)) {
90
+ fragments.set(anchor, 1);
91
+ }
66
92
  }
67
93
  }
68
94
  }
69
95
 
70
96
  // Process HTML anchors
71
- for (const token of filterByHtmlTokens(tokens)) {
97
+ for (const token of filterByTypes(tokens, [ "htmlText" ])) {
72
98
  const htmlTagInfo = getHtmlTagInfo(token);
73
99
  if (htmlTagInfo && !htmlTagInfo.close) {
74
100
  const anchorMatch = idRe.exec(token.text) ||
@@ -89,10 +115,13 @@ module.exports = {
89
115
  for (const link of links) {
90
116
  const definitions = filterByTypes(link.children, [ definitionType ]);
91
117
  for (const definition of definitions) {
118
+ const { endColumn, startColumn } = definition;
119
+ const text = unescapeStringTokenText(definition);
92
120
  if (
93
- (definition.text.length > 1) &&
94
- definition.text.startsWith("#") &&
95
- !fragments.has(definition.text)
121
+ (text.length > 1) &&
122
+ text.startsWith("#") &&
123
+ !fragments.has(text) &&
124
+ !fragments.has(`#${encodeURIComponent(text.slice(1))}`)
96
125
  ) {
97
126
  // eslint-disable-next-line no-undef-init
98
127
  let context = undefined;
@@ -104,13 +133,13 @@ module.exports = {
104
133
  context = link.text;
105
134
  range = [ link.startColumn, link.endColumn - link.startColumn ];
106
135
  fixInfo = {
107
- "editColumn": definition.startColumn,
108
- "deleteCount": definition.endColumn - definition.startColumn
136
+ "editColumn": startColumn,
137
+ "deleteCount": endColumn - startColumn
109
138
  };
110
139
  }
111
- const definitionTextLower = definition.text.toLowerCase();
140
+ const textLower = text.toLowerCase();
112
141
  const mixedCaseKey = [ ...fragments.keys() ]
113
- .find((key) => definitionTextLower === key.toLowerCase());
142
+ .find((key) => textLower === key.toLowerCase());
114
143
  if (mixedCaseKey) {
115
144
  // @ts-ignore
116
145
  (fixInfo || {}).insertText = mixedCaseKey;
@@ -118,7 +147,7 @@ module.exports = {
118
147
  onError,
119
148
  link.startLine,
120
149
  mixedCaseKey,
121
- definition.text,
150
+ text,
122
151
  undefined,
123
152
  context,
124
153
  range,
package/lib/md052.js CHANGED
@@ -11,10 +11,14 @@ module.exports = {
11
11
  "Reference links and images should use a label that is defined",
12
12
  "tags": [ "images", "links" ],
13
13
  "function": function MD052(params, onError) {
14
- const { lines } = params;
15
- const { references, definitions } = referenceLinkImageData();
14
+ const { config, lines } = params;
15
+ const shortcutSyntax = config.shortcut_syntax || false;
16
+ const { definitions, references, shortcuts } = referenceLinkImageData();
17
+ const entries = shortcutSyntax ?
18
+ [ ...references.entries(), ...shortcuts.entries() ] :
19
+ references.entries();
16
20
  // Look for links/images that use an undefined link reference
17
- for (const reference of references.entries()) {
21
+ for (const reference of entries) {
18
22
  const [ label, datas ] = reference;
19
23
  if (!definitions.has(label)) {
20
24
  for (const data of datas) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdownlint",
3
- "version": "0.30.0",
3
+ "version": "0.31.1",
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",
@@ -18,7 +18,7 @@
18
18
  "homepage": "https://github.com/DavidAnson/markdownlint",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/DavidAnson/markdownlint.git"
21
+ "url": "git+https://github.com/DavidAnson/markdownlint.git"
22
22
  },
23
23
  "bugs": "https://github.com/DavidAnson/markdownlint/issues",
24
24
  "scripts": {
@@ -52,7 +52,7 @@
52
52
  "lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos.js",
53
53
  "serial-config-docs": "npm run build-config && npm run build-docs",
54
54
  "serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration",
55
- "test": "ava 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",
55
+ "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
56
  "test-cover": "c8 --100 npm test",
57
57
  "test-declaration": "cd example/typescript && tsc && node type-check.js",
58
58
  "test-extra": "ava --timeout=5m test/markdownlint-test-extra-parse.js test/markdownlint-test-extra-type.js",
@@ -68,16 +68,16 @@
68
68
  "markdownlint-micromark": "0.1.7"
69
69
  },
70
70
  "devDependencies": {
71
- "@babel/core": "7.22.10",
72
- "@babel/preset-env": "7.22.10",
71
+ "@babel/core": "7.22.19",
72
+ "@babel/preset-env": "7.22.15",
73
73
  "ava": "5.3.1",
74
74
  "babel-loader": "9.1.3",
75
75
  "c8": "8.0.1",
76
76
  "character-entities": "2.0.2",
77
- "eslint": "8.46.0",
77
+ "eslint": "8.49.0",
78
78
  "eslint-plugin-es": "4.1.0",
79
- "eslint-plugin-jsdoc": "46.4.6",
80
- "eslint-plugin-n": "16.0.1",
79
+ "eslint-plugin-jsdoc": "46.8.0",
80
+ "eslint-plugin-n": "16.1.0",
81
81
  "eslint-plugin-regexp": "1.15.0",
82
82
  "eslint-plugin-unicorn": "48.0.1",
83
83
  "gemoji": "8.1.0",
@@ -86,16 +86,16 @@
86
86
  "markdown-it-for-inline": "0.1.1",
87
87
  "markdown-it-sub": "1.0.0",
88
88
  "markdown-it-sup": "1.0.0",
89
- "markdownlint-rule-helpers": "0.20.0",
89
+ "markdownlint-rule-helpers": "0.22.0",
90
90
  "npm-run-all": "4.1.5",
91
91
  "strip-json-comments": "5.0.1",
92
92
  "terser-webpack-plugin": "5.3.9",
93
93
  "toml": "3.0.0",
94
94
  "tv4": "1.3.0",
95
- "typescript": "5.1.6",
95
+ "typescript": "5.2.2",
96
96
  "webpack": "5.88.2",
97
97
  "webpack-cli": "5.1.4",
98
- "yaml": "2.3.1"
98
+ "yaml": "2.3.2"
99
99
  },
100
100
  "keywords": [
101
101
  "markdown",
@@ -279,7 +279,10 @@
279
279
  "MD051": true,
280
280
 
281
281
  // MD052/reference-links-images - Reference links and images should use a label that is defined
282
- "MD052": true,
282
+ "MD052": {
283
+ // Include shortcut syntax
284
+ "shortcut_syntax": false
285
+ },
283
286
 
284
287
  // MD053/link-image-reference-definitions - Link and image reference definitions should be needed
285
288
  "MD053": {
@@ -252,7 +252,9 @@ MD050:
252
252
  MD051: true
253
253
 
254
254
  # MD052/reference-links-images - Reference links and images should use a label that is defined
255
- MD052: true
255
+ MD052:
256
+ # Include shortcut syntax
257
+ shortcut_syntax: false
256
258
 
257
259
  # MD053/link-image-reference-definitions - Link and image reference definitions should be needed
258
260
  MD053:
@@ -937,8 +937,19 @@
937
937
  },
938
938
  "MD052": {
939
939
  "description": "MD052/reference-links-images - Reference links and images should use a label that is defined",
940
- "type": "boolean",
941
- "default": true
940
+ "type": [
941
+ "boolean",
942
+ "object"
943
+ ],
944
+ "default": true,
945
+ "properties": {
946
+ "shortcut_syntax": {
947
+ "description": "Include shortcut syntax",
948
+ "type": "boolean",
949
+ "default": false
950
+ }
951
+ },
952
+ "additionalProperties": false
942
953
  },
943
954
  "reference-links-images": {
944
955
  "$ref": "#/properties/MD052"