@redocly/recheck 0.1.0 → 0.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 (595) hide show
  1. package/README.md +1023 -56
  2. package/dist/cli.js +40 -7
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/markdoc-schema.d.ts +17 -0
  5. package/dist/commands/markdoc-schema.d.ts.map +1 -0
  6. package/dist/commands/markdoc-schema.js +127 -0
  7. package/dist/commands/markdoc-schema.js.map +1 -0
  8. package/dist/commands/run.d.ts +2 -1
  9. package/dist/commands/run.d.ts.map +1 -1
  10. package/dist/commands/run.js +87 -10
  11. package/dist/commands/run.js.map +1 -1
  12. package/dist/config/load.d.ts +11 -0
  13. package/dist/config/load.d.ts.map +1 -1
  14. package/dist/config/load.js +12 -2
  15. package/dist/config/load.js.map +1 -1
  16. package/dist/config/presets/google.d.ts +3 -0
  17. package/dist/config/presets/google.d.ts.map +1 -0
  18. package/dist/config/presets/google.js +1671 -0
  19. package/dist/config/presets/google.js.map +1 -0
  20. package/dist/config/presets/inclusive-language.d.ts +3 -0
  21. package/dist/config/presets/inclusive-language.d.ts.map +1 -0
  22. package/dist/config/presets/inclusive-language.js +321 -0
  23. package/dist/config/presets/inclusive-language.js.map +1 -0
  24. package/dist/config/presets/index.d.ts +67 -0
  25. package/dist/config/presets/index.d.ts.map +1 -0
  26. package/dist/config/presets/index.js +137 -0
  27. package/dist/config/presets/index.js.map +1 -0
  28. package/dist/config/presets/markdoc.d.ts +21 -0
  29. package/dist/config/presets/markdoc.d.ts.map +1 -0
  30. package/dist/config/presets/markdoc.js +101 -0
  31. package/dist/config/presets/markdoc.js.map +1 -0
  32. package/dist/config/presets/markdown-relaxed.d.ts +3 -0
  33. package/dist/config/presets/markdown-relaxed.d.ts.map +1 -0
  34. package/dist/config/presets/markdown-relaxed.js +98 -0
  35. package/dist/config/presets/markdown-relaxed.js.map +1 -0
  36. package/dist/config/presets/markdown.d.ts +43 -0
  37. package/dist/config/presets/markdown.d.ts.map +1 -0
  38. package/dist/config/presets/markdown.js +132 -0
  39. package/dist/config/presets/markdown.js.map +1 -0
  40. package/dist/config/presets/microsoft.d.ts +3 -0
  41. package/dist/config/presets/microsoft.d.ts.map +1 -0
  42. package/dist/config/presets/microsoft.js +2268 -0
  43. package/dist/config/presets/microsoft.js.map +1 -0
  44. package/dist/config/presets/minimal.d.ts +3 -0
  45. package/dist/config/presets/minimal.d.ts.map +1 -0
  46. package/dist/config/presets/minimal.js +21 -0
  47. package/dist/config/presets/minimal.js.map +1 -0
  48. package/dist/config/presets/plain-language.d.ts +3 -0
  49. package/dist/config/presets/plain-language.d.ts.map +1 -0
  50. package/dist/config/presets/plain-language.js +351 -0
  51. package/dist/config/presets/plain-language.js.map +1 -0
  52. package/dist/config/presets/prose.d.ts +52 -0
  53. package/dist/config/presets/prose.d.ts.map +1 -0
  54. package/dist/config/presets/prose.js +138 -0
  55. package/dist/config/presets/prose.js.map +1 -0
  56. package/dist/config/schema.d.ts +128 -22
  57. package/dist/config/schema.d.ts.map +1 -1
  58. package/dist/config/schema.js +105 -21
  59. package/dist/config/schema.js.map +1 -1
  60. package/dist/config/validate.d.ts +12 -2
  61. package/dist/config/validate.d.ts.map +1 -1
  62. package/dist/config/validate.js +1200 -44
  63. package/dist/config/validate.js.map +1 -1
  64. package/dist/core/auto-fix.d.ts +8 -13
  65. package/dist/core/auto-fix.d.ts.map +1 -1
  66. package/dist/core/auto-fix.js +94 -75
  67. package/dist/core/auto-fix.js.map +1 -1
  68. package/dist/core/case-preserve.d.ts +46 -0
  69. package/dist/core/case-preserve.d.ts.map +1 -0
  70. package/dist/core/case-preserve.js +57 -0
  71. package/dist/core/case-preserve.js.map +1 -0
  72. package/dist/core/directives.d.ts +9 -0
  73. package/dist/core/directives.d.ts.map +1 -0
  74. package/dist/core/directives.js +73 -0
  75. package/dist/core/directives.js.map +1 -0
  76. package/dist/core/files.d.ts +63 -0
  77. package/dist/core/files.d.ts.map +1 -1
  78. package/dist/core/files.js +185 -0
  79. package/dist/core/files.js.map +1 -1
  80. package/dist/core/inline-code.d.ts +87 -0
  81. package/dist/core/inline-code.d.ts.map +1 -0
  82. package/dist/core/inline-code.js +104 -0
  83. package/dist/core/inline-code.js.map +1 -0
  84. package/dist/core/line-endings.d.ts +32 -0
  85. package/dist/core/line-endings.d.ts.map +1 -0
  86. package/dist/core/line-endings.js +65 -0
  87. package/dist/core/line-endings.js.map +1 -0
  88. package/dist/core/markdoc-tags.d.ts +79 -0
  89. package/dist/core/markdoc-tags.d.ts.map +1 -0
  90. package/dist/core/markdoc-tags.js +131 -0
  91. package/dist/core/markdoc-tags.js.map +1 -0
  92. package/dist/core/rule-filters.d.ts +17 -0
  93. package/dist/core/rule-filters.d.ts.map +1 -1
  94. package/dist/core/rule-filters.js +64 -0
  95. package/dist/core/rule-filters.js.map +1 -1
  96. package/dist/core/runner.d.ts +92 -3
  97. package/dist/core/runner.d.ts.map +1 -1
  98. package/dist/core/runner.js +348 -110
  99. package/dist/core/runner.js.map +1 -1
  100. package/dist/core/timing.d.ts.map +1 -1
  101. package/dist/data/markdoc-realm-schema.d.ts +3 -0
  102. package/dist/data/markdoc-realm-schema.d.ts.map +1 -0
  103. package/dist/data/markdoc-realm-schema.js +760 -0
  104. package/dist/data/markdoc-realm-schema.js.map +1 -0
  105. package/dist/data/proper-nouns.d.ts +2 -0
  106. package/dist/data/proper-nouns.d.ts.map +1 -0
  107. package/dist/data/proper-nouns.js +47 -0
  108. package/dist/data/proper-nouns.js.map +1 -0
  109. package/dist/index.d.ts +90 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +152 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/metrics/formulas.d.ts +17 -0
  114. package/dist/metrics/formulas.d.ts.map +1 -0
  115. package/dist/metrics/formulas.js +70 -0
  116. package/dist/metrics/formulas.js.map +1 -0
  117. package/dist/metrics/index.d.ts +5 -0
  118. package/dist/metrics/index.d.ts.map +1 -0
  119. package/dist/metrics/index.js +3 -0
  120. package/dist/metrics/index.js.map +1 -0
  121. package/dist/metrics/statistics.d.ts +27 -0
  122. package/dist/metrics/statistics.d.ts.map +1 -0
  123. package/dist/metrics/statistics.js +56 -0
  124. package/dist/metrics/statistics.js.map +1 -0
  125. package/dist/parser/index.d.ts +18 -0
  126. package/dist/parser/index.d.ts.map +1 -0
  127. package/dist/parser/index.js +168 -0
  128. package/dist/parser/index.js.map +1 -0
  129. package/dist/parser/markdoc/extract-statics.d.ts +45 -0
  130. package/dist/parser/markdoc/extract-statics.d.ts.map +1 -0
  131. package/dist/parser/markdoc/extract-statics.js +139 -0
  132. package/dist/parser/markdoc/extract-statics.js.map +1 -0
  133. package/dist/parser/markdoc/pairing.d.ts +63 -0
  134. package/dist/parser/markdoc/pairing.d.ts.map +1 -0
  135. package/dist/parser/markdoc/pairing.js +94 -0
  136. package/dist/parser/markdoc/pairing.js.map +1 -0
  137. package/dist/parser/markdoc/schema.d.ts +85 -0
  138. package/dist/parser/markdoc/schema.d.ts.map +1 -0
  139. package/dist/parser/markdoc/schema.js +86 -0
  140. package/dist/parser/markdoc/schema.js.map +1 -0
  141. package/dist/parser/markdoc/span.d.ts +64 -0
  142. package/dist/parser/markdoc/span.d.ts.map +1 -0
  143. package/dist/parser/markdoc/span.js +729 -0
  144. package/dist/parser/markdoc/span.js.map +1 -0
  145. package/dist/parser/markdoc/structure.d.ts +28 -0
  146. package/dist/parser/markdoc/structure.d.ts.map +1 -0
  147. package/dist/parser/markdoc/structure.js +153 -0
  148. package/dist/parser/markdoc/structure.js.map +1 -0
  149. package/dist/parser/markdoc/syntax.d.ts +44 -0
  150. package/dist/parser/markdoc/syntax.d.ts.map +1 -0
  151. package/dist/parser/markdoc/syntax.js +317 -0
  152. package/dist/parser/markdoc/syntax.js.map +1 -0
  153. package/dist/parser/types.d.ts +18 -0
  154. package/dist/parser/types.d.ts.map +1 -0
  155. package/dist/parser/types.js.map +1 -0
  156. package/dist/reporter/fixes.d.ts.map +1 -1
  157. package/dist/reporter/fixes.js +22 -1
  158. package/dist/reporter/fixes.js.map +1 -1
  159. package/dist/reporter/statistics.d.ts +1 -8
  160. package/dist/reporter/statistics.d.ts.map +1 -1
  161. package/dist/reporter/statistics.js.map +1 -1
  162. package/dist/rules/registry.d.ts +15 -0
  163. package/dist/rules/registry.d.ts.map +1 -0
  164. package/dist/rules/registry.js +81 -0
  165. package/dist/rules/registry.js.map +1 -0
  166. package/dist/rules/scope/capitalization.d.ts +3 -0
  167. package/dist/rules/scope/capitalization.d.ts.map +1 -0
  168. package/dist/rules/scope/capitalization.js +163 -0
  169. package/dist/rules/scope/capitalization.js.map +1 -0
  170. package/dist/rules/scope/conditional.d.ts +3 -0
  171. package/dist/rules/scope/conditional.d.ts.map +1 -0
  172. package/dist/rules/scope/conditional.js +112 -0
  173. package/dist/rules/scope/conditional.js.map +1 -0
  174. package/dist/rules/scope/consistency.d.ts +3 -0
  175. package/dist/rules/scope/consistency.d.ts.map +1 -0
  176. package/dist/rules/scope/consistency.js +178 -0
  177. package/dist/rules/scope/consistency.js.map +1 -0
  178. package/dist/rules/scope/length.d.ts +3 -0
  179. package/dist/rules/scope/length.d.ts.map +1 -0
  180. package/dist/rules/scope/length.js +69 -0
  181. package/dist/rules/scope/length.js.map +1 -0
  182. package/dist/rules/scope/max-image-size.d.ts +3 -0
  183. package/dist/rules/scope/max-image-size.d.ts.map +1 -0
  184. package/dist/rules/scope/max-image-size.js +65 -0
  185. package/dist/rules/scope/max-image-size.js.map +1 -0
  186. package/dist/rules/scope/metric.d.ts +17 -0
  187. package/dist/rules/scope/metric.d.ts.map +1 -0
  188. package/dist/rules/scope/metric.js +216 -0
  189. package/dist/rules/scope/metric.js.map +1 -0
  190. package/dist/rules/scope/occurrence.d.ts +3 -0
  191. package/dist/rules/scope/occurrence.d.ts.map +1 -0
  192. package/dist/rules/scope/occurrence.js +48 -0
  193. package/dist/rules/scope/occurrence.js.map +1 -0
  194. package/dist/rules/scope/pattern.d.ts +3 -0
  195. package/dist/rules/scope/pattern.d.ts.map +1 -0
  196. package/dist/rules/scope/pattern.js +75 -0
  197. package/dist/rules/scope/pattern.js.map +1 -0
  198. package/dist/rules/scope/repetition.d.ts +3 -0
  199. package/dist/rules/scope/repetition.d.ts.map +1 -0
  200. package/dist/rules/scope/repetition.js +139 -0
  201. package/dist/rules/scope/repetition.js.map +1 -0
  202. package/dist/rules/scope/semantic-line-breaks.d.ts +3 -0
  203. package/dist/rules/scope/semantic-line-breaks.d.ts.map +1 -0
  204. package/dist/rules/scope/semantic-line-breaks.js +213 -0
  205. package/dist/rules/scope/semantic-line-breaks.js.map +1 -0
  206. package/dist/rules/scope/spelling.d.ts +27 -0
  207. package/dist/rules/scope/spelling.d.ts.map +1 -0
  208. package/dist/rules/scope/spelling.js +227 -0
  209. package/dist/rules/scope/spelling.js.map +1 -0
  210. package/dist/rules/scope/swap.d.ts +3 -0
  211. package/dist/rules/scope/swap.d.ts.map +1 -0
  212. package/dist/rules/scope/swap.js +149 -0
  213. package/dist/rules/scope/swap.js.map +1 -0
  214. package/dist/rules/scope/title-case.d.ts +46 -0
  215. package/dist/rules/scope/title-case.d.ts.map +1 -0
  216. package/dist/rules/scope/title-case.js +301 -0
  217. package/dist/rules/scope/title-case.js.map +1 -0
  218. package/dist/rules/token/blanks-around-fences.d.ts +3 -0
  219. package/dist/rules/token/blanks-around-fences.d.ts.map +1 -0
  220. package/dist/rules/token/blanks-around-fences.js +44 -0
  221. package/dist/rules/token/blanks-around-fences.js.map +1 -0
  222. package/dist/rules/token/blanks-around-headings.d.ts +3 -0
  223. package/dist/rules/token/blanks-around-headings.d.ts.map +1 -0
  224. package/dist/rules/token/blanks-around-headings.js +108 -0
  225. package/dist/rules/token/blanks-around-headings.js.map +1 -0
  226. package/dist/rules/token/blanks-around-lists.d.ts +3 -0
  227. package/dist/rules/token/blanks-around-lists.d.ts.map +1 -0
  228. package/dist/rules/token/blanks-around-lists.js +56 -0
  229. package/dist/rules/token/blanks-around-lists.js.map +1 -0
  230. package/dist/rules/token/blanks-around-tables.d.ts +3 -0
  231. package/dist/rules/token/blanks-around-tables.d.ts.map +1 -0
  232. package/dist/rules/token/blanks-around-tables.js +42 -0
  233. package/dist/rules/token/blanks-around-tables.js.map +1 -0
  234. package/dist/rules/token/code-block-style.d.ts +3 -0
  235. package/dist/rules/token/code-block-style.d.ts.map +1 -0
  236. package/dist/rules/token/code-block-style.js +30 -0
  237. package/dist/rules/token/code-block-style.js.map +1 -0
  238. package/dist/rules/token/code-fence-style.d.ts +3 -0
  239. package/dist/rules/token/code-fence-style.d.ts.map +1 -0
  240. package/dist/rules/token/code-fence-style.js +35 -0
  241. package/dist/rules/token/code-fence-style.js.map +1 -0
  242. package/dist/rules/token/commands-show-output.d.ts +3 -0
  243. package/dist/rules/token/commands-show-output.d.ts.map +1 -0
  244. package/dist/rules/token/commands-show-output.js +38 -0
  245. package/dist/rules/token/commands-show-output.js.map +1 -0
  246. package/dist/rules/token/descriptive-link-text.d.ts +3 -0
  247. package/dist/rules/token/descriptive-link-text.d.ts.map +1 -0
  248. package/dist/rules/token/descriptive-link-text.js +53 -0
  249. package/dist/rules/token/descriptive-link-text.js.map +1 -0
  250. package/dist/rules/token/emphasis-style.d.ts +3 -0
  251. package/dist/rules/token/emphasis-style.d.ts.map +1 -0
  252. package/dist/rules/token/emphasis-style.js +51 -0
  253. package/dist/rules/token/emphasis-style.js.map +1 -0
  254. package/dist/rules/token/fenced-code-language.d.ts +3 -0
  255. package/dist/rules/token/fenced-code-language.d.ts.map +1 -0
  256. package/dist/rules/token/fenced-code-language.js +35 -0
  257. package/dist/rules/token/fenced-code-language.js.map +1 -0
  258. package/dist/rules/token/first-line-h1.d.ts +3 -0
  259. package/dist/rules/token/first-line-h1.d.ts.map +1 -0
  260. package/dist/rules/token/first-line-h1.js +107 -0
  261. package/dist/rules/token/first-line-h1.js.map +1 -0
  262. package/dist/rules/token/heading-increment.d.ts +3 -0
  263. package/dist/rules/token/heading-increment.d.ts.map +1 -0
  264. package/dist/rules/token/heading-increment.js +27 -0
  265. package/dist/rules/token/heading-increment.js.map +1 -0
  266. package/dist/rules/token/heading-start-left.d.ts +3 -0
  267. package/dist/rules/token/heading-start-left.d.ts.map +1 -0
  268. package/dist/rules/token/heading-start-left.js +31 -0
  269. package/dist/rules/token/heading-start-left.js.map +1 -0
  270. package/dist/rules/token/heading-style.d.ts +3 -0
  271. package/dist/rules/token/heading-style.d.ts.map +1 -0
  272. package/dist/rules/token/heading-style.js +41 -0
  273. package/dist/rules/token/heading-style.js.map +1 -0
  274. package/dist/rules/token/helpers.d.ts +313 -0
  275. package/dist/rules/token/helpers.d.ts.map +1 -0
  276. package/dist/rules/token/helpers.js +746 -0
  277. package/dist/rules/token/helpers.js.map +1 -0
  278. package/dist/rules/token/hr-style.d.ts +3 -0
  279. package/dist/rules/token/hr-style.d.ts.map +1 -0
  280. package/dist/rules/token/hr-style.js +28 -0
  281. package/dist/rules/token/hr-style.js.map +1 -0
  282. package/dist/rules/token/index.d.ts +75 -0
  283. package/dist/rules/token/index.d.ts.map +1 -0
  284. package/dist/rules/token/index.js +226 -0
  285. package/dist/rules/token/index.js.map +1 -0
  286. package/dist/rules/token/line-length.d.ts +3 -0
  287. package/dist/rules/token/line-length.d.ts.map +1 -0
  288. package/dist/rules/token/line-length.js +120 -0
  289. package/dist/rules/token/line-length.js.map +1 -0
  290. package/dist/rules/token/link-fragments.d.ts +3 -0
  291. package/dist/rules/token/link-fragments.d.ts.map +1 -0
  292. package/dist/rules/token/link-fragments.js +145 -0
  293. package/dist/rules/token/link-fragments.js.map +1 -0
  294. package/dist/rules/token/link-image-reference-definitions.d.ts +3 -0
  295. package/dist/rules/token/link-image-reference-definitions.d.ts.map +1 -0
  296. package/dist/rules/token/link-image-reference-definitions.js +50 -0
  297. package/dist/rules/token/link-image-reference-definitions.js.map +1 -0
  298. package/dist/rules/token/link-image-style.d.ts +3 -0
  299. package/dist/rules/token/link-image-style.d.ts.map +1 -0
  300. package/dist/rules/token/link-image-style.js +131 -0
  301. package/dist/rules/token/link-image-style.js.map +1 -0
  302. package/dist/rules/token/list-indent.d.ts +3 -0
  303. package/dist/rules/token/list-indent.d.ts.map +1 -0
  304. package/dist/rules/token/list-indent.js +60 -0
  305. package/dist/rules/token/list-indent.js.map +1 -0
  306. package/dist/rules/token/list-length.d.ts +3 -0
  307. package/dist/rules/token/list-length.d.ts.map +1 -0
  308. package/dist/rules/token/list-length.js +55 -0
  309. package/dist/rules/token/list-length.js.map +1 -0
  310. package/dist/rules/token/list-marker-space.d.ts +3 -0
  311. package/dist/rules/token/list-marker-space.d.ts.map +1 -0
  312. package/dist/rules/token/list-marker-space.js +52 -0
  313. package/dist/rules/token/list-marker-space.js.map +1 -0
  314. package/dist/rules/token/markdoc-attributes.d.ts +3 -0
  315. package/dist/rules/token/markdoc-attributes.d.ts.map +1 -0
  316. package/dist/rules/token/markdoc-attributes.js +269 -0
  317. package/dist/rules/token/markdoc-attributes.js.map +1 -0
  318. package/dist/rules/token/markdoc-pairing.d.ts +3 -0
  319. package/dist/rules/token/markdoc-pairing.d.ts.map +1 -0
  320. package/dist/rules/token/markdoc-pairing.js +73 -0
  321. package/dist/rules/token/markdoc-pairing.js.map +1 -0
  322. package/dist/rules/token/markdoc-syntax.d.ts +3 -0
  323. package/dist/rules/token/markdoc-syntax.d.ts.map +1 -0
  324. package/dist/rules/token/markdoc-syntax.js +119 -0
  325. package/dist/rules/token/markdoc-syntax.js.map +1 -0
  326. package/dist/rules/token/markdoc-unknown-tag.d.ts +3 -0
  327. package/dist/rules/token/markdoc-unknown-tag.d.ts.map +1 -0
  328. package/dist/rules/token/markdoc-unknown-tag.js +64 -0
  329. package/dist/rules/token/markdoc-unknown-tag.js.map +1 -0
  330. package/dist/rules/token/messages.d.ts +4 -0
  331. package/dist/rules/token/messages.d.ts.map +1 -0
  332. package/dist/rules/token/messages.js +20 -0
  333. package/dist/rules/token/messages.js.map +1 -0
  334. package/dist/rules/token/no-alt-text.d.ts +3 -0
  335. package/dist/rules/token/no-alt-text.d.ts.map +1 -0
  336. package/dist/rules/token/no-alt-text.js +47 -0
  337. package/dist/rules/token/no-alt-text.js.map +1 -0
  338. package/dist/rules/token/no-bare-urls.d.ts +3 -0
  339. package/dist/rules/token/no-bare-urls.d.ts.map +1 -0
  340. package/dist/rules/token/no-bare-urls.js +88 -0
  341. package/dist/rules/token/no-bare-urls.js.map +1 -0
  342. package/dist/rules/token/no-blanks-blockquote.d.ts +3 -0
  343. package/dist/rules/token/no-blanks-blockquote.d.ts.map +1 -0
  344. package/dist/rules/token/no-blanks-blockquote.js +39 -0
  345. package/dist/rules/token/no-blanks-blockquote.js.map +1 -0
  346. package/dist/rules/token/no-duplicate-heading.d.ts +3 -0
  347. package/dist/rules/token/no-duplicate-heading.d.ts.map +1 -0
  348. package/dist/rules/token/no-duplicate-heading.js +101 -0
  349. package/dist/rules/token/no-duplicate-heading.js.map +1 -0
  350. package/dist/rules/token/no-duplicate-link-destinations.d.ts +3 -0
  351. package/dist/rules/token/no-duplicate-link-destinations.d.ts.map +1 -0
  352. package/dist/rules/token/no-duplicate-link-destinations.js +65 -0
  353. package/dist/rules/token/no-duplicate-link-destinations.js.map +1 -0
  354. package/dist/rules/token/no-emphasis-as-heading.d.ts +3 -0
  355. package/dist/rules/token/no-emphasis-as-heading.d.ts.map +1 -0
  356. package/dist/rules/token/no-emphasis-as-heading.js +44 -0
  357. package/dist/rules/token/no-emphasis-as-heading.js.map +1 -0
  358. package/dist/rules/token/no-empty-headings.d.ts +3 -0
  359. package/dist/rules/token/no-empty-headings.d.ts.map +1 -0
  360. package/dist/rules/token/no-empty-headings.js +28 -0
  361. package/dist/rules/token/no-empty-headings.js.map +1 -0
  362. package/dist/rules/token/no-empty-links.d.ts +3 -0
  363. package/dist/rules/token/no-empty-links.d.ts.map +1 -0
  364. package/dist/rules/token/no-empty-links.js +67 -0
  365. package/dist/rules/token/no-empty-links.js.map +1 -0
  366. package/dist/rules/token/no-hard-tabs.d.ts +3 -0
  367. package/dist/rules/token/no-hard-tabs.d.ts.map +1 -0
  368. package/dist/rules/token/no-hard-tabs.js +76 -0
  369. package/dist/rules/token/no-hard-tabs.js.map +1 -0
  370. package/dist/rules/token/no-inline-html.d.ts +3 -0
  371. package/dist/rules/token/no-inline-html.d.ts.map +1 -0
  372. package/dist/rules/token/no-inline-html.js +45 -0
  373. package/dist/rules/token/no-inline-html.js.map +1 -0
  374. package/dist/rules/token/no-missing-space-atx.d.ts +3 -0
  375. package/dist/rules/token/no-missing-space-atx.d.ts.map +1 -0
  376. package/dist/rules/token/no-missing-space-atx.js +36 -0
  377. package/dist/rules/token/no-missing-space-atx.js.map +1 -0
  378. package/dist/rules/token/no-missing-space-closed-atx.d.ts +3 -0
  379. package/dist/rules/token/no-missing-space-closed-atx.d.ts.map +1 -0
  380. package/dist/rules/token/no-missing-space-closed-atx.js +45 -0
  381. package/dist/rules/token/no-missing-space-closed-atx.js.map +1 -0
  382. package/dist/rules/token/no-multiple-blanks.d.ts +3 -0
  383. package/dist/rules/token/no-multiple-blanks.d.ts.map +1 -0
  384. package/dist/rules/token/no-multiple-blanks.js +35 -0
  385. package/dist/rules/token/no-multiple-blanks.js.map +1 -0
  386. package/dist/rules/token/no-multiple-space-atx.d.ts +13 -0
  387. package/dist/rules/token/no-multiple-space-atx.d.ts.map +1 -0
  388. package/dist/rules/token/no-multiple-space-atx.js +50 -0
  389. package/dist/rules/token/no-multiple-space-atx.js.map +1 -0
  390. package/dist/rules/token/no-multiple-space-blockquote.d.ts +3 -0
  391. package/dist/rules/token/no-multiple-space-blockquote.d.ts.map +1 -0
  392. package/dist/rules/token/no-multiple-space-blockquote.js +43 -0
  393. package/dist/rules/token/no-multiple-space-blockquote.js.map +1 -0
  394. package/dist/rules/token/no-multiple-space-closed-atx.d.ts +3 -0
  395. package/dist/rules/token/no-multiple-space-closed-atx.d.ts.map +1 -0
  396. package/dist/rules/token/no-multiple-space-closed-atx.js +19 -0
  397. package/dist/rules/token/no-multiple-space-closed-atx.js.map +1 -0
  398. package/dist/rules/token/no-reversed-links.d.ts +3 -0
  399. package/dist/rules/token/no-reversed-links.d.ts.map +1 -0
  400. package/dist/rules/token/no-reversed-links.js +52 -0
  401. package/dist/rules/token/no-reversed-links.js.map +1 -0
  402. package/dist/rules/token/no-space-in-code.d.ts +3 -0
  403. package/dist/rules/token/no-space-in-code.d.ts.map +1 -0
  404. package/dist/rules/token/no-space-in-code.js +75 -0
  405. package/dist/rules/token/no-space-in-code.js.map +1 -0
  406. package/dist/rules/token/no-space-in-emphasis.d.ts +3 -0
  407. package/dist/rules/token/no-space-in-emphasis.d.ts.map +1 -0
  408. package/dist/rules/token/no-space-in-emphasis.js +79 -0
  409. package/dist/rules/token/no-space-in-emphasis.js.map +1 -0
  410. package/dist/rules/token/no-space-in-links.d.ts +3 -0
  411. package/dist/rules/token/no-space-in-links.d.ts.map +1 -0
  412. package/dist/rules/token/no-space-in-links.js +48 -0
  413. package/dist/rules/token/no-space-in-links.js.map +1 -0
  414. package/dist/rules/token/no-trailing-punctuation.d.ts +3 -0
  415. package/dist/rules/token/no-trailing-punctuation.d.ts.map +1 -0
  416. package/dist/rules/token/no-trailing-punctuation.js +38 -0
  417. package/dist/rules/token/no-trailing-punctuation.js.map +1 -0
  418. package/dist/rules/token/no-trailing-spaces.d.ts +3 -0
  419. package/dist/rules/token/no-trailing-spaces.d.ts.map +1 -0
  420. package/dist/rules/token/no-trailing-spaces.js +89 -0
  421. package/dist/rules/token/no-trailing-spaces.js.map +1 -0
  422. package/dist/rules/token/ol-prefix.d.ts +3 -0
  423. package/dist/rules/token/ol-prefix.d.ts.map +1 -0
  424. package/dist/rules/token/ol-prefix.js +70 -0
  425. package/dist/rules/token/ol-prefix.js.map +1 -0
  426. package/dist/rules/token/proper-names.d.ts +3 -0
  427. package/dist/rules/token/proper-names.d.ts.map +1 -0
  428. package/dist/rules/token/proper-names.js +93 -0
  429. package/dist/rules/token/proper-names.js.map +1 -0
  430. package/dist/rules/token/reference-links-images.d.ts +3 -0
  431. package/dist/rules/token/reference-links-images.d.ts.map +1 -0
  432. package/dist/rules/token/reference-links-images.js +36 -0
  433. package/dist/rules/token/reference-links-images.js.map +1 -0
  434. package/dist/rules/token/required-headings.d.ts +3 -0
  435. package/dist/rules/token/required-headings.d.ts.map +1 -0
  436. package/dist/rules/token/required-headings.js +83 -0
  437. package/dist/rules/token/required-headings.js.map +1 -0
  438. package/dist/rules/token/single-h1.d.ts +3 -0
  439. package/dist/rules/token/single-h1.d.ts.map +1 -0
  440. package/dist/rules/token/single-h1.js +56 -0
  441. package/dist/rules/token/single-h1.js.map +1 -0
  442. package/dist/rules/token/single-trailing-newline.d.ts +3 -0
  443. package/dist/rules/token/single-trailing-newline.d.ts.map +1 -0
  444. package/dist/rules/token/single-trailing-newline.js +25 -0
  445. package/dist/rules/token/single-trailing-newline.js.map +1 -0
  446. package/dist/rules/token/strong-style.d.ts +3 -0
  447. package/dist/rules/token/strong-style.d.ts.map +1 -0
  448. package/dist/rules/token/strong-style.js +51 -0
  449. package/dist/rules/token/strong-style.js.map +1 -0
  450. package/dist/rules/token/table-column-count.d.ts +3 -0
  451. package/dist/rules/token/table-column-count.d.ts.map +1 -0
  452. package/dist/rules/token/table-column-count.js +44 -0
  453. package/dist/rules/token/table-column-count.js.map +1 -0
  454. package/dist/rules/token/table-column-style.d.ts +3 -0
  455. package/dist/rules/token/table-column-style.d.ts.map +1 -0
  456. package/dist/rules/token/table-column-style.js +179 -0
  457. package/dist/rules/token/table-column-style.js.map +1 -0
  458. package/dist/rules/token/table-pipe-style.d.ts +3 -0
  459. package/dist/rules/token/table-pipe-style.d.ts.map +1 -0
  460. package/dist/rules/token/table-pipe-style.js +54 -0
  461. package/dist/rules/token/table-pipe-style.js.map +1 -0
  462. package/dist/rules/token/ul-indent.d.ts +3 -0
  463. package/dist/rules/token/ul-indent.d.ts.map +1 -0
  464. package/dist/rules/token/ul-indent.js +72 -0
  465. package/dist/rules/token/ul-indent.js.map +1 -0
  466. package/dist/rules/token/ul-style.d.ts +3 -0
  467. package/dist/rules/token/ul-style.d.ts.map +1 -0
  468. package/dist/rules/token/ul-style.js +80 -0
  469. package/dist/rules/token/ul-style.js.map +1 -0
  470. package/dist/rules/types.d.ts +81 -0
  471. package/dist/rules/types.d.ts.map +1 -0
  472. package/dist/rules/types.js +2 -0
  473. package/dist/rules/types.js.map +1 -0
  474. package/dist/rules/utils.d.ts +29 -0
  475. package/dist/rules/utils.d.ts.map +1 -0
  476. package/dist/{assertions → rules}/utils.js +27 -0
  477. package/dist/rules/utils.js.map +1 -0
  478. package/dist/scopes/extractor.d.ts +7 -0
  479. package/dist/scopes/extractor.d.ts.map +1 -0
  480. package/dist/scopes/extractor.js +475 -0
  481. package/dist/scopes/extractor.js.map +1 -0
  482. package/dist/scopes/selector.d.ts +51 -0
  483. package/dist/scopes/selector.d.ts.map +1 -0
  484. package/dist/scopes/selector.js +121 -0
  485. package/dist/scopes/selector.js.map +1 -0
  486. package/dist/scopes/sentences.d.ts +15 -0
  487. package/dist/scopes/sentences.d.ts.map +1 -0
  488. package/dist/scopes/sentences.js +124 -0
  489. package/dist/scopes/sentences.js.map +1 -0
  490. package/dist/scopes/types.d.ts +44 -0
  491. package/dist/scopes/types.d.ts.map +1 -0
  492. package/dist/scopes/types.js +2 -0
  493. package/dist/scopes/types.js.map +1 -0
  494. package/dist/scopes/vocabulary.d.ts +16 -0
  495. package/dist/scopes/vocabulary.d.ts.map +1 -0
  496. package/dist/scopes/vocabulary.js +70 -0
  497. package/dist/scopes/vocabulary.js.map +1 -0
  498. package/dist/types/assertions.d.ts +95 -32
  499. package/dist/types/assertions.d.ts.map +1 -1
  500. package/dist/types/problems.d.ts +4 -5
  501. package/dist/types/problems.d.ts.map +1 -1
  502. package/dist/types/rules.d.ts +4 -6
  503. package/dist/types/rules.d.ts.map +1 -1
  504. package/examples/appendices/google.appendix.yaml +91 -0
  505. package/examples/appendices/inclusive-language.appendix.yaml +61 -0
  506. package/examples/appendices/microsoft.appendix.yaml +99 -0
  507. package/examples/appendices/plain-language.appendix.yaml +88 -0
  508. package/examples/google.yaml +1525 -0
  509. package/examples/inclusive-language.yaml +304 -0
  510. package/examples/microsoft.yaml +1542 -0
  511. package/examples/plain-language.yaml +325 -0
  512. package/package.json +49 -16
  513. package/presets/google/PROVENANCE.md +1022 -0
  514. package/presets/google/sources.json +192 -0
  515. package/presets/inclusive-language/PROVENANCE.md +174 -0
  516. package/presets/inclusive-language/sources.json +107 -0
  517. package/presets/microsoft/PROVENANCE.md +1555 -0
  518. package/presets/microsoft/sources.json +494 -0
  519. package/presets/plain-language/PROVENANCE.md +364 -0
  520. package/presets/plain-language/sources.json +108 -0
  521. package/dist/assertions/bullet-style.d.ts +0 -3
  522. package/dist/assertions/bullet-style.d.ts.map +0 -1
  523. package/dist/assertions/bullet-style.js +0 -60
  524. package/dist/assertions/bullet-style.js.map +0 -1
  525. package/dist/assertions/index.d.ts +0 -21
  526. package/dist/assertions/index.d.ts.map +0 -1
  527. package/dist/assertions/index.js +0 -30
  528. package/dist/assertions/index.js.map +0 -1
  529. package/dist/assertions/max-image-size.d.ts +0 -3
  530. package/dist/assertions/max-image-size.d.ts.map +0 -1
  531. package/dist/assertions/max-image-size.js +0 -73
  532. package/dist/assertions/max-image-size.js.map +0 -1
  533. package/dist/assertions/max-line-length.d.ts +0 -3
  534. package/dist/assertions/max-line-length.d.ts.map +0 -1
  535. package/dist/assertions/max-line-length.js +0 -68
  536. package/dist/assertions/max-line-length.js.map +0 -1
  537. package/dist/assertions/no-broken-fragment-links.d.ts +0 -3
  538. package/dist/assertions/no-broken-fragment-links.d.ts.map +0 -1
  539. package/dist/assertions/no-broken-fragment-links.js +0 -79
  540. package/dist/assertions/no-broken-fragment-links.js.map +0 -1
  541. package/dist/assertions/no-duplicate-headings.d.ts +0 -3
  542. package/dist/assertions/no-duplicate-headings.d.ts.map +0 -1
  543. package/dist/assertions/no-duplicate-headings.js +0 -66
  544. package/dist/assertions/no-duplicate-headings.js.map +0 -1
  545. package/dist/assertions/no-hard-tabs.d.ts +0 -3
  546. package/dist/assertions/no-hard-tabs.d.ts.map +0 -1
  547. package/dist/assertions/no-hard-tabs.js +0 -63
  548. package/dist/assertions/no-hard-tabs.js.map +0 -1
  549. package/dist/assertions/no-trailing-spaces.d.ts +0 -3
  550. package/dist/assertions/no-trailing-spaces.d.ts.map +0 -1
  551. package/dist/assertions/no-trailing-spaces.js +0 -72
  552. package/dist/assertions/no-trailing-spaces.js.map +0 -1
  553. package/dist/assertions/pattern.d.ts +0 -3
  554. package/dist/assertions/pattern.d.ts.map +0 -1
  555. package/dist/assertions/pattern.js +0 -39
  556. package/dist/assertions/pattern.js.map +0 -1
  557. package/dist/assertions/semantic-line-breaks.d.ts +0 -3
  558. package/dist/assertions/semantic-line-breaks.d.ts.map +0 -1
  559. package/dist/assertions/semantic-line-breaks.js +0 -152
  560. package/dist/assertions/semantic-line-breaks.js.map +0 -1
  561. package/dist/assertions/swap.d.ts +0 -3
  562. package/dist/assertions/swap.d.ts.map +0 -1
  563. package/dist/assertions/swap.js +0 -39
  564. package/dist/assertions/swap.js.map +0 -1
  565. package/dist/assertions/utils.d.ts +0 -8
  566. package/dist/assertions/utils.d.ts.map +0 -1
  567. package/dist/assertions/utils.js.map +0 -1
  568. package/dist/core/scope-parser.d.ts +0 -26
  569. package/dist/core/scope-parser.d.ts.map +0 -1
  570. package/dist/core/scope-parser.js +0 -110
  571. package/dist/core/scope-parser.js.map +0 -1
  572. package/dist/files.d.ts +0 -2
  573. package/dist/files.d.ts.map +0 -1
  574. package/dist/files.js +0 -39
  575. package/dist/files.js.map +0 -1
  576. package/dist/load-config.d.ts +0 -25
  577. package/dist/load-config.d.ts.map +0 -1
  578. package/dist/load-config.js +0 -104
  579. package/dist/load-config.js.map +0 -1
  580. package/dist/load.d.ts +0 -25
  581. package/dist/load.d.ts.map +0 -1
  582. package/dist/load.js +0 -112
  583. package/dist/load.js.map +0 -1
  584. package/dist/scope.d.ts +0 -26
  585. package/dist/scope.d.ts.map +0 -1
  586. package/dist/scope.js +0 -110
  587. package/dist/scope.js.map +0 -1
  588. package/dist/types.d.ts +0 -109
  589. package/dist/types.d.ts.map +0 -1
  590. package/dist/types.js.map +0 -1
  591. package/dist/validate.d.ts +0 -31
  592. package/dist/validate.d.ts.map +0 -1
  593. package/dist/validate.js +0 -154
  594. package/dist/validate.js.map +0 -1
  595. /package/dist/{types.js → parser/types.js} +0 -0
@@ -0,0 +1,48 @@
1
+ import { formatTemplate } from '../token/messages.js';
2
+ import { newLineRe } from '../../core/line-endings.js';
3
+ // Vale-parity `occurrence` check: counts regex matches within each segment
4
+ // (not per-line, unlike `pattern`) and flags the whole segment when the
5
+ // count falls outside `[min, max]`. Detection-only — the violation is the
6
+ // segment's total count, so there's no single match position to anchor a fix.
7
+ const execute = async (rule, file, ctx) => {
8
+ const problems = [];
9
+ const o = rule.assertions['occurrence'];
10
+ let regex;
11
+ try {
12
+ regex = new RegExp(o.pattern, o.ignoreCase ? 'gi' : 'g');
13
+ }
14
+ catch {
15
+ return problems; // ignore invalid regex
16
+ }
17
+ for (const segment of ctx.segments) {
18
+ // Exclude zero-width matches (e.g. a pattern like `a*` over text with
19
+ // no 'a'): matchAll's iterator advances past each one automatically
20
+ // (unlike a raw exec() loop, there's no hang to guard against), but an
21
+ // empty-text match is still a match at every position in the segment
22
+ // -- counting it would inflate the total so `max` bounds always
23
+ // violate and `min` is trivially satisfied.
24
+ const count = [...segment.content.matchAll(regex)].filter((m) => m[0].length > 0).length;
25
+ const tooFew = o.min !== undefined && count < o.min;
26
+ const tooMany = o.max !== undefined && count > o.max;
27
+ if (!tooFew && !tooMany)
28
+ continue;
29
+ const bound = tooFew ? o.min : o.max;
30
+ problems.push({
31
+ file,
32
+ line: segment.startLine,
33
+ column: segment.startColumn,
34
+ // newLineRe, not '\n': a bare split leaves a trailing '\r' on CRLF content.
35
+ text: segment.content.split(newLineRe)[0] ?? '',
36
+ match: o.pattern,
37
+ ruleName: rule.name,
38
+ severity: rule.severity,
39
+ message: formatTemplate(rule.message ??
40
+ (tooFew
41
+ ? 'Found %s matches; expected at least %s.'
42
+ : 'Found %s matches; expected at most %s.'), String(count), String(bound)),
43
+ });
44
+ }
45
+ return problems;
46
+ };
47
+ export const occurrence = { id: 'occurrence', fixable: false, execute };
48
+ //# sourceMappingURL=occurrence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrence.js","sourceRoot":"","sources":["../../../src/rules/scope/occurrence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,2EAA2E;AAC3E,wEAAwE;AACxE,0EAA0E;AAC1E,8EAA8E;AAC9E,MAAM,OAAO,GAAG,KAAK,EACnB,IAAoB,EACpB,IAAY,EACZ,GAAqB,EACD,EAAE;IACtB,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAwB,CAAC;IAE/D,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC,CAAC,uBAAuB;IAC1C,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnC,sEAAsE;QACtE,oEAAoE;QACpE,uEAAuE;QACvE,qEAAqE;QACrE,gEAAgE;QAChE,4CAA4C;QAC5C,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QACzF,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;QACpD,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;QACrD,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO;YAAE,SAAS;QAElC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,SAAS;YACvB,MAAM,EAAE,OAAO,CAAC,WAAW;YAC3B,4EAA4E;YAC5E,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YAC/C,KAAK,EAAE,CAAC,CAAC,OAAO;YAChB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,cAAc,CACrB,IAAI,CAAC,OAAO;gBACV,CAAC,MAAM;oBACL,CAAC,CAAC,yCAAyC;oBAC3C,CAAC,CAAC,wCAAwC,CAAC,EAC/C,MAAM,CAAC,KAAK,CAAC,EACb,MAAM,CAAC,KAAK,CAAC,CACd;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAc,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ export declare const pattern: ScopeRule;
3
+ //# sourceMappingURL=pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/pattern.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAkF/D,eAAO,MAAM,OAAO,EAAE,SAAsD,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { formatTemplate } from '../token/messages.js';
2
+ import { newLineRe, offsetToLineColumn } from '../../core/line-endings.js';
3
+ import { overlapsAnyRange } from '../../core/inline-code.js';
4
+ import { nonProseRanges } from '../utils.js';
5
+ // A match's raw `column` (from offsetToLineColumn) is relative to its own
6
+ // line within segment.content. On the segment's first line,
7
+ // segment.content starts mid-source-line (e.g. a heading segment's
8
+ // content excludes the '## ' marker), so segment.startColumn must be added
9
+ // to get the true source column. Matches on later lines start at source
10
+ // column 1, so they're unaffected.
11
+ function toSourceColumn(segment, lineNumber, column) {
12
+ return lineNumber === 1 ? segment.startColumn + (column - 1) : column;
13
+ }
14
+ const execute = async (rule, file, ctx) => {
15
+ const problems = [];
16
+ const options = rule.assertions['pattern'];
17
+ for (const segment of ctx.segments) {
18
+ const content = segment.content;
19
+ // newLineRe (never a bare '\n'): a '\n' split of CRLF content leaves a
20
+ // trailing '\r' on every reported `text`, and a '\n'-based line count
21
+ // keeps CR-only matches on line 1 (see offsetToLineColumn below).
22
+ const contentLines = content.split(newLineRe);
23
+ // Prose rules must not lint code: a token like 'master' would fire
24
+ // inside `git checkout master`, the usage Google's guide explicitly
25
+ // sanctions in code font. A markdoc tag's span is excluded on the same
26
+ // terms: it is markup, not the prose this rule was pointed at. The regex
27
+ // runs against the original `content`, never a masked stand-in, because an
28
+ // arbitrary user regex such as the negated class `[^\s,]+` can match
29
+ // straight through a masked run. A match whose span overlaps one of the
30
+ // excluded ranges is skipped below rather than reported; `includeCode`
31
+ // drops the code-span half.
32
+ const excluded = nonProseRanges(segment, options.includeCode);
33
+ const tokens = options.tokens || [];
34
+ for (const token of tokens) {
35
+ try {
36
+ const regex = new RegExp(token, options.ignoreCase ? 'gi' : 'g');
37
+ let match;
38
+ while ((match = regex.exec(content)) !== null) {
39
+ // A zero-width match (e.g. a `tokens` pattern like `a*`) never
40
+ // advances lastIndex on its own -- bump it or the loop hangs. It's
41
+ // also semantically meaningless for pattern (there's no real text
42
+ // to report), so skip recording it too -- otherwise a token that
43
+ // can match empty string would report a phantom problem at every
44
+ // character offset it passed through.
45
+ if (match[0].length === 0) {
46
+ regex.lastIndex++;
47
+ continue;
48
+ }
49
+ const matchEnd = match.index + match[0].length;
50
+ if (overlapsAnyRange(match.index, matchEnd, excluded)) {
51
+ continue;
52
+ }
53
+ const { line: lineNumber, column } = offsetToLineColumn(content, match.index);
54
+ const matchedText = content.slice(match.index, match.index + match[0].length);
55
+ problems.push({
56
+ file,
57
+ line: segment.startLine + lineNumber - 1,
58
+ column: toSourceColumn(segment, lineNumber, column),
59
+ text: contentLines[lineNumber - 1] || '',
60
+ match: matchedText,
61
+ ruleName: rule.name,
62
+ severity: rule.severity,
63
+ message: formatTemplate(rule.message ?? '', matchedText),
64
+ });
65
+ }
66
+ }
67
+ catch {
68
+ // ignore invalid regex
69
+ }
70
+ }
71
+ }
72
+ return problems;
73
+ };
74
+ export const pattern = { id: 'pattern', fixable: false, execute };
75
+ //# sourceMappingURL=pattern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../../src/rules/scope/pattern.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ export declare const repetition: ScopeRule;
3
+ //# sourceMappingURL=repetition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repetition.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/repetition.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAwK/D,eAAO,MAAM,UAAU,EAAE,SAA6D,CAAC"}
@@ -0,0 +1,139 @@
1
+ import { formatTemplate } from '../token/messages.js';
2
+ import { newLineRe, offsetToLineColumn } from '../../core/line-endings.js';
3
+ // Tokenizes `segment.content` with `options.pattern` (default `\w+`) and
4
+ // pairs adjacent tokens whose only separator is whitespace with at most one
5
+ // line break (a blank line never pairs across paragraphs), matched
6
+ // case-insensitively unless `ignoreCase: false`. Shared by execute() and fix().
7
+ function findRepeatedPairs(segment, options) {
8
+ let tokenRe;
9
+ try {
10
+ tokenRe = new RegExp(options.pattern ?? '\\w+', 'g');
11
+ }
12
+ catch {
13
+ return []; // ignore invalid regex
14
+ }
15
+ const tokens = [];
16
+ let match;
17
+ while ((match = tokenRe.exec(segment.content)) !== null) {
18
+ // A pattern that can match empty (e.g. `\w*`) must advance lastIndex or
19
+ // the loop hangs; the empty token itself is skipped -- an empty "word"
20
+ // can't meaningfully repeat.
21
+ if (match[0].length === 0) {
22
+ tokenRe.lastIndex++;
23
+ continue;
24
+ }
25
+ tokens.push({ text: match[0], index: match.index });
26
+ }
27
+ // Defaults TRUE (unlike every other assertion): 'The the' is the common
28
+ // typo this check exists to catch.
29
+ const ignoreCase = options.ignoreCase !== false;
30
+ const pairs = [];
31
+ for (let i = 1; i < tokens.length; i++) {
32
+ const first = tokens[i - 1];
33
+ const second = tokens[i];
34
+ const gap = segment.content.slice(first.index + first.text.length, second.index);
35
+ if (!/^\s+$/.test(gap))
36
+ continue;
37
+ const lineBreaksInGap = gap.match(newLineRe)?.length ?? 0;
38
+ if (lineBreaksInGap > 1)
39
+ continue;
40
+ const same = ignoreCase
41
+ ? first.text.toLowerCase() === second.text.toLowerCase()
42
+ : first.text === second.text;
43
+ if (same)
44
+ pairs.push({ first, second });
45
+ }
46
+ return pairs;
47
+ }
48
+ // On the segment's first line, segment.content starts mid-source-line (e.g.
49
+ // a heading's content excludes the '## ' marker), so segment.startColumn
50
+ // must be added -- see pattern.ts's toSourceColumn.
51
+ function toSourceColumn(segment, localLine, localColumn) {
52
+ return localLine === 1 ? segment.startColumn + (localColumn - 1) : localColumn;
53
+ }
54
+ const execute = async (rule, file, ctx) => {
55
+ const options = rule.assertions['repetition'];
56
+ const problems = [];
57
+ for (const segment of ctx.segments) {
58
+ const contentLines = segment.content.split(newLineRe);
59
+ for (const { second } of findRepeatedPairs(segment, options)) {
60
+ // Reported at the SECOND token's position -- exactly what fix() removes.
61
+ const { line: localLine, column: localColumn } = offsetToLineColumn(segment.content, second.index);
62
+ problems.push({
63
+ file,
64
+ line: segment.startLine + localLine - 1,
65
+ column: toSourceColumn(segment, localLine, localColumn),
66
+ text: contentLines[localLine - 1] ?? '',
67
+ match: second.text,
68
+ ruleName: rule.name,
69
+ severity: rule.severity,
70
+ message: formatTemplate(rule.message ?? 'Repeated word "%s".', second.text),
71
+ });
72
+ }
73
+ }
74
+ return problems;
75
+ };
76
+ const fix = async (rule, file, ctx) => {
77
+ const options = rule.assertions['repetition'];
78
+ const fixes = [];
79
+ // Full source lines, for the lone-token whole-line-deletion check below.
80
+ const fileLines = ctx.content.split(newLineRe);
81
+ for (const segment of ctx.segments) {
82
+ for (const { first, second } of findRepeatedPairs(segment, options)) {
83
+ const firstPos = offsetToLineColumn(segment.content, first.index);
84
+ const secondPos = offsetToLineColumn(segment.content, second.index);
85
+ if (firstPos.line === secondPos.line) {
86
+ // Same-line pair: delete the gap plus the second token, so the
87
+ // first token survives verbatim, casing included ('The the' -> 'The').
88
+ const gapLength = second.index - (first.index + first.text.length);
89
+ fixes.push({
90
+ file,
91
+ ruleName: rule.name,
92
+ lineNumber: segment.startLine + secondPos.line - 1,
93
+ editColumn: toSourceColumn(segment, firstPos.line, firstPos.column) + first.text.length,
94
+ deleteCount: gapLength + second.text.length,
95
+ });
96
+ }
97
+ else {
98
+ // Cross-line (hard-wrapped) pair: a single Fix can only edit one
99
+ // source line (see core/auto-fix.ts), so only the second token's
100
+ // line is rewritten -- deleting the token plus the whitespace run
101
+ // following it on that line.
102
+ const lineNumber = segment.startLine + secondPos.line - 1;
103
+ const editColumn = toSourceColumn(segment, secondPos.line, secondPos.column);
104
+ // Checked against the full SOURCE line, not the segment-content
105
+ // slice: a segment can end mid-line (e.g. a sentence segment), and
106
+ // whole-line deletion must never eat source text outside it.
107
+ const sourceLine = fileLines[lineNumber - 1] ?? '';
108
+ const beforeToken = sourceLine.slice(0, editColumn - 1);
109
+ const afterOnSourceLine = sourceLine.slice(editColumn - 1 + second.text.length);
110
+ if (/^\s*$/.test(beforeToken) && /^\s*$/.test(afterOnSourceLine)) {
111
+ // The duplicate token is alone on its line -- deleting just the
112
+ // token would leave an empty line behind, so delete the whole
113
+ // line instead (deleteCount: -1, see core/auto-fix.ts).
114
+ fixes.push({
115
+ file,
116
+ ruleName: rule.name,
117
+ lineNumber,
118
+ deleteCount: -1,
119
+ });
120
+ continue;
121
+ }
122
+ const lines = segment.content.split(newLineRe);
123
+ const lineText = lines[secondPos.line - 1] ?? '';
124
+ const afterToken = lineText.slice(secondPos.column - 1 + second.text.length);
125
+ const trailingWhitespace = /^\s*/.exec(afterToken)?.[0] ?? '';
126
+ fixes.push({
127
+ file,
128
+ ruleName: rule.name,
129
+ lineNumber,
130
+ editColumn,
131
+ deleteCount: second.text.length + trailingWhitespace.length,
132
+ });
133
+ }
134
+ }
135
+ }
136
+ return fixes;
137
+ };
138
+ export const repetition = { id: 'repetition', fixable: true, execute, fix };
139
+ //# sourceMappingURL=repetition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repetition.js","sourceRoot":"","sources":["../../../src/rules/scope/repetition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ export declare const semanticLineBreaks: ScopeRule;
3
+ //# sourceMappingURL=semantic-line-breaks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-line-breaks.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/semantic-line-breaks.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAkP/D,eAAO,MAAM,kBAAkB,EAAE,SAKhC,CAAC"}
@@ -0,0 +1,213 @@
1
+ import { filterByTypes } from '../../parser/index.js';
2
+ import { addRangeToSet } from '../token/helpers.js';
3
+ import { newLineRe } from '../../core/line-endings.js';
4
+ import { splitSentences } from '../../scopes/sentences.js';
5
+ // Recheck-specific list-marker/heading skips. These aren't touched by the
6
+ // AST consolidation below: an ATX heading's own line prefix is trivial to
7
+ // detect without the tree, and the lettered-list heuristic (`a. Text`) has
8
+ // no CommonMark/AST representation at all -- micromark never parses it as
9
+ // a list, so there is no token to derive it from. See the module's
10
+ // LEGITIMATE-REGEX AUDIT note in the project report for why these stay as
11
+ // they are.
12
+ //
13
+ // The bullet check requires CommonMark marker SPACING -- optional indent,
14
+ // one of the bullet markers `-`/`*`/`+`, then a space or tab. A bare
15
+ // leading `-`/`*` is not enough: multi-sentence prose that merely starts
16
+ // with emphasis (`*text* ...`), strong (`**text** ...`), or a non-list
17
+ // dash (`-3 degrees ...`) is ordinary prose and must stay flaggable and
18
+ // fixable. The marker-spaced check also subsumes the former
19
+ // bullet+lettered (`- a. Text`) and bullet+numbered (`- 1. Text`)
20
+ // nested-sub-list heuristics: both start with `marker + space`, which is
21
+ // exactly what the bullet check now skips -- without the skip,
22
+ // splitSentences reads their `a.`/`1.` as a sentence boundary and --fix
23
+ // severs the marker from its own text.
24
+ function isSkippableLine(lineText) {
25
+ return (lineText.trim() === '' ||
26
+ lineText.startsWith('#') ||
27
+ /^\s*[-*+][ \t]/.test(lineText) ||
28
+ /^\s*\d+\.\s/.test(lineText) ||
29
+ /^\s*[a-zA-Z]\.\s/.test(lineText));
30
+ }
31
+ function calculateContinuationIndent(line) {
32
+ // Peel off the blockquote prefix first: leading whitespace plus one or
33
+ // more '>' markers (each optionally followed by whitespace). It is kept
34
+ // VERBATIM on continuation lines -- unlike list markers below, a
35
+ // blockquote marker replaced by spaces would demote the split-off
36
+ // sentences to lazy continuation lines, which still render inside the
37
+ // blockquote but no longer read as part of it in the source (the whole
38
+ // point of semantic line breaks). Lines without any '>' marker leave
39
+ // `blockquotePrefix` empty and take the exact pre-existing code path
40
+ // below, so non-blockquote continuation output is unchanged byte-for-byte.
41
+ const blockquotePrefix = line.match(/^(\s*(?:>\s*)+)/)?.[1] ?? '';
42
+ const remainder = line.slice(blockquotePrefix.length);
43
+ const leadingWhitespace = remainder.match(/^(\s*)/)?.[1] || '';
44
+ // Check for list markers and return appropriate indentation: the marker
45
+ // must NOT repeat on continuation lines (that would create new list
46
+ // items), so it is replaced by spaces of equal width to align the
47
+ // continuation under the list content.
48
+ const listMarkers = [
49
+ /^(\s*[-*+]\s)/, // Bullet points (all three CommonMark markers, matching isSkippableLine)
50
+ /^(\s*\d+\.\s)/, // Numbered lists
51
+ /^(\s*[a-zA-Z]\.\s)/, // Letter lists
52
+ ];
53
+ for (const pattern of listMarkers) {
54
+ const match = remainder.match(pattern);
55
+ if (match) {
56
+ return blockquotePrefix + ' '.repeat(match[1].length);
57
+ }
58
+ }
59
+ return blockquotePrefix + leadingWhitespace;
60
+ }
61
+ // Shared by execute() and fix() so both apply the exact same gate: with
62
+ // mode !== 'sentence' (e.g. 'phrase'), this rule doesn't detect anything
63
+ // today, so fix() must not rewrite lines either -- previously fix() split
64
+ // every multi-sentence line unconditionally regardless of `mode`, letting
65
+ // --fix rewrite lines lint never flagged under a non-'sentence' mode.
66
+ function isSentenceMode(options) {
67
+ return options.mode === 'sentence';
68
+ }
69
+ function formatMessage(template, ...args) {
70
+ let result = template;
71
+ for (let i = 0; i < args.length; i++) {
72
+ result = result.replace('%s', args[i]);
73
+ }
74
+ return result;
75
+ }
76
+ /**
77
+ * Line numbers (1-based) that fall inside a real fenced/indented code block
78
+ * or a real GFM table, derived once from the whole document's token tree --
79
+ * the same whole-file self-derivation pattern `line-length.ts` (MD013) uses
80
+ * for its own `codeBlocks`/`tables` options. Replaces the old per-line
81
+ * ``` ` ``` -toggle and `line.includes('|')` heuristics: those only caught
82
+ * backtick-fenced blocks (never tilde fences or indented code) and treated
83
+ * ANY line containing a literal `|` as a table (a false positive for, e.g.,
84
+ * prose mentioning `true|false` or a shell `foo | bar` pipeline outside any
85
+ * table). Computed over `ctx.tree` regardless of the rule's own scope
86
+ * selector, since a code/table token's true extent doesn't depend on which
87
+ * segments this invocation happens to be scoped to.
88
+ */
89
+ function deriveIgnoredLineNumbers(ctx) {
90
+ const codeBlockLines = new Set();
91
+ for (const codeBlock of filterByTypes(ctx.tree, ['codeFenced', 'codeIndented'])) {
92
+ addRangeToSet(codeBlockLines, codeBlock.startLine, codeBlock.endLine);
93
+ }
94
+ const tableLines = new Set();
95
+ for (const table of filterByTypes(ctx.tree, ['table'])) {
96
+ addRangeToSet(tableLines, table.startLine, table.endLine);
97
+ }
98
+ return { codeBlockLines, tableLines };
99
+ }
100
+ /**
101
+ * The single skip-decision used by both `execute` and `fix`. `fix()` must
102
+ * never rewrite a line that `execute()` wouldn't have flagged in the first
103
+ * place -- previously `fix()` only checked for blank lines and '#'
104
+ * headings, missing the tree-derived codeBlockLines/tableLines gating (and
105
+ * `isSkippableLine` entirely), so --fix could rewrite lines lint never
106
+ * reported as problems (e.g. an indented code-block line, or a table row).
107
+ */
108
+ function isIgnoredLine(lineText, lineNumber, options, ignoredLines) {
109
+ if (options.ignoreCodeBlocks && ignoredLines.codeBlockLines.has(lineNumber))
110
+ return true;
111
+ if (options.ignoreTables && ignoredLines.tableLines.has(lineNumber))
112
+ return true;
113
+ return isSkippableLine(lineText);
114
+ }
115
+ const execute = async (rule, file, ctx) => {
116
+ const problems = [];
117
+ const options = rule.assertions['semantic-line-breaks'];
118
+ const ignoredLines = deriveIgnoredLineNumbers(ctx);
119
+ for (const segment of ctx.segments) {
120
+ const lines = segment.content.split(newLineRe);
121
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
122
+ const lineText = lines[lineIndex];
123
+ const lineNumber = segment.startLine + lineIndex;
124
+ if (isIgnoredLine(lineText, lineNumber, options, ignoredLines))
125
+ continue;
126
+ if (isSentenceMode(options)) {
127
+ const sentenceCount = splitSentences(lineText).length;
128
+ if (sentenceCount > 1) {
129
+ problems.push({
130
+ file,
131
+ line: lineNumber,
132
+ column: 1,
133
+ text: lineText,
134
+ match: lineText,
135
+ ruleName: rule.name,
136
+ severity: rule.severity,
137
+ message: formatMessage(rule.message ?? '', options.mode),
138
+ });
139
+ }
140
+ }
141
+ }
142
+ }
143
+ return problems;
144
+ };
145
+ const fix = async (rule, file, ctx) => {
146
+ const fixes = [];
147
+ const options = rule.assertions['semantic-line-breaks'];
148
+ if (!isSentenceMode(options))
149
+ return fixes;
150
+ const ignoredLines = deriveIgnoredLineNumbers(ctx);
151
+ const rawLines = ctx.content.split(newLineRe);
152
+ for (const segment of ctx.segments) {
153
+ const lines = segment.content.split(newLineRe);
154
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
155
+ const lineText = lines[lineIndex];
156
+ const lineNumber = segment.startLine + lineIndex;
157
+ if (isIgnoredLine(lineText, lineNumber, options, ignoredLines))
158
+ continue;
159
+ const sentences = splitSentences(lineText);
160
+ if (sentences.length <= 1)
161
+ continue;
162
+ // The replacement is applied with deleteCount: -1 (whole-line
163
+ // replace), so it must be rebuilt from the RAW source line, never
164
+ // from segment.content: under a scoped run (scope: summary /
165
+ // list-item / default) a list item's segment content is the SEMANTIC
166
+ // text with the list marker stripped by the token boundaries (the
167
+ // item's `content` token starts after the `- ` prefix), and
168
+ // rebuilding from it would replace `- First. Second.` with
169
+ // marker-less `First.\nSecond.`, corrupting the list. Sentence
170
+ // DETECTION stays on lineText -- the exact text execute() flags -- so
171
+ // execute()/fix() symmetry is untouched; only the replacement text
172
+ // derives from the raw line. On the segment's first line the token's
173
+ // startColumn locates the segment text within the raw line; later
174
+ // segment lines are verbatim source slices already (token text is
175
+ // content.slice(start.offset, end.offset)), and the whole-file
176
+ // segment has startColumn 1 -- both leave prefixOffset at 0, keeping
177
+ // whole-file (scope: all / unscoped) output byte-identical to before.
178
+ const rawLine = rawLines[lineNumber - 1] ?? lineText;
179
+ const prefixOffset = lineIndex === 0 ? segment.startColumn - 1 : 0;
180
+ const indentation = calculateContinuationIndent(rawLine);
181
+ const [firstSentence, ...continuationSentences] = sentences;
182
+ // Reconstruct the first sentence line from the TRUE original prefix
183
+ // (everything in the raw line before the trimmed sentence content
184
+ // starts -- indentation, blockquote markers, a list marker), not from
185
+ // `firstSentence.text` alone: splitSentences trims each span, so pure
186
+ // leading whitespace on the line is gone from `.text` with nowhere to
187
+ // go back to. Continuation lines are unaffected -- they were never
188
+ // built from the original line's own prefix in the first place.
189
+ const firstLinePrefix = rawLine.slice(0, prefixOffset + firstSentence.start);
190
+ const newLinesForThisLine = [
191
+ firstLinePrefix + firstSentence.text,
192
+ ...continuationSentences.map((sentence) => indentation + sentence.text),
193
+ ];
194
+ const newText = newLinesForThisLine.join('\n');
195
+ fixes.push({
196
+ file,
197
+ ruleName: rule.name,
198
+ lineNumber,
199
+ editColumn: 1,
200
+ deleteCount: -1,
201
+ insertText: newText,
202
+ });
203
+ }
204
+ }
205
+ return fixes;
206
+ };
207
+ export const semanticLineBreaks = {
208
+ id: 'semantic-line-breaks',
209
+ fixable: true,
210
+ execute,
211
+ fix,
212
+ };
213
+ //# sourceMappingURL=semantic-line-breaks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-line-breaks.js","sourceRoot":"","sources":["../../../src/rules/scope/semantic-line-breaks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ /**
3
+ * Resolves a `dictionary` option value (the shared base path WITHOUT the
4
+ * `.aff`/`.dic` extension) to its two file paths. Resolved relative to
5
+ * `process.cwd()`, not the config file's directory — consistent with every
6
+ * other file-shaped config value in this package; an absolute path is used
7
+ * as-is.
8
+ *
9
+ * Exported so `../../config/validate.ts`'s dictionary-file-existence check
10
+ * (see `checkSpellingPeerDependencies` there) shares this EXACT resolution
11
+ * rule instead of re-implementing it — a config that validates cleanly must
12
+ * always name the same files `readCustomDictionary` below actually reads at
13
+ * lint time, or validate() and the runtime could silently disagree about
14
+ * which files a `dictionary` path names.
15
+ */
16
+ export declare function resolveDictionaryPaths(dictionaryPath: string): {
17
+ aff: string;
18
+ dic: string;
19
+ };
20
+ /**
21
+ * Formats the fallback message's second `%s` slot: `''` for zero
22
+ * suggestions, or `' — did you mean: a, b, c?'` for one to three.
23
+ * Exported for direct unit testing.
24
+ */
25
+ export declare function formatSuggestionSuffix(suggestions: string[]): string;
26
+ export declare const spelling: ScopeRule;
27
+ //# sourceMappingURL=spelling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spelling.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/spelling.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAuC/D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAK3F;AAuGD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAGpE;AAwGD,eAAO,MAAM,QAAQ,EAAE,SAAuD,CAAC"}