chaffjs 0.16.0 → 0.18.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 (939) hide show
  1. package/dist/announced-count.d.ts +26 -0
  2. package/dist/announced-count.d.ts.map +1 -0
  3. package/dist/announced-count.js +104 -0
  4. package/dist/announced-count.js.map +1 -0
  5. package/dist/bare-url.d.ts +14 -0
  6. package/dist/bare-url.d.ts.map +1 -0
  7. package/dist/bare-url.js +28 -0
  8. package/dist/bare-url.js.map +1 -0
  9. package/dist/baseline.d.ts +5 -0
  10. package/dist/baseline.d.ts.map +1 -1
  11. package/dist/baseline.js +16 -1
  12. package/dist/baseline.js.map +1 -1
  13. package/dist/body-section.d.ts +7 -0
  14. package/dist/body-section.d.ts.map +1 -0
  15. package/dist/body-section.js +6 -0
  16. package/dist/body-section.js.map +1 -0
  17. package/dist/calendar-number.d.ts +9 -2
  18. package/dist/calendar-number.d.ts.map +1 -1
  19. package/dist/calendar-number.js +18 -4
  20. package/dist/calendar-number.js.map +1 -1
  21. package/dist/cli-args.d.ts +4 -0
  22. package/dist/cli-args.d.ts.map +1 -1
  23. package/dist/cli-args.js +5 -0
  24. package/dist/cli-args.js.map +1 -1
  25. package/dist/cli-text.d.ts.map +1 -1
  26. package/dist/cli-text.js +8 -4
  27. package/dist/cli-text.js.map +1 -1
  28. package/dist/cli.js +33 -30
  29. package/dist/cli.js.map +1 -1
  30. package/dist/closing-numbers.d.ts +20 -0
  31. package/dist/closing-numbers.d.ts.map +1 -0
  32. package/dist/closing-numbers.js +56 -0
  33. package/dist/closing-numbers.js.map +1 -0
  34. package/dist/commands/compare.d.ts +8 -0
  35. package/dist/commands/compare.d.ts.map +1 -0
  36. package/dist/commands/compare.js +72 -0
  37. package/dist/commands/compare.js.map +1 -0
  38. package/dist/commands/eval.d.ts.map +1 -1
  39. package/dist/commands/eval.js +17 -9
  40. package/dist/commands/eval.js.map +1 -1
  41. package/dist/commands/feedback.d.ts +5 -2
  42. package/dist/commands/feedback.d.ts.map +1 -1
  43. package/dist/commands/feedback.js +11 -5
  44. package/dist/commands/feedback.js.map +1 -1
  45. package/dist/commands/test.d.ts.map +1 -1
  46. package/dist/commands/test.js +13 -13
  47. package/dist/commands/test.js.map +1 -1
  48. package/dist/commands/tree.d.ts +13 -0
  49. package/dist/commands/tree.d.ts.map +1 -1
  50. package/dist/commands/tree.js +35 -5
  51. package/dist/commands/tree.js.map +1 -1
  52. package/dist/compare/atom.d.ts +31 -0
  53. package/dist/compare/atom.d.ts.map +1 -0
  54. package/dist/compare/atom.js +4 -0
  55. package/dist/compare/atom.js.map +1 -0
  56. package/dist/compare/clock-time.d.ts +8 -0
  57. package/dist/compare/clock-time.d.ts.map +1 -0
  58. package/dist/compare/clock-time.js +65 -0
  59. package/dist/compare/clock-time.js.map +1 -0
  60. package/dist/compare/extract.d.ts +15 -0
  61. package/dist/compare/extract.d.ts.map +1 -0
  62. package/dist/compare/extract.js +58 -0
  63. package/dist/compare/extract.js.map +1 -0
  64. package/dist/compare/fact-text.d.ts +23 -0
  65. package/dist/compare/fact-text.d.ts.map +1 -0
  66. package/dist/compare/fact-text.js +47 -0
  67. package/dist/compare/fact-text.js.map +1 -0
  68. package/dist/compare/markup-atoms.d.ts +11 -0
  69. package/dist/compare/markup-atoms.d.ts.map +1 -0
  70. package/dist/compare/markup-atoms.js +23 -0
  71. package/dist/compare/markup-atoms.js.map +1 -0
  72. package/dist/compare/match.d.ts +19 -0
  73. package/dist/compare/match.d.ts.map +1 -0
  74. package/dist/compare/match.js +84 -0
  75. package/dist/compare/match.js.map +1 -0
  76. package/dist/compare/outcome.d.ts +33 -0
  77. package/dist/compare/outcome.d.ts.map +1 -0
  78. package/dist/compare/outcome.js +40 -0
  79. package/dist/compare/outcome.js.map +1 -0
  80. package/dist/compare/proper-nouns.d.ts +19 -0
  81. package/dist/compare/proper-nouns.d.ts.map +1 -0
  82. package/dist/compare/proper-nouns.js +44 -0
  83. package/dist/compare/proper-nouns.js.map +1 -0
  84. package/dist/compare/render.d.ts +9 -0
  85. package/dist/compare/render.d.ts.map +1 -0
  86. package/dist/compare/render.js +64 -0
  87. package/dist/compare/render.js.map +1 -0
  88. package/dist/compare/spans.d.ts +9 -0
  89. package/dist/compare/spans.d.ts.map +1 -0
  90. package/dist/compare/spans.js +11 -0
  91. package/dist/compare/spans.js.map +1 -0
  92. package/dist/compare/text-atoms.d.ts +24 -0
  93. package/dist/compare/text-atoms.d.ts.map +1 -0
  94. package/dist/compare/text-atoms.js +67 -0
  95. package/dist/compare/text-atoms.js.map +1 -0
  96. package/dist/compare/text.d.ts +24 -0
  97. package/dist/compare/text.d.ts.map +1 -0
  98. package/dist/compare/text.js +90 -0
  99. package/dist/compare/text.js.map +1 -0
  100. package/dist/compare/tree-atoms.d.ts +20 -0
  101. package/dist/compare/tree-atoms.d.ts.map +1 -0
  102. package/dist/compare/tree-atoms.js +58 -0
  103. package/dist/compare/tree-atoms.js.map +1 -0
  104. package/dist/compare/written-names.d.ts +8 -0
  105. package/dist/compare/written-names.d.ts.map +1 -0
  106. package/dist/compare/written-names.js +24 -0
  107. package/dist/compare/written-names.js.map +1 -0
  108. package/dist/config/load.d.ts +15 -0
  109. package/dist/config/load.d.ts.map +1 -1
  110. package/dist/config/load.js +5 -0
  111. package/dist/config/load.js.map +1 -1
  112. package/dist/config/option-problems.d.ts +16 -0
  113. package/dist/config/option-problems.d.ts.map +1 -0
  114. package/dist/config/option-problems.js +58 -0
  115. package/dist/config/option-problems.js.map +1 -0
  116. package/dist/config/read.d.ts +4 -0
  117. package/dist/config/read.d.ts.map +1 -0
  118. package/dist/config/read.js +8 -0
  119. package/dist/config/read.js.map +1 -0
  120. package/dist/config/rule-problems.d.ts +2 -4
  121. package/dist/config/rule-problems.d.ts.map +1 -1
  122. package/dist/config/rule-problems.js +7 -1
  123. package/dist/config/rule-problems.js.map +1 -1
  124. package/dist/config/style.d.ts +16 -0
  125. package/dist/config/style.d.ts.map +1 -0
  126. package/dist/config/style.js +36 -0
  127. package/dist/config/style.js.map +1 -0
  128. package/dist/config/warnings.d.ts +6 -0
  129. package/dist/config/warnings.d.ts.map +1 -0
  130. package/dist/config/warnings.js +10 -0
  131. package/dist/config/warnings.js.map +1 -0
  132. package/dist/config/write.d.ts.map +1 -1
  133. package/dist/config/write.js +17 -4
  134. package/dist/config/write.js.map +1 -1
  135. package/dist/custom/bounded-match.d.ts +15 -0
  136. package/dist/custom/bounded-match.d.ts.map +1 -0
  137. package/dist/custom/bounded-match.js +43 -0
  138. package/dist/custom/bounded-match.js.map +1 -0
  139. package/dist/custom/load.d.ts +8 -0
  140. package/dist/custom/load.d.ts.map +1 -0
  141. package/dist/custom/load.js +11 -0
  142. package/dist/custom/load.js.map +1 -0
  143. package/dist/custom/parse.d.ts +70 -0
  144. package/dist/custom/parse.d.ts.map +1 -0
  145. package/dist/custom/parse.js +215 -0
  146. package/dist/custom/parse.js.map +1 -0
  147. package/dist/custom/problems.d.ts +5 -0
  148. package/dist/custom/problems.d.ts.map +1 -0
  149. package/dist/custom/problems.js +78 -0
  150. package/dist/custom/problems.js.map +1 -0
  151. package/dist/custom/regex-safety.d.ts +11 -0
  152. package/dist/custom/regex-safety.d.ts.map +1 -0
  153. package/dist/custom/regex-safety.js +110 -0
  154. package/dist/custom/regex-safety.js.map +1 -0
  155. package/dist/custom/token-pattern.d.ts +8 -0
  156. package/dist/custom/token-pattern.d.ts.map +1 -0
  157. package/dist/custom/token-pattern.js +75 -0
  158. package/dist/custom/token-pattern.js.map +1 -0
  159. package/dist/detect.d.ts.map +1 -1
  160. package/dist/detect.js +24 -2
  161. package/dist/detect.js.map +1 -1
  162. package/dist/detectors/acronym-context.d.ts +4 -0
  163. package/dist/detectors/acronym-context.d.ts.map +1 -1
  164. package/dist/detectors/acronym-context.js +25 -4
  165. package/dist/detectors/acronym-context.js.map +1 -1
  166. package/dist/detectors/acronym-expansion.d.ts +2 -0
  167. package/dist/detectors/acronym-expansion.d.ts.map +1 -1
  168. package/dist/detectors/acronym-expansion.js +104 -1
  169. package/dist/detectors/acronym-expansion.js.map +1 -1
  170. package/dist/detectors/agreement-slip.d.ts +32 -0
  171. package/dist/detectors/agreement-slip.d.ts.map +1 -0
  172. package/dist/detectors/agreement-slip.js +137 -0
  173. package/dist/detectors/agreement-slip.js.map +1 -0
  174. package/dist/detectors/ai-phrasing.d.ts +20 -0
  175. package/dist/detectors/ai-phrasing.d.ts.map +1 -0
  176. package/dist/detectors/ai-phrasing.js +112 -0
  177. package/dist/detectors/ai-phrasing.js.map +1 -0
  178. package/dist/detectors/announced-count.d.ts +4 -0
  179. package/dist/detectors/announced-count.d.ts.map +1 -0
  180. package/dist/detectors/announced-count.js +20 -0
  181. package/dist/detectors/announced-count.js.map +1 -0
  182. package/dist/detectors/broken-link.d.ts +17 -0
  183. package/dist/detectors/broken-link.d.ts.map +1 -0
  184. package/dist/detectors/broken-link.js +66 -0
  185. package/dist/detectors/broken-link.js.map +1 -0
  186. package/dist/detectors/cited-name.d.ts.map +1 -1
  187. package/dist/detectors/cited-name.js +4 -4
  188. package/dist/detectors/cited-name.js.map +1 -1
  189. package/dist/detectors/cited-title.d.ts +11 -0
  190. package/dist/detectors/cited-title.d.ts.map +1 -0
  191. package/dist/detectors/cited-title.js +75 -0
  192. package/dist/detectors/cited-title.js.map +1 -0
  193. package/dist/detectors/concrete-evidence.d.ts +1 -1
  194. package/dist/detectors/concrete-evidence.d.ts.map +1 -1
  195. package/dist/detectors/concrete-evidence.js +2 -1
  196. package/dist/detectors/concrete-evidence.js.map +1 -1
  197. package/dist/detectors/content-morphemes.d.ts +4 -0
  198. package/dist/detectors/content-morphemes.d.ts.map +1 -0
  199. package/dist/detectors/content-morphemes.js +12 -0
  200. package/dist/detectors/content-morphemes.js.map +1 -0
  201. package/dist/detectors/contrast-frame.d.ts +17 -0
  202. package/dist/detectors/contrast-frame.d.ts.map +1 -0
  203. package/dist/detectors/contrast-frame.js +32 -0
  204. package/dist/detectors/contrast-frame.js.map +1 -0
  205. package/dist/detectors/custom.d.ts +8 -0
  206. package/dist/detectors/custom.d.ts.map +1 -0
  207. package/dist/detectors/custom.js +71 -0
  208. package/dist/detectors/custom.js.map +1 -0
  209. package/dist/detectors/dangling-figure.d.ts +4 -0
  210. package/dist/detectors/dangling-figure.d.ts.map +1 -0
  211. package/dist/detectors/dangling-figure.js +18 -0
  212. package/dist/detectors/dangling-figure.js.map +1 -0
  213. package/dist/detectors/doubled-punctuation.d.ts +9 -0
  214. package/dist/detectors/doubled-punctuation.d.ts.map +1 -0
  215. package/dist/detectors/doubled-punctuation.js +33 -0
  216. package/dist/detectors/doubled-punctuation.js.map +1 -0
  217. package/dist/detectors/doubled-word.d.ts +5 -0
  218. package/dist/detectors/doubled-word.d.ts.map +1 -1
  219. package/dist/detectors/doubled-word.js +24 -11
  220. package/dist/detectors/doubled-word.js.map +1 -1
  221. package/dist/detectors/en-shape.d.ts +0 -1
  222. package/dist/detectors/en-shape.d.ts.map +1 -1
  223. package/dist/detectors/en-shape.js +0 -235
  224. package/dist/detectors/en-shape.js.map +1 -1
  225. package/dist/detectors/enumerated-runs.d.ts +1 -1
  226. package/dist/detectors/enumerated-runs.d.ts.map +1 -1
  227. package/dist/detectors/enumerated-runs.js +15 -4
  228. package/dist/detectors/enumerated-runs.js.map +1 -1
  229. package/dist/detectors/gram-furniture.d.ts +6 -0
  230. package/dist/detectors/gram-furniture.d.ts.map +1 -0
  231. package/dist/detectors/gram-furniture.js +21 -0
  232. package/dist/detectors/gram-furniture.js.map +1 -0
  233. package/dist/detectors/gram-place.d.ts +2 -0
  234. package/dist/detectors/gram-place.d.ts.map +1 -1
  235. package/dist/detectors/gram-place.js +9 -7
  236. package/dist/detectors/gram-place.js.map +1 -1
  237. package/dist/detectors/gram-windows.d.ts +9 -0
  238. package/dist/detectors/gram-windows.d.ts.map +1 -0
  239. package/dist/detectors/gram-windows.js +27 -0
  240. package/dist/detectors/gram-windows.js.map +1 -0
  241. package/dist/detectors/heading-case.d.ts +2 -0
  242. package/dist/detectors/heading-case.d.ts.map +1 -1
  243. package/dist/detectors/heading-case.js +29 -2
  244. package/dist/detectors/heading-case.js.map +1 -1
  245. package/dist/detectors/heading-code-words.d.ts +6 -0
  246. package/dist/detectors/heading-code-words.d.ts.map +1 -0
  247. package/dist/detectors/heading-code-words.js +29 -0
  248. package/dist/detectors/heading-code-words.js.map +1 -0
  249. package/dist/detectors/heading-echo.d.ts.map +1 -1
  250. package/dist/detectors/heading-echo.js +17 -20
  251. package/dist/detectors/heading-echo.js.map +1 -1
  252. package/dist/detectors/heading-level-skip.d.ts +12 -0
  253. package/dist/detectors/heading-level-skip.d.ts.map +1 -0
  254. package/dist/detectors/heading-level-skip.js +11 -0
  255. package/dist/detectors/heading-level-skip.js.map +1 -0
  256. package/dist/detectors/heading-overlap.d.ts +13 -0
  257. package/dist/detectors/heading-overlap.d.ts.map +1 -0
  258. package/dist/detectors/heading-overlap.js +52 -0
  259. package/dist/detectors/heading-overlap.js.map +1 -0
  260. package/dist/detectors/image-alt-text.d.ts +3 -0
  261. package/dist/detectors/image-alt-text.d.ts.map +1 -0
  262. package/dist/detectors/image-alt-text.js +9 -0
  263. package/dist/detectors/image-alt-text.js.map +1 -0
  264. package/dist/detectors/index.d.ts.map +1 -1
  265. package/dist/detectors/index.js +40 -2
  266. package/dist/detectors/index.js.map +1 -1
  267. package/dist/detectors/kutoten-consistency.d.ts +24 -0
  268. package/dist/detectors/kutoten-consistency.d.ts.map +1 -0
  269. package/dist/detectors/kutoten-consistency.js +77 -0
  270. package/dist/detectors/kutoten-consistency.js.map +1 -0
  271. package/dist/detectors/lead-in.d.ts +1 -0
  272. package/dist/detectors/lead-in.d.ts.map +1 -1
  273. package/dist/detectors/lead-in.js +2 -1
  274. package/dist/detectors/lead-in.js.map +1 -1
  275. package/dist/detectors/letter-joined-name.d.ts +13 -0
  276. package/dist/detectors/letter-joined-name.d.ts.map +1 -0
  277. package/dist/detectors/letter-joined-name.js +11 -0
  278. package/dist/detectors/letter-joined-name.js.map +1 -0
  279. package/dist/detectors/lexicon-match.d.ts +4 -0
  280. package/dist/detectors/lexicon-match.d.ts.map +1 -1
  281. package/dist/detectors/lexicon-match.js +7 -2
  282. package/dist/detectors/lexicon-match.js.map +1 -1
  283. package/dist/detectors/lexicon.d.ts.map +1 -1
  284. package/dist/detectors/lexicon.js +5 -2
  285. package/dist/detectors/lexicon.js.map +1 -1
  286. package/dist/detectors/list-item.d.ts +45 -0
  287. package/dist/detectors/list-item.d.ts.map +1 -0
  288. package/dist/detectors/list-item.js +88 -0
  289. package/dist/detectors/list-item.js.map +1 -0
  290. package/dist/detectors/list-items.d.ts +31 -0
  291. package/dist/detectors/list-items.d.ts.map +1 -0
  292. package/dist/detectors/list-items.js +113 -0
  293. package/dist/detectors/list-items.js.map +1 -0
  294. package/dist/detectors/list-lead-in.d.ts +7 -0
  295. package/dist/detectors/list-lead-in.d.ts.map +1 -0
  296. package/dist/detectors/list-lead-in.js +28 -0
  297. package/dist/detectors/list-lead-in.js.map +1 -0
  298. package/dist/detectors/list-sentence.d.ts +65 -0
  299. package/dist/detectors/list-sentence.d.ts.map +1 -0
  300. package/dist/detectors/list-sentence.js +105 -0
  301. package/dist/detectors/list-sentence.js.map +1 -0
  302. package/dist/detectors/list-view.d.ts +34 -0
  303. package/dist/detectors/list-view.d.ts.map +1 -0
  304. package/dist/detectors/list-view.js +137 -0
  305. package/dist/detectors/list-view.js.map +1 -0
  306. package/dist/detectors/long-vowel.d.ts +7 -0
  307. package/dist/detectors/long-vowel.d.ts.map +1 -0
  308. package/dist/detectors/long-vowel.js +57 -0
  309. package/dist/detectors/long-vowel.js.map +1 -0
  310. package/dist/detectors/markup-finding.d.ts +6 -0
  311. package/dist/detectors/markup-finding.d.ts.map +1 -0
  312. package/dist/detectors/markup-finding.js +19 -0
  313. package/dist/detectors/markup-finding.js.map +1 -0
  314. package/dist/detectors/name-numeral.d.ts +1 -1
  315. package/dist/detectors/name-numeral.d.ts.map +1 -1
  316. package/dist/detectors/name-numeral.js +2 -7
  317. package/dist/detectors/name-numeral.js.map +1 -1
  318. package/dist/detectors/orthography.d.ts.map +1 -1
  319. package/dist/detectors/orthography.js +16 -12
  320. package/dist/detectors/orthography.js.map +1 -1
  321. package/dist/detectors/oxford-comma.d.ts +9 -0
  322. package/dist/detectors/oxford-comma.d.ts.map +1 -0
  323. package/dist/detectors/oxford-comma.js +246 -0
  324. package/dist/detectors/oxford-comma.js.map +1 -0
  325. package/dist/detectors/place-run.d.ts.map +1 -1
  326. package/dist/detectors/place-run.js +10 -6
  327. package/dist/detectors/place-run.js.map +1 -1
  328. package/dist/detectors/placeholder-text.d.ts +9 -0
  329. package/dist/detectors/placeholder-text.d.ts.map +1 -0
  330. package/dist/detectors/placeholder-text.js +18 -0
  331. package/dist/detectors/placeholder-text.js.map +1 -0
  332. package/dist/detectors/quote-around.d.ts +3 -0
  333. package/dist/detectors/quote-around.d.ts.map +1 -0
  334. package/dist/detectors/quote-around.js +8 -0
  335. package/dist/detectors/quote-around.js.map +1 -0
  336. package/dist/detectors/register.d.ts +11 -3
  337. package/dist/detectors/register.d.ts.map +1 -1
  338. package/dist/detectors/register.js +28 -9
  339. package/dist/detectors/register.js.map +1 -1
  340. package/dist/detectors/roman-numeral.d.ts +2 -0
  341. package/dist/detectors/roman-numeral.d.ts.map +1 -1
  342. package/dist/detectors/roman-numeral.js +2 -0
  343. package/dist/detectors/roman-numeral.js.map +1 -1
  344. package/dist/detectors/sentence-ending.d.ts +17 -1
  345. package/dist/detectors/sentence-ending.d.ts.map +1 -1
  346. package/dist/detectors/sentence-ending.js +13 -7
  347. package/dist/detectors/sentence-ending.js.map +1 -1
  348. package/dist/detectors/sentence-length.d.ts.map +1 -1
  349. package/dist/detectors/sentence-length.js +13 -4
  350. package/dist/detectors/sentence-length.js.map +1 -1
  351. package/dist/detectors/signals.d.ts +8 -0
  352. package/dist/detectors/signals.d.ts.map +1 -1
  353. package/dist/detectors/signals.js +94 -54
  354. package/dist/detectors/signals.js.map +1 -1
  355. package/dist/detectors/stacked-hedge.d.ts +0 -7
  356. package/dist/detectors/stacked-hedge.d.ts.map +1 -1
  357. package/dist/detectors/stacked-hedge.js +6 -3
  358. package/dist/detectors/stacked-hedge.js.map +1 -1
  359. package/dist/detectors/stray-space.d.ts +7 -0
  360. package/dist/detectors/stray-space.d.ts.map +1 -0
  361. package/dist/detectors/stray-space.js +34 -0
  362. package/dist/detectors/stray-space.js.map +1 -0
  363. package/dist/detectors/structure-tree.d.ts +6 -0
  364. package/dist/detectors/structure-tree.d.ts.map +1 -1
  365. package/dist/detectors/structure-tree.js +37 -1
  366. package/dist/detectors/structure-tree.js.map +1 -1
  367. package/dist/detectors/structure.d.ts +4 -4
  368. package/dist/detectors/structure.d.ts.map +1 -1
  369. package/dist/detectors/structure.js +7 -6
  370. package/dist/detectors/structure.js.map +1 -1
  371. package/dist/detectors/superlative-name.d.ts.map +1 -1
  372. package/dist/detectors/superlative-name.js +8 -5
  373. package/dist/detectors/superlative-name.js.map +1 -1
  374. package/dist/detectors/superlative-scope.d.ts.map +1 -1
  375. package/dist/detectors/superlative-scope.js +9 -4
  376. package/dist/detectors/superlative-scope.js.map +1 -1
  377. package/dist/detectors/token-column.d.ts +46 -0
  378. package/dist/detectors/token-column.d.ts.map +1 -0
  379. package/dist/detectors/token-column.js +95 -0
  380. package/dist/detectors/token-column.js.map +1 -0
  381. package/dist/detectors/unbalanced-bracket.d.ts +22 -0
  382. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -0
  383. package/dist/detectors/unbalanced-bracket.js +119 -0
  384. package/dist/detectors/unbalanced-bracket.js.map +1 -0
  385. package/dist/detectors/url-run-on.d.ts +9 -0
  386. package/dist/detectors/url-run-on.d.ts.map +1 -0
  387. package/dist/detectors/url-run-on.js +19 -0
  388. package/dist/detectors/url-run-on.js.map +1 -0
  389. package/dist/document-sections.d.ts +13 -0
  390. package/dist/document-sections.d.ts.map +1 -0
  391. package/dist/document-sections.js +32 -0
  392. package/dist/document-sections.js.map +1 -0
  393. package/dist/document.d.ts +11 -4
  394. package/dist/document.d.ts.map +1 -1
  395. package/dist/document.js +99 -95
  396. package/dist/document.js.map +1 -1
  397. package/dist/email-parts.d.ts +28 -0
  398. package/dist/email-parts.d.ts.map +1 -0
  399. package/dist/email-parts.js +230 -0
  400. package/dist/email-parts.js.map +1 -0
  401. package/dist/eval.d.ts +2 -1
  402. package/dist/eval.d.ts.map +1 -1
  403. package/dist/eval.js +16 -4
  404. package/dist/eval.js.map +1 -1
  405. package/dist/figure-references.d.ts +30 -0
  406. package/dist/figure-references.d.ts.map +1 -0
  407. package/dist/figure-references.js +76 -0
  408. package/dist/figure-references.js.map +1 -0
  409. package/dist/files.d.ts +2 -0
  410. package/dist/files.d.ts.map +1 -1
  411. package/dist/files.js +4 -0
  412. package/dist/files.js.map +1 -1
  413. package/dist/genre-parse.d.ts +5 -1
  414. package/dist/genre-parse.d.ts.map +1 -1
  415. package/dist/genre-parse.js +16 -3
  416. package/dist/genre-parse.js.map +1 -1
  417. package/dist/genre-suggest.d.ts.map +1 -1
  418. package/dist/genre-suggest.js +15 -1
  419. package/dist/genre-suggest.js.map +1 -1
  420. package/dist/heading-label.d.ts +22 -0
  421. package/dist/heading-label.d.ts.map +1 -0
  422. package/dist/heading-label.js +50 -0
  423. package/dist/heading-label.js.map +1 -0
  424. package/dist/in-page-nav.d.ts +4 -1
  425. package/dist/in-page-nav.d.ts.map +1 -1
  426. package/dist/in-page-nav.js +53 -18
  427. package/dist/in-page-nav.js.map +1 -1
  428. package/dist/joined-view.d.ts.map +1 -1
  429. package/dist/joined-view.js +1 -0
  430. package/dist/joined-view.js.map +1 -1
  431. package/dist/levels.d.ts +5 -1
  432. package/dist/levels.d.ts.map +1 -1
  433. package/dist/levels.js +9 -0
  434. package/dist/levels.js.map +1 -1
  435. package/dist/line-paragraphs.d.ts +8 -0
  436. package/dist/line-paragraphs.d.ts.map +1 -1
  437. package/dist/line-paragraphs.js +36 -11
  438. package/dist/line-paragraphs.js.map +1 -1
  439. package/dist/long-vowel.d.ts +35 -0
  440. package/dist/long-vowel.d.ts.map +1 -0
  441. package/dist/long-vowel.js +71 -0
  442. package/dist/long-vowel.js.map +1 -0
  443. package/dist/markdown-node.d.ts +19 -0
  444. package/dist/markdown-node.d.ts.map +1 -0
  445. package/dist/markdown-node.js +6 -0
  446. package/dist/markdown-node.js.map +1 -0
  447. package/dist/markdown-read.d.ts +17 -0
  448. package/dist/markdown-read.d.ts.map +1 -0
  449. package/dist/markdown-read.js +37 -0
  450. package/dist/markdown-read.js.map +1 -0
  451. package/dist/markup.d.ts +22 -0
  452. package/dist/markup.d.ts.map +1 -0
  453. package/dist/markup.js +180 -0
  454. package/dist/markup.js.map +1 -0
  455. package/dist/mask.d.ts.map +1 -1
  456. package/dist/mask.js +10 -16
  457. package/dist/mask.js.map +1 -1
  458. package/dist/number-name.d.ts +21 -5
  459. package/dist/number-name.d.ts.map +1 -1
  460. package/dist/number-name.js +120 -18
  461. package/dist/number-name.js.map +1 -1
  462. package/dist/opening-line.d.ts +3 -0
  463. package/dist/opening-line.d.ts.map +1 -0
  464. package/dist/opening-line.js +14 -0
  465. package/dist/opening-line.js.map +1 -0
  466. package/dist/orthography.d.ts +7 -1
  467. package/dist/orthography.d.ts.map +1 -1
  468. package/dist/orthography.js +16 -5
  469. package/dist/orthography.js.map +1 -1
  470. package/dist/page-furniture.d.ts +5 -2
  471. package/dist/page-furniture.d.ts.map +1 -1
  472. package/dist/page-furniture.js +8 -2
  473. package/dist/page-furniture.js.map +1 -1
  474. package/dist/paragraph-length.d.ts +7 -0
  475. package/dist/paragraph-length.d.ts.map +1 -0
  476. package/dist/paragraph-length.js +10 -0
  477. package/dist/paragraph-length.js.map +1 -0
  478. package/dist/plain-source.d.ts +1 -0
  479. package/dist/plain-source.d.ts.map +1 -1
  480. package/dist/plain-source.js +2 -1
  481. package/dist/plain-source.js.map +1 -1
  482. package/dist/plugin.d.ts +121 -0
  483. package/dist/plugin.d.ts.map +1 -1
  484. package/dist/profile/for-file.d.ts.map +1 -1
  485. package/dist/profile/for-file.js +3 -1
  486. package/dist/profile/for-file.js.map +1 -1
  487. package/dist/quoted-span.d.ts +0 -2
  488. package/dist/quoted-span.d.ts.map +1 -1
  489. package/dist/quoted-span.js +9 -4
  490. package/dist/quoted-span.js.map +1 -1
  491. package/dist/reasons.d.ts +3 -0
  492. package/dist/reasons.d.ts.map +1 -1
  493. package/dist/reasons.js +6 -0
  494. package/dist/reasons.js.map +1 -1
  495. package/dist/reference-lists.d.ts +3 -0
  496. package/dist/reference-lists.d.ts.map +1 -0
  497. package/dist/reference-lists.js +75 -0
  498. package/dist/reference-lists.js.map +1 -0
  499. package/dist/render/explain.d.ts +7 -1
  500. package/dist/render/explain.d.ts.map +1 -1
  501. package/dist/render/explain.js +36 -12
  502. package/dist/render/explain.js.map +1 -1
  503. package/dist/render/friendly.d.ts.map +1 -1
  504. package/dist/render/friendly.js +19 -9
  505. package/dist/render/friendly.js.map +1 -1
  506. package/dist/render/options.d.ts +7 -0
  507. package/dist/render/options.d.ts.map +1 -0
  508. package/dist/render/options.js +50 -0
  509. package/dist/render/options.js.map +1 -0
  510. package/dist/render/rules-json.d.ts +4 -1
  511. package/dist/render/rules-json.d.ts.map +1 -1
  512. package/dist/render/rules-json.js +102 -12
  513. package/dist/render/rules-json.js.map +1 -1
  514. package/dist/render/rules-table.d.ts +4 -0
  515. package/dist/render/rules-table.d.ts.map +1 -0
  516. package/dist/render/rules-table.js +70 -0
  517. package/dist/render/rules-table.js.map +1 -0
  518. package/dist/render/sarif.js +4 -4
  519. package/dist/render/sarif.js.map +1 -1
  520. package/dist/render/semantic.js +3 -3
  521. package/dist/render/semantic.js.map +1 -1
  522. package/dist/render/severity-name.d.ts +6 -0
  523. package/dist/render/severity-name.d.ts.map +1 -0
  524. package/dist/render/severity-name.js +7 -0
  525. package/dist/render/severity-name.js.map +1 -0
  526. package/dist/render/text.d.ts +7 -2
  527. package/dist/render/text.d.ts.map +1 -1
  528. package/dist/render/text.js +15 -4
  529. package/dist/render/text.js.map +1 -1
  530. package/dist/resolve-genre.d.ts +1 -1
  531. package/dist/resolve-genre.d.ts.map +1 -1
  532. package/dist/resolve-genre.js +4 -1
  533. package/dist/resolve-genre.js.map +1 -1
  534. package/dist/rule-genres.d.ts +24 -0
  535. package/dist/rule-genres.d.ts.map +1 -0
  536. package/dist/rule-genres.js +11 -0
  537. package/dist/rule-genres.js.map +1 -0
  538. package/dist/rule-guide.d.ts +54 -0
  539. package/dist/rule-guide.d.ts.map +1 -0
  540. package/dist/rule-guide.js +81 -0
  541. package/dist/rule-guide.js.map +1 -0
  542. package/dist/rule-load.d.ts.map +1 -1
  543. package/dist/rule-load.js +94 -32
  544. package/dist/rule-load.js.map +1 -1
  545. package/dist/rule-options.d.ts +50 -0
  546. package/dist/rule-options.d.ts.map +1 -0
  547. package/dist/rule-options.js +106 -0
  548. package/dist/rule-options.js.map +1 -0
  549. package/dist/run-semantic.d.ts +3 -1
  550. package/dist/run-semantic.d.ts.map +1 -1
  551. package/dist/run-semantic.js +8 -3
  552. package/dist/run-semantic.js.map +1 -1
  553. package/dist/run.d.ts +15 -0
  554. package/dist/run.d.ts.map +1 -1
  555. package/dist/run.js +57 -10
  556. package/dist/run.js.map +1 -1
  557. package/dist/semantic.d.ts +1 -1
  558. package/dist/semantic.d.ts.map +1 -1
  559. package/dist/semantic.js +10 -3
  560. package/dist/semantic.js.map +1 -1
  561. package/dist/sentence-shape.d.ts.map +1 -1
  562. package/dist/sentence-shape.js +4 -4
  563. package/dist/sentence-shape.js.map +1 -1
  564. package/dist/setting-problems.d.ts +2 -1
  565. package/dist/setting-problems.d.ts.map +1 -1
  566. package/dist/setting-problems.js +6 -1
  567. package/dist/setting-problems.js.map +1 -1
  568. package/dist/span-cut.d.ts +6 -0
  569. package/dist/span-cut.d.ts.map +1 -0
  570. package/dist/span-cut.js +22 -0
  571. package/dist/span-cut.js.map +1 -0
  572. package/dist/span-merge.d.ts +4 -0
  573. package/dist/span-merge.d.ts.map +1 -0
  574. package/dist/span-merge.js +12 -0
  575. package/dist/span-merge.js.map +1 -0
  576. package/dist/speaker-labels.d.ts +4 -0
  577. package/dist/speaker-labels.d.ts.map +1 -0
  578. package/dist/speaker-labels.js +106 -0
  579. package/dist/speaker-labels.js.map +1 -0
  580. package/dist/stray-space.d.ts +17 -0
  581. package/dist/stray-space.d.ts.map +1 -0
  582. package/dist/stray-space.js +66 -0
  583. package/dist/stray-space.js.map +1 -0
  584. package/dist/structure/aside-depth.d.ts +21 -0
  585. package/dist/structure/aside-depth.d.ts.map +1 -0
  586. package/dist/structure/aside-depth.js +65 -0
  587. package/dist/structure/aside-depth.js.map +1 -0
  588. package/dist/structure/build.d.ts +5 -1
  589. package/dist/structure/build.d.ts.map +1 -1
  590. package/dist/structure/build.js +29 -17
  591. package/dist/structure/build.js.map +1 -1
  592. package/dist/structure/closed-pairs.d.ts +8 -0
  593. package/dist/structure/closed-pairs.d.ts.map +1 -0
  594. package/dist/structure/closed-pairs.js +22 -0
  595. package/dist/structure/closed-pairs.js.map +1 -0
  596. package/dist/structure/date-range.d.ts +21 -0
  597. package/dist/structure/date-range.d.ts.map +1 -0
  598. package/dist/structure/date-range.js +45 -0
  599. package/dist/structure/date-range.js.map +1 -0
  600. package/dist/structure/known-mentions.d.ts +18 -0
  601. package/dist/structure/known-mentions.d.ts.map +1 -0
  602. package/dist/structure/known-mentions.js +78 -0
  603. package/dist/structure/known-mentions.js.map +1 -0
  604. package/dist/structure/numbering.d.ts +1 -0
  605. package/dist/structure/numbering.d.ts.map +1 -1
  606. package/dist/structure/numbering.js +11 -6
  607. package/dist/structure/numbering.js.map +1 -1
  608. package/dist/structure/of.d.ts +3 -1
  609. package/dist/structure/of.d.ts.map +1 -1
  610. package/dist/structure/of.js +5 -1
  611. package/dist/structure/of.js.map +1 -1
  612. package/dist/structure/percent-sum.d.ts +16 -0
  613. package/dist/structure/percent-sum.d.ts.map +1 -0
  614. package/dist/structure/percent-sum.js +104 -0
  615. package/dist/structure/percent-sum.js.map +1 -0
  616. package/dist/structure/quoted-number.d.ts +8 -0
  617. package/dist/structure/quoted-number.d.ts.map +1 -0
  618. package/dist/structure/quoted-number.js +34 -0
  619. package/dist/structure/quoted-number.js.map +1 -0
  620. package/dist/structure/relative-find.d.ts.map +1 -1
  621. package/dist/structure/relative-find.js +34 -46
  622. package/dist/structure/relative-find.js.map +1 -1
  623. package/dist/structure/relative-resolve.d.ts.map +1 -1
  624. package/dist/structure/relative-resolve.js +94 -42
  625. package/dist/structure/relative-resolve.js.map +1 -1
  626. package/dist/structure/runs.d.ts +2 -0
  627. package/dist/structure/runs.d.ts.map +1 -1
  628. package/dist/structure/runs.js +2 -2
  629. package/dist/structure/runs.js.map +1 -1
  630. package/dist/structure/sexp.d.ts +1 -1
  631. package/dist/structure/sexp.d.ts.map +1 -1
  632. package/dist/structure/sexp.js +18 -6
  633. package/dist/structure/sexp.js.map +1 -1
  634. package/dist/structure/total.d.ts +3 -0
  635. package/dist/structure/total.d.ts.map +1 -1
  636. package/dist/structure/total.js +2 -2
  637. package/dist/structure/total.js.map +1 -1
  638. package/dist/structure/universal.d.ts +14 -2
  639. package/dist/structure/universal.d.ts.map +1 -1
  640. package/dist/structure/universal.js +17 -2
  641. package/dist/structure/universal.js.map +1 -1
  642. package/dist/structure/wrapped-tail.d.ts +14 -7
  643. package/dist/structure/wrapped-tail.d.ts.map +1 -1
  644. package/dist/structure/wrapped-tail.js +33 -8
  645. package/dist/structure/wrapped-tail.js.map +1 -1
  646. package/dist/style-load.d.ts +4 -0
  647. package/dist/style-load.d.ts.map +1 -0
  648. package/dist/style-load.js +28 -0
  649. package/dist/style-load.js.map +1 -0
  650. package/dist/style-parse.d.ts +19 -0
  651. package/dist/style-parse.d.ts.map +1 -0
  652. package/dist/style-parse.js +60 -0
  653. package/dist/style-parse.js.map +1 -0
  654. package/dist/subheading-line.d.ts +6 -0
  655. package/dist/subheading-line.d.ts.map +1 -0
  656. package/dist/subheading-line.js +57 -0
  657. package/dist/subheading-line.js.map +1 -0
  658. package/dist/team-names.d.ts.map +1 -1
  659. package/dist/team-names.js +11 -14
  660. package/dist/team-names.js.map +1 -1
  661. package/dist/template-syntax.d.ts +17 -0
  662. package/dist/template-syntax.d.ts.map +1 -0
  663. package/dist/template-syntax.js +140 -0
  664. package/dist/template-syntax.js.map +1 -0
  665. package/dist/text-above.d.ts +19 -0
  666. package/dist/text-above.d.ts.map +1 -0
  667. package/dist/text-above.js +43 -0
  668. package/dist/text-above.js.map +1 -0
  669. package/dist/text-figures.d.ts +10 -0
  670. package/dist/text-figures.d.ts.map +1 -0
  671. package/dist/text-figures.js +131 -0
  672. package/dist/text-figures.js.map +1 -0
  673. package/dist/trailing-aside.d.ts +2 -0
  674. package/dist/trailing-aside.d.ts.map +1 -0
  675. package/dist/trailing-aside.js +53 -0
  676. package/dist/trailing-aside.js.map +1 -0
  677. package/dist/tree-walk.d.ts +18 -0
  678. package/dist/tree-walk.d.ts.map +1 -0
  679. package/dist/tree-walk.js +45 -0
  680. package/dist/tree-walk.js.map +1 -0
  681. package/genres.yaml +60 -2
  682. package/package.json +5 -3
  683. package/reference-headings.yaml +17 -0
  684. package/rules/adverb-overuse.yaml +19 -0
  685. package/rules/agentless-passive.yaml +19 -0
  686. package/rules/agreement-slip.yaml +49 -0
  687. package/rules/ai-generated-composite.yaml +102 -0
  688. package/rules/ai-tell.yaml +23 -0
  689. package/rules/announced-count-mismatch.yaml +57 -0
  690. package/rules/announcing-opener.yaml +51 -0
  691. package/rules/assistant-residue.yaml +52 -0
  692. package/rules/bold-density.yaml +31 -0
  693. package/rules/broken-link.yaml +65 -0
  694. package/rules/closing-cliche.yaml +33 -0
  695. package/rules/colon-lead-in.yaml +59 -0
  696. package/rules/concrete-evidence-density.yaml +41 -0
  697. package/rules/contraction-consistency.yaml +18 -0
  698. package/rules/contrast-framing.yaml +57 -0
  699. package/rules/cushion-phrase-density.yaml +25 -0
  700. package/rules/dangling-figure-reference.yaml +61 -0
  701. package/rules/dangling-reference.yaml +53 -1
  702. package/rules/date-order.yaml +33 -1
  703. package/rules/date-range-reversed.yaml +46 -0
  704. package/rules/date-weekday-mismatch.yaml +17 -1
  705. package/rules/double-keigo.yaml +16 -0
  706. package/rules/doubled-punctuation.yaml +45 -0
  707. package/rules/doubled-word.yaml +17 -1
  708. package/rules/duplicate-definition.yaml +59 -1
  709. package/rules/emoji-density.yaml +25 -0
  710. package/rules/empty-conclusion.yaml +29 -0
  711. package/rules/empty-intensifier.yaml +19 -0
  712. package/rules/excessive-hedging.yaml +19 -0
  713. package/rules/expletive-construction.yaml +19 -0
  714. package/rules/heading-echo.yaml +32 -0
  715. package/rules/heading-level-skip.yaml +78 -0
  716. package/rules/hiragana-fukushi.yaml +16 -0
  717. package/rules/image-alt-text.yaml +54 -0
  718. package/rules/internal-jargon.yaml +21 -0
  719. package/rules/katakana-long-vowel.yaml +98 -0
  720. package/rules/kutoten-consistency.yaml +53 -0
  721. package/rules/latin-spacing.yaml +23 -4
  722. package/rules/max-kanji-continuous.yaml +16 -0
  723. package/rules/max-paragraph-length.yaml +42 -2
  724. package/rules/max-sentence-length.yaml +36 -0
  725. package/rules/ngram-repetition.yaml +29 -2
  726. package/rules/no-doubled-joshi.yaml +16 -0
  727. package/rules/no-em-dash.yaml +25 -0
  728. package/rules/no-mixed-desumasu.yaml +27 -2
  729. package/rules/no-nakaguro-parallel.yaml +20 -0
  730. package/rules/numbering-gap.yaml +53 -1
  731. package/rules/oxford-comma-consistency.yaml +19 -1
  732. package/rules/padded-intro.yaml +19 -0
  733. package/rules/paragraph-length-variance.yaml +49 -0
  734. package/rules/percent-sum-mismatch.yaml +58 -0
  735. package/rules/preamble-length.yaml +56 -0
  736. package/rules/preferred-term.yaml +27 -0
  737. package/rules/proper-noun-density.yaml +26 -0
  738. package/rules/repeated-conjunction.yaml +47 -0
  739. package/rules/repeated-sentence-head.yaml +23 -0
  740. package/rules/required-sections.yaml +49 -0
  741. package/rules/risk-disclosure.yaml +22 -0
  742. package/rules/rule-of-three.yaml +97 -0
  743. package/rules/sasete-itadaku.yaml +18 -0
  744. package/rules/section-length-uniformity.yaml +89 -0
  745. package/rules/sentence-initial-conjunction-run.yaml +18 -0
  746. package/rules/sentence-rhythm.yaml +25 -0
  747. package/rules/stock-transition.yaml +55 -0
  748. package/rules/stray-space.yaml +56 -0
  749. package/rules/taigen-dome-in-prose.yaml +19 -0
  750. package/rules/title-case-consistency.yaml +42 -0
  751. package/rules/total-mismatch.yaml +37 -1
  752. package/rules/unbalanced-bracket.yaml +56 -0
  753. package/rules/undefined-acronym.yaml +23 -0
  754. package/rules/unfilled-placeholder.yaml +50 -0
  755. package/rules/unqualified-superlative.yaml +19 -0
  756. package/rules/unsourced-number.yaml +16 -0
  757. package/rules/url-run-on.yaml +45 -0
  758. package/skills/chaff/SKILL.md +70 -0
  759. package/src/announced-count.ts +148 -0
  760. package/src/bare-url.ts +35 -0
  761. package/src/baseline.ts +17 -1
  762. package/src/body-section.ts +7 -0
  763. package/src/calendar-number.ts +33 -10
  764. package/src/cli-args.ts +6 -0
  765. package/src/cli-text.ts +8 -4
  766. package/src/cli.ts +37 -37
  767. package/src/closing-numbers.ts +72 -0
  768. package/src/commands/compare.ts +80 -0
  769. package/src/commands/eval.ts +19 -8
  770. package/src/commands/feedback.ts +12 -6
  771. package/src/commands/test.ts +20 -17
  772. package/src/commands/tree.ts +41 -5
  773. package/src/compare/atom.ts +33 -0
  774. package/src/compare/clock-time.ts +86 -0
  775. package/src/compare/extract.ts +78 -0
  776. package/src/compare/fact-text.ts +68 -0
  777. package/src/compare/markup-atoms.ts +29 -0
  778. package/src/compare/match.ts +105 -0
  779. package/src/compare/outcome.ts +70 -0
  780. package/src/compare/proper-nouns.ts +65 -0
  781. package/src/compare/render.ts +102 -0
  782. package/src/compare/spans.ts +17 -0
  783. package/src/compare/text-atoms.ts +95 -0
  784. package/src/compare/text.ts +120 -0
  785. package/src/compare/tree-atoms.ts +80 -0
  786. package/src/compare/written-names.ts +26 -0
  787. package/src/config/load.ts +21 -0
  788. package/src/config/option-problems.ts +70 -0
  789. package/src/config/read.ts +8 -0
  790. package/src/config/rule-problems.ts +12 -2
  791. package/src/config/style.ts +42 -0
  792. package/src/config/warnings.ts +13 -0
  793. package/src/config/write.ts +18 -4
  794. package/src/custom/bounded-match.ts +58 -0
  795. package/src/custom/load.ts +15 -0
  796. package/src/custom/parse.ts +274 -0
  797. package/src/custom/problems.ts +89 -0
  798. package/src/custom/regex-safety.ts +118 -0
  799. package/src/custom/token-pattern.ts +84 -0
  800. package/src/detect.ts +28 -2
  801. package/src/detectors/acronym-context.ts +32 -4
  802. package/src/detectors/acronym-expansion.ts +132 -1
  803. package/src/detectors/agreement-slip.ts +191 -0
  804. package/src/detectors/ai-phrasing.ts +137 -0
  805. package/src/detectors/announced-count.ts +25 -0
  806. package/src/detectors/broken-link.ts +90 -0
  807. package/src/detectors/cited-name.ts +6 -5
  808. package/src/detectors/cited-title.ts +96 -0
  809. package/src/detectors/concrete-evidence.ts +3 -2
  810. package/src/detectors/content-morphemes.ts +19 -0
  811. package/src/detectors/contrast-frame.ts +54 -0
  812. package/src/detectors/custom.ts +89 -0
  813. package/src/detectors/dangling-figure.ts +22 -0
  814. package/src/detectors/doubled-punctuation.ts +49 -0
  815. package/src/detectors/doubled-word.ts +19 -4
  816. package/src/detectors/en-shape.ts +0 -269
  817. package/src/detectors/enumerated-runs.ts +13 -4
  818. package/src/detectors/gram-furniture.ts +30 -0
  819. package/src/detectors/gram-place.ts +9 -5
  820. package/src/detectors/gram-windows.ts +31 -0
  821. package/src/detectors/heading-case.ts +30 -2
  822. package/src/detectors/heading-code-words.ts +35 -0
  823. package/src/detectors/heading-echo.ts +18 -22
  824. package/src/detectors/heading-level-skip.ts +19 -0
  825. package/src/detectors/heading-overlap.ts +65 -0
  826. package/src/detectors/image-alt-text.ts +11 -0
  827. package/src/detectors/index.ts +49 -2
  828. package/src/detectors/kutoten-consistency.ts +96 -0
  829. package/src/detectors/lead-in.ts +3 -1
  830. package/src/detectors/letter-joined-name.ts +15 -0
  831. package/src/detectors/lexicon-match.ts +9 -2
  832. package/src/detectors/lexicon.ts +6 -2
  833. package/src/detectors/list-item.ts +122 -0
  834. package/src/detectors/list-items.ts +163 -0
  835. package/src/detectors/list-lead-in.ts +33 -0
  836. package/src/detectors/list-sentence.ts +157 -0
  837. package/src/detectors/list-view.ts +157 -0
  838. package/src/detectors/long-vowel.ts +66 -0
  839. package/src/detectors/markup-finding.ts +24 -0
  840. package/src/detectors/name-numeral.ts +4 -2
  841. package/src/detectors/orthography.ts +24 -18
  842. package/src/detectors/oxford-comma.ts +297 -0
  843. package/src/detectors/place-run.ts +7 -4
  844. package/src/detectors/placeholder-text.ts +27 -0
  845. package/src/detectors/quote-around.ts +9 -0
  846. package/src/detectors/register.ts +37 -10
  847. package/src/detectors/roman-numeral.ts +3 -0
  848. package/src/detectors/sentence-ending.ts +14 -7
  849. package/src/detectors/sentence-length.ts +16 -5
  850. package/src/detectors/signals.ts +110 -53
  851. package/src/detectors/stacked-hedge.ts +6 -3
  852. package/src/detectors/stray-space.ts +40 -0
  853. package/src/detectors/structure-tree.ts +45 -1
  854. package/src/detectors/structure.ts +13 -6
  855. package/src/detectors/superlative-name.ts +7 -4
  856. package/src/detectors/superlative-scope.ts +8 -3
  857. package/src/detectors/token-column.ts +149 -0
  858. package/src/detectors/unbalanced-bracket.ts +153 -0
  859. package/src/detectors/url-run-on.ts +27 -0
  860. package/src/document-sections.ts +46 -0
  861. package/src/document.ts +116 -127
  862. package/src/email-parts.ts +269 -0
  863. package/src/eval.ts +14 -4
  864. package/src/figure-references.ts +112 -0
  865. package/src/files.ts +5 -0
  866. package/src/genre-parse.ts +30 -5
  867. package/src/genre-suggest.ts +15 -2
  868. package/src/heading-label.ts +55 -0
  869. package/src/in-page-nav.ts +48 -19
  870. package/src/joined-view.ts +1 -0
  871. package/src/levels.ts +14 -1
  872. package/src/line-paragraphs.ts +56 -10
  873. package/src/long-vowel.ts +99 -0
  874. package/src/markdown-node.ts +19 -0
  875. package/src/markdown-read.ts +44 -0
  876. package/src/markup.ts +210 -0
  877. package/src/mask.ts +10 -19
  878. package/src/number-name.ts +152 -25
  879. package/src/opening-line.ts +17 -0
  880. package/src/orthography.ts +20 -5
  881. package/src/page-furniture.ts +11 -2
  882. package/src/paragraph-length.ts +9 -0
  883. package/src/plain-source.ts +2 -1
  884. package/src/plugin.ts +107 -1
  885. package/src/profile/for-file.ts +3 -1
  886. package/src/quoted-span.ts +10 -4
  887. package/src/reasons.ts +9 -0
  888. package/src/reference-lists.ts +91 -0
  889. package/src/render/explain.ts +47 -13
  890. package/src/render/friendly.ts +20 -9
  891. package/src/render/options.ts +58 -0
  892. package/src/render/rules-json.ts +130 -14
  893. package/src/render/rules-table.ts +91 -0
  894. package/src/render/sarif.ts +4 -4
  895. package/src/render/semantic.ts +3 -3
  896. package/src/render/severity-name.ts +10 -0
  897. package/src/render/text.ts +21 -7
  898. package/src/resolve-genre.ts +4 -1
  899. package/src/rule-genres.ts +25 -0
  900. package/src/rule-guide.ts +135 -0
  901. package/src/rule-load.ts +98 -33
  902. package/src/rule-options.ts +131 -0
  903. package/src/run-semantic.ts +28 -20
  904. package/src/run.ts +78 -11
  905. package/src/semantic.ts +11 -3
  906. package/src/sentence-shape.ts +4 -5
  907. package/src/setting-problems.ts +7 -1
  908. package/src/span-cut.ts +28 -0
  909. package/src/span-merge.ts +13 -0
  910. package/src/speaker-labels.ts +129 -0
  911. package/src/stray-space.ts +81 -0
  912. package/src/structure/aside-depth.ts +67 -0
  913. package/src/structure/build.ts +38 -19
  914. package/src/structure/closed-pairs.ts +20 -0
  915. package/src/structure/date-range.ts +69 -0
  916. package/src/structure/known-mentions.ts +96 -0
  917. package/src/structure/numbering.ts +9 -5
  918. package/src/structure/of.ts +11 -3
  919. package/src/structure/percent-sum.ts +135 -0
  920. package/src/structure/quoted-number.ts +36 -0
  921. package/src/structure/relative-find.ts +34 -47
  922. package/src/structure/relative-resolve.ts +104 -42
  923. package/src/structure/runs.ts +2 -2
  924. package/src/structure/sexp.ts +17 -5
  925. package/src/structure/total.ts +2 -2
  926. package/src/structure/universal.ts +24 -4
  927. package/src/structure/wrapped-tail.ts +38 -13
  928. package/src/style-load.ts +28 -0
  929. package/src/style-parse.ts +77 -0
  930. package/src/subheading-line.ts +68 -0
  931. package/src/team-names.ts +13 -13
  932. package/src/template-syntax.ts +164 -0
  933. package/src/text-above.ts +49 -0
  934. package/src/text-figures.ts +147 -0
  935. package/src/trailing-aside.ts +50 -0
  936. package/src/tree-walk.ts +48 -0
  937. package/styles/bunkacho.yaml +25 -0
  938. package/styles/ieice.yaml +29 -0
  939. package/styles/jis-z8301-2011.yaml +25 -0
@@ -0,0 +1,17 @@
1
+ import { plainSource } from "./plain-source.ts";
2
+
3
+ const FRONT_MATTER_FENCE = "---";
4
+ /** An ATX heading; four spaces of indent make it a code line instead. */
5
+ const HEADING = /^ {0,3}#{1,6}(?:\s|$)/u;
6
+
7
+ /** The lines after a leading front matter block. */
8
+ const bodyLines = (lines: readonly string[]): readonly string[] => {
9
+ const close = lines[0] === FRONT_MATTER_FENCE ? lines.indexOf(FRONT_MATTER_FENCE, 1) : -1;
10
+ return close === -1 ? lines : lines.slice(close + 1);
11
+ };
12
+
13
+ /** The line a document's body opens with (a letter's salutation), past front matter, blank lines and Markdown headings. */
14
+ export const openingLine = (source: string): string | undefined =>
15
+ bodyLines(plainSource(source).split("\n"))
16
+ .find((line) => line.trim() !== "" && !HEADING.test(line))
17
+ ?.trim();
@@ -2,6 +2,14 @@
2
2
 
3
3
  export const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
4
4
 
5
+ /**
6
+ * 字に挟まれた ’ と、どこにあっても ʼ を ' にする(don’t → don't)。語彙表は ' で書くので、’ で書いた本文も同じ語に当てるため。
7
+ * 英語アダプタの解析器が同じ決めかたをする(chaff とアダプタは実行時の値を共有しないので、ここにも置く)。一字を一字に置き換えるので位置は変わらない。
8
+ */
9
+ const APOSTROPHE = /(?<=[\p{L}\p{N}])’(?=\p{L})|ʼ/gu;
10
+
11
+ export const straightApostrophes = (text: string): string => text.replace(APOSTROPHE, "'");
12
+
5
13
  /** text の中で word が現れる [始まり, 終わり) を、左から順に。大文字小文字を区別しないときは i で探す(位置は元の文字列のまま)。 */
6
14
  const spansOf = (text: string, word: string, ignoreCase: boolean): [number, number][] => {
7
15
  const pattern = new RegExp(escapeRegExp(word), ignoreCase ? "giu" : "gu");
@@ -55,7 +63,7 @@ const kindOf = (char: string | undefined, digitSide: "before-digit" | "after-dig
55
63
  return DIGIT.test(char) ? digitSide : undefined;
56
64
  };
57
65
 
58
- const isJapanese = (char: string | undefined): boolean => char !== undefined && JAPANESE.test(char);
66
+ export const isJapanese = (char: string | undefined): boolean => char !== undefined && JAPANESE.test(char);
59
67
 
60
68
  /** japanese が日本語の字のとき、other の英字・数字の種類。 */
61
69
  const latinBeside = (japanese: string | undefined, other: string | undefined, digitSide: "before-digit" | "after-digit"): SpacingKind | undefined =>
@@ -132,7 +140,9 @@ const isOrdinalRun = (chars: readonly string[], index: number): boolean => {
132
140
  const MIN_CODE_GROUPS = 3;
133
141
 
134
142
  // 通達の「5-1-1」は全角の「-」でつなぐ。ハイフン「‐」やマイナス「−」も同じに読む。長音「ー」は仮名の一部なので入れない。
135
- const HYPHEN = /[-‐‑−-]/u;
143
+ /** 正規表現の文字クラスに入れるハイフンの字。- は範囲の記号にならないよう \ を付ける。 */
144
+ export const HYPHEN_CHARS = "\\-‐‑−-";
145
+ const HYPHEN = new RegExp(`[${HYPHEN_CHARS}]`, "u");
136
146
 
137
147
  /** 数字をつなぐハイフンか。半角の - のほか、全角・和文のハイフンも。 */
138
148
  export const isHyphen = (char: string | undefined): boolean => char !== undefined && HYPHEN.test(char);
@@ -158,8 +168,7 @@ const isUncountedNumber = (chars: readonly string[], index: number): boolean =>
158
168
  return left === ORDINAL_PREFIX || (isJapanese(left) && isCode(chars, next));
159
169
  };
160
170
 
161
- const boundaryAt = (chars: readonly string[], index: number): Omit<Boundary, "offset"> | undefined => {
162
- if (isUncountedNumber(chars, index)) return undefined;
171
+ const candidateAt = (chars: readonly string[], index: number): Omit<Boundary, "offset"> | undefined => {
163
172
  const [left, right, after] = [chars[index], chars[index + 1], chars[index + 2]];
164
173
  const touching = latinBeside(left, right, "before-digit") ?? leftRunBeside(chars, index, right);
165
174
  if (touching !== undefined) return { kind: touching, spaced: false };
@@ -168,6 +177,12 @@ const boundaryAt = (chars: readonly string[], index: number): Omit<Boundary, "of
168
177
  return spaced === undefined ? undefined : { kind: spaced, spaced: true };
169
178
  };
170
179
 
180
+ // isUncountedNumber は数字の並びを端まで読む。境目の候補でだけ聞けば、並びの字ごとではなく並びごとに一度で済む。
181
+ const boundaryAt = (chars: readonly string[], index: number): Omit<Boundary, "offset"> | undefined => {
182
+ const candidate = candidateAt(chars, index);
183
+ return candidate === undefined || isUncountedNumber(chars, index) ? undefined : candidate;
184
+ };
185
+
171
186
  /**
172
187
  * 文の中の境目を全部。offset は境目の位置(左の字の直後、UTF-16)。配列を作り直さずに一度なめる。
173
188
  * text は本文でないものを空白で覆った文、written は覆う前の同じ範囲。覆ってできた空白(リンクの「[」など)は
@@ -189,7 +204,7 @@ export const latinBoundaries = (text: string, written: string = text): Boundary[
189
204
  * 混ざっているとき、そろえるべき少数派。種類(英字・数字の前・数字の後ろ)ごとに数える。
190
205
  * 同数なら、文書が先に使った書き方をその文書の書き方とみなし、後から出た書き方を少数派にする。
191
206
  */
192
- export const minorityStyle = (boundaries: readonly Boundary[]): boolean | undefined => {
207
+ export const minorityStyle = (boundaries: readonly { readonly spaced: boolean }[]): boolean | undefined => {
193
208
  const spaced = boundaries.filter((boundary) => boundary.spaced).length;
194
209
  const touching = boundaries.length - spaced;
195
210
  if (spaced === 0 || touching === 0) return undefined;
@@ -1,5 +1,7 @@
1
1
  import type { Span } from "./plugin.ts";
2
2
  import { NO_OUTLINE, type Outline } from "./structure/build.ts";
3
+ import { markdownFigures, textFigures } from "./text-figures.ts";
4
+ import type { MarkdownNode } from "./markdown-node.ts";
3
5
 
4
6
  /** 改ページから、飾りの行を探しにいく行数。飾りと改ページのあいだには空行が数行入る。 */
5
7
  const REACH = 3;
@@ -41,5 +43,12 @@ export const pageFurniture = (source: string): Span[] => {
41
43
  });
42
44
  };
43
45
 
44
- /** テキストの文書の外形。見出しもコードも無く、ページの飾りだけを覆う。木を作る入口はどれもこれを使う。 */
45
- export const textOutline = (source: string): Outline => ({ ...NO_OUTLINE, opaque: pageFurniture(source) });
46
+ /** テキストの文書の外形。見出しもコードも無く、ページの飾り・線で描いた図・メールの引用した返信だけを覆う。木を作る入口はどれもこれを使う。 */
47
+ export const textOutline = (source: string, replyQuotes: readonly Span[] = []): Outline => ({
48
+ ...NO_OUTLINE,
49
+ opaque: [...pageFurniture(source), ...textFigures(source), ...replyQuotes],
50
+ });
51
+
52
+ /** 紙面の形で本文でないもの: テキストの文書のページの飾り(Markdown には改ページが無い)と、線で描いた図。 */
53
+ export const layoutMasks = (root: MarkdownNode, source: string, markdown: boolean): Span[] =>
54
+ markdown ? markdownFigures(root, source) : [...pageFurniture(source), ...textFigures(source)];
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 段落が長すぎるか。文の数が上限を超え、しかも長さが「上限の数だけ普通の長さの文を並べた長さ」を超えるときだけ。
3
+ * 短い文をいくつ並べても、読み手が息をつけない壁にはならない。長さは adapter の単位(日本語は文字、英語は語)。
4
+ * fullSentence が無ければ、文の数だけで決める。
5
+ */
6
+ export const isTooLongParagraph = (sentenceSizes: readonly number[], limit: number, fullSentence: number | undefined): boolean => {
7
+ const size = sentenceSizes.reduce((sum, sentence) => sum + sentence, 0);
8
+ return sentenceSizes.length > limit && (fullSentence === undefined || size > limit * fullSentence);
9
+ };
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * The Markdown parser drops a leading BOM and reads a lone "\r" as a line break; the rest of chaff counts "\n" only.
3
3
  * Reading the file this way keeps every offset, line and column on the text the writer sees.
4
+ * Every leading BOM goes, so that running this twice (on reading, then in buildDocument) gives the same text as once.
4
5
  */
5
- export const plainSource = (raw: string): string => raw.replace(/^\uFEFF/u, "").replace(/\r\n?/gu, "\n");
6
+ export const plainSource = (raw: string): string => raw.replace(/^\uFEFF+/u, "").replace(/\r\n?/gu, "\n");
package/src/plugin.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  // 言語アダプタと genre pack が依存してよい唯一の面。spec §6。
2
2
  // ここに実装を置かない。型だけを置く。
3
3
 
4
+ import type { RuleGuide } from "./rule-guide.ts";
5
+
4
6
  export type Span = { readonly start: number; readonly end: number };
5
7
 
6
8
  /**
@@ -17,8 +19,15 @@ export type Sentence = {
17
19
  * tokens は全角どうしに挟まれた段落内の改行を除いた文字列から作るので、改行をまたぐ語の span は改行ごと覆い、surface より長い。
18
20
  */
19
21
  readonly wrapBreaks?: readonly Span[];
22
+ /**
23
+ * 文書と違う言語で書いた文(和文の中の英文、英文の中の和文)。adapter が入れる。無ければ文書の言語の文。
24
+ * 長さの rule はこの単位で数え、この言語の上限と比べる。
25
+ */
26
+ readonly embeddedLanguage?: EmbeddedLanguage;
20
27
  };
21
28
 
29
+ export type EmbeddedLanguage = { readonly id: string; readonly lengthUnit: LengthUnit };
30
+
22
31
  /**
23
32
  * 品詞は Universal Dependencies の UPOS に統一する。アダプタ独自の体系を露出させない。
24
33
  * features は UD の FEATS。「受動か」のように品詞だけでは足りず、かつ言語ごとに
@@ -72,7 +81,11 @@ export type AdapterCapabilities = {
72
81
  };
73
82
 
74
83
  /** prepare に渡す要求。動く rule が要らないものの代金を払わせない。 */
75
- export type AdapterNeeds = { readonly pos: boolean };
84
+ export type AdapterNeeds = {
85
+ readonly pos: boolean;
86
+ /** Token features that cost the adapter extra work (LongVowelEnding asks the dictionary about each katakana word). Only the running rules' are asked for. */
87
+ readonly features?: readonly string[];
88
+ };
76
89
 
77
90
  export type LanguageAdapter = {
78
91
  readonly kind: "language";
@@ -204,6 +217,10 @@ export type Section = {
204
217
  /** 見出しの深さ。見出しより前の導入部は 0。 */
205
218
  readonly depth: number;
206
219
  readonly heading: string;
220
+ /** 見出しを文と同じ解析器で語に分けたもの。文が tokens を持つときだけ入る。 */
221
+ readonly headingTokens?: readonly Token[];
222
+ /** 見出しの頭の番号の札(「例 3:」「1.」「第2章」「Step 3:」)を除いた題。札が無ければ見出しのまま。 */
223
+ readonly unlabeledHeading?: string;
207
224
  readonly span: Span;
208
225
  readonly sentences: readonly Sentence[];
209
226
  /** この節に含まれる強調(Markdown の ** **)の数。 */
@@ -322,6 +339,34 @@ export type ProseDocument = {
322
339
  readonly profile?: DocumentProfile | undefined;
323
340
  /** 本文でないもの(コード・HTML・強調の印)を同じ長さの空白で覆った source。位置は source と同じ。 */
324
341
  readonly prose?: string | undefined;
342
+ /** メールの引用した返信(前置きの行と「> 」の行)。ほかの人の言葉なので、見出しにも木にも入れない。 */
343
+ readonly replyQuotes?: readonly Span[] | undefined;
344
+ /** 記法の手がかり(見出し・画像・リンク)。記法を読む rule だけが触れ、触れたときに作る。 */
345
+ readonly markup?: Markup | undefined;
346
+ };
347
+
348
+ /** 見出し 1 つ。text は属性(`{#id}`)を外した言葉。 */
349
+ export type MarkupHeading = { readonly depth: number; readonly text: string; readonly start: number; readonly end: number };
350
+
351
+ /** 画像 1 つ。alt は代替テキスト。HTML の `<img>` で alt 属性が無ければ undefined。 */
352
+ export type MarkupImage = { readonly alt: string | undefined; readonly start: number; readonly end: number };
353
+
354
+ /** リンクの行き先 1 つ(`[text](url)` と、参照の定義 `[label]: url`)。 */
355
+ export type MarkupLink = { readonly destination: string; readonly start: number; readonly end: number };
356
+
357
+ /**
358
+ * 文書の記法。Markdown でない文書(.txt)は markdown が false で、見出し・画像・リンクを持たず、texts が文書全体。
359
+ * 位置はすべて doc.source の上。
360
+ */
361
+ export type Markup = {
362
+ readonly markdown: boolean;
363
+ readonly headings: readonly MarkupHeading[];
364
+ readonly images: readonly MarkupImage[];
365
+ readonly links: readonly MarkupLink[];
366
+ /** 書き手が付けたページ内の名前(見出しの `{#id}`、HTML の id と name)。 */
367
+ readonly ids: ReadonlySet<string>;
368
+ /** 読み手に字のまま見える範囲(リンクの外のテキスト)。 */
369
+ readonly texts: readonly Span[];
325
370
  };
326
371
 
327
372
  export type Severity = "error" | "warning" | "info";
@@ -346,6 +391,31 @@ export type DetectorOptions = {
346
391
  readonly lexicon?: Lexicon | undefined;
347
392
  /** 見る範囲。opening は冒頭 2 段落、closing は最後の節、whole は全体。 */
348
393
  readonly where?: string | undefined;
394
+ /** 普通の長さの文 1 つの長さ(adapter の単位)。段落の長さを文の数と一緒に見る rule だけが持つ。 */
395
+ readonly fullSentence?: number | undefined;
396
+ /** 文書と違う言語で書いた文の上限。その言語の段から解決済み。rule がその言語の段を持たなければ無い。 */
397
+ readonly embeddedLimits?: Readonly<Record<string, number>> | undefined;
398
+ /** The rule's options (RuleDefinition.options), each at the value the settings chose or its default. Only a rule with options has them. */
399
+ readonly settings?: Readonly<Record<string, OptionValue>> | undefined;
400
+ /** A custom rule's spec (RuleDefinition.custom). */
401
+ readonly custom?: CustomSpec | undefined;
402
+ };
403
+
404
+ /** The value of one rule option: a choice, a count, or a list of words. */
405
+ export type OptionValue = string | number | readonly string[];
406
+
407
+ /**
408
+ * One option a rule takes, beyond its level. The rule's YAML declares it; a team sets it under options in chaff.yaml.
409
+ * choice takes one of choices, count a whole number of 1 or more, words a list of words.
410
+ */
411
+ export type RuleOption = {
412
+ readonly kind: "choice" | "count" | "words";
413
+ readonly choices: readonly string[];
414
+ readonly default: OptionValue;
415
+ /** What the option decides, in plain words. */
416
+ readonly about: Localized;
417
+ /** What each choice means, in plain words. Only a choice has them. */
418
+ readonly choiceNames: Readonly<Record<string, Localized>>;
349
419
  };
350
420
 
351
421
  export type Detector = (doc: ProseDocument, options: DetectorOptions) => Finding[];
@@ -356,6 +426,10 @@ export type Level = "strict" | "normal" | "relaxed" | "off";
356
426
 
357
427
  export type LevelTable = Readonly<Partial<Record<Exclude<Level, "off">, number>>>;
358
428
 
429
+ export type LevelSets = "limit" | "severity";
430
+
431
+ export type LanguageLevels = { readonly levels: LevelTable; readonly by_genre: Readonly<Record<string, LevelTable>> };
432
+
359
433
  export type RuleDefinition = {
360
434
  readonly id: string;
361
435
  readonly layer: "L1" | "L2" | "L3" | "L4";
@@ -366,11 +440,17 @@ export type RuleDefinition = {
366
440
  readonly message: Localized;
367
441
  /** 見つけ方ごとの message(Finding の variant で引く)。ほとんどの rule は持たない。 */
368
442
  readonly messages: Readonly<Record<string, Localized>>;
443
+ /** How a placeholder in name, why or how_to_fix reads where no finding fills it (explain, the rule reference). */
444
+ readonly placeholders?: Readonly<Record<string, Localized>>;
369
445
  /** 4 語と数値の対応。2 つ以上。未定義の段は normal に落ちる。spec §18.1。
370
446
  * 言語別の閾値を持つ rule(max-sentence-length)は、読み込み時に言語で平坦化済み。 */
371
447
  readonly levels: LevelTable;
448
+ /** What a level changes: the limit a detector counts to, or, for a rule with nothing to count, the severity of its findings. */
449
+ readonly level_sets: LevelSets;
372
450
  /** ジャンル別の上書き。"business" は business/* 全部に効き、"business/email" が勝つ。spec §9。 */
373
451
  readonly by_genre: Readonly<Record<string, LevelTable>>;
452
+ /** 読み込んだ言語以外の levels と by_genre。文書と違う言語で書いた文(和文の中の英文)の上限に使う。 */
453
+ readonly other_languages?: Readonly<Record<string, LanguageLevels>>;
374
454
  readonly how_to_find: string;
375
455
  readonly word_list: string | undefined;
376
456
  /** word_list のほかに detector が名前で引く語彙表。どれかが無い言語では rule を動かさない。 */
@@ -378,14 +458,40 @@ export type RuleDefinition = {
378
458
  /** L4 のみ。LLM に渡す決まり。言語別。 */
379
459
  readonly what_to_check: Localized | undefined;
380
460
  readonly where: string | undefined;
461
+ /** 普通の長さの文 1 つの長さ。言語で単位が違うので、levels と同じく読み込み時に言語で平坦化済み。 */
462
+ readonly full_sentence: number | undefined;
381
463
  /** adapter に要る capability。"pos" / "lemma"。満たさなければ動かさない。spec §16。 */
382
464
  readonly requires: readonly string[];
383
465
  /** 使えるなら用意してほしい capability("pos")。requires と違い、満たせなくても動かす(品詞が無ければ文字だけで見る)。 */
384
466
  readonly uses: readonly string[];
467
+ /** Token features the rule reads that the adapter computes only when asked (AdapterNeeds.features). */
468
+ readonly token_features?: readonly string[];
385
469
  /** 複合シグナル。ここに並べた rule のうち何本が出たかを見る。spec §20.2。 */
386
470
  readonly from: readonly string[];
387
471
  /** 動かす言語。未指定は全言語。「ですます調」のように言語に固有の rule が使う。 */
388
472
  readonly languages: readonly string[] | undefined;
389
473
  readonly use_for: readonly string[];
390
474
  readonly severity: Severity;
475
+ /** Options beyond the level (the direction and length for katakana-long-vowel). Most rules have none. */
476
+ readonly options?: Readonly<Record<string, RuleOption>>;
477
+ /** A rule a team defined under custom_rules in chaff.yaml: what it looks for. Built-in rules have none. */
478
+ readonly custom?: CustomSpec;
479
+ /** What the rule reference tells a reader who is not an engineer: its group, one line, a before and after. */
480
+ readonly guide?: RuleGuide;
481
+ };
482
+
483
+ /** One token's condition in a custom rule's run of tokens. Each part written must hold; pos lists the tags that match. */
484
+ export type TokenCondition = {
485
+ readonly pos?: readonly string[] | undefined;
486
+ readonly base?: string | undefined;
487
+ readonly surface?: string | undefined;
391
488
  };
489
+
490
+ /**
491
+ * What a team's rule looks for. words: spellings to avoid, each with the one to use (or none, to only point at it).
492
+ * pattern: a regular expression, checked before it runs. tokens: a run of tokens from the language adapter.
493
+ */
494
+ export type CustomSpec =
495
+ | { readonly type: "words"; readonly words: readonly { readonly avoid: string; readonly use: string }[] }
496
+ | { readonly type: "pattern"; readonly pattern: string; readonly flags: string }
497
+ | { readonly type: "tokens"; readonly tokens: readonly TokenCondition[] };
@@ -4,6 +4,7 @@ import type { DocumentProfile } from "../plugin.ts";
4
4
  import { presetProfile } from "../genre-load.ts";
5
5
  import { loadProfiles } from "./load.ts";
6
6
  import { chooseProfile } from "./select.ts";
7
+ import { plainSource } from "../plain-source.ts";
7
8
 
8
9
  type ProfileSettings = Pick<Config, "profile" | "byPath" | "baseDir">;
9
10
 
@@ -13,6 +14,7 @@ export const profileFor = (config: ProfileSettings, path: string, source: string
13
14
  byPath: applyByPath(config.byPath, config.baseDir, path).profile,
14
15
  config: config.profile,
15
16
  genre: genre === undefined ? undefined : presetProfile(genre),
16
- source,
17
+ // 行頭で数える検出は、CR だけの改行では 1 行に見える。
18
+ source: plainSource(source),
17
19
  language,
18
20
  })?.profile;
@@ -4,7 +4,7 @@ import type { Sentence, Span } from "./plugin.ts";
4
4
  type Marks = Readonly<Record<string, string>>;
5
5
 
6
6
  /** 鉤括弧。日本語の引用と題名。 */
7
- export const KAGI_MARKS: Marks = { "「": "」", "『": "』" };
7
+ const KAGI_MARKS: Marks = { "「": "」", "『": "』" };
8
8
 
9
9
  /**
10
10
  * 引用符も含めた、人の言葉を引く印。英語の "…" は開きと閉じが同じ字なので、開いている間に来たら閉じと読む。
@@ -13,15 +13,21 @@ export const KAGI_MARKS: Marks = { "「": "」", "『": "』" };
13
13
  export const QUOTATION_MARKS: Marks = { ...KAGI_MARKS, "“": "”", '"': '"' };
14
14
 
15
15
  type Open = { readonly closer: string; readonly at: number };
16
- type Scan = { readonly open: readonly Open[]; readonly spans: readonly Span[] };
16
+ /** 1 回の読みの中だけで足し引きする。字ごとに配列を作り直すと、括弧が何万もある文で二乗に遅くなる。 */
17
+ type Scan = { readonly open: Open[]; readonly spans: Span[] };
17
18
 
18
19
  const step =
19
20
  (marks: Marks) =>
20
21
  (scan: Scan, char: string, at: number): Scan => {
21
22
  const last = scan.open.at(-1);
22
- if (last !== undefined && last.closer === char) return { open: scan.open.slice(0, -1), spans: [...scan.spans, { start: last.at + 1, end: at }] };
23
+ if (last !== undefined && last.closer === char) {
24
+ scan.open.pop();
25
+ scan.spans.push({ start: last.at + 1, end: at });
26
+ return scan;
27
+ }
23
28
  const closer = marks[char];
24
- return closer === undefined ? scan : { open: [...scan.open, { closer, at }], spans: scan.spans };
29
+ if (closer !== undefined) scan.open.push({ closer, at });
30
+ return scan;
25
31
  };
26
32
 
27
33
  /**
package/src/reasons.ts CHANGED
@@ -14,6 +14,9 @@ export type Reasons = {
14
14
  readonly unreadStructure: (clauses: number, units: number) => string;
15
15
  readonly noDetector: (name: string) => string;
16
16
  readonly noLexicon: (language: string, list: string) => string;
17
+ readonly noHeadings: string;
18
+ readonly patternTimeout: (budgetMs: number) => string;
19
+ readonly notMarkdown: string;
17
20
  };
18
21
 
19
22
  const CAPABILITY_NAME: Texts<Readonly<Record<string, string>>> = {
@@ -35,6 +38,9 @@ export const REASONS: Texts<Reasons> = {
35
38
  `条項の番号が本文に ${String(clauses)} 個あるのに、番号として読めたのは ${String(units)} 個のため(深い字下げや、行が本文につながった文書)`,
36
39
  noDetector: (name) => `検出器 ${name} がないため`,
37
40
  noLexicon: (language, list) => `${language} の語彙表 ${list} が無いため`,
41
+ noHeadings: "表題より下の見出しが無いため",
42
+ patternTimeout: (budgetMs) => `正規表現が ${String(budgetMs)} ms で終わらなかったため(chaff.yaml の pattern を単純にしてください)`,
43
+ notMarkdown: "Markdown の文書ではないため",
38
44
  },
39
45
  en: {
40
46
  otherLanguage: (language) => `not a rule for ${language}`,
@@ -49,5 +55,8 @@ export const REASONS: Texts<Reasons> = {
49
55
  `the text has ${String(clauses)} clause numbers but only ${String(units)} ${formFor(units, "was read as a numbered line", "were read as numbered lines")} (deep indents, or lines run into the text)`,
50
56
  noDetector: (name) => `no detector named ${name}`,
51
57
  noLexicon: (language, list) => `the ${language} package has no word list ${list}`,
58
+ noHeadings: "the document has no headings below its title",
59
+ patternTimeout: (budgetMs) => `the pattern did not finish within ${String(budgetMs)} ms (simplify the pattern in chaff.yaml)`,
60
+ notMarkdown: "the document is not Markdown",
52
61
  },
53
62
  };
@@ -0,0 +1,91 @@
1
+ import type { Span } from "./plugin.ts";
2
+
3
+ /**
4
+ * 文献一覧の範囲。見出しの語(参考文献、References)で見つけ、構造で範囲を決める。
5
+ * Markdown の見出しなら、次の同じ深さか浅い見出しまで。見出しの語だけの段落(HTML から写した文書)なら、すぐ後に続く箇条書きだけ。
6
+ * 箇条書きが続かなければ文献一覧とは言えないので、何も返さない。
7
+ */
8
+ type Line = { readonly text: string; readonly start: number; readonly end: number };
9
+
10
+ const ATX_HEADING = /^ {0,3}(#{1,6})(?:[ \t](.*))?$/u;
11
+ // 文献の番号(- [1]、1.、[1])で始まる行。
12
+ const LIST_ITEM = /^ {0,3}(?:[-*+]|\d{1,4}[.)]|\[\d{1,4}\])[ \t]/u;
13
+ const CONTINUATION = /^[ \t]+\S/u;
14
+ // 見出しの前の節番号(7.、7.1、VII.)、周りの強調、後ろの閉じの # とコロン。
15
+ const SECTION_NUMBER = /^(?:\d+(?:\.\d+)*\.?|[IVXLC]+\.)\s+/u;
16
+ const EMPHASIS_MARKS = ["**", "__"] as const;
17
+ const CLOSING = new Set([" ", "\t", "#", ":", ":"]);
18
+
19
+ const withoutClosing = (text: string): string => {
20
+ const characters = [...text];
21
+ return characters.slice(0, characters.findLastIndex((character) => !CLOSING.has(character)) + 1).join("");
22
+ };
23
+
24
+ const linesOf = (source: string): Line[] =>
25
+ source.split("\n").reduce<Line[]>((lines, text) => {
26
+ const start = (lines.at(-1)?.end ?? -1) + 1;
27
+ lines.push({ text, start, end: start + text.length });
28
+ return lines;
29
+ }, []);
30
+
31
+ const withoutEmphasis = (text: string): string => {
32
+ const mark = EMPHASIS_MARKS.find((candidate) => text.length > candidate.length * 2 && text.startsWith(candidate) && text.endsWith(candidate));
33
+ return mark === undefined ? text : text.slice(mark.length, -mark.length);
34
+ };
35
+
36
+ const isBlank = (line: Line | undefined): boolean => line === undefined || line.text.trim() === "";
37
+
38
+ const headingWord = (text: string): string => {
39
+ const plain = withoutEmphasis(withoutClosing(text).trim());
40
+ return withoutClosing(plain.replace(SECTION_NUMBER, "")).trim().toLowerCase();
41
+ };
42
+
43
+ const levelOf = (line: Line): number | undefined => ATX_HEADING.exec(line.text)?.[1]?.length;
44
+
45
+ /** from 以降で最初に test を満たす行。無ければ lines.length。先頭から数え直すと、見出しの多い文書で行数の 2 乗になる。 */
46
+ const firstFrom = (lines: readonly Line[], from: number, test: (line: Line) => boolean): number => {
47
+ for (let index = from; index < lines.length; index += 1) {
48
+ const line = lines[index];
49
+ if (line !== undefined && test(line)) return index;
50
+ }
51
+ return lines.length;
52
+ };
53
+
54
+ /** Markdown の見出しの節の終わり: 次の同じ深さか浅い見出しの手前。無ければ文書の終わり。 */
55
+ const sectionEnd = (lines: readonly Line[], at: number, level: number): number =>
56
+ firstFrom(lines, at + 1, (line) => (levelOf(line) ?? Number.POSITIVE_INFINITY) <= level);
57
+
58
+ const isOutsideList = (line: Line): boolean => !isBlank(line) && !LIST_ITEM.test(line.text) && !CONTINUATION.test(line.text);
59
+
60
+ /** from の後の最初の中身の行から続く箇条書きの終わり(最後の中身の行の次)。最初の中身が項目でなければ from。 */
61
+ const listEnd = (lines: readonly Line[], from: number): number => {
62
+ const first = firstFrom(lines, from, (line) => !isBlank(line));
63
+ if (!LIST_ITEM.test(lines[first]?.text ?? "")) return from;
64
+ const stop = firstFrom(lines, first + 1, isOutsideList);
65
+ return first + lines.slice(first, stop).findLastIndex((line) => !isBlank(line)) + 1;
66
+ };
67
+
68
+ const standsAlone = (lines: readonly Line[], at: number): boolean => (at === 0 || isBlank(lines[at - 1])) && isBlank(lines[at + 1]);
69
+
70
+ /** 見出しの行 at から、文献一覧の終わりの行(含まない)。文献一覧の見出しでなければ undefined。 */
71
+ const blockEnd = (lines: readonly Line[], at: number, headings: ReadonlySet<string>): number | undefined => {
72
+ const line = lines[at];
73
+ if (line === undefined) return undefined;
74
+ const level = levelOf(line);
75
+ if (level !== undefined) return headings.has(headingWord(ATX_HEADING.exec(line.text)?.[2] ?? "")) ? sectionEnd(lines, at, level) : undefined;
76
+ if (!headings.has(headingWord(line.text)) || !standsAlone(lines, at)) return undefined;
77
+ const end = listEnd(lines, at + 1);
78
+ return end === at + 1 ? undefined : end;
79
+ };
80
+
81
+ export const referenceListSpans = (source: string, headingWords: readonly string[]): Span[] => {
82
+ const headings = new Set(headingWords.map((word) => word.toLowerCase()));
83
+ const lines = linesOf(source);
84
+ const spans: Span[] = [];
85
+ lines.forEach((line, at) => {
86
+ if ((spans.at(-1)?.end ?? -1) >= line.start) return;
87
+ const end = blockEnd(lines, at, headings);
88
+ if (end !== undefined) spans.push({ start: line.start, end: lines[end - 1]?.end ?? line.end });
89
+ });
90
+ return spans;
91
+ };
@@ -1,7 +1,10 @@
1
- import { definedLevels, resolve } from "../levels.ts";
2
- import { localized } from "./text.ts";
3
- import { uiLanguageOf, type Texts } from "../ui.ts";
1
+ import { definedLevels, resolve, severityAt } from "../levels.ts";
2
+ import { readableText } from "./text.ts";
3
+ import { SEVERITY_NAME } from "./severity-name.ts";
4
+ import { uiLanguageOf, type Texts, type UiLanguage } from "../ui.ts";
4
5
  import type { Level, RuleDefinition } from "../plugin.ts";
6
+ import { optionLines } from "./options.ts";
7
+ import type { OptionLayer } from "../rule-options.ts";
5
8
 
6
9
  const TEXT: Texts<{
7
10
  readonly off: string;
@@ -9,8 +12,12 @@ const TEXT: Texts<{
9
12
  readonly genreNote: (genre: string, others: string) => string;
10
13
  readonly experimental: string;
11
14
  readonly howToFix: string;
15
+ readonly example: string;
16
+ readonly definedIn: string;
12
17
  readonly values: (unit: string) => string;
18
+ readonly severities: string;
13
19
  readonly now: (level: string) => string;
20
+ readonly from: (source: string) => string;
14
21
  readonly change: (id: string) => string;
15
22
  }> = {
16
23
  ja: {
@@ -19,8 +26,12 @@ const TEXT: Texts<{
19
26
  genreNote: (genre, others) => `この数字は ${genre} のものです。ほかに ${others} で別の数字を持っています。`,
20
27
  experimental: "このルールはまだ試験中で、既定では動きません(--experimental で動きます)。",
21
28
  howToFix: "直しかた",
29
+ example: "例",
30
+ definedIn: "このルールはチームが chaff.yaml の custom_rules で決めたものです。",
22
31
  values: (unit) => `設定できる値(単位: ${unit}):`,
32
+ severities: "設定できる値(数える上限は無く、指摘の重さが変わります):",
23
33
  now: (level) => `いまは ${level} です。`,
34
+ from: (source) => `(${source} で決めています)`,
24
35
  change: (id) => `変える: npx chaff relax ${id} --why "理由"`,
25
36
  },
26
37
  en: {
@@ -29,16 +40,24 @@ const TEXT: Texts<{
29
40
  genreNote: (genre, others) => `These numbers are for ${genre}. ${others} have numbers of their own.`,
30
41
  experimental: "This rule is still experimental and does not run by default (--experimental runs it).",
31
42
  howToFix: "How to fix",
43
+ example: "Example",
44
+ definedIn: "The team defined this rule under custom_rules in chaff.yaml.",
32
45
  values: (unit) => `Levels (unit: ${unit}):`,
46
+ severities: "Levels (there is no limit to count to; a level sets how a finding is marked):",
33
47
  now: (level) => `Now: ${level}.`,
48
+ from: (source) => ` (set by ${source})`,
34
49
  change: (id) => `Change it: npx chaff relax ${id} --why "reason"`,
35
50
  },
36
51
  };
37
52
 
38
- const levelLine = (rule: RuleDefinition, level: Level, current: Level, genre: string | undefined, off: string): string => {
53
+ /** What a level holds: the limit a detector counts to, or the severity a rule with nothing to count gives. */
54
+ const valueAt = (rule: RuleDefinition, level: Exclude<Level, "off">, genre: string | undefined, ui: UiLanguage): string =>
55
+ rule.level_sets === "severity" ? SEVERITY_NAME[ui][severityAt(rule, level, genre)] : String(resolve(rule, level, genre).limit);
56
+
57
+ const levelLine = (rule: RuleDefinition, level: Level, current: Level, genre: string | undefined, ui: UiLanguage): string => {
39
58
  const mark = level === current ? "→" : " ";
40
59
  const name = level.padEnd(9);
41
- return level === "off" ? ` ${mark} ${name}${off}` : ` ${mark} ${name}${resolve(rule, level, genre).limit}`;
60
+ return level === "off" ? ` ${mark} ${name}${TEXT[ui].off}` : ` ${mark} ${name}${valueAt(rule, level, genre, ui)}`;
42
61
  };
43
62
 
44
63
  /** ジャンルで数字が変わる rule は、それを言わないと「設定したのに効かない」に見える。 */
@@ -48,23 +67,38 @@ const genreNote = (rule: RuleDefinition, genre: string | undefined, text: (typeo
48
67
  return ["", ` ${text.genreNote(genre ?? text.defaultGenre, others.join(" / "))}`];
49
68
  };
50
69
 
70
+ /** A team's rule shows its example, before and after, and says where it was defined. */
71
+ const exampleLines = (rule: RuleDefinition, language: string, text: (typeof TEXT)["ja"]): string[] => {
72
+ const examples = rule.guide?.examples ?? {};
73
+ const example = examples[language] ?? examples["en"] ?? Object.values(examples)[0];
74
+ if (rule.custom === undefined || example === undefined) return [];
75
+ return ["", ` ${text.example}: ${example.before}`, ` → ${example.after}`, "", ` ${text.definedIn}`];
76
+ };
77
+
78
+ /** Where the rule's settings come from: the option layers, strongest first, and the source of its level when a style set it. */
79
+ export type ExplainSettings = { readonly optionLayers?: readonly OptionLayer[]; readonly levelFrom?: string | undefined };
80
+
51
81
  /** rule の意図と根拠を読む。指摘に納得できないときの入口。 */
52
- export const renderExplain = (rule: RuleDefinition, current: Level, language: string, unit: string, genre?: string): string => {
53
- const text = TEXT[uiLanguageOf(language)];
82
+ export const renderExplain = (rule: RuleDefinition, current: Level, language: string, unit: string, genre?: string, settings: ExplainSettings = {}): string => {
83
+ const { optionLayers = [], levelFrom } = settings;
84
+ const ui = uiLanguageOf(language);
85
+ const text = TEXT[ui];
54
86
  const experimental = rule.status === "experimental" ? [` ${text.experimental}`] : [];
55
87
  return [
56
88
  "",
57
- ` ${localized(rule.name, language)} (${rule.id})`,
89
+ ` ${readableText(rule, rule.name, language)} (${rule.id})`,
58
90
  "",
59
- ` ${localized(rule.why, language)}`,
91
+ ` ${readableText(rule, rule.why, language)}`,
60
92
  "",
61
- ` ${text.howToFix}: ${localized(rule.how_to_fix, language)}`,
93
+ ` ${text.howToFix}: ${readableText(rule, rule.how_to_fix, language)}`,
94
+ ...exampleLines(rule, language, text),
62
95
  "",
63
- ` ${text.values(unit)}`,
64
- ...definedLevels(rule).map((level) => levelLine(rule, level, current, genre, text.off)),
96
+ ` ${rule.level_sets === "severity" ? text.severities : text.values(unit)}`,
97
+ ...definedLevels(rule).map((level) => levelLine(rule, level, current, genre, ui)),
65
98
  ...genreNote(rule, genre, text),
99
+ ...optionLines(rule, optionLayers, language),
66
100
  "",
67
- ` ${text.now(current)}`,
101
+ ` ${text.now(current)}${levelFrom === undefined ? "" : text.from(levelFrom)}`,
68
102
  ...experimental,
69
103
  "",
70
104
  ` ${text.change(rule.id)}`,