@dougis/markdown-lint-mcp 1.0.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 (246) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/CONTRIBUTING.md +474 -0
  3. package/LICENSE +21 -0
  4. package/README.md +240 -0
  5. package/USAGE.md +40 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +39 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/rules/index.d.ts +22 -0
  11. package/dist/rules/index.d.ts.map +1 -0
  12. package/dist/rules/index.js +144 -0
  13. package/dist/rules/index.js.map +1 -0
  14. package/dist/rules/md001.d.ts +25 -0
  15. package/dist/rules/md001.d.ts.map +1 -0
  16. package/dist/rules/md001.js +79 -0
  17. package/dist/rules/md001.js.map +1 -0
  18. package/dist/rules/md003.d.ts +41 -0
  19. package/dist/rules/md003.d.ts.map +1 -0
  20. package/dist/rules/md003.js +130 -0
  21. package/dist/rules/md003.js.map +1 -0
  22. package/dist/rules/md004.d.ts +28 -0
  23. package/dist/rules/md004.d.ts.map +1 -0
  24. package/dist/rules/md004.js +79 -0
  25. package/dist/rules/md004.js.map +1 -0
  26. package/dist/rules/md005.d.ts +21 -0
  27. package/dist/rules/md005.d.ts.map +1 -0
  28. package/dist/rules/md005.js +88 -0
  29. package/dist/rules/md005.js.map +1 -0
  30. package/dist/rules/md007.d.ts +21 -0
  31. package/dist/rules/md007.d.ts.map +1 -0
  32. package/dist/rules/md007.js +66 -0
  33. package/dist/rules/md007.js.map +1 -0
  34. package/dist/rules/md009.d.ts +35 -0
  35. package/dist/rules/md009.d.ts.map +1 -0
  36. package/dist/rules/md009.js +122 -0
  37. package/dist/rules/md009.js.map +1 -0
  38. package/dist/rules/md010.d.ts +34 -0
  39. package/dist/rules/md010.d.ts.map +1 -0
  40. package/dist/rules/md010.js +75 -0
  41. package/dist/rules/md010.js.map +1 -0
  42. package/dist/rules/md011.d.ts +30 -0
  43. package/dist/rules/md011.d.ts.map +1 -0
  44. package/dist/rules/md011.js +123 -0
  45. package/dist/rules/md011.js.map +1 -0
  46. package/dist/rules/md012.d.ts +33 -0
  47. package/dist/rules/md012.d.ts.map +1 -0
  48. package/dist/rules/md012.js +125 -0
  49. package/dist/rules/md012.js.map +1 -0
  50. package/dist/rules/md013.d.ts +26 -0
  51. package/dist/rules/md013.d.ts.map +1 -0
  52. package/dist/rules/md013.js +32 -0
  53. package/dist/rules/md013.js.map +1 -0
  54. package/dist/rules/md014.d.ts +29 -0
  55. package/dist/rules/md014.d.ts.map +1 -0
  56. package/dist/rules/md014.js +176 -0
  57. package/dist/rules/md014.js.map +1 -0
  58. package/dist/rules/md018.d.ts +22 -0
  59. package/dist/rules/md018.d.ts.map +1 -0
  60. package/dist/rules/md018.js +27 -0
  61. package/dist/rules/md018.js.map +1 -0
  62. package/dist/rules/md019.d.ts +22 -0
  63. package/dist/rules/md019.d.ts.map +1 -0
  64. package/dist/rules/md019.js +27 -0
  65. package/dist/rules/md019.js.map +1 -0
  66. package/dist/rules/md020.d.ts +22 -0
  67. package/dist/rules/md020.d.ts.map +1 -0
  68. package/dist/rules/md020.js +27 -0
  69. package/dist/rules/md020.js.map +1 -0
  70. package/dist/rules/md021.d.ts +22 -0
  71. package/dist/rules/md021.d.ts.map +1 -0
  72. package/dist/rules/md021.js +27 -0
  73. package/dist/rules/md021.js.map +1 -0
  74. package/dist/rules/md022.d.ts +21 -0
  75. package/dist/rules/md022.d.ts.map +1 -0
  76. package/dist/rules/md022.js +43 -0
  77. package/dist/rules/md022.js.map +1 -0
  78. package/dist/rules/md023.d.ts +21 -0
  79. package/dist/rules/md023.d.ts.map +1 -0
  80. package/dist/rules/md023.js +34 -0
  81. package/dist/rules/md023.js.map +1 -0
  82. package/dist/rules/md024.d.ts +30 -0
  83. package/dist/rules/md024.d.ts.map +1 -0
  84. package/dist/rules/md024.js +123 -0
  85. package/dist/rules/md024.js.map +1 -0
  86. package/dist/rules/md025.d.ts +34 -0
  87. package/dist/rules/md025.d.ts.map +1 -0
  88. package/dist/rules/md025.js +134 -0
  89. package/dist/rules/md025.js.map +1 -0
  90. package/dist/rules/md026.d.ts +21 -0
  91. package/dist/rules/md026.d.ts.map +1 -0
  92. package/dist/rules/md026.js +31 -0
  93. package/dist/rules/md026.js.map +1 -0
  94. package/dist/rules/md027.d.ts +22 -0
  95. package/dist/rules/md027.d.ts.map +1 -0
  96. package/dist/rules/md027.js +27 -0
  97. package/dist/rules/md027.js.map +1 -0
  98. package/dist/rules/md028.d.ts +37 -0
  99. package/dist/rules/md028.d.ts.map +1 -0
  100. package/dist/rules/md028.js +84 -0
  101. package/dist/rules/md028.js.map +1 -0
  102. package/dist/rules/md029.d.ts +30 -0
  103. package/dist/rules/md029.d.ts.map +1 -0
  104. package/dist/rules/md029.js +36 -0
  105. package/dist/rules/md029.js.map +1 -0
  106. package/dist/rules/md030.d.ts +28 -0
  107. package/dist/rules/md030.d.ts.map +1 -0
  108. package/dist/rules/md030.js +76 -0
  109. package/dist/rules/md030.js.map +1 -0
  110. package/dist/rules/md031.d.ts +22 -0
  111. package/dist/rules/md031.d.ts.map +1 -0
  112. package/dist/rules/md031.js +55 -0
  113. package/dist/rules/md031.js.map +1 -0
  114. package/dist/rules/md032.d.ts +21 -0
  115. package/dist/rules/md032.d.ts.map +1 -0
  116. package/dist/rules/md032.js +69 -0
  117. package/dist/rules/md032.js.map +1 -0
  118. package/dist/rules/md033.d.ts +28 -0
  119. package/dist/rules/md033.d.ts.map +1 -0
  120. package/dist/rules/md033.js +34 -0
  121. package/dist/rules/md033.js.map +1 -0
  122. package/dist/rules/md034.d.ts +28 -0
  123. package/dist/rules/md034.d.ts.map +1 -0
  124. package/dist/rules/md034.js +100 -0
  125. package/dist/rules/md034.js.map +1 -0
  126. package/dist/rules/md035.d.ts +23 -0
  127. package/dist/rules/md035.d.ts.map +1 -0
  128. package/dist/rules/md035.js +52 -0
  129. package/dist/rules/md035.js.map +1 -0
  130. package/dist/rules/md036.d.ts +34 -0
  131. package/dist/rules/md036.d.ts.map +1 -0
  132. package/dist/rules/md036.js +112 -0
  133. package/dist/rules/md036.js.map +1 -0
  134. package/dist/rules/md037.d.ts +28 -0
  135. package/dist/rules/md037.d.ts.map +1 -0
  136. package/dist/rules/md037.js +122 -0
  137. package/dist/rules/md037.js.map +1 -0
  138. package/dist/rules/md038.d.ts +28 -0
  139. package/dist/rules/md038.d.ts.map +1 -0
  140. package/dist/rules/md038.js +62 -0
  141. package/dist/rules/md038.js.map +1 -0
  142. package/dist/rules/md039.d.ts +21 -0
  143. package/dist/rules/md039.d.ts.map +1 -0
  144. package/dist/rules/md039.js +34 -0
  145. package/dist/rules/md039.js.map +1 -0
  146. package/dist/rules/md040.d.ts +21 -0
  147. package/dist/rules/md040.d.ts.map +1 -0
  148. package/dist/rules/md040.js +46 -0
  149. package/dist/rules/md040.js.map +1 -0
  150. package/dist/rules/md041.d.ts +33 -0
  151. package/dist/rules/md041.d.ts.map +1 -0
  152. package/dist/rules/md041.js +92 -0
  153. package/dist/rules/md041.js.map +1 -0
  154. package/dist/rules/md042.d.ts +22 -0
  155. package/dist/rules/md042.d.ts.map +1 -0
  156. package/dist/rules/md042.js +50 -0
  157. package/dist/rules/md042.js.map +1 -0
  158. package/dist/rules/md043.d.ts +39 -0
  159. package/dist/rules/md043.d.ts.map +1 -0
  160. package/dist/rules/md043.js +116 -0
  161. package/dist/rules/md043.js.map +1 -0
  162. package/dist/rules/md044.d.ts +40 -0
  163. package/dist/rules/md044.d.ts.map +1 -0
  164. package/dist/rules/md044.js +167 -0
  165. package/dist/rules/md044.js.map +1 -0
  166. package/dist/rules/md045.d.ts +22 -0
  167. package/dist/rules/md045.d.ts.map +1 -0
  168. package/dist/rules/md045.js +57 -0
  169. package/dist/rules/md045.js.map +1 -0
  170. package/dist/rules/md046.d.ts +23 -0
  171. package/dist/rules/md046.d.ts.map +1 -0
  172. package/dist/rules/md046.js +174 -0
  173. package/dist/rules/md046.js.map +1 -0
  174. package/dist/rules/md047.d.ts +22 -0
  175. package/dist/rules/md047.d.ts.map +1 -0
  176. package/dist/rules/md047.js +35 -0
  177. package/dist/rules/md047.js.map +1 -0
  178. package/dist/rules/md048.d.ts +22 -0
  179. package/dist/rules/md048.d.ts.map +1 -0
  180. package/dist/rules/md048.js +80 -0
  181. package/dist/rules/md048.js.map +1 -0
  182. package/dist/rules/md049.d.ts +33 -0
  183. package/dist/rules/md049.d.ts.map +1 -0
  184. package/dist/rules/md049.js +189 -0
  185. package/dist/rules/md049.js.map +1 -0
  186. package/dist/rules/md050.d.ts +22 -0
  187. package/dist/rules/md050.d.ts.map +1 -0
  188. package/dist/rules/md050.js +32 -0
  189. package/dist/rules/md050.js.map +1 -0
  190. package/dist/rules/md051.d.ts +23 -0
  191. package/dist/rules/md051.d.ts.map +1 -0
  192. package/dist/rules/md051.js +63 -0
  193. package/dist/rules/md051.js.map +1 -0
  194. package/dist/rules/md052.d.ts +21 -0
  195. package/dist/rules/md052.d.ts.map +1 -0
  196. package/dist/rules/md052.js +71 -0
  197. package/dist/rules/md052.js.map +1 -0
  198. package/dist/rules/md053.d.ts +21 -0
  199. package/dist/rules/md053.d.ts.map +1 -0
  200. package/dist/rules/md053.js +95 -0
  201. package/dist/rules/md053.js.map +1 -0
  202. package/dist/rules/md054.d.ts +21 -0
  203. package/dist/rules/md054.d.ts.map +1 -0
  204. package/dist/rules/md054.js +87 -0
  205. package/dist/rules/md054.js.map +1 -0
  206. package/dist/rules/md055.d.ts +22 -0
  207. package/dist/rules/md055.d.ts.map +1 -0
  208. package/dist/rules/md055.js +157 -0
  209. package/dist/rules/md055.js.map +1 -0
  210. package/dist/rules/md056.d.ts +21 -0
  211. package/dist/rules/md056.d.ts.map +1 -0
  212. package/dist/rules/md056.js +154 -0
  213. package/dist/rules/md056.js.map +1 -0
  214. package/dist/rules/md058.d.ts +27 -0
  215. package/dist/rules/md058.d.ts.map +1 -0
  216. package/dist/rules/md058.js +71 -0
  217. package/dist/rules/md058.js.map +1 -0
  218. package/dist/rules/md059.d.ts +22 -0
  219. package/dist/rules/md059.d.ts.map +1 -0
  220. package/dist/rules/md059.js +161 -0
  221. package/dist/rules/md059.js.map +1 -0
  222. package/dist/rules/rule-interface.d.ts +51 -0
  223. package/dist/rules/rule-interface.d.ts.map +1 -0
  224. package/dist/rules/rule-interface.js +2 -0
  225. package/dist/rules/rule-interface.js.map +1 -0
  226. package/dist/server.d.ts +59 -0
  227. package/dist/server.d.ts.map +1 -0
  228. package/dist/server.js +419 -0
  229. package/dist/server.js.map +1 -0
  230. package/dist/types.d.ts +74 -0
  231. package/dist/types.d.ts.map +1 -0
  232. package/dist/types.js +14 -0
  233. package/dist/types.js.map +1 -0
  234. package/dist/utils/file.d.ts +39 -0
  235. package/dist/utils/file.d.ts.map +1 -0
  236. package/dist/utils/file.js +124 -0
  237. package/dist/utils/file.js.map +1 -0
  238. package/dist/utils/logger.d.ts +61 -0
  239. package/dist/utils/logger.d.ts.map +1 -0
  240. package/dist/utils/logger.js +85 -0
  241. package/dist/utils/logger.js.map +1 -0
  242. package/dist/utils/safe-match.d.ts +4 -0
  243. package/dist/utils/safe-match.d.ts.map +1 -0
  244. package/dist/utils/safe-match.js +51 -0
  245. package/dist/utils/safe-match.js.map +1 -0
  246. package/package.json +85 -0
@@ -0,0 +1,174 @@
1
+ /**
2
+ * MD046: Code block style
3
+ *
4
+ * This rule is triggered when code blocks don't use a consistent style
5
+ * throughout a document. Markdown supports two different code block styles:
6
+ * fenced code blocks using ``` or ~~~ delimiters, and indented code blocks
7
+ * using 4 spaces for indentation. This rule ensures a consistent style is used.
8
+ */
9
+ export const name = 'MD046';
10
+ export const description = 'Code block style';
11
+ /**
12
+ * Check if a line starts a fenced code block
13
+ * @param line The line to check
14
+ * @returns True if the line starts a fenced code block
15
+ */
16
+ function isFencedCodeBlockStart(line) {
17
+ return /^```|^~~~/.test(line.trim());
18
+ }
19
+ /**
20
+ * Check if a line ends a fenced code block
21
+ * @param line The line to check
22
+ * @returns True if the line ends a fenced code block
23
+ */
24
+ function isFencedCodeBlockEnd(line) {
25
+ return line.trim() === '```' || line.trim() === '~~~';
26
+ }
27
+ /**
28
+ * Check if a line appears to be part of an indented code block
29
+ * @param line The line to check
30
+ * @returns True if the line looks like an indented code block
31
+ */
32
+ function isIndentedCodeBlockLine(line, previousLineEmpty) {
33
+ // Indented code blocks start with 4 spaces or 1 tab and must be preceded by an empty line
34
+ // unless it's the first line of the file
35
+ return /^( |\t)/.test(line) && (previousLineEmpty || false);
36
+ }
37
+ /**
38
+ * Fix code block style by ensuring a consistent style throughout the document
39
+ * @param lines Array of string lines to fix
40
+ * @returns Fixed lines array with consistent code block style
41
+ */
42
+ export function fix(lines) {
43
+ if (lines.length === 0)
44
+ return lines;
45
+ // Count fenced and indented code blocks to determine the preferred style
46
+ let fencedCount = 0;
47
+ let indentedCount = 0;
48
+ // First pass: count the different types of code blocks
49
+ let inFencedBlock = false;
50
+ let previousLineEmpty = true; // Start assuming the document starts with a blank line (worse case)
51
+ for (let i = 0; i < lines.length; i++) {
52
+ const line = lines[i];
53
+ if (inFencedBlock) {
54
+ if (isFencedCodeBlockEnd(line)) {
55
+ inFencedBlock = false;
56
+ }
57
+ }
58
+ else if (isFencedCodeBlockStart(line)) {
59
+ fencedCount++;
60
+ inFencedBlock = true;
61
+ }
62
+ else if (isIndentedCodeBlockLine(line, previousLineEmpty)) {
63
+ // Potential start of an indented code block
64
+ indentedCount++;
65
+ // Skip ahead to count the entire indented block as one
66
+ while (i + 1 < lines.length &&
67
+ (isIndentedCodeBlockLine(lines[i + 1], false) || lines[i + 1].trim() === '')) {
68
+ i++;
69
+ }
70
+ }
71
+ previousLineEmpty = line.trim() === '';
72
+ }
73
+ // Determine preferred style - default to fenced if equal or no blocks found
74
+ const preferFenced = fencedCount >= indentedCount;
75
+ // Second pass: convert all code blocks to the preferred style
76
+ const result = [];
77
+ inFencedBlock = false;
78
+ previousLineEmpty = true;
79
+ let currentIndentedBlock = [];
80
+ for (let i = 0; i < lines.length; i++) {
81
+ const line = lines[i];
82
+ if (inFencedBlock) {
83
+ // Inside a fenced code block, just add the line
84
+ result.push(line);
85
+ if (isFencedCodeBlockEnd(line)) {
86
+ inFencedBlock = false;
87
+ }
88
+ }
89
+ else if (isFencedCodeBlockStart(line)) {
90
+ // Start of a fenced code block
91
+ if (preferFenced) {
92
+ // Keep the fenced block as is
93
+ result.push(line);
94
+ inFencedBlock = true;
95
+ }
96
+ else {
97
+ // Convert to indented block
98
+ // Add a blank line before the indented block if needed
99
+ if (result.length > 0 && result[result.length - 1].trim() !== '') {
100
+ result.push('');
101
+ }
102
+ // Capture the content of the fenced block
103
+ const content = [];
104
+ let j = i + 1;
105
+ while (j < lines.length && !isFencedCodeBlockEnd(lines[j])) {
106
+ content.push(' ' + lines[j]);
107
+ j++;
108
+ }
109
+ // Add the indented content
110
+ result.push(...content);
111
+ // Add a blank line after the indented block
112
+ if (j + 1 < lines.length && lines[j + 1].trim() !== '') {
113
+ result.push('');
114
+ }
115
+ // Skip to the end of the fenced block
116
+ i = j;
117
+ }
118
+ }
119
+ else if (isIndentedCodeBlockLine(line, previousLineEmpty)) {
120
+ // Start of an indented code block
121
+ currentIndentedBlock = [line];
122
+ // Collect the entire indented block
123
+ let j = i + 1;
124
+ while (j < lines.length &&
125
+ (isIndentedCodeBlockLine(lines[j], false) || lines[j].trim() === '')) {
126
+ if (lines[j].trim() !== '') {
127
+ currentIndentedBlock.push(lines[j]);
128
+ }
129
+ j++;
130
+ }
131
+ if (preferFenced) {
132
+ // Convert to fenced block
133
+ // Add a blank line before the fenced block if needed
134
+ if (result.length > 0 && result[result.length - 1].trim() !== '') {
135
+ result.push('');
136
+ }
137
+ // Add the fenced opening
138
+ result.push('```');
139
+ // Add the content without the indentation
140
+ for (const blockLine of currentIndentedBlock) {
141
+ result.push(blockLine.replace(/^( |\t)/, ''));
142
+ }
143
+ // Add the fenced closing
144
+ result.push('```');
145
+ // Add a blank line after the fenced block if needed
146
+ if (j < lines.length && lines[j].trim() !== '') {
147
+ result.push('');
148
+ }
149
+ }
150
+ else {
151
+ // Keep indented block as is
152
+ result.push(...currentIndentedBlock);
153
+ }
154
+ // Skip to the end of the indented block
155
+ i = j - 1;
156
+ }
157
+ else {
158
+ // Regular line, add as is
159
+ result.push(line);
160
+ }
161
+ previousLineEmpty = line.trim() === '';
162
+ }
163
+ return result;
164
+ }
165
+ /**
166
+ * Rule implementation for MD046
167
+ */
168
+ export const rule = {
169
+ name,
170
+ description,
171
+ fix,
172
+ };
173
+ export default rule;
174
+ //# sourceMappingURL=md046.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md046.js","sourceRoot":"","sources":["../../src/rules/md046.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Rule } from './rule-interface';
2
+ /**
3
+ * MD047: Files should end with a single newline character
4
+ *
5
+ * This rule is triggered when there is no newline character at the end of a file.
6
+ * The POSIX standard requires every text file to end with a newline character,
7
+ * and many tools and editors will automatically add one if it's missing.
8
+ */
9
+ export declare const name = "MD047";
10
+ export declare const description = "Files should end with a single newline character";
11
+ /**
12
+ * Fix files by ensuring they end with exactly one newline character
13
+ * @param lines Array of string lines to fix
14
+ * @returns Fixed lines array with a single newline at the end
15
+ */
16
+ export declare function fix(lines: string[]): string[];
17
+ /**
18
+ * Rule implementation for MD047
19
+ */
20
+ export declare const rule: Rule;
21
+ export default rule;
22
+ //# sourceMappingURL=md047.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md047.d.ts","sourceRoot":"","sources":["../../src/rules/md047.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,qDAAqD,CAAC;AAE9E;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAa7C;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * MD047: Files should end with a single newline character
3
+ *
4
+ * This rule is triggered when there is no newline character at the end of a file.
5
+ * The POSIX standard requires every text file to end with a newline character,
6
+ * and many tools and editors will automatically add one if it's missing.
7
+ */
8
+ export const name = 'MD047';
9
+ export const description = 'Files should end with a single newline character';
10
+ /**
11
+ * Fix files by ensuring they end with exactly one newline character
12
+ * @param lines Array of string lines to fix
13
+ * @returns Fixed lines array with a single newline at the end
14
+ */
15
+ export function fix(lines) {
16
+ // Create a copy of the lines array to avoid modifying the original
17
+ const result = [...lines];
18
+ // Remove any trailing empty lines
19
+ while (result.length > 0 && result[result.length - 1].trim() === '') {
20
+ result.pop();
21
+ }
22
+ // Add a single empty line at the end
23
+ result.push('');
24
+ return result;
25
+ }
26
+ /**
27
+ * Rule implementation for MD047
28
+ */
29
+ export const rule = {
30
+ name,
31
+ description,
32
+ fix,
33
+ };
34
+ export default rule;
35
+ //# sourceMappingURL=md047.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md047.js","sourceRoot":"","sources":["../../src/rules/md047.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,kDAAkD,CAAC;AAE9E;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,mEAAmE;IACnE,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAE1B,kCAAkC;IAClC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpE,MAAM,CAAC,GAAG,EAAE,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAS;IACxB,IAAI;IACJ,WAAW;IACX,GAAG;CACJ,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { Rule } from './rule-interface';
2
+ /**
3
+ * MD048: Code fence style
4
+ *
5
+ * This rule is triggered when the code fence style in a document is inconsistent.
6
+ * In Markdown, code fences can be created using either backticks (```) or
7
+ * tildes (~~~). This rule ensures that only one style is used throughout the document.
8
+ */
9
+ export declare const name = "MD048";
10
+ export declare const description = "Code fence style";
11
+ /**
12
+ * Fix code fence style by ensuring a consistent style throughout the document
13
+ * @param lines Array of string lines to fix
14
+ * @returns Fixed lines array with consistent code fence style
15
+ */
16
+ export declare function fix(lines: string[]): string[];
17
+ /**
18
+ * Rule implementation for MD048
19
+ */
20
+ export declare const rule: Rule;
21
+ export default rule;
22
+ //# sourceMappingURL=md048.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md048.d.ts","sourceRoot":"","sources":["../../src/rules/md048.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAqB9C;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA+C7C;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * MD048: Code fence style
3
+ *
4
+ * This rule is triggered when the code fence style in a document is inconsistent.
5
+ * In Markdown, code fences can be created using either backticks (```) or
6
+ * tildes (~~~). This rule ensures that only one style is used throughout the document.
7
+ */
8
+ export const name = 'MD048';
9
+ export const description = 'Code fence style';
10
+ /**
11
+ * Check if a line is a code fence (either opening or closing)
12
+ * @param line The line to check
13
+ * @returns True if the line is a code fence
14
+ */
15
+ function isCodeFence(line) {
16
+ return /^(`{3,}|~{3,})/.test(line.trim());
17
+ }
18
+ /**
19
+ * Get the code fence style (backtick or tilde) from a line
20
+ * @param line The line to check
21
+ * @returns The code fence style character, or empty string if not a fence
22
+ */
23
+ function getCodeFenceStyle(line) {
24
+ const match = line.trim().match(/^(`{3,}|~{3,})/);
25
+ return match ? match[1][0] : '';
26
+ }
27
+ /**
28
+ * Fix code fence style by ensuring a consistent style throughout the document
29
+ * @param lines Array of string lines to fix
30
+ * @returns Fixed lines array with consistent code fence style
31
+ */
32
+ export function fix(lines) {
33
+ if (lines.length === 0)
34
+ return lines;
35
+ // Find the first code fence to determine the preferred style
36
+ let preferredStyle = '`'; // Default to backtick if no code fence is found
37
+ for (const line of lines) {
38
+ if (isCodeFence(line)) {
39
+ preferredStyle = getCodeFenceStyle(line);
40
+ break;
41
+ }
42
+ }
43
+ // Now fix all code fences to match the preferred style
44
+ let inCodeBlock = false;
45
+ return lines.map(line => {
46
+ if (isCodeFence(line)) {
47
+ const style = getCodeFenceStyle(line);
48
+ if (style !== preferredStyle) {
49
+ // Need to replace the fence character
50
+ const trimmed = line.trim();
51
+ const indentation = line.slice(0, line.indexOf(trimmed));
52
+ // Find how many fence characters we have
53
+ const fenceCount = trimmed.match(/^(`{3,}|~{3,})/)?.[0].length || 3;
54
+ // Get any language specifier if it exists (for opening fences)
55
+ const language = !inCodeBlock ? trimmed.slice(fenceCount).trim() : '';
56
+ // Create the new fence with the preferred style
57
+ const newFence = preferredStyle.repeat(fenceCount);
58
+ // Toggle the inCodeBlock state
59
+ inCodeBlock = !inCodeBlock;
60
+ // Return the updated line
61
+ return `${indentation}${newFence}${language ? ' ' + language : ''}`;
62
+ }
63
+ else {
64
+ // Toggle the inCodeBlock state if the style is already correct
65
+ inCodeBlock = !inCodeBlock;
66
+ }
67
+ }
68
+ return line;
69
+ });
70
+ }
71
+ /**
72
+ * Rule implementation for MD048
73
+ */
74
+ export const rule = {
75
+ name,
76
+ description,
77
+ fix,
78
+ };
79
+ export default rule;
80
+ //# sourceMappingURL=md048.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md048.js","sourceRoot":"","sources":["../../src/rules/md048.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAE9C;;;;GAIG;AACH,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,6DAA6D;IAC7D,IAAI,cAAc,GAAG,GAAG,CAAC,CAAC,gDAAgD;IAE1E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM;QACR,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACtB,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEtC,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;gBAC7B,sCAAsC;gBACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;gBAEzD,yCAAyC;gBACzC,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;gBAEpE,+DAA+D;gBAC/D,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEtE,gDAAgD;gBAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAEnD,+BAA+B;gBAC/B,WAAW,GAAG,CAAC,WAAW,CAAC;gBAE3B,0BAA0B;gBAC1B,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACN,+DAA+D;gBAC/D,WAAW,GAAG,CAAC,WAAW,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAS;IACxB,IAAI;IACJ,WAAW;IACX,GAAG;CACJ,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Rule, RuleViolation } from './rule-interface';
2
+ /**
3
+ * MD049: Emphasis style
4
+ *
5
+ * This rule is triggered when the style used for emphasis (italics)
6
+ * is inconsistent. By default, this rule enforces asterisks (*) for emphasis,
7
+ * but it can be configured to enforce underscores (_) instead.
8
+ */
9
+ export declare const name = "MD049";
10
+ export declare const description = "Emphasis style";
11
+ /**
12
+ * Validate function to check emphasis style consistency
13
+ * @param lines Array of string lines to validate
14
+ * @param config Optional rule configuration
15
+ * @returns Array of rule violations
16
+ */
17
+ interface MD049Config {
18
+ style?: 'asterisk' | 'underscore';
19
+ }
20
+ export declare function validate(lines: string[], _config?: MD049Config): RuleViolation[];
21
+ /**
22
+ * Fix emphasis style by standardizing to the configured style
23
+ * @param lines Array of string lines to fix
24
+ * @param config Optional rule configuration
25
+ * @returns Fixed lines array with consistent emphasis style
26
+ */
27
+ export declare function fix(lines: string[], _config?: MD049Config): string[];
28
+ /**
29
+ * Rule implementation for MD049
30
+ */
31
+ export declare const rule: Rule;
32
+ export default rule;
33
+ //# sourceMappingURL=md049.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md049.d.ts","sourceRoot":"","sources":["../../src/rules/md049.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAuH5C;;;;;GAKG;AACH,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,aAAa,EAAE,CAuChF;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CAuCpE;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAKlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * MD049: Emphasis style
3
+ *
4
+ * This rule is triggered when the style used for emphasis (italics)
5
+ * is inconsistent. By default, this rule enforces asterisks (*) for emphasis,
6
+ * but it can be configured to enforce underscores (_) instead.
7
+ */
8
+ export const name = 'MD049';
9
+ export const description = 'Emphasis style';
10
+ /**
11
+ * Check if a line is within a code block (fenced or indented)
12
+ * @param lines Array of all lines
13
+ * @param lineIndex Index of the line to check
14
+ * @returns True if the line is within a code block
15
+ */
16
+ function isInCodeBlock(lines, lineIndex) {
17
+ let inFencedBlock = false;
18
+ let fenceChar = '';
19
+ // Check if current line is indented code block (4+ spaces)
20
+ const currentLine = lines[lineIndex];
21
+ if (currentLine.match(/^ /)) {
22
+ return true;
23
+ }
24
+ // Check lines before current line for fenced code blocks
25
+ for (let i = 0; i < lineIndex; i++) {
26
+ const line = lines[i].trim();
27
+ // Check for fenced code block start/end
28
+ const backtickMatch = line.match(/^`{3,}/);
29
+ const tildeMatch = line.match(/^~{3,}/);
30
+ if (backtickMatch || tildeMatch) {
31
+ const currentFence = backtickMatch ? '`' : '~';
32
+ if (!inFencedBlock) {
33
+ // Starting a fenced block
34
+ inFencedBlock = true;
35
+ fenceChar = currentFence;
36
+ }
37
+ else if (fenceChar === currentFence) {
38
+ // Ending a fenced block
39
+ inFencedBlock = false;
40
+ fenceChar = '';
41
+ }
42
+ }
43
+ }
44
+ return inFencedBlock;
45
+ }
46
+ /**
47
+ * Find emphasis markers in a line, avoiding code spans
48
+ * @param line Line to search
49
+ * @returns Array of emphasis markers found
50
+ */
51
+ function findEmphasisMarkers(line) {
52
+ const markers = [];
53
+ let i = 0;
54
+ while (i < line.length) {
55
+ const char = line[i];
56
+ // Skip code spans
57
+ if (char === '`') {
58
+ i++;
59
+ while (i < line.length && line[i] !== '`') {
60
+ i++;
61
+ }
62
+ if (i < line.length) {
63
+ i++; // Skip closing backtick
64
+ }
65
+ continue;
66
+ }
67
+ // Look for emphasis markers
68
+ if (char === '*' || char === '_') {
69
+ const markerChar = char;
70
+ const markerStart = i;
71
+ // Skip if it's part of bold (**text** or __text__)
72
+ if (i + 1 < line.length && line[i + 1] === markerChar) {
73
+ i += 2;
74
+ continue;
75
+ }
76
+ // Look for closing marker
77
+ i++;
78
+ const textStart = i;
79
+ while (i < line.length && line[i] !== markerChar) {
80
+ i++;
81
+ }
82
+ if (i < line.length && i > textStart) {
83
+ // Found a complete emphasis
84
+ const text = line.substring(textStart, i);
85
+ // Skip if emphasis has spaces at the beginning or end (not valid emphasis)
86
+ if (text.startsWith(' ') || text.endsWith(' ')) {
87
+ i++; // Skip closing marker
88
+ continue;
89
+ }
90
+ markers.push({
91
+ type: markerChar === '*' ? 'asterisk' : 'underscore',
92
+ start: markerStart,
93
+ end: i + 1,
94
+ text,
95
+ });
96
+ i++; // Skip closing marker
97
+ }
98
+ }
99
+ else {
100
+ i++;
101
+ }
102
+ }
103
+ return markers;
104
+ }
105
+ export function validate(lines, _config) {
106
+ const violations = [];
107
+ const style = _config?.style || 'asterisk'; // Default to asterisk
108
+ // Track what styles we've seen
109
+ const stylesFound = new Set();
110
+ for (let i = 0; i < lines.length; i++) {
111
+ const line = lines[i];
112
+ // Skip code blocks
113
+ if (isInCodeBlock(lines, i)) {
114
+ continue;
115
+ }
116
+ // Find emphasis markers in this line
117
+ const markers = findEmphasisMarkers(line);
118
+ for (const marker of markers) {
119
+ stylesFound.add(marker.type);
120
+ // Check if this marker matches the configured style
121
+ if (style === 'asterisk' && marker.type === 'underscore') {
122
+ violations.push({
123
+ lineNumber: i + 1,
124
+ details: `Emphasis style should be asterisk (*) not underscore (_)`,
125
+ range: [marker.start, marker.end],
126
+ });
127
+ }
128
+ else if (style === 'underscore' && marker.type === 'asterisk') {
129
+ violations.push({
130
+ lineNumber: i + 1,
131
+ details: `Emphasis style should be underscore (_) not asterisk (*)`,
132
+ range: [marker.start, marker.end],
133
+ });
134
+ }
135
+ }
136
+ }
137
+ return violations;
138
+ }
139
+ /**
140
+ * Fix emphasis style by standardizing to the configured style
141
+ * @param lines Array of string lines to fix
142
+ * @param config Optional rule configuration
143
+ * @returns Fixed lines array with consistent emphasis style
144
+ */
145
+ export function fix(lines, _config) {
146
+ const style = _config?.style || 'asterisk'; // Default to asterisk
147
+ return lines.map((line, index) => {
148
+ // Skip code blocks
149
+ if (isInCodeBlock(lines, index)) {
150
+ return line;
151
+ }
152
+ // Find emphasis markers that need to be fixed
153
+ const markers = findEmphasisMarkers(line);
154
+ let fixedLine = line;
155
+ // Process markers from right to left to avoid index shifting issues
156
+ for (let i = markers.length - 1; i >= 0; i--) {
157
+ const marker = markers[i];
158
+ // Check if this marker needs to be fixed
159
+ let shouldFix = false;
160
+ let newMarker = '';
161
+ if (style === 'asterisk' && marker.type === 'underscore') {
162
+ shouldFix = true;
163
+ newMarker = '*';
164
+ }
165
+ else if (style === 'underscore' && marker.type === 'asterisk') {
166
+ shouldFix = true;
167
+ newMarker = '_';
168
+ }
169
+ if (shouldFix) {
170
+ // Replace the emphasis markers
171
+ const beforePart = fixedLine.substring(0, marker.start);
172
+ const afterPart = fixedLine.substring(marker.end);
173
+ fixedLine = beforePart + newMarker + marker.text + newMarker + afterPart;
174
+ }
175
+ }
176
+ return fixedLine;
177
+ });
178
+ }
179
+ /**
180
+ * Rule implementation for MD049
181
+ */
182
+ export const rule = {
183
+ name,
184
+ description,
185
+ validate,
186
+ fix,
187
+ };
188
+ export default rule;
189
+ //# sourceMappingURL=md049.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md049.js","sourceRoot":"","sources":["../../src/rules/md049.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Rule } from './rule-interface';
2
+ /**
3
+ * MD050: Strong style
4
+ *
5
+ * This rule is triggered when the style used for strong emphasis (bold)
6
+ * is inconsistent. By default, this rule enforces double asterisks (**) for strong emphasis,
7
+ * but it can be configured to enforce double underscores (__) instead.
8
+ */
9
+ export declare const name = "MD050";
10
+ export declare const description = "Strong style";
11
+ /**
12
+ * Fix strong style by standardizing to double asterisks
13
+ * @param lines Array of string lines to fix
14
+ * @returns Fixed lines array with consistent strong style
15
+ */
16
+ export declare function fix(lines: string[]): string[];
17
+ /**
18
+ * Rule implementation for MD050
19
+ */
20
+ export declare const rule: Rule;
21
+ export default rule;
22
+ //# sourceMappingURL=md050.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md050.d.ts","sourceRoot":"","sources":["../../src/rules/md050.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ7C;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * MD050: Strong style
3
+ *
4
+ * This rule is triggered when the style used for strong emphasis (bold)
5
+ * is inconsistent. By default, this rule enforces double asterisks (**) for strong emphasis,
6
+ * but it can be configured to enforce double underscores (__) instead.
7
+ */
8
+ export const name = 'MD050';
9
+ export const description = 'Strong style';
10
+ /**
11
+ * Fix strong style by standardizing to double asterisks
12
+ * @param lines Array of string lines to fix
13
+ * @returns Fixed lines array with consistent strong style
14
+ */
15
+ export function fix(lines) {
16
+ return lines.map(line => {
17
+ // Convert double underscore strong emphasis to double asterisk
18
+ // Replace __ with ** for strong emphasis
19
+ const fixedLine = line.replace(/__([^_]+?)__/g, '**$1**');
20
+ return fixedLine;
21
+ });
22
+ }
23
+ /**
24
+ * Rule implementation for MD050
25
+ */
26
+ export const rule = {
27
+ name,
28
+ description,
29
+ fix,
30
+ };
31
+ export default rule;
32
+ //# sourceMappingURL=md050.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md050.js","sourceRoot":"","sources":["../../src/rules/md050.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACtB,+DAA+D;QAC/D,yCAAyC;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QAE1D,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAS;IACxB,IAAI;IACJ,WAAW;IACX,GAAG;CACJ,CAAC;AAEF,eAAe,IAAI,CAAC"}