@alexlit/lint-kit 127.2.0 → 127.3.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 (141) hide show
  1. package/package.json +1 -1
  2. package/packages/config-markdownlint/node_modules/markdownlint/CHANGELOG.md +457 -0
  3. package/packages/config-markdownlint/node_modules/markdownlint/CONTRIBUTING.md +93 -0
  4. package/packages/config-markdownlint/node_modules/markdownlint/LICENSE +21 -0
  5. package/packages/config-markdownlint/node_modules/markdownlint/README.md +1047 -0
  6. package/packages/config-markdownlint/node_modules/markdownlint/demo/markdownlint-browser.js +7094 -0
  7. package/packages/config-markdownlint/node_modules/markdownlint/doc/CustomRules.md +388 -0
  8. package/packages/config-markdownlint/node_modules/markdownlint/doc/Prettier.md +27 -0
  9. package/packages/config-markdownlint/node_modules/markdownlint/doc/ReleaseProcess.md +20 -0
  10. package/packages/config-markdownlint/node_modules/markdownlint/doc/Rules.md +2528 -0
  11. package/packages/config-markdownlint/node_modules/markdownlint/doc/md001.md +37 -0
  12. package/packages/config-markdownlint/node_modules/markdownlint/doc/md003.md +59 -0
  13. package/packages/config-markdownlint/node_modules/markdownlint/doc/md004.md +49 -0
  14. package/packages/config-markdownlint/node_modules/markdownlint/doc/md005.md +53 -0
  15. package/packages/config-markdownlint/node_modules/markdownlint/doc/md007.md +52 -0
  16. package/packages/config-markdownlint/node_modules/markdownlint/doc/md009.md +51 -0
  17. package/packages/config-markdownlint/node_modules/markdownlint/doc/md010.md +56 -0
  18. package/packages/config-markdownlint/node_modules/markdownlint/doc/md011.md +30 -0
  19. package/packages/config-markdownlint/node_modules/markdownlint/doc/md012.md +38 -0
  20. package/packages/config-markdownlint/node_modules/markdownlint/doc/md013.md +58 -0
  21. package/packages/config-markdownlint/node_modules/markdownlint/doc/md014.md +54 -0
  22. package/packages/config-markdownlint/node_modules/markdownlint/doc/md018.md +27 -0
  23. package/packages/config-markdownlint/node_modules/markdownlint/doc/md019.md +28 -0
  24. package/packages/config-markdownlint/node_modules/markdownlint/doc/md020.md +29 -0
  25. package/packages/config-markdownlint/node_modules/markdownlint/doc/md021.md +31 -0
  26. package/packages/config-markdownlint/node_modules/markdownlint/doc/md022.md +52 -0
  27. package/packages/config-markdownlint/node_modules/markdownlint/doc/md023.md +33 -0
  28. package/packages/config-markdownlint/node_modules/markdownlint/doc/md024.md +44 -0
  29. package/packages/config-markdownlint/node_modules/markdownlint/doc/md025.md +49 -0
  30. package/packages/config-markdownlint/node_modules/markdownlint/doc/md026.md +40 -0
  31. package/packages/config-markdownlint/node_modules/markdownlint/doc/md027.md +24 -0
  32. package/packages/config-markdownlint/node_modules/markdownlint/doc/md028.md +40 -0
  33. package/packages/config-markdownlint/node_modules/markdownlint/doc/md029.md +98 -0
  34. package/packages/config-markdownlint/node_modules/markdownlint/doc/md030.md +82 -0
  35. package/packages/config-markdownlint/node_modules/markdownlint/doc/md031.md +50 -0
  36. package/packages/config-markdownlint/node_modules/markdownlint/doc/md032.md +55 -0
  37. package/packages/config-markdownlint/node_modules/markdownlint/doc/md033.md +27 -0
  38. package/packages/config-markdownlint/node_modules/markdownlint/doc/md034.md +55 -0
  39. package/packages/config-markdownlint/node_modules/markdownlint/doc/md035.md +42 -0
  40. package/packages/config-markdownlint/node_modules/markdownlint/doc/md036.md +45 -0
  41. package/packages/config-markdownlint/node_modules/markdownlint/doc/md037.md +37 -0
  42. package/packages/config-markdownlint/node_modules/markdownlint/doc/md038.md +40 -0
  43. package/packages/config-markdownlint/node_modules/markdownlint/doc/md039.md +21 -0
  44. package/packages/config-markdownlint/node_modules/markdownlint/doc/md040.md +52 -0
  45. package/packages/config-markdownlint/node_modules/markdownlint/doc/md041.md +49 -0
  46. package/packages/config-markdownlint/node_modules/markdownlint/doc/md042.md +32 -0
  47. package/packages/config-markdownlint/node_modules/markdownlint/doc/md043.md +69 -0
  48. package/packages/config-markdownlint/node_modules/markdownlint/doc/md044.md +45 -0
  49. package/packages/config-markdownlint/node_modules/markdownlint/doc/md045.md +40 -0
  50. package/packages/config-markdownlint/node_modules/markdownlint/doc/md046.md +40 -0
  51. package/packages/config-markdownlint/node_modules/markdownlint/doc/md047.md +34 -0
  52. package/packages/config-markdownlint/node_modules/markdownlint/doc/md048.md +41 -0
  53. package/packages/config-markdownlint/node_modules/markdownlint/doc/md049.md +35 -0
  54. package/packages/config-markdownlint/node_modules/markdownlint/doc/md050.md +35 -0
  55. package/packages/config-markdownlint/node_modules/markdownlint/doc/md051.md +87 -0
  56. package/packages/config-markdownlint/node_modules/markdownlint/doc/md052.md +40 -0
  57. package/packages/config-markdownlint/node_modules/markdownlint/doc/md053.md +38 -0
  58. package/packages/config-markdownlint/node_modules/markdownlint/doc/md054.md +100 -0
  59. package/packages/config-markdownlint/node_modules/markdownlint/doc/md055.md +54 -0
  60. package/packages/config-markdownlint/node_modules/markdownlint/doc/md056.md +37 -0
  61. package/packages/config-markdownlint/node_modules/markdownlint/doc/md058.md +48 -0
  62. package/packages/config-markdownlint/node_modules/markdownlint/helpers/LICENSE +21 -0
  63. package/packages/config-markdownlint/node_modules/markdownlint/helpers/README.md +46 -0
  64. package/packages/config-markdownlint/node_modules/markdownlint/helpers/helpers.js +793 -0
  65. package/packages/config-markdownlint/node_modules/markdownlint/helpers/micromark.cjs +544 -0
  66. package/packages/config-markdownlint/node_modules/markdownlint/helpers/package.json +26 -0
  67. package/packages/config-markdownlint/node_modules/markdownlint/helpers/shared.js +10 -0
  68. package/packages/config-markdownlint/node_modules/markdownlint/lib/cache.js +70 -0
  69. package/packages/config-markdownlint/node_modules/markdownlint/lib/configuration-strict.d.ts +1185 -0
  70. package/packages/config-markdownlint/node_modules/markdownlint/lib/configuration.d.ts +8 -0
  71. package/packages/config-markdownlint/node_modules/markdownlint/lib/constants.js +15 -0
  72. package/packages/config-markdownlint/node_modules/markdownlint/lib/markdownlint.d.ts +488 -0
  73. package/packages/config-markdownlint/node_modules/markdownlint/lib/markdownlint.js +1572 -0
  74. package/packages/config-markdownlint/node_modules/markdownlint/lib/md001.js +31 -0
  75. package/packages/config-markdownlint/node_modules/markdownlint/lib/md003.js +50 -0
  76. package/packages/config-markdownlint/node_modules/markdownlint/lib/md004.js +86 -0
  77. package/packages/config-markdownlint/node_modules/markdownlint/lib/md005.js +72 -0
  78. package/packages/config-markdownlint/node_modules/markdownlint/lib/md007.js +88 -0
  79. package/packages/config-markdownlint/node_modules/markdownlint/lib/md009.js +95 -0
  80. package/packages/config-markdownlint/node_modules/markdownlint/lib/md010.js +78 -0
  81. package/packages/config-markdownlint/node_modules/markdownlint/lib/md011.js +57 -0
  82. package/packages/config-markdownlint/node_modules/markdownlint/lib/md012.js +43 -0
  83. package/packages/config-markdownlint/node_modules/markdownlint/lib/md013.js +105 -0
  84. package/packages/config-markdownlint/node_modules/markdownlint/lib/md014.js +54 -0
  85. package/packages/config-markdownlint/node_modules/markdownlint/lib/md018.js +46 -0
  86. package/packages/config-markdownlint/node_modules/markdownlint/lib/md019-md021.js +80 -0
  87. package/packages/config-markdownlint/node_modules/markdownlint/lib/md020.js +71 -0
  88. package/packages/config-markdownlint/node_modules/markdownlint/lib/md022.js +106 -0
  89. package/packages/config-markdownlint/node_modules/markdownlint/lib/md023.js +40 -0
  90. package/packages/config-markdownlint/node_modules/markdownlint/lib/md024.js +48 -0
  91. package/packages/config-markdownlint/node_modules/markdownlint/lib/md025.js +40 -0
  92. package/packages/config-markdownlint/node_modules/markdownlint/lib/md026.js +49 -0
  93. package/packages/config-markdownlint/node_modules/markdownlint/lib/md027.js +37 -0
  94. package/packages/config-markdownlint/node_modules/markdownlint/lib/md028.js +42 -0
  95. package/packages/config-markdownlint/node_modules/markdownlint/lib/md029.js +76 -0
  96. package/packages/config-markdownlint/node_modules/markdownlint/lib/md030.js +60 -0
  97. package/packages/config-markdownlint/node_modules/markdownlint/lib/md031.js +63 -0
  98. package/packages/config-markdownlint/node_modules/markdownlint/lib/md032.js +66 -0
  99. package/packages/config-markdownlint/node_modules/markdownlint/lib/md033.js +41 -0
  100. package/packages/config-markdownlint/node_modules/markdownlint/lib/md034.js +100 -0
  101. package/packages/config-markdownlint/node_modules/markdownlint/lib/md035.js +26 -0
  102. package/packages/config-markdownlint/node_modules/markdownlint/lib/md036.js +51 -0
  103. package/packages/config-markdownlint/node_modules/markdownlint/lib/md037.js +94 -0
  104. package/packages/config-markdownlint/node_modules/markdownlint/lib/md038.js +100 -0
  105. package/packages/config-markdownlint/node_modules/markdownlint/lib/md039.js +83 -0
  106. package/packages/config-markdownlint/node_modules/markdownlint/lib/md040.js +37 -0
  107. package/packages/config-markdownlint/node_modules/markdownlint/lib/md041.js +37 -0
  108. package/packages/config-markdownlint/node_modules/markdownlint/lib/md042.js +63 -0
  109. package/packages/config-markdownlint/node_modules/markdownlint/lib/md043.js +73 -0
  110. package/packages/config-markdownlint/node_modules/markdownlint/lib/md044.js +110 -0
  111. package/packages/config-markdownlint/node_modules/markdownlint/lib/md045.js +62 -0
  112. package/packages/config-markdownlint/node_modules/markdownlint/lib/md046.js +34 -0
  113. package/packages/config-markdownlint/node_modules/markdownlint/lib/md047.js +31 -0
  114. package/packages/config-markdownlint/node_modules/markdownlint/lib/md048.js +39 -0
  115. package/packages/config-markdownlint/node_modules/markdownlint/lib/md049-md050.js +103 -0
  116. package/packages/config-markdownlint/node_modules/markdownlint/lib/md051.js +170 -0
  117. package/packages/config-markdownlint/node_modules/markdownlint/lib/md052.js +42 -0
  118. package/packages/config-markdownlint/node_modules/markdownlint/lib/md053.js +62 -0
  119. package/packages/config-markdownlint/node_modules/markdownlint/lib/md054.js +125 -0
  120. package/packages/config-markdownlint/node_modules/markdownlint/lib/md055.js +79 -0
  121. package/packages/config-markdownlint/node_modules/markdownlint/lib/md056.js +56 -0
  122. package/packages/config-markdownlint/node_modules/markdownlint/lib/md058.js +43 -0
  123. package/packages/config-markdownlint/node_modules/markdownlint/lib/rules.js +74 -0
  124. package/packages/config-markdownlint/node_modules/markdownlint/package.json +105 -0
  125. package/packages/config-markdownlint/node_modules/markdownlint/schema/.markdownlint.jsonc +307 -0
  126. package/packages/config-markdownlint/node_modules/markdownlint/schema/.markdownlint.yaml +275 -0
  127. package/packages/config-markdownlint/node_modules/markdownlint/schema/ValidatingConfiguration.md +26 -0
  128. package/packages/config-markdownlint/node_modules/markdownlint/schema/markdownlint-config-schema-strict.json +1819 -0
  129. package/packages/config-markdownlint/node_modules/markdownlint/schema/markdownlint-config-schema.json +1824 -0
  130. package/packages/config-markdownlint/node_modules/markdownlint/style/all.json +5 -0
  131. package/packages/config-markdownlint/node_modules/markdownlint/style/cirosantilli.json +22 -0
  132. package/packages/config-markdownlint/node_modules/markdownlint/style/prettier.json +27 -0
  133. package/packages/config-markdownlint/node_modules/markdownlint/style/relaxed.json +12 -0
  134. package/packages/config-markdownlint/node_modules/markdownlint-micromark/LICENSE +21 -0
  135. package/packages/config-markdownlint/node_modules/markdownlint-micromark/README.md +10 -0
  136. package/packages/config-markdownlint/node_modules/markdownlint-micromark/micromark-browser.js +2 -0
  137. package/packages/config-markdownlint/node_modules/markdownlint-micromark/micromark-html-browser.js +2 -0
  138. package/packages/config-markdownlint/node_modules/markdownlint-micromark/micromark.cjs +1 -0
  139. package/packages/config-markdownlint/node_modules/markdownlint-micromark/micromark.d.cts +1751 -0
  140. package/packages/config-markdownlint/node_modules/markdownlint-micromark/package.json +46 -0
  141. package/packages/config-markdownlint/package.json +2 -2
@@ -0,0 +1,103 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addError, emphasisOrStrongStyleFor } = require("../helpers");
6
+ const { filterByPredicate, tokenIfType } = require("../helpers/micromark.cjs");
7
+
8
+ const intrawordRe = /^\w$/;
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
+ */
19
+ const impl =
20
+ (params, onError, type, typeSequence, asterisk, underline, style = "consistent") => {
21
+ const { lines, parsers } = params;
22
+ const emphasisTokens = filterByPredicate(
23
+ parsers.micromark.tokens,
24
+ (token) => token.type === type,
25
+ (token) => ((token.type === "htmlFlow") ? [] : token.children)
26
+ );
27
+ for (const token of emphasisTokens) {
28
+ const { children } = token;
29
+ const startSequence = tokenIfType(children[0], typeSequence);
30
+ const endSequence = tokenIfType(children[children.length - 1], typeSequence);
31
+ if (startSequence && endSequence) {
32
+ const markupStyle = emphasisOrStrongStyleFor(startSequence.text);
33
+ if (style === "consistent") {
34
+ style = markupStyle;
35
+ }
36
+ if (style !== markupStyle) {
37
+ const underscoreIntraword = (style === "underscore") && (
38
+ intrawordRe.test(
39
+ lines[startSequence.startLine - 1][startSequence.startColumn - 2]
40
+ ) ||
41
+ intrawordRe.test(
42
+ lines[endSequence.endLine - 1][endSequence.endColumn - 1]
43
+ )
44
+ );
45
+ if (!underscoreIntraword) {
46
+ for (const sequence of [ startSequence, endSequence ]) {
47
+ addError(
48
+ onError,
49
+ sequence.startLine,
50
+ `Expected: ${style}; Actual: ${markupStyle}`,
51
+ undefined,
52
+ [ sequence.startColumn, sequence.text.length ],
53
+ {
54
+ "editColumn": sequence.startColumn,
55
+ "deleteCount": sequence.text.length,
56
+ "insertText": (style === "asterisk") ? asterisk : underline
57
+ }
58
+ );
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ };
65
+
66
+ // eslint-disable-next-line jsdoc/valid-types
67
+ /** @type import("./markdownlint").Rule[] */
68
+ module.exports = [
69
+ {
70
+ "names": [ "MD049", "emphasis-style" ],
71
+ "description": "Emphasis style",
72
+ "tags": [ "emphasis" ],
73
+ "parser": "micromark",
74
+ "function": function MD049(params, onError) {
75
+ return impl(
76
+ params,
77
+ onError,
78
+ "emphasis",
79
+ "emphasisSequence",
80
+ "*",
81
+ "_",
82
+ params.config.style || undefined
83
+ );
84
+ }
85
+ },
86
+ {
87
+ "names": [ "MD050", "strong-style" ],
88
+ "description": "Strong style",
89
+ "tags": [ "emphasis" ],
90
+ "parser": "micromark",
91
+ "function": function MD050(params, onError) {
92
+ return impl(
93
+ params,
94
+ onError,
95
+ "strong",
96
+ "strongSequence",
97
+ "**",
98
+ "__",
99
+ params.config.style || undefined
100
+ );
101
+ }
102
+ }
103
+ ];
@@ -0,0 +1,170 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addError, addErrorDetailIf, getHtmlAttributeRe } = require("../helpers");
6
+ const { filterByPredicate, filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
7
+ const { filterByTypesCached } = require("./cache");
8
+
9
+ // Regular expression for identifying HTML anchor names
10
+ const idRe = getHtmlAttributeRe("id");
11
+ const nameRe = getHtmlAttributeRe("name");
12
+ const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
13
+ const lineFragmentRe = /^#(?:L\d+(?:C\d+)?-L\d+(?:C\d+)?|L\d+)$/;
14
+
15
+ // Sets for filtering heading tokens during conversion
16
+ const childrenExclude = new Set([ "image", "reference", "resource" ]);
17
+ const tokensInclude = new Set(
18
+ [ "characterEscapeValue", "codeTextData", "data", "mathTextData" ]
19
+ );
20
+
21
+ /**
22
+ * Converts a Markdown heading into an HTML fragment according to the rules
23
+ * used by GitHub.
24
+ *
25
+ * @param {import("../helpers/micromark.cjs").Token} headingText Heading text token.
26
+ * @returns {string} Fragment string for heading.
27
+ */
28
+ function convertHeadingToHTMLFragment(headingText) {
29
+ const inlineText =
30
+ filterByPredicate(
31
+ headingText.children,
32
+ (token) => tokensInclude.has(token.type),
33
+ (token) => (childrenExclude.has(token.type) ? [] : token.children)
34
+ )
35
+ .map((token) => token.text)
36
+ .join("");
37
+ return "#" + encodeURIComponent(
38
+ inlineText
39
+ .toLowerCase()
40
+ // RegExp source with Ruby's \p{Word} expanded into its General Categories
41
+ // https://github.com/gjtorikian/html-pipeline/blob/main/lib/html/pipeline/toc_filter.rb
42
+ // https://ruby-doc.org/core-3.0.2/Regexp.html
43
+ .replace(
44
+ /[^\p{Letter}\p{Mark}\p{Number}\p{Connector_Punctuation}\- ]/gu,
45
+ ""
46
+ )
47
+ .replace(/ /gu, "-")
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Unescapes the text of a String-type micromark Token.
53
+ *
54
+ * @param {import("../helpers/micromark.cjs").Token} token String-type micromark Token.
55
+ * @returns {string} Unescaped token text.
56
+ */
57
+ function unescapeStringTokenText(token) {
58
+ return filterByTypes(token.children, [ "characterEscapeValue", "data" ])
59
+ .map((child) => child.text)
60
+ .join("");
61
+ }
62
+
63
+ // eslint-disable-next-line jsdoc/valid-types
64
+ /** @type import("./markdownlint").Rule */
65
+ module.exports = {
66
+ "names": [ "MD051", "link-fragments" ],
67
+ "description": "Link fragments should be valid",
68
+ "tags": [ "links" ],
69
+ "parser": "micromark",
70
+ "function": function MD051(params, onError) {
71
+ const fragments = new Map();
72
+
73
+ // Process headings
74
+ const headingTexts = filterByTypesCached([ "atxHeadingText", "setextHeadingText" ]);
75
+ for (const headingText of headingTexts) {
76
+ const fragment = convertHeadingToHTMLFragment(headingText);
77
+ if (fragment !== "#") {
78
+ const count = fragments.get(fragment) || 0;
79
+ if (count) {
80
+ fragments.set(`${fragment}-${count}`, 0);
81
+ }
82
+ fragments.set(fragment, count + 1);
83
+ let match = null;
84
+ while ((match = anchorRe.exec(headingText.text)) !== null) {
85
+ const [ , anchor ] = match;
86
+ if (!fragments.has(anchor)) {
87
+ fragments.set(anchor, 1);
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ // Process HTML anchors
94
+ for (const token of filterByTypesCached([ "htmlText" ], true)) {
95
+ const htmlTagInfo = getHtmlTagInfo(token);
96
+ if (htmlTagInfo && !htmlTagInfo.close) {
97
+ const anchorMatch = idRe.exec(token.text) ||
98
+ (htmlTagInfo.name.toLowerCase() === "a" && nameRe.exec(token.text));
99
+ if (anchorMatch && anchorMatch.length > 0) {
100
+ fragments.set(`#${anchorMatch[1]}`, 0);
101
+ }
102
+ }
103
+ }
104
+
105
+ // Process link and definition fragments
106
+ // eslint-disable-next-line jsdoc/valid-types
107
+ /** @type import("../helpers/micromark.cjs").TokenType[][] */
108
+ const parentChilds = [
109
+ [ "link", "resourceDestinationString" ],
110
+ [ "definition", "definitionDestinationString" ]
111
+ ];
112
+ for (const [ parentType, definitionType ] of parentChilds) {
113
+ const links = filterByTypesCached([ parentType ]);
114
+ for (const link of links) {
115
+ const definitions = filterByTypes(link.children, [ definitionType ]);
116
+ for (const definition of definitions) {
117
+ const { endColumn, startColumn } = definition;
118
+ const text = unescapeStringTokenText(definition);
119
+ const encodedText = `#${encodeURIComponent(text.slice(1))}`;
120
+ if (
121
+ (text.length > 1) &&
122
+ text.startsWith("#") &&
123
+ !fragments.has(encodedText) &&
124
+ !lineFragmentRe.test(encodedText)
125
+ ) {
126
+ // eslint-disable-next-line no-undef-init
127
+ let context = undefined;
128
+ // eslint-disable-next-line no-undef-init
129
+ let range = undefined;
130
+ // eslint-disable-next-line no-undef-init
131
+ let fixInfo = undefined;
132
+ if (link.startLine === link.endLine) {
133
+ context = link.text;
134
+ range = [ link.startColumn, link.endColumn - link.startColumn ];
135
+ fixInfo = {
136
+ "editColumn": startColumn,
137
+ "deleteCount": endColumn - startColumn
138
+ };
139
+ }
140
+ const textLower = text.toLowerCase();
141
+ const mixedCaseKey = [ ...fragments.keys() ]
142
+ .find((key) => textLower === key.toLowerCase());
143
+ if (mixedCaseKey) {
144
+ // @ts-ignore
145
+ (fixInfo || {}).insertText = mixedCaseKey;
146
+ addErrorDetailIf(
147
+ onError,
148
+ link.startLine,
149
+ mixedCaseKey,
150
+ text,
151
+ undefined,
152
+ context,
153
+ range,
154
+ fixInfo
155
+ );
156
+ } else {
157
+ addError(
158
+ onError,
159
+ link.startLine,
160
+ undefined,
161
+ context,
162
+ range
163
+ );
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ };
@@ -0,0 +1,42 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addError } = require("../helpers");
6
+ const { getReferenceLinkImageData } = require("./cache");
7
+
8
+ // eslint-disable-next-line jsdoc/valid-types
9
+ /** @type import("./markdownlint").Rule */
10
+ module.exports = {
11
+ "names": [ "MD052", "reference-links-images" ],
12
+ "description":
13
+ "Reference links and images should use a label that is defined",
14
+ "tags": [ "images", "links" ],
15
+ "parser": "none",
16
+ "function": function MD052(params, onError) {
17
+ const { config, lines } = params;
18
+ const shortcutSyntax = config.shortcut_syntax || false;
19
+ const { definitions, references, shortcuts } = getReferenceLinkImageData();
20
+ const entries = shortcutSyntax ?
21
+ [ ...references.entries(), ...shortcuts.entries() ] :
22
+ references.entries();
23
+ // Look for links/images that use an undefined link reference
24
+ for (const reference of entries) {
25
+ const [ label, datas ] = reference;
26
+ if (!definitions.has(label)) {
27
+ for (const data of datas) {
28
+ const [ lineIndex, index, length ] = data;
29
+ // Context will be incomplete if reporting for a multi-line link
30
+ const context = lines[lineIndex].slice(index, index + length);
31
+ addError(
32
+ onError,
33
+ lineIndex + 1,
34
+ `Missing link or image reference definition: "${label}"`,
35
+ context,
36
+ [ index + 1, context.length ]
37
+ );
38
+ }
39
+ }
40
+ }
41
+ }
42
+ };
@@ -0,0 +1,62 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addError, ellipsify, linkReferenceDefinitionRe } =
6
+ require("../helpers");
7
+ const { getReferenceLinkImageData } = require("./cache");
8
+
9
+ // eslint-disable-next-line jsdoc/valid-types
10
+ /** @type import("./markdownlint").Rule */
11
+ module.exports = {
12
+ "names": [ "MD053", "link-image-reference-definitions" ],
13
+ "description": "Link and image reference definitions should be needed",
14
+ "tags": [ "images", "links" ],
15
+ "parser": "none",
16
+ "function": function MD053(params, onError) {
17
+ const ignored = new Set(params.config.ignored_definitions || [ "//" ]);
18
+ const lines = params.lines;
19
+ const { references, shortcuts, definitions, duplicateDefinitions } =
20
+ getReferenceLinkImageData();
21
+ const singleLineDefinition = (line) => (
22
+ line.replace(linkReferenceDefinitionRe, "").trim().length > 0
23
+ );
24
+ const deleteFixInfo = {
25
+ "deleteCount": -1
26
+ };
27
+ // Look for unused link references (unreferenced by any link/image)
28
+ for (const definition of definitions.entries()) {
29
+ const [ label, [ lineIndex ] ] = definition;
30
+ if (
31
+ !ignored.has(label) &&
32
+ !references.has(label) &&
33
+ !shortcuts.has(label)
34
+ ) {
35
+ const line = lines[lineIndex];
36
+ addError(
37
+ onError,
38
+ lineIndex + 1,
39
+ `Unused link or image reference definition: "${label}"`,
40
+ ellipsify(line),
41
+ [ 1, line.length ],
42
+ singleLineDefinition(line) ? deleteFixInfo : 0
43
+ );
44
+ }
45
+ }
46
+ // Look for duplicate link references (defined more than once)
47
+ for (const duplicateDefinition of duplicateDefinitions) {
48
+ const [ label, lineIndex ] = duplicateDefinition;
49
+ if (!ignored.has(label)) {
50
+ const line = lines[lineIndex];
51
+ addError(
52
+ onError,
53
+ lineIndex + 1,
54
+ `Duplicate link or image reference definition: "${label}"`,
55
+ ellipsify(line),
56
+ [ 1, line.length ],
57
+ singleLineDefinition(line) ? deleteFixInfo : 0
58
+ );
59
+ }
60
+ }
61
+ }
62
+ };
@@ -0,0 +1,125 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContext, nextLinesRe } = require("../helpers");
6
+ const { filterByPredicate, getTokenTextByType } = require("../helpers/micromark.cjs");
7
+ const { getReferenceLinkImageData, filterByTypesCached } = require("./cache");
8
+
9
+ const backslashEscapeRe = /\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g;
10
+ const removeBackslashEscapes = (text) => text.replace(backslashEscapeRe, "$1");
11
+ const autolinkDisallowedRe = /[ <>]/;
12
+ const autolinkAble = (destination) => {
13
+ try {
14
+ // eslint-disable-next-line no-new
15
+ new URL(destination);
16
+ } catch {
17
+ // Not an absolute URL
18
+ return false;
19
+ }
20
+ return !autolinkDisallowedRe.test(destination);
21
+ };
22
+
23
+ // eslint-disable-next-line jsdoc/valid-types
24
+ /** @type import("./markdownlint").Rule */
25
+ module.exports = {
26
+ "names": [ "MD054", "link-image-style" ],
27
+ "description": "Link and image style",
28
+ "tags": [ "images", "links" ],
29
+ "parser": "micromark",
30
+ "function": (params, onError) => {
31
+ const config = params.config;
32
+ const autolink = (config.autolink === undefined) || !!config.autolink;
33
+ const inline = (config.inline === undefined) || !!config.inline;
34
+ const full = (config.full === undefined) || !!config.full;
35
+ const collapsed = (config.collapsed === undefined) || !!config.collapsed;
36
+ const shortcut = (config.shortcut === undefined) || !!config.shortcut;
37
+ const urlInline = (config.url_inline === undefined) || !!config.url_inline;
38
+ if (autolink && inline && full && collapsed && shortcut && urlInline) {
39
+ // Everything allowed, nothing to check
40
+ return;
41
+ }
42
+ const { definitions } = getReferenceLinkImageData();
43
+ const links = filterByTypesCached([ "autolink", "image", "link" ]);
44
+ for (const link of links) {
45
+ let label = null;
46
+ let destination = null;
47
+ const {
48
+ children, endColumn, endLine, startColumn, startLine, text, type
49
+ } = link;
50
+ const image = (type === "image");
51
+ let isError = false;
52
+ if (type === "autolink") {
53
+ // link kind is an autolink
54
+ destination = getTokenTextByType(children, "autolinkProtocol");
55
+ label = destination;
56
+ isError = !autolink;
57
+ } else {
58
+ // link type is "image" or "link"
59
+ const descendents = filterByPredicate(children);
60
+ label = getTokenTextByType(descendents, "labelText");
61
+ destination =
62
+ getTokenTextByType(descendents, "resourceDestinationString");
63
+ if (destination) {
64
+ // link kind is an inline link
65
+ const title = getTokenTextByType(descendents, "resourceTitleString");
66
+ isError = !inline || (
67
+ !urlInline &&
68
+ autolink &&
69
+ !image &&
70
+ !title &&
71
+ (label === destination) &&
72
+ autolinkAble(destination)
73
+ );
74
+ } else {
75
+ // link kind is a full/collapsed/shortcut reference link
76
+ const isShortcut = !children.some((t) => t.type === "reference");
77
+ const referenceString = getTokenTextByType(descendents, "referenceString");
78
+ const isCollapsed = (referenceString === null);
79
+ const definition = definitions.get(referenceString || label);
80
+ destination = definition && definition[1];
81
+ isError = destination &&
82
+ (isShortcut ? !shortcut : (isCollapsed ? !collapsed : !full));
83
+ }
84
+ }
85
+ if (isError) {
86
+ // eslint-disable-next-line no-undef-init
87
+ let range = undefined;
88
+ let fixInfo = null;
89
+ if (startLine === endLine) {
90
+ range = [ startColumn, endColumn - startColumn ];
91
+ let insertText = null;
92
+ const canInline = (inline && label);
93
+ const canAutolink = (autolink && !image && autolinkAble(destination));
94
+ if (canInline && (urlInline || !canAutolink)) {
95
+ // Most useful form
96
+ const prefix = (image ? "!" : "");
97
+ // @ts-ignore
98
+ const escapedLabel = label.replace(/[[\]]/g, "\\$&");
99
+ const escapedDestination = destination.replace(/[()]/g, "\\$&");
100
+ insertText = `${prefix}[${escapedLabel}](${escapedDestination})`;
101
+ } else if (canAutolink) {
102
+ // Simplest form
103
+ insertText = `<${removeBackslashEscapes(destination)}>`;
104
+ }
105
+ if (insertText) {
106
+ fixInfo = {
107
+ "editColumn": range[0],
108
+ insertText,
109
+ "deleteCount": range[1]
110
+ };
111
+ }
112
+ }
113
+ addErrorContext(
114
+ onError,
115
+ startLine,
116
+ text.replace(nextLinesRe, ""),
117
+ undefined,
118
+ undefined,
119
+ range,
120
+ fixInfo
121
+ );
122
+ }
123
+ }
124
+ }
125
+ };
@@ -0,0 +1,79 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes } = require("../helpers/micromark.cjs");
7
+ const { filterByTypesCached } = require("./cache");
8
+
9
+ const whitespaceTypes = new Set([ "linePrefix", "whitespace" ]);
10
+ const ignoreWhitespace = (tokens) => tokens.filter(
11
+ (token) => !whitespaceTypes.has(token.type)
12
+ );
13
+ const firstOrNothing = (items) => items[0];
14
+ const lastOrNothing = (items) => items[items.length - 1];
15
+ const makeRange = (start, end) => [ start, end - start + 1 ];
16
+
17
+ // eslint-disable-next-line jsdoc/valid-types
18
+ /** @type import("./markdownlint").Rule */
19
+ module.exports = {
20
+ "names": [ "MD055", "table-pipe-style" ],
21
+ "description": "Table pipe style",
22
+ "tags": [ "table" ],
23
+ "parser": "micromark",
24
+ "function": function MD055(params, onError) {
25
+ const style = String(params.config.style || "consistent");
26
+ let expectedStyle = style;
27
+ let expectedLeadingPipe =
28
+ ((expectedStyle !== "no_leading_or_trailing") && (expectedStyle !== "trailing_only"));
29
+ let expectedTrailingPipe =
30
+ ((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
+ }
76
+ }
77
+ }
78
+ }
79
+ };
@@ -0,0 +1,56 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorDetailIf } = require("../helpers");
6
+ const { filterByTypes } = require("../helpers/micromark.cjs");
7
+ const { filterByTypesCached } = require("./cache");
8
+
9
+ const makeRange = (start, end) => [ start, end - start + 1 ];
10
+
11
+ // eslint-disable-next-line jsdoc/valid-types
12
+ /** @type import("./markdownlint").Rule */
13
+ module.exports = {
14
+ "names": [ "MD056", "table-column-count" ],
15
+ "description": "Table column count",
16
+ "tags": [ "table" ],
17
+ "parser": "micromark",
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
+ );
53
+ }
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,43 @@
1
+ // @ts-check
2
+
3
+ "use strict";
4
+
5
+ const { addErrorContextForLine, isBlankLine } = require("../helpers");
6
+ const { filterByTypesCached } = require("./cache");
7
+
8
+ // eslint-disable-next-line jsdoc/valid-types
9
+ /** @type import("./markdownlint").Rule */
10
+ module.exports = {
11
+ "names": [ "MD058", "blanks-around-tables" ],
12
+ "description": "Tables should be surrounded by blank lines",
13
+ "tags": [ "table" ],
14
+ "parser": "micromark",
15
+ "function": function MD058(params, onError) {
16
+ const { lines } = params;
17
+ // For every table...
18
+ const tables = filterByTypesCached([ "table" ]);
19
+ for (const table of tables) {
20
+ // Look for a blank line above the table
21
+ const firstIndex = table.startLine - 1;
22
+ if (!isBlankLine(lines[firstIndex - 1])) {
23
+ addErrorContextForLine(
24
+ onError,
25
+ // @ts-ignore
26
+ lines,
27
+ firstIndex
28
+ );
29
+ }
30
+ // Look for a blank line below the table
31
+ const lastIndex = table.endLine - 1;
32
+ if (!isBlankLine(lines[lastIndex + 1])) {
33
+ addErrorContextForLine(
34
+ onError,
35
+ // @ts-ignore
36
+ lines,
37
+ lastIndex,
38
+ lastIndex + 2
39
+ );
40
+ }
41
+ }
42
+ }
43
+ };