@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,178 @@
1
+ import { formatTemplate } from '../token/messages.js';
2
+ import { newLineRe, offsetToLineColumn } from '../../core/line-endings.js';
3
+ import { applyMatchCase } from '../../core/case-preserve.js';
4
+ // Mechanical proxy for "is this pair a same-word normalization (safe to
5
+ // rewrite blindly) or a substitution that can expand ambiguously (not
6
+ // safe)?" -- same shape as applyMatchCase's multi-word guard in
7
+ // case-preserve.ts: a checkable structural property (word count) that
8
+ // correlates with the semantic hazard, rather than an attempt to
9
+ // understand the words themselves. `colour`/`color` is one word either
10
+ // way. `it's`/`it is` is one word vs. two -- and that word-count jump is
11
+ // exactly where the ambiguity lives: `it's` expands to EITHER "it is" OR
12
+ // "it has", so picking "it is" as the winner and rewriting every "it's" to
13
+ // it is flat wrong whenever the source meant "it has" (see this file's
14
+ // fix() doc comment and the bug this guard closes: "It is fine. ... it's
15
+ // been growing for hours." -> "it is been growing for hours."). Splitting
16
+ // on whitespace is deliberately simple -- like applyMatchCase's `/\s/`
17
+ // check, it does not try to be a linguistic word tokenizer, just a cheap,
18
+ // reliable signal for "the replacement isn't shaped like the match
19
+ // any more."
20
+ //
21
+ // KNOWN EDGE, not fixed here (false positive, accepted cost): this guard
22
+ // cannot distinguish "crosses a word boundary AND is ambiguous" (`it's` ->
23
+ // EITHER "it is" or "it has") from "crosses a word boundary but has only
24
+ // ONE possible expansion" (`don't` -> always "do not", never anything
25
+ // else). `microsoft/contraction-consistency` ships exactly this shape
26
+ // alongside `it's`/`it is`: `don't`/`do not`, `won't`/`will not`, and
27
+ // `isn't`/`is not` are each a single, unambiguous contraction/expansion
28
+ // pair (1 word vs. 2), and this guard blocks fixing all three, same as it
29
+ // blocks `it's`/`it is` -- even though, unlike `it's`, none of them has a
30
+ // second meaning a blind rewrite could pick wrong. `can't`/`cannot` is the
31
+ // one pair in that same rule the guard does NOT block, only because
32
+ // "cannot" happens to be written as one word rather than two ("can not"
33
+ // would trip the guard identically, despite being just as unambiguous as
34
+ // "do not"). Word count is a proxy for "may be ambiguous," not a test of
35
+ // ambiguity itself, so it necessarily also catches unambiguous pairs that
36
+ // merely happen to differ in word count -- the same shape as
37
+ // applyMatchCase's own accepted edge (a hyphen-only replacement counts as
38
+ // "one word" and still gets shouted). Narrowing further (e.g. a hand-listed
39
+ // exception for "known-unambiguous" contractions) would repeat the exact
40
+ // per-pair-criterion pattern this whole change retires elsewhere in this
41
+ // package -- so the false positive is accepted, not patched, and recorded
42
+ // here so it is a known trade-off rather than an undocumented side effect.
43
+ function wordCount(text) {
44
+ return text.trim().split(/\s+/).filter(Boolean).length;
45
+ }
46
+ // On the segment's first line, segment.content starts mid-source-line (e.g.
47
+ // a heading's content excludes the '## ' marker), so segment.startColumn
48
+ // must be added -- see pattern.ts's toSourceColumn.
49
+ function toSourceColumn(segment, localLine, localColumn) {
50
+ return localLine === 1 ? segment.startColumn + (localColumn - 1) : localColumn;
51
+ }
52
+ // Fallback when a programmatically-built rule has no `message` (validate()
53
+ // requires one). %s slots: matched text, then the first-seen winner.
54
+ const FALLBACK_MESSAGE = 'Inconsistent spelling: "%s" conflicts with first-seen "%s".';
55
+ // Shared by execute() and fix(). For each `either` pair, scans ALL segments
56
+ // for BOTH variants (regex-escaped literals with \b word boundaries, like
57
+ // `swap` keys), maps every match to its absolute source position, then:
58
+ //
59
+ // 1. Dedupes by `line:column:variant` BEFORE deciding the winner:
60
+ // overlapping scopes (e.g. `[paragraph, sentence]`) match the same
61
+ // source occurrence once per covering segment, double-counting it and
62
+ // scrambling which variant looks 'first'.
63
+ // 2. Sorts by (line, column): the winner is the first match in SOURCE
64
+ // ORDER, file-wide -- not collection order, which scans the pair's key
65
+ // before its value and would always crown the key.
66
+ //
67
+ // Every later match of the OTHER (losing) variant yields one site.
68
+ function collectMatches(rule, ctx) {
69
+ const options = (rule.assertions['consistency'] ?? {});
70
+ const flags = options.ignoreCase ? 'gi' : 'g';
71
+ const sites = [];
72
+ for (const [key, value] of Object.entries(options.either ?? {})) {
73
+ // Same-word-count guard, computed once per PAIR (not per occurrence):
74
+ // whichever variant wins first-seen, a fix is only offered when the key
75
+ // and value are the same number of words. See wordCount()'s doc comment
76
+ // above for why a word-count mismatch (e.g. `it's` vs. `it is`) is
77
+ // exactly where a contraction's ambiguous expansion lives.
78
+ const fixable = wordCount(key) === wordCount(String(value));
79
+ const seen = new Set();
80
+ const matches = [];
81
+ for (const variant of [key, String(value)]) {
82
+ // An empty variant (only reachable when a caller bypasses validate())
83
+ // would escape to the zero-width `\b\b`, matching nearly every
84
+ // position and spuriously winning as "first-seen". Skip it.
85
+ if (variant.length === 0)
86
+ continue;
87
+ // Same escaping as swap keys: variants are literals, so regex
88
+ // metacharacters (e.g. 'e.g.') must not act as syntax.
89
+ const escaped = variant.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
90
+ const regex = new RegExp(`\\b${escaped}\\b`, flags);
91
+ for (const segment of ctx.segments) {
92
+ // newLineRe, not '\n': a bare split leaves a trailing '\r' on CRLF content.
93
+ const contentLines = segment.content.split(newLineRe);
94
+ regex.lastIndex = 0;
95
+ let match;
96
+ while ((match = regex.exec(segment.content)) !== null) {
97
+ // No zero-width guard needed (unlike swap/conditional/repetition):
98
+ // the empty-variant skip above guarantees `escaped` is a non-empty
99
+ // literal, and \b...\b only adds zero-width assertions around it,
100
+ // so `match[0]` can never be empty here.
101
+ const local = offsetToLineColumn(segment.content, match.index);
102
+ const line = segment.startLine + local.line - 1;
103
+ const column = toSourceColumn(segment, local.line, local.column);
104
+ const positionKey = `${line}:${column}:${variant}`;
105
+ if (seen.has(positionKey))
106
+ continue; // overlapping segments, same source occurrence
107
+ seen.add(positionKey);
108
+ matches.push({
109
+ line,
110
+ column,
111
+ text: match[0],
112
+ lineText: contentLines[local.line - 1] ?? '',
113
+ variant,
114
+ });
115
+ }
116
+ }
117
+ }
118
+ if (matches.length === 0)
119
+ continue;
120
+ matches.sort((a, b) => a.line - b.line || a.column - b.column);
121
+ const winner = matches[0].variant;
122
+ for (const found of matches) {
123
+ if (found.variant !== winner) {
124
+ sites.push({
125
+ line: found.line,
126
+ column: found.column,
127
+ text: found.text,
128
+ lineText: found.lineText,
129
+ winner,
130
+ fixable,
131
+ });
132
+ }
133
+ }
134
+ }
135
+ // Pairs are processed one at a time, so multi-pair results arrive grouped
136
+ // by pair; re-sort so problems/fixes read in source order.
137
+ sites.sort((a, b) => a.line - b.line || a.column - b.column);
138
+ return sites;
139
+ }
140
+ const execute = async (rule, file, ctx) => {
141
+ return collectMatches(rule, ctx).map((site) => ({
142
+ file,
143
+ line: site.line,
144
+ column: site.column,
145
+ text: site.lineText,
146
+ match: site.text,
147
+ ruleName: rule.name,
148
+ severity: rule.severity,
149
+ message: formatTemplate(rule.message ?? FALLBACK_MESSAGE, site.text, site.winner),
150
+ }));
151
+ };
152
+ const fix = async (rule, file, ctx) => {
153
+ // Same-word-count guard (see wordCount()'s doc comment above): a
154
+ // different-word-count pair (e.g. `it's`/`it is`) still gets REPORTED by
155
+ // execute() above -- collectMatches() doesn't distinguish the two
156
+ // functions -- but must never be auto-fixed, so it's filtered out here,
157
+ // after collection, rather than skipped during collection itself.
158
+ return collectMatches(rule, ctx)
159
+ .filter((site) => site.fixable)
160
+ .map((site) => ({
161
+ file,
162
+ ruleName: rule.name,
163
+ lineNumber: site.line,
164
+ editColumn: site.column,
165
+ deleteCount: site.text.length,
166
+ // Apply the MATCHED text's observed casing to the winner, not the
167
+ // winner as authored in config: with `ignoreCase: true`, a
168
+ // sentence-initial 'Behaviour' would otherwise be replaced by the
169
+ // literal (lowercase-first) authored winner 'behavior', silently
170
+ // lowercasing the start of the sentence -- the exact hazard
171
+ // applyMatchCase exists to prevent, and swap.ts:177 already guards
172
+ // against for the `swap` assertion. `consistency` shares the same
173
+ // ignoreCase/fix shape, so it needs the same guard.
174
+ insertText: applyMatchCase(site.text, site.winner),
175
+ }));
176
+ };
177
+ export const consistency = { id: 'consistency', fixable: true, execute, fix };
178
+ //# sourceMappingURL=consistency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistency.js","sourceRoot":"","sources":["../../../src/rules/scope/consistency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ export declare const length: ScopeRule;
3
+ //# sourceMappingURL=length.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"length.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/length.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAsF/D,eAAO,MAAM,MAAM,EAAE,SAAqD,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { formatTemplate } from '../token/messages.js';
2
+ import { newLineRe } from '../../core/line-endings.js';
3
+ import { splitSentences } from '../../scopes/sentences.js';
4
+ import { tokenizeWords } from '../../metrics/statistics.js';
5
+ const FALLBACK_MAX = 'Segment is %s %s; at most %s allowed';
6
+ const FALLBACK_MIN = 'Segment is %s %s; at least %s required';
7
+ // Single measurement helper, used by nothing else: `sentences` delegates to
8
+ // the shared sentence-boundary definition (scopes/sentences.ts), and `words`
9
+ // delegates to the metrics module's own tokenizer (see its export-site
10
+ // comment for why sharing that implementation with `metric` matters).
11
+ //
12
+ // `characters` takes the whole segment, not just its content, because a masked
13
+ // markdoc tag's span is blanked to same-width spaces rather than removed.
14
+ // `tokenizeWords` and `splitSentences` already read through that mask
15
+ // correctly, treating a run of blanks as a gap like real whitespace, but a raw
16
+ // `content.length` would count those invisible characters as visible prose:
17
+ // `# Head text {% #averylonganchorname %}` measured 36 characters for the 10 a
18
+ // reader actually sees. Subtracting each masked span's width corrects the
19
+ // count. A segment that was never masked has no `maskedRanges`, so this is
20
+ // exactly `content.length`.
21
+ function measure(segment, unit) {
22
+ const { content } = segment;
23
+ if (unit === 'characters') {
24
+ const maskedWidth = (segment.maskedRanges ?? []).reduce((total, range) => total + (range.end - range.start), 0);
25
+ return content.length - maskedWidth;
26
+ }
27
+ if (unit === 'sentences')
28
+ return splitSentences(content).length;
29
+ return tokenizeWords(content).length;
30
+ }
31
+ // Recheck-original `length` check: measures each scoped segment's size and
32
+ // flags it when the measurement falls outside `[min, max]`. Detection-only
33
+ // -- like `occurrence`, a size violation has no single position to anchor
34
+ // an edit to (shrinking or growing a segment to fit is an editorial
35
+ // decision, not a mechanical rewrite). Unlike `metric`, this honors
36
+ // whichever `scope` the rule configures -- e.g. `scope: alt` to cap image
37
+ // alt text length, `scope: sentence` to cap sentence length in words.
38
+ const execute = async (rule, file, ctx) => {
39
+ const problems = [];
40
+ const o = rule.assertions['length'];
41
+ for (const segment of ctx.segments) {
42
+ const size = measure(segment, o.unit);
43
+ const tooSmall = o.min !== undefined && size < o.min;
44
+ const tooLarge = o.max !== undefined && size > o.max;
45
+ if (!tooSmall && !tooLarge)
46
+ continue;
47
+ // Picking `tooSmall`'s branch first is only exhaustive because
48
+ // validate() rejects `min > max`, so a segment can never be both
49
+ // tooSmall and tooLarge at once -- a hand-built rule that skips
50
+ // validate() must preserve that invariant itself or this silently
51
+ // reports the wrong bound.
52
+ const bound = tooSmall ? o.min : o.max;
53
+ problems.push({
54
+ file,
55
+ line: segment.startLine,
56
+ column: segment.startColumn,
57
+ // newLineRe, not '\n': a bare split leaves a trailing '\r' on CRLF
58
+ // content (see occurrence.ts).
59
+ text: segment.content.split(newLineRe)[0] ?? '',
60
+ match: String(size),
61
+ ruleName: rule.name,
62
+ severity: rule.severity,
63
+ message: formatTemplate(rule.message ?? (tooSmall ? FALLBACK_MIN : FALLBACK_MAX), String(size), o.unit, String(bound)),
64
+ });
65
+ }
66
+ return problems;
67
+ };
68
+ export const length = { id: 'length', fixable: false, execute };
69
+ //# sourceMappingURL=length.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"length.js","sourceRoot":"","sources":["../../../src/rules/scope/length.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ export declare const maxImageSize: ScopeRule;
3
+ //# sourceMappingURL=max-image-size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"max-image-size.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/max-image-size.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AA0F/D,eAAO,MAAM,YAAY,EAAE,SAA6D,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { newLineRe } from '../../core/line-endings.js';
2
+ import { getImageDestinations, hasOverlap } from '../token/helpers.js';
3
+ function getFileExtension(filePath) {
4
+ const lastDot = filePath.lastIndexOf('.');
5
+ return lastDot === -1 ? '' : filePath.substring(lastDot + 1).toLowerCase();
6
+ }
7
+ // `ctx.segments` is a single synthetic `scope: 'all'` segment (see
8
+ // `wholeFileSegment` in core/runner.ts) exactly when the rule is unscoped
9
+ // (the default) — `extractScopes` itself never emits a segment with that
10
+ // scope name, so this check is an unambiguous whole-file-vs-scoped
11
+ // discriminator, matching the convention documented for scope rules in
12
+ // rules/CONTRIBUTING.md ("Unscoped rules (`scope: all`, the default):
13
+ // `ctx.segments` is a single whole-file segment with `scope: 'all'`").
14
+ function isWholeFile(segments) {
15
+ return segments.length === 1 && segments[0].scope === 'all';
16
+ }
17
+ const execute = async (rule, file, ctx) => {
18
+ const problems = [];
19
+ const options = rule.assertions['max-image-size'];
20
+ const maxSizeKB = options?.maxSizeKB ?? 100;
21
+ const allowedExtensions = new Set(options?.extensions ?? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg']);
22
+ const maxSizeBytes = maxSizeKB * 1024;
23
+ // Reference-style destinations (`![alt][ref]`) resolve against
24
+ // definitions anywhere in the document, so resolution always runs over
25
+ // the whole tree; only the resulting image tokens are scope-filtered
26
+ // below, matching how every other scope rule narrows to `ctx.segments`
27
+ // without re-deriving cross-references itself.
28
+ const wholeFile = isWholeFile(ctx.segments);
29
+ const images = getImageDestinations(ctx.tree).filter(({ token }) => wholeFile || ctx.segments.some((segment) => hasOverlap(segment, token)));
30
+ // newLineRe (never a bare '\n'): these lines feed Problem.text, and a
31
+ // '\n' split of CRLF content would leave a trailing '\r' on each one.
32
+ const lines = ctx.content.split(newLineRe);
33
+ for (const { token, destination } of images) {
34
+ if (destination.startsWith('http://') || destination.startsWith('https://')) {
35
+ continue;
36
+ }
37
+ const extension = getFileExtension(destination);
38
+ if (!allowedExtensions.has(extension)) {
39
+ continue;
40
+ }
41
+ const imageMetadata = ctx.fileMetadata?.images?.get(destination);
42
+ if (!imageMetadata) {
43
+ continue;
44
+ }
45
+ if (!imageMetadata.exists) {
46
+ continue;
47
+ }
48
+ if (imageMetadata.size > maxSizeBytes) {
49
+ const actualSizeKB = Math.round(imageMetadata.size / 1024);
50
+ problems.push({
51
+ file,
52
+ line: token.startLine,
53
+ column: token.startColumn,
54
+ text: lines[token.startLine - 1] || '',
55
+ match: token.text,
56
+ ruleName: rule.name,
57
+ severity: rule.severity,
58
+ message: (rule.message ?? '').replace('%s', `${destination} (${actualSizeKB}KB > ${maxSizeKB}KB)`),
59
+ });
60
+ }
61
+ }
62
+ return problems;
63
+ };
64
+ export const maxImageSize = { id: 'max-image-size', fixable: false, execute };
65
+ //# sourceMappingURL=max-image-size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"max-image-size.js","sourceRoot":"","sources":["../../../src/rules/scope/max-image-size.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ /**
3
+ * Strips markup that is never readable prose (Markdoc tag markers, inline
4
+ * code spans) from RAW segment text -- i.e. text that has not already been
5
+ * structurally masked, see `MARKDOC_TAG_RE`'s comment. Inline code spans
6
+ * are REMOVED outright (not masked-and-restored like
7
+ * capitalization.ts/spelling.ts do): there is no position-sensitive rewrite
8
+ * downstream to keep offsets aligned for, just a word/syllable count that
9
+ * must never include a code span's content. BACKTICK_SPAN_RE
10
+ * (core/inline-code.ts) gives this the same CommonMark-correct
11
+ * open-run/close-run-of-equal-length span recognition capitalization.ts and
12
+ * spelling.ts use, including a span whose content itself contains a
13
+ * shorter, unpaired backtick run. Exported for direct unit testing.
14
+ */
15
+ export declare function stripNonProse(text: string): string;
16
+ export declare const metric: ScopeRule;
17
+ //# sourceMappingURL=metric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/metric.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAwB/D;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AA4MD,eAAO,MAAM,MAAM,EAAE,SAAqD,CAAC"}
@@ -0,0 +1,216 @@
1
+ import { formatTemplate } from '../token/messages.js';
2
+ import { computeTextStatistics, computeReadability } from '../../metrics/index.js';
3
+ import { BACKTICK_SPAN_RE } from '../../core/inline-code.js';
4
+ /**
5
+ * Markdoc tag-marker spans -- `{% tag attr="x" %}`, `{% /tag %}`, and the
6
+ * `{%- ... -%}` whitespace-trim variant. Non-greedy (`[\s\S]*?`) so it stops
7
+ * at the NEAREST `%}`: back-to-back tags like `{% admonition %}` ...
8
+ * `{% /admonition %}` each strip as their OWN span rather than one tag's
9
+ * opener swallowing everything up to the other tag's closer -- which would
10
+ * delete the prose BETWEEN them too.
11
+ *
12
+ * Only used when markdoc parsing is off. With it on, `maskProse` in
13
+ * scopes/extractor.ts has already found every real `markdocTag` token and
14
+ * recorded its exact span in the segment's `maskedRanges`, so `extractProse`
15
+ * below splices those spans out instead of re-discovering tags with this
16
+ * regex. The regex is still needed with the flag off: the parser doesn't
17
+ * recognize tags at all in that mode, so `{% ... %}` is just ordinary text and
18
+ * nothing else keeps it out of the readability formulas.
19
+ */
20
+ const MARKDOC_TAG_RE = /\{%-?[\s\S]*?-?%\}/g;
21
+ /**
22
+ * Strips markup that is never readable prose (Markdoc tag markers, inline
23
+ * code spans) from RAW segment text -- i.e. text that has not already been
24
+ * structurally masked, see `MARKDOC_TAG_RE`'s comment. Inline code spans
25
+ * are REMOVED outright (not masked-and-restored like
26
+ * capitalization.ts/spelling.ts do): there is no position-sensitive rewrite
27
+ * downstream to keep offsets aligned for, just a word/syllable count that
28
+ * must never include a code span's content. BACKTICK_SPAN_RE
29
+ * (core/inline-code.ts) gives this the same CommonMark-correct
30
+ * open-run/close-run-of-equal-length span recognition capitalization.ts and
31
+ * spelling.ts use, including a span whose content itself contains a
32
+ * shorter, unpaired backtick run. Exported for direct unit testing.
33
+ */
34
+ export function stripNonProse(text) {
35
+ return text.replace(MARKDOC_TAG_RE, '').replace(BACKTICK_SPAN_RE, '');
36
+ }
37
+ /**
38
+ * Counterpart to `stripNonProse` for a masked segment: its tag spans are
39
+ * already known exactly (`segment.maskedRanges`, set by `maskProse` only when
40
+ * it actually blanked something), so this splices each span out of `content`
41
+ * rather than leaving the mask's same-width spaces in place.
42
+ *
43
+ * Deletion, not blanking, matters here. `length.ts`'s `measure()` only needs a
44
+ * width to subtract from a character count, so reading through the mask as if
45
+ * it were whitespace is harmless there. `metric` tokenizes words by splitting
46
+ * on whitespace, so mask spaces are not interchangeable with deletion whenever
47
+ * a tag sits flush against real text with no separating space — for example
48
+ * `<code>{% $optionName %}</code>`, a shape that occurs in the repo's own docs.
49
+ * Left as mask spaces, `<code>` and `</code>` tokenize as two separate words;
50
+ * deleting the span joins them back into the single adjacent run they actually
51
+ * are. Splicing reproduces exactly what the regex strip did on unmasked source.
52
+ */
53
+ function spliceOutMaskedSpans(segment) {
54
+ const ranges = segment.maskedRanges;
55
+ if (ranges === undefined)
56
+ return segment.content;
57
+ let result = '';
58
+ let cursor = 0;
59
+ for (const range of ranges) {
60
+ // `maskedRanges` is produced ascending and non-overlapping (maskProse
61
+ // sorts and clamps; shiftRanges preserves order). The clamp here mirrors
62
+ // maskProse's own defense: an out-of-order range would otherwise move
63
+ // `cursor` backward and re-emit already-copied characters.
64
+ result += segment.content.slice(cursor, Math.max(range.start, cursor));
65
+ cursor = Math.max(range.end, cursor);
66
+ }
67
+ return result + segment.content.slice(cursor);
68
+ }
69
+ const FALLBACK_MESSAGE = 'Readability (%s) is %s; expected between %s and %s.';
70
+ // Compares two (line, column) source positions the way source order does:
71
+ // earlier line first, then earlier column on the same line.
72
+ function comparePosition(aLine, aColumn, bLine, bColumn) {
73
+ return aLine - bLine || aColumn - bColumn;
74
+ }
75
+ /**
76
+ * Whether `outer`'s span fully contains `inner`'s -- `outer` starts at or
77
+ * before `inner` and ends at or after it. `startLine`/`startColumn`/
78
+ * `endLine`/`endColumn` are already the exact verbatim source span each
79
+ * segment's `content` covers (see extractor.ts's `segmentFromToken` and the
80
+ * `tableRow` case's explicit anchor/trim arithmetic), so containment can be
81
+ * decided directly from those four numbers -- no separate span needs
82
+ * re-deriving from `content` (e.g. via counting newlines) here.
83
+ */
84
+ function spanContains(outer, inner) {
85
+ return (comparePosition(outer.startLine, outer.startColumn, inner.startLine, inner.startColumn) <= 0 &&
86
+ comparePosition(outer.endLine, outer.endColumn, inner.endLine, inner.endColumn) >= 0);
87
+ }
88
+ /**
89
+ * Dedupes prose segments whose source span is fully nested inside another
90
+ * kept segment's span. A list nested inside a blockquote emits BOTH the
91
+ * blockquote segment (its whole raw body, list markup and all) AND each
92
+ * list-item segment (the same words again, just the item's own subspan);
93
+ * a blockquote nested inside another blockquote is the same shape one
94
+ * level up. Left uncaught, the nested words are scored twice and
95
+ * readability drifts. The old dedup only matched IDENTICAL start
96
+ * positions, which misses every one of these cases (the nested segment
97
+ * starts later than its container).
98
+ *
99
+ * Segments are sorted by (startLine, startColumn) ascending so a container
100
+ * is always visited before anything nested inside it; ties (a container
101
+ * and its first child starting at the exact same position, e.g. a
102
+ * blockquote and its very first list item) are broken by span
103
+ * DESCENDING -- the later-ending segment first -- so the outer container is
104
+ * always the one considered "already kept" when its nested sibling is
105
+ * checked, never the other way around.
106
+ *
107
+ * `stack` holds the chain of still-open containers, innermost last. Only
108
+ * the top is ever checked against a new candidate: markdown block spans
109
+ * form a laminar family (any two are either disjoint or one fully
110
+ * contains the other, never a partial "crossing" overlap), so once
111
+ * containers whose span has already ended (`end < candidate.start`) are
112
+ * popped off, the remaining top is the ONLY still-open span the next
113
+ * candidate could possibly nest inside. This is what keeps same-line
114
+ * SIBLINGS with disjoint spans (e.g. two table cells on one row) safe:
115
+ * each one's span ends before the next one's begins, so it is popped
116
+ * before the next is checked, and neither is ever mistaken for containing
117
+ * the other.
118
+ */
119
+ function dedupeBySpanContainment(segments) {
120
+ const ordered = [...segments].sort((a, b) => {
121
+ const byStart = comparePosition(a.startLine, a.startColumn, b.startLine, b.startColumn);
122
+ if (byStart !== 0)
123
+ return byStart;
124
+ return comparePosition(b.endLine, b.endColumn, a.endLine, a.endColumn);
125
+ });
126
+ const stack = [];
127
+ const kept = [];
128
+ for (const segment of ordered) {
129
+ while (stack.length > 0) {
130
+ const top = stack[stack.length - 1];
131
+ if (comparePosition(top.endLine, top.endColumn, segment.startLine, segment.startColumn) < 0) {
132
+ stack.pop();
133
+ }
134
+ else {
135
+ break;
136
+ }
137
+ }
138
+ const container = stack[stack.length - 1];
139
+ if (container && spanContains(container, segment))
140
+ continue;
141
+ kept.push(segment);
142
+ stack.push(segment);
143
+ }
144
+ return kept;
145
+ }
146
+ /**
147
+ * Builds the whole-document prose string `metric` scores against, from
148
+ * `ctx.segments`.
149
+ *
150
+ * `metric` rules are always summary-scoped: config normalization
151
+ * (config/validate.ts, normalizeMetricScope) forces `scope: 'summary'` on
152
+ * every rule with a `metric` assertion — readability is a whole-document
153
+ * score over the document's prose, exactly what the extractor's `summary`
154
+ * segments carry — so `ctx.segments` arrives as those summary segments and
155
+ * no scope re-extraction happens here. See the README's `metric` entry.
156
+ */
157
+ function extractProse(ctx) {
158
+ // Span-containment dedup: a segment fully nested inside another kept
159
+ // segment's source span must not have its text counted a second time --
160
+ // see dedupeBySpanContainment. The extractor already avoids the most
161
+ // common case on its own (see its `isNestedContainerParagraph`), but
162
+ // this catches every other overlap among the summary segments too
163
+ // (e.g. a list nested inside a blockquote).
164
+ const deduped = dedupeBySpanContainment(ctx.segments);
165
+ // Re-sort explicitly so the joined prose's sentence order can never
166
+ // depend on the extractor's traversal order (or dedupeBySpanContainment's
167
+ // own tie-breaking order, which favors span DESC, not source order).
168
+ deduped.sort((a, b) => a.startLine - b.startLine || a.startColumn - b.startColumn);
169
+ return deduped
170
+ .map((segment) => segment.maskedRanges !== undefined
171
+ ? // This segment's tag spans are already known exactly, so splice them
172
+ // out directly instead of re-discovering them with MARKDOC_TAG_RE,
173
+ // which couldn't match them anyway now that their `{`/`%` characters
174
+ // are mask spaces. Backtick stripping still runs: masking never
175
+ // touches inline code spans.
176
+ spliceOutMaskedSpans(segment).replace(BACKTICK_SPAN_RE, '')
177
+ : // Markdoc parsing off, or a tag the extractor never recognized as one
178
+ // (e.g. written inside an inline code span): content still carries
179
+ // whatever raw markup it always did, so fall back to the regex-based
180
+ // strip.
181
+ stripNonProse(segment.content))
182
+ .join('\n');
183
+ }
184
+ const execute = async (rule, file, ctx) => {
185
+ const options = rule.assertions['metric'];
186
+ const prose = extractProse(ctx);
187
+ const stats = computeTextStatistics(prose);
188
+ // computeReadability returns 0 for zero words/sentences as a "not enough
189
+ // text to score" placeholder (see metrics/formulas.ts), not a genuine
190
+ // score -- a file with no prose must never be flagged as "too low", so
191
+ // skip the bounds check entirely.
192
+ if (stats.words === 0 || stats.sentences === 0)
193
+ return [];
194
+ const score = computeReadability(options.formula, stats);
195
+ const tooLow = options.min !== undefined && score < options.min;
196
+ const tooHigh = options.max !== undefined && score > options.max;
197
+ if (!tooLow && !tooHigh)
198
+ return [];
199
+ // Detection-only, whole-document: always exactly one problem, always at
200
+ // line 1 column 1 -- there is no single source position a readability
201
+ // score "belongs" to.
202
+ return [
203
+ {
204
+ file,
205
+ line: 1,
206
+ column: 1,
207
+ text: '',
208
+ match: '',
209
+ ruleName: rule.name,
210
+ severity: rule.severity,
211
+ message: formatTemplate(rule.message ?? FALLBACK_MESSAGE, options.formula, String(score), options.min !== undefined ? String(options.min) : '-∞', options.max !== undefined ? String(options.max) : '∞'),
212
+ },
213
+ ];
214
+ };
215
+ export const metric = { id: 'metric', fixable: false, execute };
216
+ //# sourceMappingURL=metric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric.js","sourceRoot":"","sources":["../../../src/rules/scope/metric.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ScopeRule } from '../types.js';
2
+ export declare const occurrence: ScopeRule;
3
+ //# sourceMappingURL=occurrence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occurrence.d.ts","sourceRoot":"","sources":["../../../src/rules/scope/occurrence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AA2D/D,eAAO,MAAM,UAAU,EAAE,SAAyD,CAAC"}