markdownlint 0.33.0 → 0.34.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 (70) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/CONTRIBUTING.md +4 -3
  3. package/demo/markdownlint-browser.js +2730 -1541
  4. package/doc/CustomRules.md +14 -7
  5. package/doc/Rules.md +40 -7
  6. package/doc/md013.md +8 -7
  7. package/doc/md049.md +3 -0
  8. package/doc/md050.md +3 -0
  9. package/doc/md051.md +26 -0
  10. package/helpers/README.md +5 -3
  11. package/helpers/helpers.js +5 -5
  12. package/helpers/micromark.cjs +45 -27
  13. package/helpers/package.json +2 -2
  14. package/lib/configuration.d.ts +102 -102
  15. package/lib/constants.js +1 -1
  16. package/lib/markdownlint.d.ts +79 -6
  17. package/lib/markdownlint.js +95 -20
  18. package/lib/md001.js +3 -0
  19. package/lib/md003.js +3 -0
  20. package/lib/md004.js +3 -0
  21. package/lib/md005.js +9 -1
  22. package/lib/md007.js +14 -9
  23. package/lib/md009.js +3 -0
  24. package/lib/md010.js +4 -1
  25. package/lib/md011.js +3 -0
  26. package/lib/md012.js +3 -0
  27. package/lib/md013.js +3 -0
  28. package/lib/md014.js +4 -0
  29. package/lib/md018.js +4 -0
  30. package/lib/md019.js +3 -0
  31. package/lib/md020.js +3 -0
  32. package/lib/md021.js +3 -0
  33. package/lib/md022.js +10 -2
  34. package/lib/md023.js +3 -0
  35. package/lib/md024.js +3 -0
  36. package/lib/md025.js +3 -0
  37. package/lib/md026.js +9 -5
  38. package/lib/md027.js +29 -43
  39. package/lib/md028.js +31 -14
  40. package/lib/md029.js +3 -0
  41. package/lib/md030.js +9 -4
  42. package/lib/md031.js +3 -0
  43. package/lib/md032.js +12 -14
  44. package/lib/md033.js +9 -2
  45. package/lib/md034.js +31 -5
  46. package/lib/md035.js +9 -2
  47. package/lib/md036.js +33 -39
  48. package/lib/md037.js +10 -2
  49. package/lib/md038.js +10 -3
  50. package/lib/md039.js +4 -0
  51. package/lib/md040.js +26 -21
  52. package/lib/md041.js +21 -26
  53. package/lib/md042.js +4 -0
  54. package/lib/md043.js +3 -0
  55. package/lib/md044.js +9 -1
  56. package/lib/md045.js +10 -3
  57. package/lib/md046.js +14 -7
  58. package/lib/md047.js +5 -2
  59. package/lib/md048.js +26 -13
  60. package/lib/md049-md050.js +26 -7
  61. package/lib/md051.js +20 -16
  62. package/lib/md052.js +3 -0
  63. package/lib/md053.js +3 -0
  64. package/lib/md054.js +10 -5
  65. package/lib/md055.js +9 -1
  66. package/lib/md056.js +9 -1
  67. package/package.json +17 -22
  68. package/schema/.markdownlint.jsonc +50 -50
  69. package/schema/.markdownlint.yaml +50 -50
  70. package/schema/markdownlint-config-schema.json +104 -104
package/lib/md040.js CHANGED
@@ -2,36 +2,41 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- const { addError, addErrorContext, filterTokens } = require("../helpers");
5
+ const { addError, addErrorContext } = require("../helpers");
6
+ const { filterByTypes, getTokenTextByType, tokenIfType } =
7
+ require("../helpers/micromark.cjs");
6
8
 
9
+ // eslint-disable-next-line jsdoc/valid-types
10
+ /** @type import("./markdownlint").Rule */
7
11
  module.exports = {
8
12
  "names": [ "MD040", "fenced-code-language" ],
9
13
  "description": "Fenced code blocks should have a language specified",
10
14
  "tags": [ "code", "language" ],
15
+ "parser": "micromark",
11
16
  "function": function MD040(params, onError) {
12
17
  let allowed = params.config.allowed_languages;
13
18
  allowed = Array.isArray(allowed) ? allowed : [];
14
19
  const languageOnly = !!params.config.language_only;
15
-
16
- filterTokens(params, "fence", function forToken(token) {
17
- const lang = token.info.trim().split(/\s+/u).shift();
18
- if (lang === "") {
19
- addErrorContext(onError, token.lineNumber, token.line);
20
- } else if ((allowed.length > 0) && !allowed.includes(lang)) {
21
- addError(
22
- onError,
23
- token.lineNumber,
24
- `"${lang}" is not allowed`
25
- );
26
- }
27
-
28
- if (languageOnly && (token.info !== lang)) {
29
- addError(
30
- onError,
31
- token.lineNumber,
32
- `Info string contains more than language: "${token.info}"`
33
- );
20
+ // eslint-disable-next-line jsdoc/valid-types
21
+ /** @type import("../helpers/micromark.cjs").Token[] */
22
+ const micromarkTokens =
23
+ // @ts-ignore
24
+ params.parsers.micromark.tokens;
25
+ const fencedCodes = filterByTypes(micromarkTokens, [ "codeFenced" ]);
26
+ for (const fencedCode of fencedCodes) {
27
+ const openingFence = tokenIfType(fencedCode.children[0], "codeFencedFence");
28
+ if (openingFence) {
29
+ const { children, startLine, text } = openingFence;
30
+ const info = getTokenTextByType(children, "codeFencedFenceInfo");
31
+ if (!info) {
32
+ addErrorContext(onError, startLine, text);
33
+ } else if ((allowed.length > 0) && !allowed.includes(info)) {
34
+ addError(onError, startLine, `"${info}" is not allowed`);
35
+ }
36
+ if (languageOnly && getTokenTextByType(children, "codeFencedFenceMeta")) {
37
+ addError(onError, startLine, `Info string contains more than language: "${text}"`);
38
+ }
34
39
  }
35
- });
40
+ }
36
41
  }
37
42
  };
package/lib/md041.js CHANGED
@@ -3,40 +3,35 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorContext, frontMatterHasTitle } = require("../helpers");
6
+ const { filterByTypes, getHeadingLevel, getHtmlTagInfo, isHtmlFlowComment, nonContentTokens } =
7
+ require("../helpers/micromark.cjs");
6
8
 
9
+ // eslint-disable-next-line jsdoc/valid-types
10
+ /** @type import("./markdownlint").Rule */
7
11
  module.exports = {
8
12
  "names": [ "MD041", "first-line-heading", "first-line-h1" ],
9
13
  "description": "First line in a file should be a top-level heading",
10
14
  "tags": [ "headings" ],
15
+ "parser": "micromark",
11
16
  "function": function MD041(params, onError) {
12
17
  const level = Number(params.config.level || 1);
13
- const tag = "h" + level;
14
- const foundFrontMatterTitle =
15
- frontMatterHasTitle(
16
- params.frontMatterLines,
17
- params.config.front_matter_title
18
- );
19
- if (!foundFrontMatterTitle) {
20
- const htmlHeadingRe = new RegExp(`^<h${level}[ />]`, "i");
21
- params.parsers.markdownit.tokens.every((token) => {
22
- let isError = false;
23
- if (token.type === "html_block") {
24
- if (token.content.startsWith("<!--")) {
25
- // Ignore leading HTML comments
26
- return true;
27
- } else if (!htmlHeadingRe.test(token.content)) {
28
- // Something other than an HTML heading
29
- isError = true;
18
+ if (!frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title)) {
19
+ params.parsers.micromark.tokens.
20
+ filter((token) => !nonContentTokens.has(token.type) && !isHtmlFlowComment(token)).
21
+ every((token) => {
22
+ let isError = true;
23
+ if ((token.type === "atxHeading") || (token.type === "setextHeading")) {
24
+ isError = (getHeadingLevel(token) !== level);
25
+ } else if (token.type === "htmlFlow") {
26
+ const htmlTexts = filterByTypes(token.children, [ "htmlText" ]);
27
+ const tagInfo = (htmlTexts.length > 0) && getHtmlTagInfo(htmlTexts[0]);
28
+ isError = !tagInfo || (tagInfo.name.toLowerCase() !== `h${level}`);
30
29
  }
31
- } else if ((token.type !== "heading_open") || (token.tag !== tag)) {
32
- // Something other than a Markdown heading
33
- isError = true;
34
- }
35
- if (isError) {
36
- addErrorContext(onError, token.lineNumber, token.line);
37
- }
38
- return false;
39
- });
30
+ if (isError) {
31
+ addErrorContext(onError, token.startLine, params.lines[token.startLine - 1]);
32
+ }
33
+ return false;
34
+ });
40
35
  }
41
36
  }
42
37
  };
package/lib/md042.js CHANGED
@@ -5,10 +5,13 @@
5
5
  const { addErrorContext, escapeForRegExp, filterTokens } =
6
6
  require("../helpers");
7
7
 
8
+ // eslint-disable-next-line jsdoc/valid-types
9
+ /** @type import("./markdownlint").Rule */
8
10
  module.exports = {
9
11
  "names": [ "MD042", "no-empty-links" ],
10
12
  "description": "No empty links",
11
13
  "tags": [ "links" ],
14
+ "parser": "markdownit",
12
15
  "function": function MD042(params, onError) {
13
16
  filterTokens(params, "inline", function forToken(token) {
14
17
  let inLink = false;
@@ -33,6 +36,7 @@ module.exports = {
33
36
  );
34
37
  if (match) {
35
38
  context = match[0];
39
+ // @ts-ignore
36
40
  range = [ match.index + 1, match[0].length ];
37
41
  }
38
42
  addErrorContext(
package/lib/md043.js CHANGED
@@ -5,10 +5,13 @@
5
5
  const { addErrorContext, addErrorDetailIf, forEachHeading } =
6
6
  require("../helpers");
7
7
 
8
+ // eslint-disable-next-line jsdoc/valid-types
9
+ /** @type import("./markdownlint").Rule */
8
10
  module.exports = {
9
11
  "names": [ "MD043", "required-headings" ],
10
12
  "description": "Required heading structure",
11
13
  "tags": [ "headings" ],
14
+ "parser": "markdownit",
12
15
  "function": function MD043(params, onError) {
13
16
  const requiredHeadings = params.config.headings;
14
17
  if (!Array.isArray(requiredHeadings)) {
package/lib/md044.js CHANGED
@@ -11,10 +11,13 @@ const ignoredChildTypes = new Set(
11
11
  [ "codeFencedFence", "definition", "reference", "resource" ]
12
12
  );
13
13
 
14
+ // eslint-disable-next-line jsdoc/valid-types
15
+ /** @type import("./markdownlint").Rule */
14
16
  module.exports = {
15
17
  "names": [ "MD044", "proper-names" ],
16
18
  "description": "Proper names should have the correct capitalization",
17
19
  "tags": [ "spelling" ],
20
+ "parser": "micromark",
18
21
  "function": function MD044(params, onError) {
19
22
  let names = params.config.names;
20
23
  names = Array.isArray(names) ? names : [];
@@ -29,6 +32,11 @@ module.exports = {
29
32
  const htmlElements = params.config.html_elements;
30
33
  const includeHtmlElements =
31
34
  (htmlElements === undefined) ? true : !!htmlElements;
35
+ // eslint-disable-next-line jsdoc/valid-types
36
+ /** @type import("../helpers/micromark.cjs").Token[] */
37
+ const micromarkTokens =
38
+ // @ts-ignore
39
+ params.parsers.micromark.tokens;
32
40
  const scannedTypes = new Set([ "data" ]);
33
41
  if (includeCodeBlocks) {
34
42
  scannedTypes.add("codeFlowValue");
@@ -40,7 +48,7 @@ module.exports = {
40
48
  }
41
49
  const contentTokens =
42
50
  filterByPredicate(
43
- params.parsers.micromark.tokens,
51
+ micromarkTokens,
44
52
  (token) => scannedTypes.has(token.type),
45
53
  (token) => (
46
54
  token.children.filter((t) => !ignoredChildTypes.has(t.type))
package/lib/md045.js CHANGED
@@ -7,15 +7,22 @@ const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
7
7
 
8
8
  const altRe = getHtmlAttributeRe("alt");
9
9
 
10
+ // eslint-disable-next-line jsdoc/valid-types
11
+ /** @type import("./markdownlint").Rule */
10
12
  module.exports = {
11
13
  "names": [ "MD045", "no-alt-text" ],
12
14
  "description": "Images should have alternate text (alt text)",
13
15
  "tags": [ "accessibility", "images" ],
16
+ "parser": "micromark",
14
17
  "function": function MD045(params, onError) {
15
- const { tokens } = params.parsers.micromark;
18
+ // eslint-disable-next-line jsdoc/valid-types
19
+ /** @type import("../helpers/micromark.cjs").Token[] */
20
+ const micromarkTokens =
21
+ // @ts-ignore
22
+ params.parsers.micromark.tokens;
16
23
 
17
24
  // Process Markdown images
18
- const images = filterByTypes(tokens, [ "image" ]);
25
+ const images = filterByTypes(micromarkTokens, [ "image" ]);
19
26
  for (const image of images) {
20
27
  const labelTexts = filterByTypes(image.children, [ "labelText" ]);
21
28
  if (labelTexts.some((labelText) => labelText.text.length === 0)) {
@@ -33,7 +40,7 @@ module.exports = {
33
40
  }
34
41
 
35
42
  // Process HTML images
36
- const htmlTexts = filterByTypes(tokens, [ "htmlText" ]);
43
+ const htmlTexts = filterByTypes(micromarkTokens, [ "htmlText" ]);
37
44
  for (const htmlText of htmlTexts) {
38
45
  const { startColumn, startLine, text } = htmlText;
39
46
  const htmlTagInfo = getHtmlTagInfo(htmlText);
package/lib/md046.js CHANGED
@@ -3,29 +3,36 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes } = require("../helpers/micromark.cjs");
6
7
 
7
8
  const tokenTypeToStyle = {
8
- "fence": "fenced",
9
- "code_block": "indented"
9
+ "codeFenced": "fenced",
10
+ "codeIndented": "indented"
10
11
  };
11
12
 
13
+ // eslint-disable-next-line jsdoc/valid-types
14
+ /** @type import("./markdownlint").Rule */
12
15
  module.exports = {
13
16
  "names": [ "MD046", "code-block-style" ],
14
17
  "description": "Code block style",
15
18
  "tags": [ "code" ],
19
+ "parser": "micromark",
16
20
  "function": function MD046(params, onError) {
17
21
  let expectedStyle = String(params.config.style || "consistent");
18
- const codeBlocksAndFences = params.parsers.markdownit.tokens.filter(
19
- (token) => (token.type === "code_block") || (token.type === "fence")
20
- );
22
+ // eslint-disable-next-line jsdoc/valid-types
23
+ /** @type import("../helpers/micromark.cjs").Token[] */
24
+ const micromarkTokens =
25
+ // @ts-ignore
26
+ params.parsers.micromark.tokens;
27
+ const codeBlocksAndFences = filterByTypes(micromarkTokens, [ "codeFenced", "codeIndented" ]);
21
28
  for (const token of codeBlocksAndFences) {
22
- const { lineNumber, type } = token;
29
+ const { startLine, type } = token;
23
30
  if (expectedStyle === "consistent") {
24
31
  expectedStyle = tokenTypeToStyle[type];
25
32
  }
26
33
  addErrorDetailIf(
27
34
  onError,
28
- lineNumber,
35
+ startLine,
29
36
  expectedStyle,
30
37
  tokenTypeToStyle[type]);
31
38
  }
package/lib/md047.js CHANGED
@@ -4,10 +4,13 @@
4
4
 
5
5
  const { addError, isBlankLine } = require("../helpers");
6
6
 
7
+ // eslint-disable-next-line jsdoc/valid-types
8
+ /** @type import("./markdownlint").Rule */
7
9
  module.exports = {
8
10
  "names": [ "MD047", "single-trailing-newline" ],
9
11
  "description": "Files should end with a single newline character",
10
12
  "tags": [ "blank_lines" ],
13
+ "parser": "none",
11
14
  "function": function MD047(params, onError) {
12
15
  const lastLineNumber = params.lines.length;
13
16
  const lastLine = params.lines[lastLineNumber - 1];
@@ -15,8 +18,8 @@ module.exports = {
15
18
  addError(
16
19
  onError,
17
20
  lastLineNumber,
18
- null,
19
- null,
21
+ undefined,
22
+ undefined,
20
23
  [ lastLine.length, 1 ],
21
24
  {
22
25
  "insertText": "\n",
package/lib/md048.js CHANGED
@@ -3,28 +3,41 @@
3
3
  "use strict";
4
4
 
5
5
  const { addErrorDetailIf, fencedCodeBlockStyleFor } = require("../helpers");
6
+ const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs");
6
7
 
8
+ // eslint-disable-next-line jsdoc/valid-types
9
+ /** @type import("./markdownlint").Rule */
7
10
  module.exports = {
8
11
  "names": [ "MD048", "code-fence-style" ],
9
12
  "description": "Code fence style",
10
13
  "tags": [ "code" ],
14
+ "parser": "micromark",
11
15
  "function": function MD048(params, onError) {
12
16
  const style = String(params.config.style || "consistent");
17
+ // eslint-disable-next-line jsdoc/valid-types
18
+ /** @type import("../helpers/micromark.cjs").Token[] */
19
+ const micromarkTokens =
20
+ // @ts-ignore
21
+ params.parsers.micromark.tokens;
13
22
  let expectedStyle = style;
14
- const fenceTokens = params.parsers.markdownit.tokens.filter(
15
- (token) => token.type === "fence"
16
- );
17
- for (const fenceToken of fenceTokens) {
18
- const { lineNumber, markup } = fenceToken;
19
- if (expectedStyle === "consistent") {
20
- expectedStyle = fencedCodeBlockStyleFor(markup);
23
+ const codeFenceds = filterByTypes(micromarkTokens, [ "codeFenced" ]);
24
+ for (const codeFenced of codeFenceds) {
25
+ const codeFencedFence = tokenIfType(codeFenced.children[0], "codeFencedFence");
26
+ if (codeFencedFence) {
27
+ const codeFencedFenceSequence = tokenIfType(codeFencedFence.children[0], "codeFencedFenceSequence");
28
+ if (codeFencedFenceSequence) {
29
+ const { startLine, text } = codeFencedFenceSequence;
30
+ if (expectedStyle === "consistent") {
31
+ expectedStyle = fencedCodeBlockStyleFor(text);
32
+ }
33
+ addErrorDetailIf(
34
+ onError,
35
+ startLine,
36
+ expectedStyle,
37
+ fencedCodeBlockStyleFor(text)
38
+ );
39
+ }
21
40
  }
22
- addErrorDetailIf(
23
- onError,
24
- lineNumber,
25
- expectedStyle,
26
- fencedCodeBlockStyleFor(markup)
27
- );
28
41
  }
29
42
  }
30
43
  };
@@ -5,21 +5,34 @@
5
5
  const { addError, emphasisOrStrongStyleFor } = require("../helpers");
6
6
  const { filterByPredicate, tokenIfType } = require("../helpers/micromark.cjs");
7
7
 
8
- const intrawordRe = /\w/;
8
+ const intrawordRe = /^\w$/;
9
9
 
10
+ /**
11
+ * @param {import("./markdownlint").RuleParams} params Rule parameters.
12
+ * @param {import("./markdownlint").RuleOnError} onError Error-reporting callback.
13
+ * @param {import("markdownlint-micromark").TokenType} type Token type.
14
+ * @param {import("markdownlint-micromark").TokenType} typeSequence Token sequence type.
15
+ * @param {"*" | "**"} asterisk Asterisk kind.
16
+ * @param {"_" | "__"} underline Underline kind.
17
+ * @param {"asterisk" | "consistent" | "underscore"} style Style string.
18
+ */
10
19
  const impl =
11
- (params, onError, type, asterisk, underline, style = "consistent") => {
12
- const { lines, parsers } = params;
20
+ (params, onError, type, typeSequence, asterisk, underline, style = "consistent") => {
21
+ // eslint-disable-next-line jsdoc/valid-types
22
+ /** @type import("../helpers/micromark.cjs").Token[] */
23
+ const micromarkTokens =
24
+ // @ts-ignore
25
+ params.parsers.micromark.tokens;
26
+ const { lines } = params;
13
27
  const emphasisTokens = filterByPredicate(
14
- parsers.micromark.tokens,
28
+ micromarkTokens,
15
29
  (token) => token.type === type,
16
30
  (token) => ((token.type === "htmlFlow") ? [] : token.children)
17
31
  );
18
32
  for (const token of emphasisTokens) {
19
33
  const { children } = token;
20
- const childType = `${type}Sequence`;
21
- const startSequence = tokenIfType(children[0], childType);
22
- const endSequence = tokenIfType(children[children.length - 1], childType);
34
+ const startSequence = tokenIfType(children[0], typeSequence);
35
+ const endSequence = tokenIfType(children[children.length - 1], typeSequence);
23
36
  if (startSequence && endSequence) {
24
37
  const markupStyle = emphasisOrStrongStyleFor(startSequence.text);
25
38
  if (style === "consistent") {
@@ -55,16 +68,20 @@ const impl =
55
68
  }
56
69
  };
57
70
 
71
+ // eslint-disable-next-line jsdoc/valid-types
72
+ /** @type import("./markdownlint").Rule[] */
58
73
  module.exports = [
59
74
  {
60
75
  "names": [ "MD049", "emphasis-style" ],
61
76
  "description": "Emphasis style",
62
77
  "tags": [ "emphasis" ],
78
+ "parser": "micromark",
63
79
  "function": function MD049(params, onError) {
64
80
  return impl(
65
81
  params,
66
82
  onError,
67
83
  "emphasis",
84
+ "emphasisSequence",
68
85
  "*",
69
86
  "_",
70
87
  params.config.style || undefined
@@ -75,11 +92,13 @@ module.exports = [
75
92
  "names": [ "MD050", "strong-style" ],
76
93
  "description": "Strong style",
77
94
  "tags": [ "emphasis" ],
95
+ "parser": "micromark",
78
96
  "function": function MD050(params, onError) {
79
97
  return impl(
80
98
  params,
81
99
  onError,
82
100
  "strong",
101
+ "strongSequence",
83
102
  "**",
84
103
  "__",
85
104
  params.config.style || undefined
package/lib/md051.js CHANGED
@@ -11,22 +11,19 @@ const { filterByPredicate, filterByTypes, getHtmlTagInfo } =
11
11
  const idRe = getHtmlAttributeRe("id");
12
12
  const nameRe = getHtmlAttributeRe("name");
13
13
  const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
14
+ const lineFragmentRe = /^#(?:L\d+(?:C\d+)?-L\d+(?:C\d+)?|L\d+)$/;
14
15
 
15
16
  // Sets for filtering heading tokens during conversion
16
17
  const childrenExclude = new Set([ "image", "reference", "resource" ]);
17
18
  const tokensInclude = new Set(
18
- [ "characterEscapeValue", "codeTextData", "data" ]
19
+ [ "characterEscapeValue", "codeTextData", "data", "mathTextData" ]
19
20
  );
20
21
 
21
- /**
22
- * @typedef {import("../helpers/micromark.cjs").Token} Token
23
- */
24
-
25
22
  /**
26
23
  * Converts a Markdown heading into an HTML fragment according to the rules
27
24
  * used by GitHub.
28
25
  *
29
- * @param {Token} headingText Heading text token.
26
+ * @param {import("../helpers/micromark.cjs").Token} headingText Heading text token.
30
27
  * @returns {string} Fragment string for heading.
31
28
  */
32
29
  function convertHeadingToHTMLFragment(headingText) {
@@ -55,7 +52,7 @@ function convertHeadingToHTMLFragment(headingText) {
55
52
  /**
56
53
  * Unescapes the text of a String-type micromark Token.
57
54
  *
58
- * @param {Token} token String-type micromark Token.
55
+ * @param {import("../helpers/micromark.cjs").Token} token String-type micromark Token.
59
56
  * @returns {string} Unescaped token text.
60
57
  */
61
58
  function unescapeStringTokenText(token) {
@@ -64,19 +61,23 @@ function unescapeStringTokenText(token) {
64
61
  .join("");
65
62
  }
66
63
 
64
+ // eslint-disable-next-line jsdoc/valid-types
65
+ /** @type import("./markdownlint").Rule */
67
66
  module.exports = {
68
67
  "names": [ "MD051", "link-fragments" ],
69
68
  "description": "Link fragments should be valid",
70
69
  "tags": [ "links" ],
70
+ "parser": "micromark",
71
71
  "function": function MD051(params, onError) {
72
- const { tokens } = params.parsers.micromark;
72
+ // eslint-disable-next-line jsdoc/valid-types
73
+ /** @type import("../helpers/micromark.cjs").Token[] */
74
+ const micromarkTokens =
75
+ // @ts-ignore
76
+ params.parsers.micromark.tokens;
73
77
  const fragments = new Map();
74
78
 
75
79
  // Process headings
76
- const headingTexts = filterByTypes(
77
- tokens,
78
- [ "atxHeadingText", "setextHeadingText" ]
79
- );
80
+ const headingTexts = filterByTypes(micromarkTokens, [ "atxHeadingText", "setextHeadingText" ]);
80
81
  for (const headingText of headingTexts) {
81
82
  const fragment = convertHeadingToHTMLFragment(headingText);
82
83
  if (fragment !== "#") {
@@ -96,7 +97,7 @@ module.exports = {
96
97
  }
97
98
 
98
99
  // Process HTML anchors
99
- for (const token of filterByTypes(tokens, [ "htmlText" ])) {
100
+ for (const token of filterByTypes(micromarkTokens, [ "htmlText" ])) {
100
101
  const htmlTagInfo = getHtmlTagInfo(token);
101
102
  if (htmlTagInfo && !htmlTagInfo.close) {
102
103
  const anchorMatch = idRe.exec(token.text) ||
@@ -108,22 +109,25 @@ module.exports = {
108
109
  }
109
110
 
110
111
  // Process link and definition fragments
112
+ // eslint-disable-next-line jsdoc/valid-types
113
+ /** @type import("../helpers/micromark.cjs").TokenType[][] */
111
114
  const parentChilds = [
112
115
  [ "link", "resourceDestinationString" ],
113
116
  [ "definition", "definitionDestinationString" ]
114
117
  ];
115
118
  for (const [ parentType, definitionType ] of parentChilds) {
116
- const links = filterByTypes(tokens, [ parentType ]);
119
+ const links = filterByTypes(micromarkTokens, [ parentType ]);
117
120
  for (const link of links) {
118
121
  const definitions = filterByTypes(link.children, [ definitionType ]);
119
122
  for (const definition of definitions) {
120
123
  const { endColumn, startColumn } = definition;
121
124
  const text = unescapeStringTokenText(definition);
125
+ const encodedText = `#${encodeURIComponent(text.slice(1))}`;
122
126
  if (
123
127
  (text.length > 1) &&
124
128
  text.startsWith("#") &&
125
- !fragments.has(text) &&
126
- !fragments.has(`#${encodeURIComponent(text.slice(1))}`)
129
+ !fragments.has(encodedText) &&
130
+ !lineFragmentRe.test(encodedText)
127
131
  ) {
128
132
  // eslint-disable-next-line no-undef-init
129
133
  let context = undefined;
package/lib/md052.js CHANGED
@@ -5,11 +5,14 @@
5
5
  const { addError } = require("../helpers");
6
6
  const { referenceLinkImageData } = require("./cache");
7
7
 
8
+ // eslint-disable-next-line jsdoc/valid-types
9
+ /** @type import("./markdownlint").Rule */
8
10
  module.exports = {
9
11
  "names": [ "MD052", "reference-links-images" ],
10
12
  "description":
11
13
  "Reference links and images should use a label that is defined",
12
14
  "tags": [ "images", "links" ],
15
+ "parser": "none",
13
16
  "function": function MD052(params, onError) {
14
17
  const { config, lines } = params;
15
18
  const shortcutSyntax = config.shortcut_syntax || false;
package/lib/md053.js CHANGED
@@ -6,10 +6,13 @@ const { addError, ellipsify, linkReferenceDefinitionRe } =
6
6
  require("../helpers");
7
7
  const { referenceLinkImageData } = require("./cache");
8
8
 
9
+ // eslint-disable-next-line jsdoc/valid-types
10
+ /** @type import("./markdownlint").Rule */
9
11
  module.exports = {
10
12
  "names": [ "MD053", "link-image-reference-definitions" ],
11
13
  "description": "Link and image reference definitions should be needed",
12
14
  "tags": [ "images", "links" ],
15
+ "parser": "none",
13
16
  "function": function MD053(params, onError) {
14
17
  const ignored = new Set(params.config.ignored_definitions || [ "//" ]);
15
18
  const lines = params.lines;
package/lib/md054.js CHANGED
@@ -21,12 +21,15 @@ const autolinkAble = (destination) => {
21
21
  return !autolinkDisallowedRe.test(destination);
22
22
  };
23
23
 
24
+ // eslint-disable-next-line jsdoc/valid-types
25
+ /** @type import("./markdownlint").Rule */
24
26
  module.exports = {
25
27
  "names": [ "MD054", "link-image-style" ],
26
28
  "description": "Link and image style",
27
29
  "tags": [ "images", "links" ],
30
+ "parser": "micromark",
28
31
  "function": (params, onError) => {
29
- const { parsers, config } = params;
32
+ const config = params.config;
30
33
  const autolink = (config.autolink === undefined) || !!config.autolink;
31
34
  const inline = (config.inline === undefined) || !!config.inline;
32
35
  const full = (config.full === undefined) || !!config.full;
@@ -37,11 +40,13 @@ module.exports = {
37
40
  // Everything allowed, nothing to check
38
41
  return;
39
42
  }
43
+ // eslint-disable-next-line jsdoc/valid-types
44
+ /** @type import("../helpers/micromark.cjs").Token[] */
45
+ const micromarkTokens =
46
+ // @ts-ignore
47
+ params.parsers.micromark.tokens;
40
48
  const { definitions } = referenceLinkImageData();
41
- const links = filterByTypes(
42
- parsers.micromark.tokens,
43
- [ "autolink", "image", "link" ]
44
- );
49
+ const links = filterByTypes(micromarkTokens, [ "autolink", "image", "link" ]);
45
50
  for (const link of links) {
46
51
  let label = null;
47
52
  let destination = null;
package/lib/md055.js CHANGED
@@ -13,10 +13,13 @@ const firstOrNothing = (items) => items[0];
13
13
  const lastOrNothing = (items) => items[items.length - 1];
14
14
  const makeRange = (start, end) => [ start, end - start + 1 ];
15
15
 
16
+ // eslint-disable-next-line jsdoc/valid-types
17
+ /** @type import("./markdownlint").Rule */
16
18
  module.exports = {
17
19
  "names": [ "MD055", "table-pipe-style" ],
18
20
  "description": "Table pipe style",
19
21
  "tags": [ "table" ],
22
+ "parser": "micromark",
20
23
  "function": function MD055(params, onError) {
21
24
  const style = String(params.config.style || "consistent");
22
25
  let expectedStyle = style;
@@ -24,7 +27,12 @@ module.exports = {
24
27
  ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
25
28
  let expectedTrailingPipe =
26
29
  ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "leading_only"));
27
- const tables = filterByTypes(params.parsers.micromark.tokens, [ "table" ]);
30
+ // eslint-disable-next-line jsdoc/valid-types
31
+ /** @type import("../helpers/micromark.cjs").Token[] */
32
+ const micromarkTokens =
33
+ // @ts-ignore
34
+ params.parsers.micromark.tokens;
35
+ const tables = filterByTypes(micromarkTokens, [ "table" ]);
28
36
  for (const table of tables) {
29
37
  const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]);
30
38
  for (const row of rows) {
package/lib/md056.js CHANGED
@@ -7,12 +7,20 @@ const { filterByTypes } = require("../helpers/micromark.cjs");
7
7
 
8
8
  const makeRange = (start, end) => [ start, end - start + 1 ];
9
9
 
10
+ // eslint-disable-next-line jsdoc/valid-types
11
+ /** @type import("./markdownlint").Rule */
10
12
  module.exports = {
11
13
  "names": [ "MD056", "table-column-count" ],
12
14
  "description": "Table column count",
13
15
  "tags": [ "table" ],
16
+ "parser": "micromark",
14
17
  "function": function MD056(params, onError) {
15
- const tables = filterByTypes(params.parsers.micromark.tokens, [ "table" ]);
18
+ // eslint-disable-next-line jsdoc/valid-types
19
+ /** @type import("../helpers/micromark.cjs").Token[] */
20
+ const micromarkTokens =
21
+ // @ts-ignore
22
+ params.parsers.micromark.tokens;
23
+ const tables = filterByTypes(micromarkTokens, [ "table" ]);
16
24
  for (const table of tables) {
17
25
  const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]);
18
26
  let expectedCount = 0;