chaffjs 0.20.0 → 0.22.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 (762) hide show
  1. package/README.md +7 -5
  2. package/dist/api.d.ts +16 -1
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js.map +1 -1
  5. package/dist/cli-text.d.ts +2 -0
  6. package/dist/cli-text.d.ts.map +1 -1
  7. package/dist/cli-text.js +18 -5
  8. package/dist/cli-text.js.map +1 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +8 -11
  11. package/dist/cli.js.map +1 -1
  12. package/dist/command-help.d.ts +7 -0
  13. package/dist/command-help.d.ts.map +1 -0
  14. package/dist/command-help.js +18 -0
  15. package/dist/command-help.js.map +1 -0
  16. package/dist/commands/eval.js +2 -2
  17. package/dist/commands/eval.js.map +1 -1
  18. package/dist/commands/fix-plan.d.ts.map +1 -1
  19. package/dist/commands/fix-plan.js +11 -1
  20. package/dist/commands/fix-plan.js.map +1 -1
  21. package/dist/commands/help.d.ts +4 -0
  22. package/dist/commands/help.d.ts.map +1 -0
  23. package/dist/commands/help.js +7 -0
  24. package/dist/commands/help.js.map +1 -0
  25. package/dist/commands/init-command.d.ts +4 -0
  26. package/dist/commands/init-command.d.ts.map +1 -0
  27. package/dist/commands/init-command.js +15 -0
  28. package/dist/commands/init-command.js.map +1 -0
  29. package/dist/commands/plugin-init.d.ts +20 -0
  30. package/dist/commands/plugin-init.d.ts.map +1 -0
  31. package/dist/commands/plugin-init.js +129 -0
  32. package/dist/commands/plugin-init.js.map +1 -0
  33. package/dist/commands/plugin-test.d.ts +11 -0
  34. package/dist/commands/plugin-test.d.ts.map +1 -0
  35. package/dist/commands/plugin-test.js +81 -0
  36. package/dist/commands/plugin-test.js.map +1 -0
  37. package/dist/config/load.d.ts +2 -0
  38. package/dist/config/load.d.ts.map +1 -1
  39. package/dist/config/load.js +1 -0
  40. package/dist/config/load.js.map +1 -1
  41. package/dist/config/option-problems.js +2 -2
  42. package/dist/config/option-problems.js.map +1 -1
  43. package/dist/config/rule-problems.js +2 -2
  44. package/dist/config/rule-problems.js.map +1 -1
  45. package/dist/custom/checked.d.ts +9 -0
  46. package/dist/custom/checked.d.ts.map +1 -0
  47. package/dist/custom/checked.js +3 -0
  48. package/dist/custom/checked.js.map +1 -0
  49. package/dist/custom/dsl-fields.d.ts +27 -0
  50. package/dist/custom/dsl-fields.d.ts.map +1 -0
  51. package/dist/custom/dsl-fields.js +86 -0
  52. package/dist/custom/dsl-fields.js.map +1 -0
  53. package/dist/custom/load.d.ts.map +1 -1
  54. package/dist/custom/load.js +2 -0
  55. package/dist/custom/load.js.map +1 -1
  56. package/dist/custom/parse.d.ts +14 -3
  57. package/dist/custom/parse.d.ts.map +1 -1
  58. package/dist/custom/parse.js +44 -40
  59. package/dist/custom/parse.js.map +1 -1
  60. package/dist/custom/problems.d.ts.map +1 -1
  61. package/dist/custom/problems.js +10 -1
  62. package/dist/custom/problems.js.map +1 -1
  63. package/dist/detectors/amount-for-count.d.ts +21 -0
  64. package/dist/detectors/amount-for-count.d.ts.map +1 -0
  65. package/dist/detectors/amount-for-count.js +55 -0
  66. package/dist/detectors/amount-for-count.js.map +1 -0
  67. package/dist/detectors/blank-structure.d.ts.map +1 -1
  68. package/dist/detectors/blank-structure.js +6 -4
  69. package/dist/detectors/blank-structure.js.map +1 -1
  70. package/dist/detectors/clause-shape.d.ts +22 -0
  71. package/dist/detectors/clause-shape.d.ts.map +1 -0
  72. package/dist/detectors/clause-shape.js +149 -0
  73. package/dist/detectors/clause-shape.js.map +1 -0
  74. package/dist/detectors/code-fences.d.ts +34 -0
  75. package/dist/detectors/code-fences.d.ts.map +1 -0
  76. package/dist/detectors/code-fences.js +100 -0
  77. package/dist/detectors/code-fences.js.map +1 -0
  78. package/dist/detectors/cross-definitions.d.ts +4 -0
  79. package/dist/detectors/cross-definitions.d.ts.map +1 -0
  80. package/dist/detectors/cross-definitions.js +43 -0
  81. package/dist/detectors/cross-definitions.js.map +1 -0
  82. package/dist/detectors/cross-facts.d.ts +4 -0
  83. package/dist/detectors/cross-facts.d.ts.map +1 -0
  84. package/dist/detectors/cross-facts.js +53 -0
  85. package/dist/detectors/cross-facts.js.map +1 -0
  86. package/dist/detectors/cross-registry/cross-doc-duplicate-definition.d.ts +3 -0
  87. package/dist/detectors/cross-registry/cross-doc-duplicate-definition.d.ts.map +1 -0
  88. package/dist/detectors/cross-registry/cross-doc-duplicate-definition.js +3 -0
  89. package/dist/detectors/cross-registry/cross-doc-duplicate-definition.js.map +1 -0
  90. package/dist/detectors/cross-registry/cross-doc-fact-conflict.d.ts +3 -0
  91. package/dist/detectors/cross-registry/cross-doc-fact-conflict.d.ts.map +1 -0
  92. package/dist/detectors/cross-registry/cross-doc-fact-conflict.js +3 -0
  93. package/dist/detectors/cross-registry/cross-doc-fact-conflict.js.map +1 -0
  94. package/dist/detectors/currency-notation.d.ts +29 -0
  95. package/dist/detectors/currency-notation.d.ts.map +1 -0
  96. package/dist/detectors/currency-notation.js +58 -0
  97. package/dist/detectors/currency-notation.js.map +1 -0
  98. package/dist/detectors/custom.d.ts.map +1 -1
  99. package/dist/detectors/custom.js +4 -1
  100. package/dist/detectors/custom.js.map +1 -1
  101. package/dist/detectors/dangling-opener.d.ts +14 -0
  102. package/dist/detectors/dangling-opener.d.ts.map +1 -0
  103. package/dist/detectors/dangling-opener.js +55 -0
  104. package/dist/detectors/dangling-opener.js.map +1 -0
  105. package/dist/detectors/defined-term-form.d.ts +25 -0
  106. package/dist/detectors/defined-term-form.d.ts.map +1 -0
  107. package/dist/detectors/defined-term-form.js +170 -0
  108. package/dist/detectors/defined-term-form.js.map +1 -0
  109. package/dist/detectors/email-letter.d.ts +46 -0
  110. package/dist/detectors/email-letter.d.ts.map +1 -0
  111. package/dist/detectors/email-letter.js +234 -0
  112. package/dist/detectors/email-letter.js.map +1 -0
  113. package/dist/detectors/footnote-mismatch.d.ts +11 -0
  114. package/dist/detectors/footnote-mismatch.d.ts.map +1 -0
  115. package/dist/detectors/footnote-mismatch.js +55 -0
  116. package/dist/detectors/footnote-mismatch.js.map +1 -0
  117. package/dist/detectors/form-minority.d.ts +13 -0
  118. package/dist/detectors/form-minority.d.ts.map +1 -0
  119. package/dist/detectors/form-minority.js +19 -0
  120. package/dist/detectors/form-minority.js.map +1 -0
  121. package/dist/detectors/heading-end-mark.d.ts +10 -0
  122. package/dist/detectors/heading-end-mark.d.ts.map +1 -0
  123. package/dist/detectors/heading-end-mark.js +59 -0
  124. package/dist/detectors/heading-end-mark.js.map +1 -0
  125. package/dist/detectors/impossible-date.d.ts +20 -0
  126. package/dist/detectors/impossible-date.d.ts.map +1 -0
  127. package/dist/detectors/impossible-date.js +105 -0
  128. package/dist/detectors/impossible-date.js.map +1 -0
  129. package/dist/detectors/impossible-time.d.ts +18 -0
  130. package/dist/detectors/impossible-time.d.ts.map +1 -0
  131. package/dist/detectors/impossible-time.js +116 -0
  132. package/dist/detectors/impossible-time.js.map +1 -0
  133. package/dist/detectors/link-shape.d.ts +11 -0
  134. package/dist/detectors/link-shape.d.ts.map +1 -0
  135. package/dist/detectors/link-shape.js +56 -0
  136. package/dist/detectors/link-shape.js.map +1 -0
  137. package/dist/detectors/list-marker.d.ts +7 -0
  138. package/dist/detectors/list-marker.d.ts.map +1 -0
  139. package/dist/detectors/list-marker.js +50 -0
  140. package/dist/detectors/list-marker.js.map +1 -0
  141. package/dist/detectors/mark-shape.d.ts +53 -0
  142. package/dist/detectors/mark-shape.d.ts.map +1 -0
  143. package/dist/detectors/mark-shape.js +160 -0
  144. package/dist/detectors/mark-shape.js.map +1 -0
  145. package/dist/detectors/markdown-slip.d.ts +19 -0
  146. package/dist/detectors/markdown-slip.d.ts.map +1 -0
  147. package/dist/detectors/markdown-slip.js +122 -0
  148. package/dist/detectors/markdown-slip.js.map +1 -0
  149. package/dist/detectors/numeral-opener.d.ts +10 -0
  150. package/dist/detectors/numeral-opener.d.ts.map +1 -0
  151. package/dist/detectors/numeral-opener.js +65 -0
  152. package/dist/detectors/numeral-opener.js.map +1 -0
  153. package/dist/detectors/ordinal-suffix.d.ts +12 -0
  154. package/dist/detectors/ordinal-suffix.d.ts.map +1 -0
  155. package/dist/detectors/ordinal-suffix.js +33 -0
  156. package/dist/detectors/ordinal-suffix.js.map +1 -0
  157. package/dist/detectors/range-notation.d.ts +15 -0
  158. package/dist/detectors/range-notation.d.ts.map +1 -0
  159. package/dist/detectors/range-notation.js +58 -0
  160. package/dist/detectors/range-notation.js.map +1 -0
  161. package/dist/detectors/registry/adverb-polarity.d.ts +3 -0
  162. package/dist/detectors/registry/adverb-polarity.d.ts.map +1 -0
  163. package/dist/detectors/registry/adverb-polarity.js +3 -0
  164. package/dist/detectors/registry/adverb-polarity.js.map +1 -0
  165. package/dist/detectors/registry/amount-for-count.d.ts +3 -0
  166. package/dist/detectors/registry/amount-for-count.d.ts.map +1 -0
  167. package/dist/detectors/registry/amount-for-count.js +3 -0
  168. package/dist/detectors/registry/amount-for-count.js.map +1 -0
  169. package/dist/detectors/registry/attachment-missing.d.ts +3 -0
  170. package/dist/detectors/registry/attachment-missing.d.ts.map +1 -0
  171. package/dist/detectors/registry/attachment-missing.js +3 -0
  172. package/dist/detectors/registry/attachment-missing.js.map +1 -0
  173. package/dist/detectors/registry/bare-url-mix.d.ts +3 -0
  174. package/dist/detectors/registry/bare-url-mix.d.ts.map +1 -0
  175. package/dist/detectors/registry/bare-url-mix.js +3 -0
  176. package/dist/detectors/registry/bare-url-mix.js.map +1 -0
  177. package/dist/detectors/registry/caps-shouting.d.ts +3 -0
  178. package/dist/detectors/registry/caps-shouting.d.ts.map +1 -0
  179. package/dist/detectors/registry/caps-shouting.js +3 -0
  180. package/dist/detectors/registry/caps-shouting.js.map +1 -0
  181. package/dist/detectors/registry/code-fence-language.d.ts +3 -0
  182. package/dist/detectors/registry/code-fence-language.d.ts.map +1 -0
  183. package/dist/detectors/registry/code-fence-language.js +3 -0
  184. package/dist/detectors/registry/code-fence-language.js.map +1 -0
  185. package/dist/detectors/registry/currency-notation.d.ts +3 -0
  186. package/dist/detectors/registry/currency-notation.d.ts.map +1 -0
  187. package/dist/detectors/registry/currency-notation.js +3 -0
  188. package/dist/detectors/registry/currency-notation.js.map +1 -0
  189. package/dist/detectors/registry/dangling-opener.d.ts +3 -0
  190. package/dist/detectors/registry/dangling-opener.d.ts.map +1 -0
  191. package/dist/detectors/registry/dangling-opener.js +3 -0
  192. package/dist/detectors/registry/dangling-opener.js.map +1 -0
  193. package/dist/detectors/registry/defined-name-repeated.d.ts +3 -0
  194. package/dist/detectors/registry/defined-name-repeated.d.ts.map +1 -0
  195. package/dist/detectors/registry/defined-name-repeated.js +3 -0
  196. package/dist/detectors/registry/defined-name-repeated.js.map +1 -0
  197. package/dist/detectors/registry/defined-term-form.d.ts +3 -0
  198. package/dist/detectors/registry/defined-term-form.d.ts.map +1 -0
  199. package/dist/detectors/registry/defined-term-form.js +3 -0
  200. package/dist/detectors/registry/defined-term-form.js.map +1 -0
  201. package/dist/detectors/registry/email-frame.d.ts +3 -0
  202. package/dist/detectors/registry/email-frame.d.ts.map +1 -0
  203. package/dist/detectors/registry/email-frame.js +3 -0
  204. package/dist/detectors/registry/email-frame.js.map +1 -0
  205. package/dist/detectors/registry/email-subject.d.ts +3 -0
  206. package/dist/detectors/registry/email-subject.d.ts.map +1 -0
  207. package/dist/detectors/registry/email-subject.js +3 -0
  208. package/dist/detectors/registry/email-subject.js.map +1 -0
  209. package/dist/detectors/registry/ending-run.d.ts +3 -0
  210. package/dist/detectors/registry/ending-run.d.ts.map +1 -0
  211. package/dist/detectors/registry/ending-run.js +3 -0
  212. package/dist/detectors/registry/ending-run.js.map +1 -0
  213. package/dist/detectors/registry/footnote-mismatch.d.ts +3 -0
  214. package/dist/detectors/registry/footnote-mismatch.d.ts.map +1 -0
  215. package/dist/detectors/registry/footnote-mismatch.js +3 -0
  216. package/dist/detectors/registry/footnote-mismatch.js.map +1 -0
  217. package/dist/detectors/registry/heading-command.d.ts +3 -0
  218. package/dist/detectors/registry/heading-command.d.ts.map +1 -0
  219. package/dist/detectors/registry/heading-command.js +3 -0
  220. package/dist/detectors/registry/heading-command.js.map +1 -0
  221. package/dist/detectors/registry/heading-end-punctuation.d.ts +3 -0
  222. package/dist/detectors/registry/heading-end-punctuation.d.ts.map +1 -0
  223. package/dist/detectors/registry/heading-end-punctuation.js +3 -0
  224. package/dist/detectors/registry/heading-end-punctuation.js.map +1 -0
  225. package/dist/detectors/registry/hyphen-dash.d.ts +3 -0
  226. package/dist/detectors/registry/hyphen-dash.d.ts.map +1 -0
  227. package/dist/detectors/registry/hyphen-dash.js +3 -0
  228. package/dist/detectors/registry/hyphen-dash.js.map +1 -0
  229. package/dist/detectors/registry/image-file-name-alt.d.ts +3 -0
  230. package/dist/detectors/registry/image-file-name-alt.d.ts.map +1 -0
  231. package/dist/detectors/registry/image-file-name-alt.js +3 -0
  232. package/dist/detectors/registry/image-file-name-alt.js.map +1 -0
  233. package/dist/detectors/registry/impossible-date.d.ts +3 -0
  234. package/dist/detectors/registry/impossible-date.d.ts.map +1 -0
  235. package/dist/detectors/registry/impossible-date.js +3 -0
  236. package/dist/detectors/registry/impossible-date.js.map +1 -0
  237. package/dist/detectors/registry/impossible-time.d.ts +3 -0
  238. package/dist/detectors/registry/impossible-time.d.ts.map +1 -0
  239. package/dist/detectors/registry/impossible-time.js +3 -0
  240. package/dist/detectors/registry/impossible-time.js.map +1 -0
  241. package/dist/detectors/registry/latin-abbreviation.d.ts +3 -0
  242. package/dist/detectors/registry/latin-abbreviation.d.ts.map +1 -0
  243. package/dist/detectors/registry/latin-abbreviation.js +3 -0
  244. package/dist/detectors/registry/latin-abbreviation.js.map +1 -0
  245. package/dist/detectors/registry/link-text-url-mismatch.d.ts +3 -0
  246. package/dist/detectors/registry/link-text-url-mismatch.d.ts.map +1 -0
  247. package/dist/detectors/registry/link-text-url-mismatch.js +3 -0
  248. package/dist/detectors/registry/link-text-url-mismatch.js.map +1 -0
  249. package/dist/detectors/registry/list-marker.d.ts +3 -0
  250. package/dist/detectors/registry/list-marker.d.ts.map +1 -0
  251. package/dist/detectors/registry/list-marker.js +3 -0
  252. package/dist/detectors/registry/list-marker.js.map +1 -0
  253. package/dist/detectors/registry/mark-consistency.d.ts +3 -0
  254. package/dist/detectors/registry/mark-consistency.d.ts.map +1 -0
  255. package/dist/detectors/registry/mark-consistency.js +3 -0
  256. package/dist/detectors/registry/mark-consistency.js.map +1 -0
  257. package/dist/detectors/registry/numeral-opener.d.ts +3 -0
  258. package/dist/detectors/registry/numeral-opener.d.ts.map +1 -0
  259. package/dist/detectors/registry/numeral-opener.js +3 -0
  260. package/dist/detectors/registry/numeral-opener.js.map +1 -0
  261. package/dist/detectors/registry/ordinal-suffix.d.ts +3 -0
  262. package/dist/detectors/registry/ordinal-suffix.d.ts.map +1 -0
  263. package/dist/detectors/registry/ordinal-suffix.js +3 -0
  264. package/dist/detectors/registry/ordinal-suffix.js.map +1 -0
  265. package/dist/detectors/registry/origin-particle.d.ts +3 -0
  266. package/dist/detectors/registry/origin-particle.d.ts.map +1 -0
  267. package/dist/detectors/registry/origin-particle.js +3 -0
  268. package/dist/detectors/registry/origin-particle.js.map +1 -0
  269. package/dist/detectors/registry/range-notation.d.ts +3 -0
  270. package/dist/detectors/registry/range-notation.d.ts.map +1 -0
  271. package/dist/detectors/registry/range-notation.js +3 -0
  272. package/dist/detectors/registry/range-notation.js.map +1 -0
  273. package/dist/detectors/registry/relative-pronoun-mix.d.ts +3 -0
  274. package/dist/detectors/registry/relative-pronoun-mix.d.ts.map +1 -0
  275. package/dist/detectors/registry/relative-pronoun-mix.js +3 -0
  276. package/dist/detectors/registry/relative-pronoun-mix.js.map +1 -0
  277. package/dist/detectors/registry/request-without-deadline.d.ts +3 -0
  278. package/dist/detectors/registry/request-without-deadline.d.ts.map +1 -0
  279. package/dist/detectors/registry/request-without-deadline.js +3 -0
  280. package/dist/detectors/registry/request-without-deadline.js.map +1 -0
  281. package/dist/detectors/registry/sentence-spacing.d.ts +3 -0
  282. package/dist/detectors/registry/sentence-spacing.d.ts.map +1 -0
  283. package/dist/detectors/registry/sentence-spacing.js +3 -0
  284. package/dist/detectors/registry/sentence-spacing.js.map +1 -0
  285. package/dist/detectors/registry/share-over-hundred.d.ts +3 -0
  286. package/dist/detectors/registry/share-over-hundred.d.ts.map +1 -0
  287. package/dist/detectors/registry/share-over-hundred.js +3 -0
  288. package/dist/detectors/registry/share-over-hundred.js.map +1 -0
  289. package/dist/detectors/registry/shell-prompt.d.ts +3 -0
  290. package/dist/detectors/registry/shell-prompt.d.ts.map +1 -0
  291. package/dist/detectors/registry/shell-prompt.js +3 -0
  292. package/dist/detectors/registry/shell-prompt.js.map +1 -0
  293. package/dist/detectors/registry/step-reference.d.ts +3 -0
  294. package/dist/detectors/registry/step-reference.d.ts.map +1 -0
  295. package/dist/detectors/registry/step-reference.js +3 -0
  296. package/dist/detectors/registry/step-reference.js.map +1 -0
  297. package/dist/detectors/registry/step-statement.d.ts +3 -0
  298. package/dist/detectors/registry/step-statement.d.ts.map +1 -0
  299. package/dist/detectors/registry/step-statement.js +3 -0
  300. package/dist/detectors/registry/step-statement.js.map +1 -0
  301. package/dist/detectors/registry/table-row-overflow.d.ts +3 -0
  302. package/dist/detectors/registry/table-row-overflow.d.ts.map +1 -0
  303. package/dist/detectors/registry/table-row-overflow.js +3 -0
  304. package/dist/detectors/registry/table-row-overflow.js.map +1 -0
  305. package/dist/detectors/registry/toc-heading.d.ts +3 -0
  306. package/dist/detectors/registry/toc-heading.d.ts.map +1 -0
  307. package/dist/detectors/registry/toc-heading.js +3 -0
  308. package/dist/detectors/registry/toc-heading.js.map +1 -0
  309. package/dist/detectors/registry/unclosed-code-fence.d.ts +3 -0
  310. package/dist/detectors/registry/unclosed-code-fence.d.ts.map +1 -0
  311. package/dist/detectors/registry/unclosed-code-fence.js +3 -0
  312. package/dist/detectors/registry/unclosed-code-fence.js.map +1 -0
  313. package/dist/detectors/registry/unpaired-parallel.d.ts +3 -0
  314. package/dist/detectors/registry/unpaired-parallel.d.ts.map +1 -0
  315. package/dist/detectors/registry/unpaired-parallel.js +3 -0
  316. package/dist/detectors/registry/unpaired-parallel.js.map +1 -0
  317. package/dist/detectors/registry/unrendered-emphasis.d.ts +3 -0
  318. package/dist/detectors/registry/unrendered-emphasis.d.ts.map +1 -0
  319. package/dist/detectors/registry/unrendered-emphasis.js +3 -0
  320. package/dist/detectors/registry/unrendered-emphasis.js.map +1 -0
  321. package/dist/detectors/relative-pronoun-mix.d.ts +19 -0
  322. package/dist/detectors/relative-pronoun-mix.d.ts.map +1 -0
  323. package/dist/detectors/relative-pronoun-mix.js +60 -0
  324. package/dist/detectors/relative-pronoun-mix.js.map +1 -0
  325. package/dist/detectors/request-owner.d.ts +23 -0
  326. package/dist/detectors/request-owner.d.ts.map +1 -0
  327. package/dist/detectors/request-owner.js +110 -0
  328. package/dist/detectors/request-owner.js.map +1 -0
  329. package/dist/detectors/share-over-hundred.d.ts +20 -0
  330. package/dist/detectors/share-over-hundred.d.ts.map +1 -0
  331. package/dist/detectors/share-over-hundred.js +55 -0
  332. package/dist/detectors/share-over-hundred.js.map +1 -0
  333. package/dist/detectors/step-reference.d.ts +20 -0
  334. package/dist/detectors/step-reference.d.ts.map +1 -0
  335. package/dist/detectors/step-reference.js +57 -0
  336. package/dist/detectors/step-reference.js.map +1 -0
  337. package/dist/detectors/technical-docs.d.ts +32 -0
  338. package/dist/detectors/technical-docs.d.ts.map +1 -0
  339. package/dist/detectors/technical-docs.js +199 -0
  340. package/dist/detectors/technical-docs.js.map +1 -0
  341. package/dist/detectors/toc-heading.d.ts +10 -0
  342. package/dist/detectors/toc-heading.d.ts.map +1 -0
  343. package/dist/detectors/toc-heading.js +99 -0
  344. package/dist/detectors/toc-heading.js.map +1 -0
  345. package/dist/extension/pack-read.d.ts +21 -0
  346. package/dist/extension/pack-read.d.ts.map +1 -0
  347. package/dist/extension/pack-read.js +117 -0
  348. package/dist/extension/pack-read.js.map +1 -0
  349. package/dist/extension/plugin-load.d.ts.map +1 -1
  350. package/dist/extension/plugin-load.js +44 -10
  351. package/dist/extension/plugin-load.js.map +1 -1
  352. package/dist/extension/plugin-parse.d.ts.map +1 -1
  353. package/dist/extension/plugin-parse.js +10 -3
  354. package/dist/extension/plugin-parse.js.map +1 -1
  355. package/dist/facts/address-values.d.ts +5 -0
  356. package/dist/facts/address-values.d.ts.map +1 -0
  357. package/dist/facts/address-values.js +64 -0
  358. package/dist/facts/address-values.js.map +1 -0
  359. package/dist/facts/cross-facts.d.ts +20 -0
  360. package/dist/facts/cross-facts.d.ts.map +1 -0
  361. package/dist/facts/cross-facts.js +41 -0
  362. package/dist/facts/cross-facts.js.map +1 -0
  363. package/dist/fix-plan/chosen-depth.d.ts +10 -0
  364. package/dist/fix-plan/chosen-depth.d.ts.map +1 -0
  365. package/dist/fix-plan/chosen-depth.js +24 -0
  366. package/dist/fix-plan/chosen-depth.js.map +1 -0
  367. package/dist/fix-plan/mode.d.ts +13 -4
  368. package/dist/fix-plan/mode.d.ts.map +1 -1
  369. package/dist/fix-plan/mode.js +38 -7
  370. package/dist/fix-plan/mode.js.map +1 -1
  371. package/dist/fix-plan/plan.d.ts +20 -0
  372. package/dist/fix-plan/plan.d.ts.map +1 -1
  373. package/dist/fix-plan/plan.js +23 -5
  374. package/dist/fix-plan/plan.js.map +1 -1
  375. package/dist/fix-plan/render.d.ts.map +1 -1
  376. package/dist/fix-plan/render.js +24 -0
  377. package/dist/fix-plan/render.js.map +1 -1
  378. package/dist/fix-plan/text.d.ts +8 -0
  379. package/dist/fix-plan/text.d.ts.map +1 -1
  380. package/dist/fix-plan/text.js +36 -10
  381. package/dist/fix-plan/text.js.map +1 -1
  382. package/dist/genre-load.d.ts +1 -1
  383. package/dist/genre-load.d.ts.map +1 -1
  384. package/dist/genre-load.js +7 -4
  385. package/dist/genre-load.js.map +1 -1
  386. package/dist/genre-parse.d.ts +6 -0
  387. package/dist/genre-parse.d.ts.map +1 -1
  388. package/dist/genre-parse.js +18 -0
  389. package/dist/genre-parse.js.map +1 -1
  390. package/dist/init.js +10 -10
  391. package/dist/init.js.map +1 -1
  392. package/dist/known-genres.d.ts +8 -0
  393. package/dist/known-genres.d.ts.map +1 -0
  394. package/dist/known-genres.js +17 -0
  395. package/dist/known-genres.js.map +1 -0
  396. package/dist/link-shape.d.ts +20 -0
  397. package/dist/link-shape.d.ts.map +1 -0
  398. package/dist/link-shape.js +58 -0
  399. package/dist/link-shape.js.map +1 -0
  400. package/dist/list-marks.d.ts +21 -0
  401. package/dist/list-marks.d.ts.map +1 -0
  402. package/dist/list-marks.js +82 -0
  403. package/dist/list-marks.js.map +1 -0
  404. package/dist/reasons.d.ts.map +1 -1
  405. package/dist/reasons.js +15 -4
  406. package/dist/reasons.js.map +1 -1
  407. package/dist/render/explain.d.ts.map +1 -1
  408. package/dist/render/explain.js +11 -2
  409. package/dist/render/explain.js.map +1 -1
  410. package/dist/render/friendly.js +1 -1
  411. package/dist/render/friendly.js.map +1 -1
  412. package/dist/render/rules-json.d.ts.map +1 -1
  413. package/dist/render/rules-json.js +12 -3
  414. package/dist/render/rules-json.js.map +1 -1
  415. package/dist/render/rules-table.js +6 -6
  416. package/dist/render/rules-table.js.map +1 -1
  417. package/dist/render/semantic.js +2 -2
  418. package/dist/render/semantic.js.map +1 -1
  419. package/dist/render/suppressions.js +2 -2
  420. package/dist/render/suppressions.js.map +1 -1
  421. package/dist/rewrite-depth.d.ts +22 -0
  422. package/dist/rewrite-depth.d.ts.map +1 -0
  423. package/dist/rewrite-depth.js +42 -0
  424. package/dist/rewrite-depth.js.map +1 -0
  425. package/dist/rule-fields.d.ts +28 -0
  426. package/dist/rule-fields.d.ts.map +1 -0
  427. package/dist/rule-fields.js +85 -0
  428. package/dist/rule-fields.js.map +1 -0
  429. package/dist/rule-guide.d.ts +3 -0
  430. package/dist/rule-guide.d.ts.map +1 -1
  431. package/dist/rule-guide.js +6 -0
  432. package/dist/rule-guide.js.map +1 -1
  433. package/dist/rule-load.d.ts.map +1 -1
  434. package/dist/rule-load.js +13 -5
  435. package/dist/rule-load.js.map +1 -1
  436. package/dist/rule-offs.d.ts +14 -0
  437. package/dist/rule-offs.d.ts.map +1 -0
  438. package/dist/rule-offs.js +45 -0
  439. package/dist/rule-offs.js.map +1 -0
  440. package/dist/structure/build.d.ts.map +1 -1
  441. package/dist/structure/build.js +14 -1
  442. package/dist/structure/build.js.map +1 -1
  443. package/dist/structure/cross-definitions.d.ts +23 -0
  444. package/dist/structure/cross-definitions.d.ts.map +1 -0
  445. package/dist/structure/cross-definitions.js +34 -0
  446. package/dist/structure/cross-definitions.js.map +1 -0
  447. package/genres.yaml +14 -313
  448. package/package.json +3 -3
  449. package/rules/absolute-exception.yaml +3 -1
  450. package/rules/abstract-length.yaml +7 -1
  451. package/rules/acronym-expansion-conflict.yaml +2 -1
  452. package/rules/adverb-overuse.yaml +7 -1
  453. package/rules/adverb-without-negation.yaml +60 -0
  454. package/rules/adversative-ga-repeat.yaml +2 -1
  455. package/rules/agentless-passive.yaml +10 -1
  456. package/rules/agreement-slip.yaml +4 -1
  457. package/rules/ai-generated-composite.yaml +6 -1
  458. package/rules/ai-structure.yaml +8 -2
  459. package/rules/ai-tell.yaml +7 -1
  460. package/rules/all-caps-shouting.yaml +61 -0
  461. package/rules/announced-count-mismatch.yaml +3 -1
  462. package/rules/announcing-opener.yaml +7 -1
  463. package/rules/article-sound.yaml +6 -2
  464. package/rules/assistant-residue.yaml +4 -1
  465. package/rules/attachment-not-attached.yaml +112 -0
  466. package/rules/baito-keigo.yaml +64 -0
  467. package/rules/bare-url-mix.yaml +86 -0
  468. package/rules/bold-density.yaml +1 -0
  469. package/rules/bold-label-list.yaml +9 -1
  470. package/rules/bracket-nesting.yaml +2 -1
  471. package/rules/bracket-width-consistency.yaml +64 -0
  472. package/rules/broken-link.yaml +1 -1
  473. package/rules/chat-citation-residue.yaml +2 -1
  474. package/rules/citation-reference-mismatch.yaml +7 -1
  475. package/rules/citation-style-mix.yaml +7 -1
  476. package/rules/clause-chain.yaml +6 -1
  477. package/rules/cliche.yaml +67 -0
  478. package/rules/closing-cliche.yaml +7 -0
  479. package/rules/code-fence-language-mix.yaml +176 -0
  480. package/rules/colloquial-opener.yaml +62 -0
  481. package/rules/colon-lead-in.yaml +7 -1
  482. package/rules/concrete-evidence-density.yaml +6 -0
  483. package/rules/contraction-consistency.yaml +4 -1
  484. package/rules/contrast-framing.yaml +7 -1
  485. package/rules/cross-doc-duplicate-definition.yaml +70 -0
  486. package/rules/cross-doc-fact-conflict.yaml +64 -0
  487. package/rules/currency-notation-consistency.yaml +77 -0
  488. package/rules/cushion-phrase-density.yaml +8 -1
  489. package/rules/dangling-figure-reference.yaml +3 -1
  490. package/rules/dangling-participle.yaml +58 -0
  491. package/rules/dangling-reference.yaml +3 -1
  492. package/rules/date-format-consistency.yaml +3 -2
  493. package/rules/date-order.yaml +3 -1
  494. package/rules/date-range-reversed.yaml +3 -1
  495. package/rules/date-weekday-mismatch.yaml +3 -1
  496. package/rules/date-without-year.yaml +4 -3
  497. package/rules/defined-name-repeated.yaml +97 -0
  498. package/rules/defined-term-form.yaml +113 -0
  499. package/rules/demonstrative-opener-run.yaml +2 -1
  500. package/rules/double-keigo.yaml +6 -1
  501. package/rules/double-negative.yaml +5 -1
  502. package/rules/doubled-nado.yaml +2 -1
  503. package/rules/doubled-punctuation.yaml +1 -1
  504. package/rules/doubled-word.yaml +4 -1
  505. package/rules/duplicate-definition.yaml +3 -1
  506. package/rules/duplicate-heading.yaml +1 -1
  507. package/rules/duration-mismatch.yaml +2 -1
  508. package/rules/elapsed-years-mismatch.yaml +4 -1
  509. package/rules/email-greeting-closing.yaml +122 -0
  510. package/rules/email-subject-length.yaml +112 -0
  511. package/rules/emoji-density.yaml +3 -1
  512. package/rules/emoji-heading.yaml +7 -1
  513. package/rules/empty-intensifier.yaml +4 -0
  514. package/rules/empty-list-item.yaml +2 -1
  515. package/rules/empty-section.yaml +1 -1
  516. package/rules/empty-table-cell.yaml +2 -1
  517. package/rules/excessive-hedging.yaml +7 -1
  518. package/rules/exclamation-width-consistency.yaml +64 -0
  519. package/rules/expletive-construction.yaml +7 -1
  520. package/rules/fact-conflict.yaml +4 -1
  521. package/rules/figure-reference-order.yaml +7 -1
  522. package/rules/footnote-mismatch.yaml +91 -0
  523. package/rules/fullwidth-alnum-consistency.yaml +2 -2
  524. package/rules/hankaku-kana.yaml +1 -1
  525. package/rules/heading-command-missing.yaml +109 -0
  526. package/rules/heading-echo.yaml +6 -1
  527. package/rules/heading-end-punctuation-mix.yaml +158 -0
  528. package/rules/heading-level-skip.yaml +3 -3
  529. package/rules/heading-numbering-mix.yaml +4 -3
  530. package/rules/hiragana-fukushi.yaml +4 -1
  531. package/rules/homophone-slip.yaml +5 -1
  532. package/rules/humble-for-others.yaml +63 -0
  533. package/rules/hyphen-as-dash.yaml +59 -0
  534. package/rules/idiom-misuse.yaml +4 -1
  535. package/rules/image-file-name-alt.yaml +83 -0
  536. package/rules/impossible-date.yaml +79 -0
  537. package/rules/impossible-time.yaml +76 -0
  538. package/rules/internal-jargon.yaml +1 -1
  539. package/rules/invisible-character.yaml +1 -1
  540. package/rules/katakana-density.yaml +2 -1
  541. package/rules/katakana-long-vowel.yaml +1 -1
  542. package/rules/known-misspelling.yaml +2 -1
  543. package/rules/kutoten-consistency.yaml +1 -1
  544. package/rules/latin-abbreviation-form.yaml +58 -0
  545. package/rules/latin-spacing.yaml +6 -2
  546. package/rules/less-for-fewer.yaml +59 -0
  547. package/rules/link-text-url-mismatch.yaml +72 -0
  548. package/rules/list-item-form-mix.yaml +7 -1
  549. package/rules/list-marker-mix.yaml +111 -0
  550. package/rules/max-kanji-continuous.yaml +10 -2
  551. package/rules/max-paragraph-length.yaml +4 -1
  552. package/rules/max-sentence-length.yaml +29 -21
  553. package/rules/max-ten.yaml +4 -1
  554. package/rules/misconversion.yaml +2 -1
  555. package/rules/modal-conflict.yaml +2 -1
  556. package/rules/name-variant.yaml +4 -3
  557. package/rules/ngram-repetition.yaml +5 -0
  558. package/rules/no-doubled-joshi.yaml +5 -1
  559. package/rules/no-em-dash.yaml +4 -1
  560. package/rules/no-lead.yaml +6 -1
  561. package/rules/no-mixed-desumasu.yaml +5 -2
  562. package/rules/no-nakaguro-parallel.yaml +3 -0
  563. package/rules/nominalization.yaml +5 -1
  564. package/rules/nonstandard-word.yaml +80 -0
  565. package/rules/number-style-consistency.yaml +6 -1
  566. package/rules/number-without-unit.yaml +2 -1
  567. package/rules/numbering-gap.yaml +1 -1
  568. package/rules/numeral-sentence-start.yaml +56 -0
  569. package/rules/one-sentence-paragraph-run.yaml +5 -1
  570. package/rules/ordinal-suffix-mismatch.yaml +65 -0
  571. package/rules/orthographic-variant.yaml +4 -1
  572. package/rules/outside-announced-list.yaml +2 -1
  573. package/rules/oxford-comma-consistency.yaml +3 -1
  574. package/rules/padded-intro.yaml +7 -0
  575. package/rules/paragraph-length-variance.yaml +7 -1
  576. package/rules/paragraph-restatement.yaml +6 -1
  577. package/rules/percent-sum-mismatch.yaml +3 -1
  578. package/rules/person-consistency.yaml +4 -1
  579. package/rules/preamble-length.yaml +6 -0
  580. package/rules/preferred-term.yaml +1 -1
  581. package/rules/proper-noun-density.yaml +8 -1
  582. package/rules/quote-style-consistency.yaml +66 -0
  583. package/rules/ra-nuki.yaml +4 -1
  584. package/rules/range-notation-consistency.yaml +73 -0
  585. package/rules/redundant-expression.yaml +4 -1
  586. package/rules/reference-title-mismatch.yaml +4 -3
  587. package/rules/reference-topic-missing.yaml +2 -1
  588. package/rules/relative-date-mismatch.yaml +2 -1
  589. package/rules/repeated-conjunction.yaml +4 -1
  590. package/rules/repeated-sentence-ending.yaml +62 -0
  591. package/rules/repeated-sentence-head.yaml +4 -0
  592. package/rules/request-without-deadline.yaml +92 -0
  593. package/rules/required-sections.yaml +1 -1
  594. package/rules/requirement-modal.yaml +1 -1
  595. package/rules/requirement-smell.yaml +12 -4
  596. package/rules/rule-of-three.yaml +8 -1
  597. package/rules/sasete-itadaku.yaml +7 -1
  598. package/rules/section-length-uniformity.yaml +7 -1
  599. package/rules/sentence-initial-conjunction-run.yaml +5 -1
  600. package/rules/sentence-initial-so.yaml +6 -1
  601. package/rules/sentence-rhythm.yaml +8 -1
  602. package/rules/sentence-spacing-consistency.yaml +63 -0
  603. package/rules/share-over-hundred.yaml +65 -0
  604. package/rules/shell-prompt-mix.yaml +128 -0
  605. package/rules/space-before-punctuation.yaml +1 -1
  606. package/rules/spelling-consistency.yaml +3 -1
  607. package/rules/step-reference-missing.yaml +85 -0
  608. package/rules/step-statement-mix.yaml +76 -0
  609. package/rules/stock-transition.yaml +8 -1
  610. package/rules/stray-space.yaml +2 -2
  611. package/rules/summary-fact-mismatch.yaml +4 -1
  612. package/rules/table-header-variant.yaml +2 -1
  613. package/rules/table-row-overflow.yaml +90 -0
  614. package/rules/taigen-dome-in-prose.yaml +6 -0
  615. package/rules/tari-unpaired.yaml +58 -0
  616. package/rules/teki-overuse.yaml +2 -1
  617. package/rules/title-case-consistency.yaml +1 -1
  618. package/rules/title-length.yaml +7 -1
  619. package/rules/toc-heading-mismatch.yaml +136 -0
  620. package/rules/topic-predicate-distance.yaml +6 -1
  621. package/rules/total-mismatch.yaml +3 -1
  622. package/rules/translationese-density.yaml +4 -1
  623. package/rules/unbalanced-bracket.yaml +3 -3
  624. package/rules/unclosed-code-fence.yaml +107 -0
  625. package/rules/uncomparable-graded.yaml +65 -0
  626. package/rules/undefined-acronym.yaml +8 -1
  627. package/rules/unfilled-placeholder.yaml +1 -1
  628. package/rules/unit-mismatch.yaml +2 -1
  629. package/rules/unknown-word.yaml +4 -1
  630. package/rules/unqualified-superlative.yaml +6 -1
  631. package/rules/unrendered-emphasis.yaml +73 -0
  632. package/rules/unused-definition.yaml +4 -3
  633. package/rules/url-run-on.yaml +1 -1
  634. package/rules/use-before-definition.yaml +4 -3
  635. package/rules/vague-figure-reference.yaml +3 -1
  636. package/rules/vague-link-text.yaml +2 -1
  637. package/rules/vague-word-density.yaml +2 -1
  638. package/rules/very-adjective.yaml +5 -1
  639. package/rules/weasel-word.yaml +6 -1
  640. package/rules/which-that-consistency.yaml +64 -0
  641. package/rules/wordy-phrase.yaml +6 -1
  642. package/rules/yori-as-from.yaml +61 -0
  643. package/skills/chaff/SKILL.md +7 -7
  644. package/src/api.ts +13 -1
  645. package/src/cli-text.ts +22 -7
  646. package/src/cli.ts +8 -9
  647. package/src/command-help.ts +26 -0
  648. package/src/commands/eval.ts +2 -2
  649. package/src/commands/fix-plan.ts +13 -1
  650. package/src/commands/help.ts +8 -0
  651. package/src/commands/init-command.ts +13 -0
  652. package/src/commands/plugin-init.ts +150 -0
  653. package/src/commands/plugin-test.ts +111 -0
  654. package/src/config/load.ts +3 -0
  655. package/src/config/option-problems.ts +2 -2
  656. package/src/config/rule-problems.ts +2 -2
  657. package/src/custom/checked.ts +8 -0
  658. package/src/custom/dsl-fields.ts +102 -0
  659. package/src/custom/load.ts +2 -0
  660. package/src/custom/parse.ts +72 -50
  661. package/src/custom/problems.ts +16 -2
  662. package/src/detectors/amount-for-count.ts +90 -0
  663. package/src/detectors/blank-structure.ts +12 -4
  664. package/src/detectors/clause-shape.ts +199 -0
  665. package/src/detectors/code-fences.ts +113 -0
  666. package/src/detectors/cross-definitions.ts +49 -0
  667. package/src/detectors/cross-facts.ts +60 -0
  668. package/src/detectors/cross-registry/cross-doc-duplicate-definition.ts +4 -0
  669. package/src/detectors/cross-registry/cross-doc-fact-conflict.ts +4 -0
  670. package/src/detectors/currency-notation.ts +90 -0
  671. package/src/detectors/custom.ts +10 -2
  672. package/src/detectors/dangling-opener.ts +74 -0
  673. package/src/detectors/defined-term-form.ts +200 -0
  674. package/src/detectors/email-letter.ts +262 -0
  675. package/src/detectors/footnote-mismatch.ts +72 -0
  676. package/src/detectors/form-minority.ts +21 -0
  677. package/src/detectors/heading-end-mark.ts +82 -0
  678. package/src/detectors/impossible-date.ts +141 -0
  679. package/src/detectors/impossible-time.ts +151 -0
  680. package/src/detectors/link-shape.ts +70 -0
  681. package/src/detectors/list-marker.ts +60 -0
  682. package/src/detectors/mark-shape.ts +202 -0
  683. package/src/detectors/markdown-slip.ts +140 -0
  684. package/src/detectors/numeral-opener.ts +72 -0
  685. package/src/detectors/ordinal-suffix.ts +40 -0
  686. package/src/detectors/range-notation.ts +76 -0
  687. package/src/detectors/registry/adverb-polarity.ts +4 -0
  688. package/src/detectors/registry/amount-for-count.ts +4 -0
  689. package/src/detectors/registry/attachment-missing.ts +4 -0
  690. package/src/detectors/registry/bare-url-mix.ts +4 -0
  691. package/src/detectors/registry/caps-shouting.ts +4 -0
  692. package/src/detectors/registry/code-fence-language.ts +4 -0
  693. package/src/detectors/registry/currency-notation.ts +4 -0
  694. package/src/detectors/registry/dangling-opener.ts +4 -0
  695. package/src/detectors/registry/defined-name-repeated.ts +4 -0
  696. package/src/detectors/registry/defined-term-form.ts +4 -0
  697. package/src/detectors/registry/email-frame.ts +4 -0
  698. package/src/detectors/registry/email-subject.ts +4 -0
  699. package/src/detectors/registry/ending-run.ts +4 -0
  700. package/src/detectors/registry/footnote-mismatch.ts +4 -0
  701. package/src/detectors/registry/heading-command.ts +4 -0
  702. package/src/detectors/registry/heading-end-punctuation.ts +4 -0
  703. package/src/detectors/registry/hyphen-dash.ts +4 -0
  704. package/src/detectors/registry/image-file-name-alt.ts +4 -0
  705. package/src/detectors/registry/impossible-date.ts +4 -0
  706. package/src/detectors/registry/impossible-time.ts +4 -0
  707. package/src/detectors/registry/latin-abbreviation.ts +4 -0
  708. package/src/detectors/registry/link-text-url-mismatch.ts +4 -0
  709. package/src/detectors/registry/list-marker.ts +4 -0
  710. package/src/detectors/registry/mark-consistency.ts +4 -0
  711. package/src/detectors/registry/numeral-opener.ts +4 -0
  712. package/src/detectors/registry/ordinal-suffix.ts +4 -0
  713. package/src/detectors/registry/origin-particle.ts +4 -0
  714. package/src/detectors/registry/range-notation.ts +4 -0
  715. package/src/detectors/registry/relative-pronoun-mix.ts +4 -0
  716. package/src/detectors/registry/request-without-deadline.ts +4 -0
  717. package/src/detectors/registry/sentence-spacing.ts +4 -0
  718. package/src/detectors/registry/share-over-hundred.ts +4 -0
  719. package/src/detectors/registry/shell-prompt.ts +4 -0
  720. package/src/detectors/registry/step-reference.ts +4 -0
  721. package/src/detectors/registry/step-statement.ts +4 -0
  722. package/src/detectors/registry/table-row-overflow.ts +4 -0
  723. package/src/detectors/registry/toc-heading.ts +4 -0
  724. package/src/detectors/registry/unclosed-code-fence.ts +4 -0
  725. package/src/detectors/registry/unpaired-parallel.ts +4 -0
  726. package/src/detectors/registry/unrendered-emphasis.ts +4 -0
  727. package/src/detectors/relative-pronoun-mix.ts +79 -0
  728. package/src/detectors/request-owner.ts +141 -0
  729. package/src/detectors/share-over-hundred.ts +75 -0
  730. package/src/detectors/step-reference.ts +83 -0
  731. package/src/detectors/technical-docs.ts +230 -0
  732. package/src/detectors/toc-heading.ts +125 -0
  733. package/src/extension/pack-read.ts +128 -0
  734. package/src/extension/plugin-load.ts +49 -9
  735. package/src/extension/plugin-parse.ts +10 -3
  736. package/src/facts/address-values.ts +74 -0
  737. package/src/facts/cross-facts.ts +54 -0
  738. package/src/fix-plan/chosen-depth.ts +28 -0
  739. package/src/fix-plan/mode.ts +57 -11
  740. package/src/fix-plan/plan.ts +37 -5
  741. package/src/fix-plan/render.ts +24 -0
  742. package/src/fix-plan/text.ts +47 -10
  743. package/src/genre-load.ts +7 -4
  744. package/src/genre-parse.ts +19 -0
  745. package/src/init.ts +10 -10
  746. package/src/known-genres.ts +19 -0
  747. package/src/link-shape.ts +62 -0
  748. package/src/list-marks.ts +106 -0
  749. package/src/reasons.ts +16 -4
  750. package/src/render/explain.ts +14 -2
  751. package/src/render/friendly.ts +1 -1
  752. package/src/render/rules-json.ts +14 -3
  753. package/src/render/rules-table.ts +6 -6
  754. package/src/render/semantic.ts +2 -2
  755. package/src/render/suppressions.ts +2 -2
  756. package/src/rewrite-depth.ts +60 -0
  757. package/src/rule-fields.ts +123 -0
  758. package/src/rule-guide.ts +9 -0
  759. package/src/rule-load.ts +10 -4
  760. package/src/rule-offs.ts +50 -0
  761. package/src/structure/build.ts +21 -1
  762. package/src/structure/cross-definitions.ts +60 -0
@@ -0,0 +1,72 @@
1
+ import type { Detector, Finding, Sentence, Span } from "../plugin.ts";
2
+
3
+ /**
4
+ * 数字で始まる文(20 people came.)。読み手は文の頭を大文字で探すので、数字の頭は文の切れ目を見えにくくする。
5
+ * 数字の後ろが小文字の語のときだけ読む: 「1 Introduction」のような番号の付いた題や「9:00 Opening」のような時刻の行は文ではない。
6
+ * 年(2026 was a good year.)は綴れないので読まない。
7
+ */
8
+
9
+ const OPENING_NUMERAL = /^(?<numeral>\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?%?(?=\s+\p{Ll})/u;
10
+ const SENTENCE_END = /[.!?]["'”’)]*$/u;
11
+ const YEAR = /^[12]\d{3}$/u;
12
+ const HEADING_LINE = /(?:^|\n)#{1,6}\s[^\n]*$/u;
13
+ const CLOSERS = new Set(['"', "'", "”", "’", ")"]);
14
+ const STOP = /[.!?]$/u;
15
+ const WORD_CHAR = /[\p{L}\p{N}.]/u;
16
+ const DIGITS = /^\d+$/u;
17
+ /** 前の文の終わりを探す字数。見出しの行と、終わりの語が入れば足りる。 */
18
+ const LOOKBACK = 300;
19
+ const PLAIN_WORD = /^\p{L}{2,}$/u;
20
+
21
+ /** 文の頭の数字。年、数字の後ろが小文字の語でないもの、言い終えていない行(見出しのような)は無い。 */
22
+ export const openingNumeral = (text: string): string | undefined => {
23
+ const trimmed = text.trim();
24
+ const match = OPENING_NUMERAL.exec(trimmed);
25
+ const numeral = match?.groups?.["numeral"];
26
+ if (match === null || numeral === undefined || YEAR.test(numeral) || !SENTENCE_END.test(trimmed)) return undefined;
27
+ return match[0];
28
+ };
29
+
30
+ /** text の終わりに続く、belongs を満たす字の並びの始まり(UTF-16 の位置)。 */
31
+ const tailStart = (text: string, belongs: (char: string) => boolean): number =>
32
+ text.split("").reduceRight((at, char, index) => (at === index + 1 && belongs(char) ? index : at), text.length);
33
+
34
+ /** 終わりの印(. ! ?)の前の語。点を含めて読む(H.R. は「H.R」)。印で終わっていなければ undefined。 */
35
+ const lastWordBeforeStop = (text: string): string | undefined => {
36
+ const closed = text.slice(
37
+ 0,
38
+ tailStart(text, (char) => CLOSERS.has(char)),
39
+ );
40
+ if (!STOP.test(closed)) return undefined;
41
+ const body = closed.slice(0, -1);
42
+ const start = tailStart(body, (char) => WORD_CHAR.test(char));
43
+ return start === body.length ? undefined : body.slice(start);
44
+ };
45
+
46
+ /**
47
+ * offset の前で、文がほんとうに終わっているか。文書か見出しの直後か、前の文が二字以上の語か数で言い終えているときだけ。
48
+ * 番号に付ける略した語(vol. 28、H.R. 5376)や、句点の無い行(Lane\n\n2 contains、HTML から移したリンクの切れ目)の後ろの数は文の頭ではない。
49
+ */
50
+ export const followsSentenceEnd = (source: string, offset: number, labels: ReadonlySet<string>): boolean => {
51
+ const from = Math.max(0, offset - LOOKBACK);
52
+ const ended = source.slice(from, offset).trimEnd();
53
+ if ((ended === "" && from === 0) || HEADING_LINE.test(ended)) return true;
54
+ const word = lastWordBeforeStop(ended);
55
+ if (word === undefined) return false;
56
+ return DIGITS.test(word) || (PLAIN_WORD.test(word) && !labels.has(word.toLowerCase()));
57
+ };
58
+
59
+ const inside = (spans: readonly Span[], offset: number): boolean => spans.some((span) => span.start <= offset && offset < span.end);
60
+
61
+ const leadingSpace = (sentence: Sentence): number => sentence.text.length - sentence.text.trimStart().length;
62
+
63
+ export const numeralOpener: Detector = (doc): Finding[] => {
64
+ const labels = new Set((doc.lexicons["numeral-reference-label"] ?? []).map((entry) => entry.pattern.toLowerCase()));
65
+ return doc.sentences.flatMap((sentence) => {
66
+ const offset = sentence.span.start + leadingSpace(sentence);
67
+ if (sentence.embeddedLanguage !== undefined || inside(doc.listSpans, offset)) return [];
68
+ const numeral = openingNumeral(sentence.text);
69
+ if (numeral === undefined || !followsSentenceEnd(doc.source, offset, labels)) return [];
70
+ return [{ rule: "", severity: "warning", line: 0, column: 0, quote: sentence.text.trim(), values: { numeral, offset } }];
71
+ });
72
+ };
@@ -0,0 +1,40 @@
1
+ import type { Detector, Finding, Lexicon } from "../plugin.ts";
2
+ import { escapeRegExp } from "../orthography.ts";
3
+ import { quoteAround } from "./quote-around.ts";
4
+
5
+ // 数と序数の字が合わない所(3th、22th、11st)。どの数の終わりにどの字が付くかは語彙表 ordinal-suffix が言う。
6
+
7
+ /** 合わない序数 1 つ。expected はその数に付く字(一つとは限らない)。 */
8
+ export type OrdinalSlip = { readonly offset: number; readonly written: string; readonly number: string; readonly expected: readonly string[] };
9
+
10
+ /** 数の終わりのうち、語彙表の組にある最も長いものに付く字。 */
11
+ const suffixesFor = (digits: string, suffixes: Lexicon): string[] => {
12
+ const ending = suffixes
13
+ .map((entry) => entry.group ?? "")
14
+ .filter((group) => digits.endsWith(group))
15
+ .reduce((longest, group) => (group.length > longest.length ? group : longest), "");
16
+ return suffixes.filter((entry) => (entry.group ?? "") === ending).map((entry) => entry.pattern);
17
+ };
18
+
19
+ /** 文字列の中の、数と字の合わない序数。語や番号の一部(v1th、0x2nd、1-2th)は読まない。 */
20
+ export const ordinalSlips = (text: string, suffixes: Lexicon): OrdinalSlip[] => {
21
+ const written = [...new Set(suffixes.map((entry) => entry.pattern))];
22
+ if (written.length === 0) return [];
23
+ const pattern = new RegExp(`(?<![\\p{L}\\p{N}_.,\\-])(?<n>\\d+(?:,\\d{3})*)(?<suffix>${written.map(escapeRegExp).join("|")})(?![\\p{L}\\p{N}_])`, "gu");
24
+ return [...text.matchAll(pattern)].flatMap((match) => {
25
+ const expected = suffixesFor((match.groups?.["n"] ?? "").replaceAll(",", ""), suffixes);
26
+ return expected.includes(match.groups?.["suffix"] ?? "") ? [] : [{ offset: match.index, written: match[0], number: match.groups?.["n"] ?? "", expected }];
27
+ });
28
+ };
29
+
30
+ export const ordinalSuffix: Detector = (doc): Finding[] => {
31
+ const text = doc.prose ?? doc.source;
32
+ return ordinalSlips(text, doc.lexicons["ordinal-suffix"] ?? []).map((slip) => ({
33
+ rule: "",
34
+ severity: "warning",
35
+ line: 0,
36
+ column: 0,
37
+ quote: quoteAround(text, slip.offset, slip.offset + slip.written.length),
38
+ values: { written: slip.written, expected: `${slip.number}${slip.expected[0] ?? ""}`, offset: slip.offset },
39
+ }));
40
+ };
@@ -0,0 +1,76 @@
1
+ import type { Detector, Finding } from "../plugin.ts";
2
+ import { escapeRegExp } from "../orthography.ts";
3
+ import { formMinority } from "./form-minority.ts";
4
+ import { quoteAround } from "./quote-around.ts";
5
+
6
+ // 一つの文書で、数の範囲を二通りの記号で書いた所(10〜20 と 10-20、10–20 と 10-20)。どちらが正しいかは決めず、少ないほうを指す。
7
+ // 範囲の記号は語彙表 range-notation が言う。
8
+
9
+ /** 数の範囲 1 つ。form は二つの数のあいだの記号。 */
10
+ export type WrittenRange = { readonly offset: number; readonly written: string; readonly form: string };
11
+
12
+ const FULLWIDTH_OFFSET = 0xfee0;
13
+ const NUMBER = "[0-90-9]+(?:[..][0-90-9]+)?";
14
+
15
+ /** 範囲のすぐ後ろ(空白一つまで)の単位や語。番号にも使う記号(ハイフン)は、これが続くときだけ範囲と読む。 */
16
+ const UNIT_AFTER = /^\s?[\p{L}%%]/u;
17
+
18
+ /** 行の頭(見出しや箇条書きの印の後ろ)の「1-2」は節の番号、閉じ括弧のすぐ後ろの「(703) 292-7827」は電話番号。 */
19
+ const LABEL_BEFORE = /(?:^\s*[#>*+|-][\s#>*+|-]*|\)\s?)$/u;
20
+
21
+ /** 番号の前の札。語彙表の札の語(図、Section)か、頭が大文字の英語の語(NSF)。 */
22
+ const isNumberLabel = (lineBefore: string, labels: readonly string[]): boolean => {
23
+ const trimmed = lineBefore.trimEnd();
24
+ if (labels.some((label) => trimmed.endsWith(label))) return true;
25
+ return /^\p{Lu}/u.test(trimmed.split(/\s/u).at(-1) ?? "");
26
+ };
27
+
28
+ const halfWidth = (text: string): string => text.replace(/[0-9.]/gu, (char) => String.fromCharCode(char.charCodeAt(0) - FULLWIDTH_OFFSET));
29
+
30
+ /**
31
+ * 文字列の中の数の範囲。前後にさらに数が続く並び(日付 2026-10-02、電話番号、時刻 10:00、版 1.2-3)は範囲ではない。
32
+ * 終わりが始まりより小さいもの(郵便番号 100-0001、試合の 3-2)も範囲ではない。ambiguous の記号は、後ろに単位や語が続き、
33
+ * 前が番号の札(図 2-1、Section 1-2、NSF 13-542)でないときだけ。
34
+ */
35
+ export const rangesIn = (text: string, marks: readonly string[], ambiguous: readonly string[] = [], labels: readonly string[] = []): WrittenRange[] => {
36
+ if (marks.length === 0) return [];
37
+ const joiner = marks
38
+ .toSorted((left, right) => right.length - left.length)
39
+ .map(escapeRegExp)
40
+ .join("|");
41
+ const pattern = new RegExp(
42
+ `(?<![\\w0-9..,::/\\--–〜~~])(?<from>${NUMBER})\\s?(?<mark>${joiner})\\s?(?<to>${NUMBER})(?![\\w0-9]|[..,::/\\--–〜~~][0-90-9])`,
43
+ "gu",
44
+ );
45
+ return [...text.matchAll(pattern)].flatMap((match) => {
46
+ const from = Number(halfWidth(match.groups?.["from"] ?? ""));
47
+ const to = Number(halfWidth(match.groups?.["to"] ?? ""));
48
+ const mark = match.groups?.["mark"] ?? "";
49
+ const unitFollows = UNIT_AFTER.test(text.slice(match.index + match[0].length));
50
+ const lineBefore = text.slice(text.lastIndexOf("\n", match.index - 1) + 1, match.index);
51
+ return to > from && !LABEL_BEFORE.test(lineBefore) && (!ambiguous.includes(mark) || (unitFollows && !isNumberLabel(lineBefore, labels)))
52
+ ? [{ offset: match.index, written: match[0], form: mark }]
53
+ : [];
54
+ });
55
+ };
56
+
57
+ export const rangeNotation: Detector = (doc, options): Finding[] => {
58
+ const text = doc.prose ?? doc.source;
59
+ const entries = doc.lexicons["range-notation"] ?? [];
60
+ const ranges = rangesIn(
61
+ text,
62
+ entries.map((entry) => entry.pattern),
63
+ entries.filter((entry) => entry.group === "ambiguous").map((entry) => entry.pattern),
64
+ ["figure-label", "numbered-division", "numbered-label"].flatMap((id) => (doc.lexicons[id] ?? []).map((entry) => entry.pattern)),
65
+ );
66
+ const minority = formMinority(ranges, options.limit);
67
+ if (minority === undefined) return [];
68
+ return minority.odd.map((range) => ({
69
+ rule: "",
70
+ severity: "info",
71
+ line: 0,
72
+ column: 0,
73
+ quote: quoteAround(text, range.offset, range.offset + range.written.length),
74
+ values: { written: range.written, mark: range.form, usual: minority.usual.written, count: minority.odd.length, of: ranges.length, offset: range.offset },
75
+ }));
76
+ };
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { adverbPolarity } from "../clause-shape.ts";
3
+
4
+ export const detector: Detector = adverbPolarity;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { amountForCount } from "../amount-for-count.ts";
3
+
4
+ export const detector: Detector = amountForCount;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { attachmentMissing } from "../email-letter.ts";
3
+
4
+ export const detector: Detector = attachmentMissing;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { bareUrlMix } from "../link-shape.ts";
3
+
4
+ export const detector: Detector = bareUrlMix;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { capsShouting } from "../mark-shape.ts";
3
+
4
+ export const detector: Detector = capsShouting;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { codeFenceLanguage } from "../technical-docs.ts";
3
+
4
+ export const detector: Detector = codeFenceLanguage;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { currencyNotation } from "../currency-notation.ts";
3
+
4
+ export const detector: Detector = currencyNotation;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { danglingOpener } from "../dangling-opener.ts";
3
+
4
+ export const detector: Detector = danglingOpener;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { definedNameRepeated } from "../defined-term-form.ts";
3
+
4
+ export const detector: Detector = definedNameRepeated;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { definedTermForm } from "../defined-term-form.ts";
3
+
4
+ export const detector: Detector = definedTermForm;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { emailFrame } from "../email-letter.ts";
3
+
4
+ export const detector: Detector = emailFrame;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { emailSubject } from "../email-letter.ts";
3
+
4
+ export const detector: Detector = emailSubject;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { endingRun } from "../clause-shape.ts";
3
+
4
+ export const detector: Detector = endingRun;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { footnoteMismatch } from "../footnote-mismatch.ts";
3
+
4
+ export const detector: Detector = footnoteMismatch;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { headingCommand } from "../technical-docs.ts";
3
+
4
+ export const detector: Detector = headingCommand;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { headingEndMark } from "../heading-end-mark.ts";
3
+
4
+ export const detector: Detector = headingEndMark;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { hyphenDash } from "../mark-shape.ts";
3
+
4
+ export const detector: Detector = hyphenDash;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { imageFileNameAlt } from "../link-shape.ts";
3
+
4
+ export const detector: Detector = imageFileNameAlt;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { impossibleDate } from "../impossible-date.ts";
3
+
4
+ export const detector: Detector = impossibleDate;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { impossibleTime } from "../impossible-time.ts";
3
+
4
+ export const detector: Detector = impossibleTime;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { latinAbbreviation } from "../mark-shape.ts";
3
+
4
+ export const detector: Detector = latinAbbreviation;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { linkTextUrlMismatch } from "../link-shape.ts";
3
+
4
+ export const detector: Detector = linkTextUrlMismatch;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { listMarkerMix } from "../list-marker.ts";
3
+
4
+ export const detector: Detector = listMarkerMix;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { markConsistency } from "../mark-shape.ts";
3
+
4
+ export const detector: Detector = markConsistency;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { numeralOpener } from "../numeral-opener.ts";
3
+
4
+ export const detector: Detector = numeralOpener;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { ordinalSuffix } from "../ordinal-suffix.ts";
3
+
4
+ export const detector: Detector = ordinalSuffix;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { originParticle } from "../clause-shape.ts";
3
+
4
+ export const detector: Detector = originParticle;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { rangeNotation } from "../range-notation.ts";
3
+
4
+ export const detector: Detector = rangeNotation;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { relativePronounMix } from "../relative-pronoun-mix.ts";
3
+
4
+ export const detector: Detector = relativePronounMix;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { requestWithoutDeadline } from "../request-owner.ts";
3
+
4
+ export const detector: Detector = requestWithoutDeadline;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { sentenceSpacing } from "../mark-shape.ts";
3
+
4
+ export const detector: Detector = sentenceSpacing;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { shareOverHundred } from "../share-over-hundred.ts";
3
+
4
+ export const detector: Detector = shareOverHundred;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { shellPrompt } from "../technical-docs.ts";
3
+
4
+ export const detector: Detector = shellPrompt;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { stepReference } from "../step-reference.ts";
3
+
4
+ export const detector: Detector = stepReference;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { stepStatement } from "../technical-docs.ts";
3
+
4
+ export const detector: Detector = stepStatement;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { tableRowOverflow } from "../markdown-slip.ts";
3
+
4
+ export const detector: Detector = tableRowOverflow;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { tocHeading } from "../toc-heading.ts";
3
+
4
+ export const detector: Detector = tocHeading;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { unclosedCodeFence } from "../markdown-slip.ts";
3
+
4
+ export const detector: Detector = unclosedCodeFence;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { unpairedParallel } from "../clause-shape.ts";
3
+
4
+ export const detector: Detector = unpairedParallel;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { unrenderedEmphasis } from "../markdown-slip.ts";
3
+
4
+ export const detector: Detector = unrenderedEmphasis;
@@ -0,0 +1,79 @@
1
+ import type { Detector, Finding, Lexicon, Token } from "../plugin.ts";
2
+ import { minorityOf } from "./technical-docs.ts";
3
+ import { isWithinAny, quotedIn, QUOTATION_MARKS } from "../quoted-span.ts";
4
+
5
+ /**
6
+ * 限定の関係節を which で書く所と that で書く所が、一つの文書に混ざっている所(the file which contains / the file that contains)。
7
+ * どちらが正しいかは決めず、少ないほうを指す。読むのは「名詞 + which|that + 動詞」の、読点を挟まない形だけ。
8
+ * that の後ろに主語が来る形(the fact that it works)は、関係節か同格の節か語の並びで決まらないので数えない。
9
+ */
10
+
11
+ export type RelativeUse = { readonly word: Token; readonly kind: string };
12
+
13
+ /** 多いほうの書き方が、文書の書き方と言えるだけの数。 */
14
+ const MIN_USUAL = 3;
15
+ const VERBAL = new Set(["VERB", "AUX"]);
16
+
17
+ /** 解析器は三人称の動詞を複数の名詞と読むことがある(the script that checks links の checks)。 */
18
+ const isThirdPersonVerb = (token: Token): boolean => token.pos === "NOUN" && token.features?.["AlsoVerb"] === "Yes" && token.features["Number"] === "Plur";
19
+
20
+ const isTaggedFiniteVerb = (token: Token | undefined): boolean =>
21
+ token !== undefined && VERBAL.has(token.pos) && token.features?.["VerbForm"] !== "Part" && token.features?.["VerbForm"] !== "Ger";
22
+
23
+ /**
24
+ * 動詞と読める語。名詞と読まれた三人称の動詞は、後ろに動詞が無いときだけ(the idea that results matter の results は主語)。
25
+ */
26
+ const isFiniteVerb = (token: Token | undefined, next: Token | undefined): boolean =>
27
+ isTaggedFiniteVerb(token) || (token !== undefined && isThirdPersonVerb(token) && !isTaggedFiniteVerb(next));
28
+
29
+ const isBaseForm = (verb: Token): boolean => verb.pos === "VERB" && verb.lemma?.toLowerCase() === verb.surface.toLowerCase();
30
+
31
+ /**
32
+ * 名詞の後ろの関係節の動詞。原形の動詞は複数の名詞にだけ続く(resources which set)。単数の名詞の後ろの原形は、
33
+ * 関係節ではなく「どの」の which(tells the command which file to use)。
34
+ */
35
+ const opensRelative = (noun: Token | undefined, verb: Token | undefined, next: Token | undefined): boolean =>
36
+ noun?.pos === "NOUN" && verb !== undefined && isFiniteVerb(verb, next) && (!isBaseForm(verb) || noun.features?.["Number"] === "Plur");
37
+
38
+ /** which / that の後ろの、副詞を飛ばした最初の語(the file which usually stores の stores)。 */
39
+ const verbAfter = (tokens: readonly Token[], at: number): number => {
40
+ const found = tokens.findIndex((token, index) => index > at && token.pos !== "ADV");
41
+ return found === -1 ? tokens.length : found;
42
+ };
43
+
44
+ /** 語彙表の組(which / that)で、tokens の中の限定の関係節の頭。 */
45
+ export const relativeUses = (tokens: readonly Token[], kinds: Lexicon): RelativeUse[] =>
46
+ tokens.flatMap((word, at) => {
47
+ const entry = kinds.find((candidate) => candidate.pattern.toLowerCase() === word.surface.toLowerCase());
48
+ const verb = verbAfter(tokens, at);
49
+ if (entry?.group === undefined || !opensRelative(tokens[at - 1], tokens[verb], tokens[verb + 1])) return [];
50
+ return [{ word, kind: entry.group }];
51
+ });
52
+
53
+ /** 二通りの書き方のうち少ないほう。多いほうが MIN_USUAL に満たなければ、文書の書き方と言えないので空。 */
54
+ export const oddRelatives = (uses: readonly RelativeUse[], limit: number): { readonly odd: readonly RelativeUse[]; readonly usual: string } => {
55
+ const kinds = [...new Set(uses.map((use) => use.kind))];
56
+ const [first, second] = kinds.map((kind) => uses.filter((use) => use.kind === kind));
57
+ if (kinds.length !== 2 || first === undefined || second === undefined) return { odd: [], usual: "" };
58
+ const odd = minorityOf(first, second, limit);
59
+ const usual = odd === first ? second : first;
60
+ return usual.length < MIN_USUAL ? { odd: [], usual: "" } : { odd, usual: usual[0]?.word.surface.toLowerCase() ?? "" };
61
+ };
62
+
63
+ export const relativePronounMix: Detector = (doc, options): Finding[] => {
64
+ const kinds = doc.lexicons["restrictive-relative"] ?? [];
65
+ const uses = doc.sentences.flatMap((sentence) => {
66
+ if (sentence.embeddedLanguage !== undefined) return [];
67
+ const quoted = quotedIn(sentence, QUOTATION_MARKS);
68
+ return relativeUses(sentence.tokens ?? [], kinds).filter((use) => !isWithinAny(quoted, use.word.span));
69
+ });
70
+ const { odd, usual } = oddRelatives(uses, options.limit);
71
+ return odd.map((use) => ({
72
+ rule: "",
73
+ severity: "info",
74
+ line: 0,
75
+ column: 0,
76
+ quote: doc.sentences.find((sentence) => sentence.span.start <= use.word.span.start && use.word.span.start < sentence.span.end)?.text.trim() ?? "",
77
+ values: { word: use.word.surface, usual, count: odd.length, limit: options.limit, offset: use.word.span.start },
78
+ }));
79
+ };