chaffjs 0.33.0 → 0.35.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 (802) hide show
  1. package/dist/api.d.ts +7 -1
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js.map +1 -1
  4. package/dist/capitals-passage.d.ts +3 -0
  5. package/dist/capitals-passage.d.ts.map +1 -0
  6. package/dist/capitals-passage.js +26 -0
  7. package/dist/capitals-passage.js.map +1 -0
  8. package/dist/cli-text.d.ts.map +1 -1
  9. package/dist/cli-text.js +4 -2
  10. package/dist/cli-text.js.map +1 -1
  11. package/dist/coined-hyphen-name.d.ts +13 -0
  12. package/dist/coined-hyphen-name.d.ts.map +1 -0
  13. package/dist/coined-hyphen-name.js +21 -0
  14. package/dist/coined-hyphen-name.js.map +1 -0
  15. package/dist/commands/grade.d.ts.map +1 -1
  16. package/dist/commands/grade.js +66 -21
  17. package/dist/commands/grade.js.map +1 -1
  18. package/dist/company-kana-spelling.d.ts +6 -1
  19. package/dist/company-kana-spelling.d.ts.map +1 -1
  20. package/dist/company-kana-spelling.js +19 -2
  21. package/dist/company-kana-spelling.js.map +1 -1
  22. package/dist/company-name-ending.d.ts +7 -0
  23. package/dist/company-name-ending.d.ts.map +1 -0
  24. package/dist/company-name-ending.js +44 -0
  25. package/dist/company-name-ending.js.map +1 -0
  26. package/dist/company-names.d.ts +17 -4
  27. package/dist/company-names.d.ts.map +1 -1
  28. package/dist/company-names.js +49 -17
  29. package/dist/company-names.js.map +1 -1
  30. package/dist/custom/no-rewrite.d.ts +3 -0
  31. package/dist/custom/no-rewrite.d.ts.map +1 -0
  32. package/dist/custom/no-rewrite.js +3 -0
  33. package/dist/custom/no-rewrite.js.map +1 -0
  34. package/dist/custom/parse.d.ts.map +1 -1
  35. package/dist/custom/parse.js +14 -2
  36. package/dist/custom/parse.js.map +1 -1
  37. package/dist/detectors/acronym-context.d.ts +1 -1
  38. package/dist/detectors/acronym-context.d.ts.map +1 -1
  39. package/dist/detectors/acronym-context.js +4 -4
  40. package/dist/detectors/acronym-context.js.map +1 -1
  41. package/dist/detectors/acronym-definition.d.ts +13 -0
  42. package/dist/detectors/acronym-definition.d.ts.map +1 -0
  43. package/dist/detectors/acronym-definition.js +90 -0
  44. package/dist/detectors/acronym-definition.js.map +1 -0
  45. package/dist/detectors/acronym-lone.d.ts +13 -0
  46. package/dist/detectors/acronym-lone.d.ts.map +1 -0
  47. package/dist/detectors/acronym-lone.js +22 -0
  48. package/dist/detectors/acronym-lone.js.map +1 -0
  49. package/dist/detectors/acronym-name.d.ts +55 -0
  50. package/dist/detectors/acronym-name.d.ts.map +1 -0
  51. package/dist/detectors/acronym-name.js +75 -0
  52. package/dist/detectors/acronym-name.js.map +1 -0
  53. package/dist/detectors/age-words.d.ts +5 -0
  54. package/dist/detectors/age-words.d.ts.map +1 -0
  55. package/dist/detectors/age-words.js +8 -0
  56. package/dist/detectors/age-words.js.map +1 -0
  57. package/dist/detectors/annual-pay-mismatch.d.ts.map +1 -1
  58. package/dist/detectors/annual-pay-mismatch.js +2 -12
  59. package/dist/detectors/annual-pay-mismatch.js.map +1 -1
  60. package/dist/detectors/blank-structure.d.ts.map +1 -1
  61. package/dist/detectors/blank-structure.js +4 -3
  62. package/dist/detectors/blank-structure.js.map +1 -1
  63. package/dist/detectors/capitalised-term.d.ts +14 -2
  64. package/dist/detectors/capitalised-term.d.ts.map +1 -1
  65. package/dist/detectors/capitalised-term.js +115 -4
  66. package/dist/detectors/capitalised-term.js.map +1 -1
  67. package/dist/detectors/caps-caption.d.ts +11 -0
  68. package/dist/detectors/caps-caption.d.ts.map +1 -0
  69. package/dist/detectors/caps-caption.js +51 -0
  70. package/dist/detectors/caps-caption.js.map +1 -0
  71. package/dist/detectors/char-shape.d.ts.map +1 -1
  72. package/dist/detectors/char-shape.js +47 -18
  73. package/dist/detectors/char-shape.js.map +1 -1
  74. package/dist/detectors/clause-shape.d.ts +1 -1
  75. package/dist/detectors/clause-shape.d.ts.map +1 -1
  76. package/dist/detectors/clause-shape.js +9 -4
  77. package/dist/detectors/clause-shape.js.map +1 -1
  78. package/dist/detectors/closing-balance-mismatch.d.ts.map +1 -1
  79. package/dist/detectors/closing-balance-mismatch.js +1 -0
  80. package/dist/detectors/closing-balance-mismatch.js.map +1 -1
  81. package/dist/detectors/code-fences.d.ts +5 -0
  82. package/dist/detectors/code-fences.d.ts.map +1 -1
  83. package/dist/detectors/code-fences.js +9 -0
  84. package/dist/detectors/code-fences.js.map +1 -1
  85. package/dist/detectors/concrete-evidence.d.ts +13 -1
  86. package/dist/detectors/concrete-evidence.d.ts.map +1 -1
  87. package/dist/detectors/concrete-evidence.js +59 -0
  88. package/dist/detectors/concrete-evidence.js.map +1 -1
  89. package/dist/detectors/condition-toki.d.ts +16 -0
  90. package/dist/detectors/condition-toki.d.ts.map +1 -0
  91. package/dist/detectors/condition-toki.js +42 -0
  92. package/dist/detectors/condition-toki.js.map +1 -0
  93. package/dist/detectors/conjugated-entry.d.ts +17 -0
  94. package/dist/detectors/conjugated-entry.d.ts.map +1 -0
  95. package/dist/detectors/conjugated-entry.js +50 -0
  96. package/dist/detectors/conjugated-entry.js.map +1 -0
  97. package/dist/detectors/content-morphemes.d.ts +2 -0
  98. package/dist/detectors/content-morphemes.d.ts.map +1 -1
  99. package/dist/detectors/content-morphemes.js +1 -1
  100. package/dist/detectors/content-morphemes.js.map +1 -1
  101. package/dist/detectors/contraction-minority.d.ts +11 -0
  102. package/dist/detectors/contraction-minority.d.ts.map +1 -0
  103. package/dist/detectors/contraction-minority.js +10 -0
  104. package/dist/detectors/contraction-minority.js.map +1 -0
  105. package/dist/detectors/counter-edge.d.ts +5 -0
  106. package/dist/detectors/counter-edge.d.ts.map +1 -1
  107. package/dist/detectors/counter-edge.js +23 -0
  108. package/dist/detectors/counter-edge.js.map +1 -1
  109. package/dist/detectors/cross-facts.d.ts.map +1 -1
  110. package/dist/detectors/cross-facts.js +2 -1
  111. package/dist/detectors/cross-facts.js.map +1 -1
  112. package/dist/detectors/custom.d.ts.map +1 -1
  113. package/dist/detectors/custom.js +8 -2
  114. package/dist/detectors/custom.js.map +1 -1
  115. package/dist/detectors/date-any-year.d.ts +6 -3
  116. package/dist/detectors/date-any-year.d.ts.map +1 -1
  117. package/dist/detectors/date-any-year.js +47 -10
  118. package/dist/detectors/date-any-year.js.map +1 -1
  119. package/dist/detectors/date-heading-year.d.ts +18 -0
  120. package/dist/detectors/date-heading-year.d.ts.map +1 -0
  121. package/dist/detectors/date-heading-year.js +38 -0
  122. package/dist/detectors/date-heading-year.js.map +1 -0
  123. package/dist/detectors/date-year.d.ts +12 -2
  124. package/dist/detectors/date-year.d.ts.map +1 -1
  125. package/dist/detectors/date-year.js +31 -6
  126. package/dist/detectors/date-year.js.map +1 -1
  127. package/dist/detectors/defined-term-form.d.ts.map +1 -1
  128. package/dist/detectors/defined-term-form.js +26 -5
  129. package/dist/detectors/defined-term-form.js.map +1 -1
  130. package/dist/detectors/document-shape.d.ts.map +1 -1
  131. package/dist/detectors/document-shape.js +6 -0
  132. package/dist/detectors/document-shape.js.map +1 -1
  133. package/dist/detectors/due-date.d.ts.map +1 -1
  134. package/dist/detectors/due-date.js +18 -2
  135. package/dist/detectors/due-date.js.map +1 -1
  136. package/dist/detectors/en-shape.d.ts.map +1 -1
  137. package/dist/detectors/en-shape.js +5 -1
  138. package/dist/detectors/en-shape.js.map +1 -1
  139. package/dist/detectors/fact-consistency.d.ts.map +1 -1
  140. package/dist/detectors/fact-consistency.js +15 -15
  141. package/dist/detectors/fact-consistency.js.map +1 -1
  142. package/dist/detectors/form-line.d.ts +9 -0
  143. package/dist/detectors/form-line.d.ts.map +1 -0
  144. package/dist/detectors/form-line.js +36 -0
  145. package/dist/detectors/form-line.js.map +1 -0
  146. package/dist/detectors/formula-amount.d.ts.map +1 -1
  147. package/dist/detectors/formula-amount.js +2 -12
  148. package/dist/detectors/formula-amount.js.map +1 -1
  149. package/dist/detectors/gram-passages.d.ts +11 -0
  150. package/dist/detectors/gram-passages.d.ts.map +1 -0
  151. package/dist/detectors/gram-passages.js +26 -0
  152. package/dist/detectors/gram-passages.js.map +1 -0
  153. package/dist/detectors/heading-claim.d.ts +14 -0
  154. package/dist/detectors/heading-claim.d.ts.map +1 -0
  155. package/dist/detectors/heading-claim.js +49 -0
  156. package/dist/detectors/heading-claim.js.map +1 -0
  157. package/dist/detectors/heading-echo.d.ts.map +1 -1
  158. package/dist/detectors/heading-echo.js +29 -1
  159. package/dist/detectors/heading-echo.js.map +1 -1
  160. package/dist/detectors/heading-end-mark.d.ts +8 -3
  161. package/dist/detectors/heading-end-mark.d.ts.map +1 -1
  162. package/dist/detectors/heading-end-mark.js +18 -8
  163. package/dist/detectors/heading-end-mark.js.map +1 -1
  164. package/dist/detectors/heading-names.d.ts +7 -0
  165. package/dist/detectors/heading-names.d.ts.map +1 -0
  166. package/dist/detectors/heading-names.js +24 -0
  167. package/dist/detectors/heading-names.js.map +1 -0
  168. package/dist/detectors/heading-numbering.d.ts.map +1 -1
  169. package/dist/detectors/heading-numbering.js +7 -2
  170. package/dist/detectors/heading-numbering.js.map +1 -1
  171. package/dist/detectors/inch-mark.d.ts +10 -0
  172. package/dist/detectors/inch-mark.d.ts.map +1 -0
  173. package/dist/detectors/inch-mark.js +48 -0
  174. package/dist/detectors/inch-mark.js.map +1 -0
  175. package/dist/detectors/installment-total-mismatch.d.ts.map +1 -1
  176. package/dist/detectors/installment-total-mismatch.js +2 -12
  177. package/dist/detectors/installment-total-mismatch.js.map +1 -1
  178. package/dist/detectors/lexicon.d.ts +0 -1
  179. package/dist/detectors/lexicon.d.ts.map +1 -1
  180. package/dist/detectors/lexicon.js +29 -23
  181. package/dist/detectors/lexicon.js.map +1 -1
  182. package/dist/detectors/list-parallel.d.ts +5 -2
  183. package/dist/detectors/list-parallel.d.ts.map +1 -1
  184. package/dist/detectors/list-parallel.js +45 -7
  185. package/dist/detectors/list-parallel.js.map +1 -1
  186. package/dist/detectors/mark-shape.d.ts +6 -3
  187. package/dist/detectors/mark-shape.d.ts.map +1 -1
  188. package/dist/detectors/mark-shape.js +12 -6
  189. package/dist/detectors/mark-shape.js.map +1 -1
  190. package/dist/detectors/name-variant-apart.d.ts +27 -0
  191. package/dist/detectors/name-variant-apart.d.ts.map +1 -0
  192. package/dist/detectors/name-variant-apart.js +51 -0
  193. package/dist/detectors/name-variant-apart.js.map +1 -0
  194. package/dist/detectors/name-variant.d.ts.map +1 -1
  195. package/dist/detectors/name-variant.js +51 -17
  196. package/dist/detectors/name-variant.js.map +1 -1
  197. package/dist/detectors/number-unit.d.ts +10 -0
  198. package/dist/detectors/number-unit.d.ts.map +1 -1
  199. package/dist/detectors/number-unit.js +28 -8
  200. package/dist/detectors/number-unit.js.map +1 -1
  201. package/dist/detectors/numeral-word.d.ts +15 -0
  202. package/dist/detectors/numeral-word.d.ts.map +1 -0
  203. package/dist/detectors/numeral-word.js +26 -0
  204. package/dist/detectors/numeral-word.js.map +1 -0
  205. package/dist/detectors/organisation-run.d.ts +14 -0
  206. package/dist/detectors/organisation-run.d.ts.map +1 -0
  207. package/dist/detectors/organisation-run.js +73 -0
  208. package/dist/detectors/organisation-run.js.map +1 -0
  209. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  210. package/dist/detectors/orthographic-variant.js +13 -5
  211. package/dist/detectors/orthographic-variant.js.map +1 -1
  212. package/dist/detectors/orthography.d.ts.map +1 -1
  213. package/dist/detectors/orthography.js +16 -7
  214. package/dist/detectors/orthography.js.map +1 -1
  215. package/dist/detectors/outline-label.d.ts +14 -0
  216. package/dist/detectors/outline-label.d.ts.map +1 -0
  217. package/dist/detectors/outline-label.js +32 -0
  218. package/dist/detectors/outline-label.js.map +1 -0
  219. package/dist/detectors/page-marker.d.ts +6 -0
  220. package/dist/detectors/page-marker.d.ts.map +1 -0
  221. package/dist/detectors/page-marker.js +19 -0
  222. package/dist/detectors/page-marker.js.map +1 -0
  223. package/dist/detectors/parallel-definition.d.ts +16 -0
  224. package/dist/detectors/parallel-definition.d.ts.map +1 -0
  225. package/dist/detectors/parallel-definition.js +51 -0
  226. package/dist/detectors/parallel-definition.js.map +1 -0
  227. package/dist/detectors/per-unit-words.d.ts +7 -0
  228. package/dist/detectors/per-unit-words.d.ts.map +1 -0
  229. package/dist/detectors/per-unit-words.js +17 -0
  230. package/dist/detectors/per-unit-words.js.map +1 -0
  231. package/dist/detectors/period-multiple-mismatch.d.ts.map +1 -1
  232. package/dist/detectors/period-multiple-mismatch.js +2 -12
  233. package/dist/detectors/period-multiple-mismatch.js.map +1 -1
  234. package/dist/detectors/reference-number-variant.d.ts.map +1 -1
  235. package/dist/detectors/reference-number-variant.js +21 -3
  236. package/dist/detectors/reference-number-variant.js.map +1 -1
  237. package/dist/detectors/reference-text.d.ts.map +1 -1
  238. package/dist/detectors/reference-text.js +1 -0
  239. package/dist/detectors/reference-text.js.map +1 -1
  240. package/dist/detectors/registry/condition-toki.d.ts +3 -0
  241. package/dist/detectors/registry/condition-toki.d.ts.map +1 -0
  242. package/dist/detectors/registry/condition-toki.js +3 -0
  243. package/dist/detectors/registry/condition-toki.js.map +1 -0
  244. package/dist/detectors/registry/unfilled-placeholder.d.ts.map +1 -1
  245. package/dist/detectors/registry/unfilled-placeholder.js +2 -2
  246. package/dist/detectors/registry/unfilled-placeholder.js.map +1 -1
  247. package/dist/detectors/registry/vague-density.js +1 -1
  248. package/dist/detectors/registry/vague-density.js.map +1 -1
  249. package/dist/detectors/rent-multiple-mismatch.d.ts.map +1 -1
  250. package/dist/detectors/rent-multiple-mismatch.js +2 -12
  251. package/dist/detectors/rent-multiple-mismatch.js.map +1 -1
  252. package/dist/detectors/request-owner.d.ts +6 -2
  253. package/dist/detectors/request-owner.d.ts.map +1 -1
  254. package/dist/detectors/request-owner.js +57 -7
  255. package/dist/detectors/request-owner.js.map +1 -1
  256. package/dist/detectors/requirement-smell.d.ts.map +1 -1
  257. package/dist/detectors/requirement-smell.js +10 -2
  258. package/dist/detectors/requirement-smell.js.map +1 -1
  259. package/dist/detectors/row-sentence-amounts.d.ts.map +1 -1
  260. package/dist/detectors/row-sentence-amounts.js +5 -10
  261. package/dist/detectors/row-sentence-amounts.js.map +1 -1
  262. package/dist/detectors/sentence-length.d.ts.map +1 -1
  263. package/dist/detectors/sentence-length.js +24 -16
  264. package/dist/detectors/sentence-length.js.map +1 -1
  265. package/dist/detectors/sentence-rhythm.d.ts.map +1 -1
  266. package/dist/detectors/sentence-rhythm.js +6 -3
  267. package/dist/detectors/sentence-rhythm.js.map +1 -1
  268. package/dist/detectors/series-label.d.ts +2 -1
  269. package/dist/detectors/series-label.d.ts.map +1 -1
  270. package/dist/detectors/series-label.js +10 -4
  271. package/dist/detectors/series-label.js.map +1 -1
  272. package/dist/detectors/signals.d.ts +4 -0
  273. package/dist/detectors/signals.d.ts.map +1 -1
  274. package/dist/detectors/signals.js +95 -36
  275. package/dist/detectors/signals.js.map +1 -1
  276. package/dist/detectors/stated-amounts.d.ts +4 -0
  277. package/dist/detectors/stated-amounts.d.ts.map +1 -0
  278. package/dist/detectors/stated-amounts.js +12 -0
  279. package/dist/detectors/stated-amounts.js.map +1 -0
  280. package/dist/detectors/step-time-sum.d.ts.map +1 -1
  281. package/dist/detectors/step-time-sum.js +2 -1
  282. package/dist/detectors/step-time-sum.js.map +1 -1
  283. package/dist/detectors/structure-tree.d.ts.map +1 -1
  284. package/dist/detectors/structure-tree.js +11 -7
  285. package/dist/detectors/structure-tree.js.map +1 -1
  286. package/dist/detectors/team.d.ts.map +1 -1
  287. package/dist/detectors/team.js +10 -6
  288. package/dist/detectors/team.js.map +1 -1
  289. package/dist/detectors/template-sections.d.ts +14 -0
  290. package/dist/detectors/template-sections.d.ts.map +1 -0
  291. package/dist/detectors/template-sections.js +25 -0
  292. package/dist/detectors/template-sections.js.map +1 -0
  293. package/dist/detectors/time-order.d.ts.map +1 -1
  294. package/dist/detectors/time-order.js +17 -13
  295. package/dist/detectors/time-order.js.map +1 -1
  296. package/dist/detectors/titled-run.d.ts +22 -0
  297. package/dist/detectors/titled-run.d.ts.map +1 -0
  298. package/dist/detectors/titled-run.js +34 -0
  299. package/dist/detectors/titled-run.js.map +1 -0
  300. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
  301. package/dist/detectors/unbalanced-bracket.js +4 -0
  302. package/dist/detectors/unbalanced-bracket.js.map +1 -1
  303. package/dist/detectors/undefined-term.d.ts.map +1 -1
  304. package/dist/detectors/undefined-term.js +8 -0
  305. package/dist/detectors/undefined-term.js.map +1 -1
  306. package/dist/detectors/unfilled-placeholder.d.ts +4 -0
  307. package/dist/detectors/unfilled-placeholder.d.ts.map +1 -0
  308. package/dist/detectors/unfilled-placeholder.js +9 -0
  309. package/dist/detectors/unfilled-placeholder.js.map +1 -0
  310. package/dist/detectors/unknown-word.d.ts +4 -1
  311. package/dist/detectors/unknown-word.d.ts.map +1 -1
  312. package/dist/detectors/unknown-word.js +18 -2
  313. package/dist/detectors/unknown-word.js.map +1 -1
  314. package/dist/detectors/use-interval.d.ts +1 -0
  315. package/dist/detectors/use-interval.d.ts.map +1 -1
  316. package/dist/detectors/use-interval.js +15 -10
  317. package/dist/detectors/use-interval.js.map +1 -1
  318. package/dist/detectors/use-maximum.d.ts.map +1 -1
  319. package/dist/detectors/use-maximum.js +3 -1
  320. package/dist/detectors/use-maximum.js.map +1 -1
  321. package/dist/detectors/vague-density.d.ts +5 -0
  322. package/dist/detectors/vague-density.d.ts.map +1 -0
  323. package/dist/detectors/vague-density.js +52 -0
  324. package/dist/detectors/vague-density.js.map +1 -0
  325. package/dist/extension/document-view.d.ts +2 -2
  326. package/dist/extension/document-view.d.ts.map +1 -1
  327. package/dist/extension/document-view.js +17 -8
  328. package/dist/extension/document-view.js.map +1 -1
  329. package/dist/extension/entry-genres.d.ts +5 -0
  330. package/dist/extension/entry-genres.d.ts.map +1 -0
  331. package/dist/extension/entry-genres.js +13 -0
  332. package/dist/extension/entry-genres.js.map +1 -0
  333. package/dist/extension/module-detector.d.ts.map +1 -1
  334. package/dist/extension/module-detector.js +4 -4
  335. package/dist/extension/module-detector.js.map +1 -1
  336. package/dist/extension/plugin-parse.d.ts +1 -1
  337. package/dist/extension/plugin-parse.d.ts.map +1 -1
  338. package/dist/extension/plugin-parse.js +24 -7
  339. package/dist/extension/plugin-parse.js.map +1 -1
  340. package/dist/extension/problem-text.d.ts.map +1 -1
  341. package/dist/extension/problem-text.js +2 -0
  342. package/dist/extension/problem-text.js.map +1 -1
  343. package/dist/facts/age-values.d.ts.map +1 -1
  344. package/dist/facts/age-values.js +20 -2
  345. package/dist/facts/age-values.js.map +1 -1
  346. package/dist/facts/column-units.d.ts +31 -0
  347. package/dist/facts/column-units.d.ts.map +1 -0
  348. package/dist/facts/column-units.js +37 -0
  349. package/dist/facts/column-units.js.map +1 -0
  350. package/dist/facts/fact-scope.d.ts +10 -1
  351. package/dist/facts/fact-scope.d.ts.map +1 -1
  352. package/dist/facts/fact-scope.js +34 -3
  353. package/dist/facts/fact-scope.js.map +1 -1
  354. package/dist/facts/fact-values.d.ts +4 -0
  355. package/dist/facts/fact-values.d.ts.map +1 -1
  356. package/dist/facts/fact-values.js +3 -1
  357. package/dist/facts/fact-values.js.map +1 -1
  358. package/dist/facts/labelled-facts.d.ts +10 -0
  359. package/dist/facts/labelled-facts.d.ts.map +1 -1
  360. package/dist/facts/labelled-facts.js +6 -1
  361. package/dist/facts/labelled-facts.js.map +1 -1
  362. package/dist/facts/per-unit.d.ts +36 -0
  363. package/dist/facts/per-unit.d.ts.map +1 -0
  364. package/dist/facts/per-unit.js +56 -0
  365. package/dist/facts/per-unit.js.map +1 -0
  366. package/dist/facts/row-sentence-amounts.d.ts +3 -12
  367. package/dist/facts/row-sentence-amounts.d.ts.map +1 -1
  368. package/dist/facts/row-sentence-amounts.js +1 -15
  369. package/dist/facts/row-sentence-amounts.js.map +1 -1
  370. package/dist/facts/table-facts.d.ts +13 -3
  371. package/dist/facts/table-facts.d.ts.map +1 -1
  372. package/dist/facts/table-facts.js +35 -13
  373. package/dist/facts/table-facts.js.map +1 -1
  374. package/dist/facts/term-values.d.ts +13 -1
  375. package/dist/facts/term-values.d.ts.map +1 -1
  376. package/dist/facts/term-values.js +71 -12
  377. package/dist/facts/term-values.js.map +1 -1
  378. package/dist/grade/baseline.d.ts +4 -2
  379. package/dist/grade/baseline.d.ts.map +1 -1
  380. package/dist/grade/baseline.js +13 -11
  381. package/dist/grade/baseline.js.map +1 -1
  382. package/dist/grade/expect-read.d.ts +16 -0
  383. package/dist/grade/expect-read.d.ts.map +1 -0
  384. package/dist/grade/expect-read.js +52 -0
  385. package/dist/grade/expect-read.js.map +1 -0
  386. package/dist/grade/expect.d.ts +50 -0
  387. package/dist/grade/expect.d.ts.map +1 -0
  388. package/dist/grade/expect.js +53 -0
  389. package/dist/grade/expect.js.map +1 -0
  390. package/dist/grade/grade-item.d.ts +1 -1
  391. package/dist/grade/grade-item.d.ts.map +1 -1
  392. package/dist/grade/grade-item.js +13 -3
  393. package/dist/grade/grade-item.js.map +1 -1
  394. package/dist/grade/item.d.ts +9 -1
  395. package/dist/grade/item.d.ts.map +1 -1
  396. package/dist/grade/item.js +32 -7
  397. package/dist/grade/item.js.map +1 -1
  398. package/dist/grade/result.d.ts +5 -0
  399. package/dist/grade/result.d.ts.map +1 -1
  400. package/dist/grade/results-read.d.ts.map +1 -1
  401. package/dist/grade/results-read.js +4 -2
  402. package/dist/grade/results-read.js.map +1 -1
  403. package/dist/grade/rubric-file.d.ts +23 -0
  404. package/dist/grade/rubric-file.d.ts.map +1 -0
  405. package/dist/grade/rubric-file.js +35 -0
  406. package/dist/grade/rubric-file.js.map +1 -0
  407. package/dist/grade/rubric.d.ts +2 -0
  408. package/dist/grade/rubric.d.ts.map +1 -1
  409. package/dist/grade/rubric.js +75 -47
  410. package/dist/grade/rubric.js.map +1 -1
  411. package/dist/grade/setup.d.ts +2 -1
  412. package/dist/grade/setup.d.ts.map +1 -1
  413. package/dist/grade/setup.js +2 -2
  414. package/dist/grade/setup.js.map +1 -1
  415. package/dist/grade/stamp.d.ts +2 -0
  416. package/dist/grade/stamp.d.ts.map +1 -1
  417. package/dist/grade/stamp.js +8 -2
  418. package/dist/grade/stamp.js.map +1 -1
  419. package/dist/grade/task-rubric.d.ts +16 -0
  420. package/dist/grade/task-rubric.d.ts.map +1 -0
  421. package/dist/grade/task-rubric.js +34 -0
  422. package/dist/grade/task-rubric.js.map +1 -0
  423. package/dist/grade/text.d.ts +5 -1
  424. package/dist/grade/text.d.ts.map +1 -1
  425. package/dist/grade/text.js +16 -4
  426. package/dist/grade/text.js.map +1 -1
  427. package/dist/grade-api.d.ts +9 -2
  428. package/dist/grade-api.d.ts.map +1 -1
  429. package/dist/grade-api.js +31 -15
  430. package/dist/grade-api.js.map +1 -1
  431. package/dist/heading-numbering.d.ts +5 -2
  432. package/dist/heading-numbering.d.ts.map +1 -1
  433. package/dist/heading-numbering.js +27 -6
  434. package/dist/heading-numbering.js.map +1 -1
  435. package/dist/name-char-reading.d.ts +5 -0
  436. package/dist/name-char-reading.d.ts.map +1 -1
  437. package/dist/name-char-reading.js +15 -0
  438. package/dist/name-char-reading.js.map +1 -1
  439. package/dist/name-end-letter.d.ts +24 -0
  440. package/dist/name-end-letter.d.ts.map +1 -0
  441. package/dist/name-end-letter.js +45 -0
  442. package/dist/name-end-letter.js.map +1 -0
  443. package/dist/name-given-before.d.ts +15 -0
  444. package/dist/name-given-before.d.ts.map +1 -0
  445. package/dist/name-given-before.js +30 -0
  446. package/dist/name-given-before.js.map +1 -0
  447. package/dist/name-neighbours.d.ts.map +1 -1
  448. package/dist/name-neighbours.js +2 -1
  449. package/dist/name-neighbours.js.map +1 -1
  450. package/dist/name-separator.d.ts +6 -0
  451. package/dist/name-separator.d.ts.map +1 -1
  452. package/dist/name-separator.js +80 -0
  453. package/dist/name-separator.js.map +1 -1
  454. package/dist/name-variants.d.ts +8 -3
  455. package/dist/name-variants.d.ts.map +1 -1
  456. package/dist/name-variants.js +40 -12
  457. package/dist/name-variants.js.map +1 -1
  458. package/dist/name-word-order.d.ts +9 -5
  459. package/dist/name-word-order.d.ts.map +1 -1
  460. package/dist/name-word-order.js +47 -15
  461. package/dist/name-word-order.js.map +1 -1
  462. package/dist/nominal-stem.d.ts +13 -0
  463. package/dist/nominal-stem.d.ts.map +1 -0
  464. package/dist/nominal-stem.js +32 -0
  465. package/dist/nominal-stem.js.map +1 -0
  466. package/dist/number-name.d.ts.map +1 -1
  467. package/dist/number-name.js +11 -2
  468. package/dist/number-name.js.map +1 -1
  469. package/dist/profile/cue-lines.d.ts +6 -0
  470. package/dist/profile/cue-lines.d.ts.map +1 -0
  471. package/dist/profile/cue-lines.js +13 -0
  472. package/dist/profile/cue-lines.js.map +1 -0
  473. package/dist/profile/parse.d.ts +1 -1
  474. package/dist/profile/parse.d.ts.map +1 -1
  475. package/dist/profile/parse.js +3 -2
  476. package/dist/profile/parse.js.map +1 -1
  477. package/dist/reference-numbers.d.ts +2 -0
  478. package/dist/reference-numbers.d.ts.map +1 -1
  479. package/dist/reference-numbers.js +1 -1
  480. package/dist/reference-numbers.js.map +1 -1
  481. package/dist/sentence-load.d.ts +2 -1
  482. package/dist/sentence-load.d.ts.map +1 -1
  483. package/dist/sentence-load.js +6 -2
  484. package/dist/sentence-load.js.map +1 -1
  485. package/dist/spaced-person-name.d.ts.map +1 -1
  486. package/dist/spaced-person-name.js +26 -1
  487. package/dist/spaced-person-name.js.map +1 -1
  488. package/dist/spacing-code.d.ts.map +1 -1
  489. package/dist/spacing-code.js +10 -1
  490. package/dist/spacing-code.js.map +1 -1
  491. package/dist/spacing-minority.d.ts +7 -0
  492. package/dist/spacing-minority.d.ts.map +1 -1
  493. package/dist/spacing-minority.js +14 -0
  494. package/dist/spacing-minority.js.map +1 -1
  495. package/dist/structure/cited-document-section.d.ts +7 -0
  496. package/dist/structure/cited-document-section.d.ts.map +1 -0
  497. package/dist/structure/cited-document-section.js +33 -0
  498. package/dist/structure/cited-document-section.js.map +1 -0
  499. package/dist/structure/closing-balance.d.ts +9 -0
  500. package/dist/structure/closing-balance.d.ts.map +1 -1
  501. package/dist/structure/closing-balance.js +34 -7
  502. package/dist/structure/closing-balance.js.map +1 -1
  503. package/dist/structure/definition-use.d.ts.map +1 -1
  504. package/dist/structure/definition-use.js +20 -1
  505. package/dist/structure/definition-use.js.map +1 -1
  506. package/dist/structure/document-context.d.ts +2 -0
  507. package/dist/structure/document-context.d.ts.map +1 -0
  508. package/dist/structure/document-context.js +42 -0
  509. package/dist/structure/document-context.js.map +1 -0
  510. package/dist/structure/fenced-lines.d.ts +7 -0
  511. package/dist/structure/fenced-lines.d.ts.map +1 -0
  512. package/dist/structure/fenced-lines.js +27 -0
  513. package/dist/structure/fenced-lines.js.map +1 -0
  514. package/dist/structure/html-text-blocks.d.ts +8 -0
  515. package/dist/structure/html-text-blocks.d.ts.map +1 -0
  516. package/dist/structure/html-text-blocks.js +47 -0
  517. package/dist/structure/html-text-blocks.js.map +1 -0
  518. package/dist/structure/issues.d.ts +1 -1
  519. package/dist/structure/issues.d.ts.map +1 -1
  520. package/dist/structure/issues.js +19 -4
  521. package/dist/structure/issues.js.map +1 -1
  522. package/dist/structure/labelled-date-order.d.ts +34 -9
  523. package/dist/structure/labelled-date-order.d.ts.map +1 -1
  524. package/dist/structure/labelled-date-order.js +60 -15
  525. package/dist/structure/labelled-date-order.js.map +1 -1
  526. package/dist/structure/labelled-order.d.ts +10 -1
  527. package/dist/structure/labelled-order.d.ts.map +1 -1
  528. package/dist/structure/labelled-order.js +18 -6
  529. package/dist/structure/labelled-order.js.map +1 -1
  530. package/dist/structure/line-amount-label.d.ts.map +1 -1
  531. package/dist/structure/line-amount-label.js +2 -1
  532. package/dist/structure/line-amount-label.js.map +1 -1
  533. package/dist/structure/line-amount.d.ts +0 -5
  534. package/dist/structure/line-amount.d.ts.map +1 -1
  535. package/dist/structure/line-amount.js +1 -10
  536. package/dist/structure/line-amount.js.map +1 -1
  537. package/dist/structure/list-numbering.d.ts +20 -4
  538. package/dist/structure/list-numbering.d.ts.map +1 -1
  539. package/dist/structure/list-numbering.js +65 -9
  540. package/dist/structure/list-numbering.js.map +1 -1
  541. package/dist/structure/listed-paragraph.d.ts +16 -0
  542. package/dist/structure/listed-paragraph.d.ts.map +1 -0
  543. package/dist/structure/listed-paragraph.js +37 -0
  544. package/dist/structure/listed-paragraph.js.map +1 -0
  545. package/dist/structure/numbering.d.ts +3 -2
  546. package/dist/structure/numbering.d.ts.map +1 -1
  547. package/dist/structure/numbering.js +31 -6
  548. package/dist/structure/numbering.js.map +1 -1
  549. package/dist/structure/prose-total.d.ts +8 -0
  550. package/dist/structure/prose-total.d.ts.map +1 -1
  551. package/dist/structure/prose-total.js +70 -2
  552. package/dist/structure/prose-total.js.map +1 -1
  553. package/dist/structure/reference-text.d.ts +9 -1
  554. package/dist/structure/reference-text.d.ts.map +1 -1
  555. package/dist/structure/reference-text.js +21 -3
  556. package/dist/structure/reference-text.js.map +1 -1
  557. package/dist/structure/runs.d.ts.map +1 -1
  558. package/dist/structure/runs.js +9 -1
  559. package/dist/structure/runs.js.map +1 -1
  560. package/dist/structure/section-names.d.ts +12 -0
  561. package/dist/structure/section-names.d.ts.map +1 -0
  562. package/dist/structure/section-names.js +26 -0
  563. package/dist/structure/section-names.js.map +1 -0
  564. package/dist/structure/signed-date-line.d.ts +15 -0
  565. package/dist/structure/signed-date-line.d.ts.map +1 -0
  566. package/dist/structure/signed-date-line.js +68 -0
  567. package/dist/structure/signed-date-line.js.map +1 -0
  568. package/dist/structure/tax.d.ts.map +1 -1
  569. package/dist/structure/tax.js +5 -3
  570. package/dist/structure/tax.js.map +1 -1
  571. package/dist/structure/total-line.d.ts.map +1 -1
  572. package/dist/structure/total-line.js +10 -6
  573. package/dist/structure/total-line.js.map +1 -1
  574. package/dist/structure/total.d.ts +2 -0
  575. package/dist/structure/total.d.ts.map +1 -1
  576. package/dist/structure/total.js +34 -3
  577. package/dist/structure/total.js.map +1 -1
  578. package/dist/structure/versioned-label.d.ts +16 -0
  579. package/dist/structure/versioned-label.d.ts.map +1 -0
  580. package/dist/structure/versioned-label.js +48 -0
  581. package/dist/structure/versioned-label.js.map +1 -0
  582. package/dist/structure/written-headings.d.ts +31 -0
  583. package/dist/structure/written-headings.d.ts.map +1 -0
  584. package/dist/structure/written-headings.js +119 -0
  585. package/dist/structure/written-headings.js.map +1 -0
  586. package/dist/structure/written-resolve.d.ts +12 -0
  587. package/dist/structure/written-resolve.d.ts.map +1 -0
  588. package/dist/structure/written-resolve.js +49 -0
  589. package/dist/structure/written-resolve.js.map +1 -0
  590. package/dist/subject-codes.d.ts +21 -0
  591. package/dist/subject-codes.d.ts.map +1 -0
  592. package/dist/subject-codes.js +79 -0
  593. package/dist/subject-codes.js.map +1 -0
  594. package/dist/unlabelled-references.d.ts +6 -2
  595. package/dist/unlabelled-references.d.ts.map +1 -1
  596. package/dist/unlabelled-references.js +11 -10
  597. package/dist/unlabelled-references.js.map +1 -1
  598. package/genres.yaml +17 -0
  599. package/package.json +3 -3
  600. package/profiles/listing.yaml +1 -1
  601. package/rules/all-caps-shouting.yaml +2 -2
  602. package/rules/closing-balance-mismatch.yaml +3 -3
  603. package/rules/concrete-evidence-density.yaml +2 -2
  604. package/rules/contraction-consistency.yaml +13 -13
  605. package/rules/dangling-reference.yaml +2 -2
  606. package/rules/date-without-year.yaml +2 -2
  607. package/rules/defined-name-repeated.yaml +2 -2
  608. package/rules/due-before-issue.yaml +9 -5
  609. package/rules/fact-conflict.yaml +2 -2
  610. package/rules/heading-echo.yaml +2 -2
  611. package/rules/heading-end-punctuation-mix.yaml +2 -2
  612. package/rules/heading-numbering-mix.yaml +2 -2
  613. package/rules/internal-jargon.yaml +2 -2
  614. package/rules/latin-spacing.yaml +4 -4
  615. package/rules/list-item-form-mix.yaml +1 -1
  616. package/rules/max-kanji-continuous.yaml +5 -3
  617. package/rules/max-sentence-length.yaml +3 -2
  618. package/rules/name-variant.yaml +5 -2
  619. package/rules/ngram-repetition.yaml +2 -2
  620. package/rules/no-lead.yaml +2 -2
  621. package/rules/number-without-unit.yaml +2 -2
  622. package/rules/numbering-gap.yaml +2 -2
  623. package/rules/orthographic-variant.yaml +2 -2
  624. package/rules/reference-number-variant.yaml +3 -3
  625. package/rules/reference-title-mismatch.yaml +2 -2
  626. package/rules/repeated-sentence-ending.yaml +3 -2
  627. package/rules/request-without-deadline.yaml +2 -2
  628. package/rules/requirement-smell.yaml +2 -2
  629. package/rules/sentence-rhythm.yaml +2 -2
  630. package/rules/title-case-consistency.yaml +2 -2
  631. package/rules/toki-as-condition.yaml +71 -0
  632. package/rules/total-mismatch.yaml +4 -4
  633. package/rules/unbalanced-bracket.yaml +2 -2
  634. package/rules/undefined-acronym.yaml +11 -2
  635. package/rules/undefined-term.yaml +2 -2
  636. package/rules/unfilled-placeholder.yaml +2 -2
  637. package/rules/unknown-word.yaml +2 -2
  638. package/rules/use-before-definition.yaml +2 -2
  639. package/rules/vague-word-density.yaml +2 -2
  640. package/src/api.ts +11 -2
  641. package/src/capitals-passage.ts +31 -0
  642. package/src/cli-text.ts +4 -2
  643. package/src/coined-hyphen-name.ts +27 -0
  644. package/src/commands/grade.ts +75 -23
  645. package/src/company-kana-spelling.ts +22 -2
  646. package/src/company-name-ending.ts +50 -0
  647. package/src/company-names.ts +76 -20
  648. package/src/custom/no-rewrite.ts +2 -0
  649. package/src/custom/parse.ts +18 -2
  650. package/src/detectors/acronym-context.ts +5 -6
  651. package/src/detectors/acronym-definition.ts +123 -0
  652. package/src/detectors/acronym-lone.ts +26 -0
  653. package/src/detectors/acronym-name.ts +117 -0
  654. package/src/detectors/age-words.ts +12 -0
  655. package/src/detectors/annual-pay-mismatch.ts +3 -18
  656. package/src/detectors/blank-structure.ts +4 -3
  657. package/src/detectors/capitalised-term.ts +154 -4
  658. package/src/detectors/caps-caption.ts +61 -0
  659. package/src/detectors/char-shape.ts +74 -22
  660. package/src/detectors/clause-shape.ts +14 -4
  661. package/src/detectors/closing-balance-mismatch.ts +1 -0
  662. package/src/detectors/code-fences.ts +10 -0
  663. package/src/detectors/concrete-evidence.ts +77 -1
  664. package/src/detectors/condition-toki.ts +60 -0
  665. package/src/detectors/conjugated-entry.ts +53 -0
  666. package/src/detectors/content-morphemes.ts +2 -1
  667. package/src/detectors/contraction-minority.ts +11 -0
  668. package/src/detectors/counter-edge.ts +23 -0
  669. package/src/detectors/cross-facts.ts +2 -1
  670. package/src/detectors/custom.ts +9 -2
  671. package/src/detectors/date-any-year.ts +56 -10
  672. package/src/detectors/date-heading-year.ts +55 -0
  673. package/src/detectors/date-year.ts +54 -9
  674. package/src/detectors/defined-term-form.ts +26 -5
  675. package/src/detectors/document-shape.ts +8 -0
  676. package/src/detectors/due-date.ts +26 -7
  677. package/src/detectors/en-shape.ts +5 -1
  678. package/src/detectors/fact-consistency.ts +16 -19
  679. package/src/detectors/form-line.ts +47 -0
  680. package/src/detectors/formula-amount.ts +2 -18
  681. package/src/detectors/gram-passages.ts +36 -0
  682. package/src/detectors/heading-claim.ts +76 -0
  683. package/src/detectors/heading-echo.ts +32 -1
  684. package/src/detectors/heading-end-mark.ts +23 -10
  685. package/src/detectors/heading-names.ts +31 -0
  686. package/src/detectors/heading-numbering.ts +7 -2
  687. package/src/detectors/inch-mark.ts +49 -0
  688. package/src/detectors/installment-total-mismatch.ts +3 -18
  689. package/src/detectors/lexicon.ts +32 -21
  690. package/src/detectors/list-parallel.ts +46 -7
  691. package/src/detectors/mark-shape.ts +12 -6
  692. package/src/detectors/name-variant-apart.ts +63 -0
  693. package/src/detectors/name-variant.ts +73 -18
  694. package/src/detectors/number-unit.ts +35 -9
  695. package/src/detectors/numeral-word.ts +33 -0
  696. package/src/detectors/organisation-run.ts +86 -0
  697. package/src/detectors/orthographic-variant.ts +22 -6
  698. package/src/detectors/orthography.ts +17 -8
  699. package/src/detectors/outline-label.ts +48 -0
  700. package/src/detectors/page-marker.ts +26 -0
  701. package/src/detectors/parallel-definition.ts +64 -0
  702. package/src/detectors/per-unit-words.ts +24 -0
  703. package/src/detectors/period-multiple-mismatch.ts +2 -18
  704. package/src/detectors/reference-number-variant.ts +27 -5
  705. package/src/detectors/reference-text.ts +1 -0
  706. package/src/detectors/registry/condition-toki.ts +4 -0
  707. package/src/detectors/registry/unfilled-placeholder.ts +2 -2
  708. package/src/detectors/registry/vague-density.ts +1 -1
  709. package/src/detectors/rent-multiple-mismatch.ts +2 -18
  710. package/src/detectors/request-owner.ts +71 -8
  711. package/src/detectors/requirement-smell.ts +15 -2
  712. package/src/detectors/row-sentence-amounts.ts +5 -20
  713. package/src/detectors/sentence-length.ts +14 -6
  714. package/src/detectors/sentence-rhythm.ts +8 -4
  715. package/src/detectors/series-label.ts +13 -4
  716. package/src/detectors/signals.ts +94 -26
  717. package/src/detectors/stated-amounts.ts +20 -0
  718. package/src/detectors/step-time-sum.ts +2 -1
  719. package/src/detectors/structure-tree.ts +13 -8
  720. package/src/detectors/team.ts +13 -7
  721. package/src/detectors/template-sections.ts +37 -0
  722. package/src/detectors/time-order.ts +6 -3
  723. package/src/detectors/titled-run.ts +43 -0
  724. package/src/detectors/unbalanced-bracket.ts +3 -0
  725. package/src/detectors/undefined-term.ts +8 -0
  726. package/src/detectors/unfilled-placeholder.ts +10 -0
  727. package/src/detectors/unknown-word.ts +20 -2
  728. package/src/detectors/use-interval.ts +8 -4
  729. package/src/detectors/use-maximum.ts +3 -1
  730. package/src/detectors/vague-density.ts +68 -0
  731. package/src/extension/document-view.ts +18 -9
  732. package/src/extension/entry-genres.ts +15 -0
  733. package/src/extension/module-detector.ts +9 -4
  734. package/src/extension/plugin-parse.ts +29 -7
  735. package/src/extension/problem-text.ts +4 -0
  736. package/src/facts/age-values.ts +24 -2
  737. package/src/facts/column-units.ts +67 -0
  738. package/src/facts/fact-scope.ts +53 -4
  739. package/src/facts/fact-values.ts +11 -1
  740. package/src/facts/labelled-facts.ts +16 -2
  741. package/src/facts/per-unit.ts +105 -0
  742. package/src/facts/row-sentence-amounts.ts +4 -26
  743. package/src/facts/table-facts.ts +50 -10
  744. package/src/facts/term-values.ts +94 -13
  745. package/src/grade/baseline.ts +20 -12
  746. package/src/grade/expect-read.ts +65 -0
  747. package/src/grade/expect.ts +74 -0
  748. package/src/grade/grade-item.ts +14 -3
  749. package/src/grade/item.ts +48 -8
  750. package/src/grade/result.ts +5 -0
  751. package/src/grade/results-read.ts +7 -2
  752. package/src/grade/rubric-file.ts +46 -0
  753. package/src/grade/rubric.ts +77 -47
  754. package/src/grade/setup.ts +3 -3
  755. package/src/grade/stamp.ts +10 -2
  756. package/src/grade/task-rubric.ts +39 -0
  757. package/src/grade/text.ts +27 -5
  758. package/src/grade-api.ts +38 -16
  759. package/src/heading-numbering.ts +35 -8
  760. package/src/name-char-reading.ts +16 -0
  761. package/src/name-end-letter.ts +61 -0
  762. package/src/name-given-before.ts +40 -0
  763. package/src/name-neighbours.ts +2 -1
  764. package/src/name-separator.ts +93 -0
  765. package/src/name-variants.ts +69 -18
  766. package/src/name-word-order.ts +62 -17
  767. package/src/nominal-stem.ts +36 -0
  768. package/src/number-name.ts +12 -3
  769. package/src/profile/cue-lines.ts +14 -0
  770. package/src/profile/parse.ts +3 -2
  771. package/src/reference-numbers.ts +1 -1
  772. package/src/sentence-load.ts +7 -2
  773. package/src/spaced-person-name.ts +27 -2
  774. package/src/spacing-code.ts +13 -2
  775. package/src/spacing-minority.ts +17 -0
  776. package/src/structure/cited-document-section.ts +42 -0
  777. package/src/structure/closing-balance.ts +46 -8
  778. package/src/structure/definition-use.ts +24 -1
  779. package/src/structure/document-context.ts +46 -0
  780. package/src/structure/fenced-lines.ts +28 -0
  781. package/src/structure/html-text-blocks.ts +45 -0
  782. package/src/structure/issues.ts +19 -4
  783. package/src/structure/labelled-date-order.ts +108 -21
  784. package/src/structure/labelled-order.ts +33 -13
  785. package/src/structure/line-amount-label.ts +2 -1
  786. package/src/structure/line-amount.ts +1 -11
  787. package/src/structure/list-numbering.ts +100 -11
  788. package/src/structure/listed-paragraph.ts +45 -0
  789. package/src/structure/numbering.ts +48 -19
  790. package/src/structure/prose-total.ts +81 -2
  791. package/src/structure/reference-text.ts +25 -3
  792. package/src/structure/runs.ts +10 -1
  793. package/src/structure/section-names.ts +32 -0
  794. package/src/structure/signed-date-line.ts +78 -0
  795. package/src/structure/tax.ts +6 -3
  796. package/src/structure/total-line.ts +12 -6
  797. package/src/structure/total.ts +42 -3
  798. package/src/structure/versioned-label.ts +52 -0
  799. package/src/structure/written-headings.ts +137 -0
  800. package/src/structure/written-resolve.ts +57 -0
  801. package/src/subject-codes.ts +105 -0
  802. package/src/unlabelled-references.ts +24 -16
@@ -1,10 +1,11 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
1
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { packageFor } from "../adapter-load.ts";
4
4
  import type { Config } from "../config/load.ts";
5
5
  import { readDocumentFile } from "../files.ts";
6
6
  import { GENRES } from "../genre.ts";
7
7
  import { gradeItem, type GradeSetup } from "../grade/grade-item.ts";
8
+ import { expectProblems } from "../grade/expect-read.ts";
8
9
  import { DEFAULT_VARIANT_FIELD, ITEM_FIELDS, parseItems, type GradeItem, type VariantField } from "../grade/item.ts";
9
10
  import { renderMarkdown } from "../grade/render-markdown.ts";
10
11
  import { renderVariants, renderVariantsCompact } from "../grade/render-variants.ts";
@@ -14,6 +15,8 @@ import { renderCompact, renderSummary } from "../grade/render.ts";
14
15
  import type { GradeResult } from "../grade/result.ts";
15
16
  import { gradeSetup } from "../grade/setup.ts";
16
17
  import { parseRubric, type Rubric } from "../grade/rubric.ts";
18
+ import { parseRubricFile, type RubricFileProblem } from "../grade/rubric-file.ts";
19
+ import { rubricRuleEntries, taskNamesOf, taskRuleIds } from "../grade/task-rubric.ts";
17
20
  import { rulesOf } from "../custom/load.ts";
18
21
  import { summaryOf } from "../grade/summary.ts";
19
22
  import { GRADE_TEXT, type GradeText } from "../grade/text.ts";
@@ -26,7 +29,7 @@ import { chooseBaseline } from "./grade-baseline.ts";
26
29
  /** Exit codes (spec §29.3). 2 keeps "the grader did not run" apart from "an output is bad" at a CI gate. */
27
30
  export const GRADE_EXIT = { passed: 0, failed: 1, unreadable: 2 } as const;
28
31
 
29
- const VALUED: ReadonlySet<string> = new Set(["--out", "--genre", "--baseline", "--format", "--variant-key"]);
32
+ const VALUED: ReadonlySet<string> = new Set(["--out", "--genre", "--baseline", "--format", "--variant-key", "--rubric"]);
30
33
 
31
34
  const FORMATS = ["text", "json", "markdown"] as const;
32
35
 
@@ -56,11 +59,13 @@ export type GradeContext = {
56
59
  readonly ui: UiLanguage;
57
60
  };
58
61
 
59
- const readItems = async (path: string, variantField: VariantField, text: GradeText): Promise<readonly GradeItem[] | undefined> => {
62
+ type ReadItems = { readonly items: readonly GradeItem[]; readonly lines: readonly number[] };
63
+
64
+ const readItems = async (path: string, variantField: VariantField, tasks: readonly string[], text: GradeText): Promise<ReadItems | undefined> => {
60
65
  try {
61
- const vocabulary = { isLanguage: (language: string) => packageFor(language) !== undefined, genres: GENRES };
66
+ const vocabulary = { isLanguage: (language: string) => packageFor(language) !== undefined, genres: GENRES, tasks };
62
67
  const parsed = parseItems(await readDocumentFile(path), vocabulary, variantField);
63
- if ("items" in parsed) return parsed.items;
68
+ if ("items" in parsed) return parsed;
64
69
  parsed.problems.forEach((problem) => console.error(`${path}: ${text.problem(problem)}`));
65
70
  } catch (error) {
66
71
  console.error(text.unreadable(path, error instanceof Error ? error.message : String(error)));
@@ -68,39 +73,75 @@ const readItems = async (path: string, variantField: VariantField, text: GradeTe
68
73
  return undefined;
69
74
  };
70
75
 
71
- /** The `grade:` rubric, or undefined after saying what is wrong with it. `rubric: undefined` is a run with no rubric. */
72
- const readRubric = (config: Config, text: GradeText): { readonly rubric: Rubric | undefined } | undefined => {
76
+ /** The rubric a run grades by, and the --rubric file it came from when it came from one. */
77
+ type RubricRead = { readonly rubric: Rubric | undefined; readonly file?: { readonly path: string; readonly digest: string } | undefined };
78
+
79
+ /** chaff.yaml's `grade:` rubric, or undefined after saying what is wrong with it. `rubric: undefined` is a run with no rubric. */
80
+ const readConfigRubric = (config: Config, text: GradeText): RubricRead | undefined => {
73
81
  const parsed = parseRubric(config.grade);
74
82
  if ("rubric" in parsed) return parsed;
75
83
  parsed.problems.forEach((problem) => console.error(`chaff: ${text.rubricProblem(problem)}`));
76
84
  return undefined;
77
85
  };
78
86
 
79
- /** A rule id under grade.rules that chaff does not know. Said once here; each result also lists it as not run. */
80
- const warnUnknownRules = (rubric: Rubric | undefined, config: Config, text: GradeText): void => {
87
+ const fileProblemText = (path: string, problem: RubricFileProblem, text: GradeText): string => {
88
+ if (problem.kind === "format") return text.rubricFormat(path);
89
+ if (problem.kind === "syntax") return text.rubricSyntax(path, problem.why);
90
+ return text.rubricProblem(problem.problem, path);
91
+ };
92
+
93
+ /** A --rubric file's rubric, which replaces chaff.yaml's `grade:`, or undefined after saying why it cannot be read. */
94
+ const readRubricFile = (path: string, text: GradeText): RubricRead | undefined => {
95
+ try {
96
+ const parsed = parseRubricFile(path, readFileSync(path, "utf8"));
97
+ if ("rubric" in parsed) return { rubric: parsed.rubric, file: { path, digest: parsed.digest } };
98
+ parsed.problems.forEach((problem) => console.error(fileProblemText(path, problem, text)));
99
+ } catch (error) {
100
+ console.error(text.unreadable(path, error instanceof Error ? error.message : String(error)));
101
+ }
102
+ return undefined;
103
+ };
104
+
105
+ const readRubric = (rubricPath: string | undefined, config: Config, text: GradeText): RubricRead | undefined =>
106
+ rubricPath === undefined ? readConfigRubric(config, text) : readRubricFile(rubricPath, text);
107
+
108
+ /** A rule id under the rubric's rules that chaff does not know. Said once here; each result also lists it as not run. */
109
+ const warnUnknownRules = (rubric: RubricRead, config: Config, text: GradeText): void => {
81
110
  const known = new Set(rulesOf(config.language ?? "en", config).map((rule) => rule.id));
82
- Object.keys(rubric?.rules ?? {})
83
- .filter((id) => !known.has(id))
84
- .forEach((id) => console.error(`chaff: grade.rules.${id}: ${text.unknownRule}`));
111
+ const where = rubric.file === undefined ? "chaff: grade." : `${rubric.file.path}: `;
112
+ rubricRuleEntries(rubric.rubric)
113
+ .filter((entry) => !known.has(entry.id))
114
+ .forEach((entry) => console.error(`${where}${entry.path}.${entry.id}: ${text.unknownRule}`));
85
115
  };
86
116
 
87
117
  const setupFor = async (
88
118
  items: readonly GradeItem[],
89
- rubric: Rubric | undefined,
119
+ rubric: RubricRead,
90
120
  argv: readonly string[],
91
121
  context: GradeContext,
92
122
  text: GradeText,
93
123
  ): Promise<GradeSetup | undefined> => {
94
124
  const languages = items.flatMap((item) => (item.language === undefined ? [] : [item.language]));
95
- const run = { experimental: context.config.experimental || argv.includes("--experimental"), genre: context.flag(argv, "--genre") };
125
+ const run = {
126
+ experimental: context.config.experimental || argv.includes("--experimental"),
127
+ genre: context.flag(argv, "--genre"),
128
+ rubricFile: rubric.file?.digest,
129
+ };
96
130
  try {
97
- return await gradeSetup(context.config, run, languages, rubric);
131
+ return await gradeSetup(context.config, run, languages, rubric.rubric);
98
132
  } catch (error) {
99
133
  console.error(text.cannotLoad(error instanceof Error ? error.message : String(error)));
100
134
  return undefined;
101
135
  }
102
136
  };
103
137
 
138
+ /** Whether every expect entry is one fact; else says which are not, on their lines, before anything is graded. */
139
+ const expectReadable = async (path: string, read: ReadItems, setup: GradeSetup, text: GradeText): Promise<boolean> => {
140
+ const problems = (await Promise.all(read.items.map((item, index) => expectProblems(item, read.lines[index] ?? 0, setup)))).flat();
141
+ problems.forEach((problem) => console.error(`${path}: ${text.problem(problem)}`));
142
+ return problems.length === 0;
143
+ };
144
+
104
145
  /** One output after another, in the file's order: the results file lines up with the input. */
105
146
  const gradeInOrder = (items: readonly GradeItem[], setup: GradeSetup): Promise<GradeResult[]> =>
106
147
  items.reduce<Promise<GradeResult[]>>(async (previous, item) => [...(await previous), await gradeItem(item, setup)], Promise.resolve([]));
@@ -144,14 +185,24 @@ const printSummary = (path: string, results: readonly GradeResult[], compared: C
144
185
  } else printText(path, results, variants, compared, printing);
145
186
  };
146
187
 
147
- type RunOptions = { readonly path: string; readonly format: Format; readonly variantField: VariantField };
188
+ type RunOptions = { readonly path: string; readonly format: Format; readonly variantField: VariantField; readonly rubric: string | undefined };
189
+
190
+ /** --rubric's file: undefined when not given, null when given without one (a usage error, not a quiet fall back to chaff.yaml). */
191
+ const rubricPathOf = (argv: readonly string[], context: GradeContext): string | undefined | null => {
192
+ if (!argv.includes("--rubric")) return undefined;
193
+ const path = context.flag(argv, "--rubric");
194
+ return path === undefined || path === "" || path.startsWith("--") ? null : path;
195
+ };
148
196
 
149
197
  /** The file to grade and how to read and print it, or undefined after printing the usage. */
150
198
  const runOptionsOf = (argv: readonly string[], context: GradeContext): RunOptions | undefined => {
151
199
  const [path, ...extra] = gradeTargets(argv);
152
200
  const format = formatOf(argv, context);
153
201
  const variantField = variantFieldOf(argv, context);
154
- if (path !== undefined && extra.length === 0 && format !== undefined && variantField !== undefined) return { path, format, variantField };
202
+ const rubric = rubricPathOf(argv, context);
203
+ if (path !== undefined && extra.length === 0 && format !== undefined && variantField !== undefined && rubric !== null) {
204
+ return { path, format, variantField, rubric };
205
+ }
155
206
  console.error(GRADE_TEXT[context.ui].usage);
156
207
  return undefined;
157
208
  };
@@ -171,16 +222,17 @@ export const runGrade = async (argv: readonly string[], context: GradeContext):
171
222
  const options = runOptionsOf(argv, context);
172
223
  if (options === undefined) return GRADE_EXIT.unreadable;
173
224
  const { path } = options;
174
- const rubric = readRubric(context.config, host);
175
- const items = rubric === undefined ? undefined : await readItems(path, options.variantField, host);
176
- const setup = items === undefined || rubric === undefined ? undefined : await setupFor(items, rubric.rubric, argv, context, host);
177
- if (setup === undefined || items === undefined) return GRADE_EXIT.unreadable;
225
+ const rubric = readRubric(options.rubric, context.config, host);
226
+ const read = rubric === undefined ? undefined : await readItems(path, options.variantField, taskNamesOf(rubric.rubric), host);
227
+ const setup = read === undefined || rubric === undefined ? undefined : await setupFor(read.items, rubric, argv, context, host);
228
+ if (setup === undefined || read === undefined || rubric === undefined || !(await expectReadable(path, read, setup, host))) return GRADE_EXIT.unreadable;
229
+ const { items } = read;
178
230
  const baseline = await chooseBaseline(context.flag(argv, "--baseline"), setup.stamp, argv.includes("--allow-stamp-mismatch"), context.ui);
179
231
  if (baseline.kind === "stop") return GRADE_EXIT.unreadable;
180
- warnUnknownRules(setup.rubric, context.config, host);
232
+ warnUnknownRules(rubric, context.config, host);
181
233
  const results = await gradeInOrder(items, setup);
182
234
  writeResults(context.flag(argv, "--out"), results, host);
183
- const rubricRules = new Set(Object.keys(setup.rubric?.rules ?? {}));
235
+ const rubricRules = (result: GradeResult): ReadonlySet<string> => taskRuleIds(setup.rubric, result.task);
184
236
  const compared = baseline.kind === "compare" ? { path: baseline.path, comparison: compareRuns(baseline.before, results, rubricRules) } : undefined;
185
237
  const ui = sharedLanguage(
186
238
  results.map((result) => result.language),
@@ -42,7 +42,26 @@ export const kanjiReadingOf = (
42
42
  const baseStartOf = (mention: CompanyMention): number =>
43
43
  mention.position === "after" ? mention.offset : mention.offset + mention.surface.length - mention.base.length;
44
44
 
45
- /** 会社の名前の、漢字一字をその読みのひらがなかカタカナで書いた形(みどりの生命保険株式会社、みどりノ生命保険株式会社)。 */
45
+ /** 濁る頭の音(カ行、サ行、タ行、ハ行)。 */
46
+ const VOICEABLE = /^[カキクケコサシスセソタチツテトハヒフヘホ]/u;
47
+ const VOICED_MARK = "゙";
48
+
49
+ /** 名前の中ほどの字の読みは、頭の音を濁らせて書くことがある(こむぎ畑 ハタケ を こむぎばたけ)。頭の音が濁らない読みには無い。 */
50
+ export const voicedReadingOf = (reading: string): string | undefined => {
51
+ const first = VOICEABLE.exec(reading)?.[0];
52
+ return first === undefined ? undefined : `${(first + VOICED_MARK).normalize("NFC")}${reading.slice(first.length)}`;
53
+ };
54
+
55
+ /** 名前の字の読みの、かなの書き方。名前の頭でない字は、頭の音を濁らせた読みも。 */
56
+ const readingsAt = (reading: string, inside: boolean): string[] => {
57
+ const voiced = inside ? voicedReadingOf(reading) : undefined;
58
+ return voiced === undefined ? [reading] : [reading, voiced];
59
+ };
60
+
61
+ /**
62
+ * 会社の名前の、漢字一字をその読みのひらがなかカタカナで書いた形(みどりの生命保険株式会社、みどりノ生命保険株式会社)。
63
+ * 名前の頭でない字は、頭の音を濁らせた読みでも(こむぎばたけベーカリー)。
64
+ */
46
65
  export const kanaSpellingsOf = (mention: CompanyMention, words: readonly ReadWord[]): string[] => {
47
66
  const baseStart = baseStartOf(mention);
48
67
  const baseEnd = baseStart + mention.base.length;
@@ -53,7 +72,8 @@ export const kanaSpellingsOf = (mention: CompanyMention, words: readonly ReadWor
53
72
  if (read === undefined) return [];
54
73
  const at = word.start - mention.offset + read.index;
55
74
  const [before, after] = [mention.surface.slice(0, at), mention.surface.slice(at + read.kanji.length)];
56
- return [toHiragana(read.reading), read.reading].map((kana) => `${before}${kana}${after}`);
75
+ const inside = word.start + read.index > baseStart;
76
+ return readingsAt(read.reading, inside).flatMap((reading) => [toHiragana(reading), reading].map((kana) => `${before}${kana}${after}`));
57
77
  });
58
78
  };
59
79
 
@@ -0,0 +1,50 @@
1
+ // 会社の名前の一語の終わりだけの違い。長い語の終わりの二字まで(Brightmoor と Brightmore、Lumenvale と Lumenvail)と、最後の語の
2
+ // 単数と複数(Water Utility と Water Utilities)。名前のほかの語は同じもの。
3
+
4
+ const LATIN_WORD = /^[a-z]+$/u;
5
+
6
+ /** 終わりの二字の違いを見る語の長さ。短い語(Alpha と Alpine)は別の名前のことが多い。 */
7
+ const MIN_ENDING_WORD_LENGTH = 8;
8
+ /** 頭からそろった字の後ろに残る字の数。 */
9
+ const MAX_ENDING_LENGTH = 2;
10
+
11
+ const wordsOf = (base: string): string[] =>
12
+ base
13
+ .toLowerCase()
14
+ .split(/\s+/u)
15
+ .filter((word) => word !== "");
16
+
17
+ /** 二つの名前の語の数が同じで、違うのが一語だけなら、その語の組と位置。 */
18
+ const differingWord = (left: string, right: string): { readonly pair: readonly [string, string]; readonly last: boolean } | undefined => {
19
+ const [leftWords, rightWords] = [wordsOf(left), wordsOf(right)];
20
+ const differing = leftWords.flatMap((word, index) => (word === rightWords[index] ? [] : [index]));
21
+ const [at] = differing;
22
+ const [leftWord, rightWord] = [leftWords[at ?? -1], rightWords[at ?? -1]];
23
+ if (leftWords.length !== rightWords.length || differing.length !== 1 || leftWord === undefined || rightWord === undefined) return undefined;
24
+ return { pair: [leftWord, rightWord], last: at === leftWords.length - 1 };
25
+ };
26
+
27
+ const sharedPrefix = (left: string, right: string): number => {
28
+ const differ = [...left].findIndex((char, index) => char !== right.charAt(index));
29
+ return differ < 0 ? left.length : differ;
30
+ };
31
+
32
+ /** 八字以上の英字の語の、頭がそろい、終わりの二字までだけが違うか(moor と more)。 */
33
+ export const isEndingApart = (left: string, right: string): boolean => {
34
+ if (left === right || !LATIN_WORD.test(left) || !LATIN_WORD.test(right) || Math.min(left.length, right.length) < MIN_ENDING_WORD_LENGTH) return false;
35
+ const prefix = sharedPrefix(left, right);
36
+ return left.length - prefix <= MAX_ENDING_LENGTH && right.length - prefix <= MAX_ENDING_LENGTH;
37
+ };
38
+
39
+ /** 片方が他方の複数の形か(Tool と Tools、Box と Boxes、Utility と Utilities)。 */
40
+ export const isPluralOf = (singular: string, plural: string): boolean =>
41
+ LATIN_WORD.test(singular) &&
42
+ (plural === `${singular}s` || plural === `${singular}es` || (singular.endsWith("y") && plural === `${singular.slice(0, -1)}ies`));
43
+
44
+ /** 二つの会社の名前の部分が、一語の終わりだけ違うか。長い語の終わりの二字までか、最後の語の単数と複数。 */
45
+ export const isNameEndingSlip = (left: string, right: string): boolean => {
46
+ const differing = differingWord(left, right);
47
+ if (differing === undefined) return false;
48
+ const [leftWord, rightWord] = differing.pair;
49
+ return isEndingApart(leftWord, rightWord) || (differing.last && (isPluralOf(leftWord, rightWord) || isPluralOf(rightWord, leftWord)));
50
+ };
@@ -1,5 +1,6 @@
1
1
  import { nameKey } from "./name-variants.ts";
2
2
  import { escapeRegExp } from "./orthography.ts";
3
+ import { isNameEndingSlip } from "./company-name-ending.ts";
3
4
 
4
5
  // 会社の名前を、文書の中で二通りに書いた所(株式会社アオバシステム と アオバシステム株式会社、Aoba Systems Inc. と Aoba Systems Ltd.)。
5
6
  // 会社の形の語(株式会社、Inc)は語彙表 company-form が言う。group が同じ語は同じ形(Inc と Incorporated、株式会社 と (株))、
@@ -27,8 +28,11 @@ export type CompanyMention = {
27
28
  readonly foreign?: boolean | undefined;
28
29
  };
29
30
 
30
- /** 二つの書き方の違い。spelling は記号・幅・大小だけ、form は会社の形、position は形の語の側、near は名前の一字違い。 */
31
- type CompanyRelation = "spelling" | "form" | "position" | "near";
31
+ /**
32
+ * 二つの書き方の違い。spelling は記号・幅・大小だけ、form は会社の形、position は形の語の側、near は名前の一字違い、ending は
33
+ * 名前の一語の終わりだけの違い(company-name-ending.ts)。
34
+ */
35
+ type CompanyRelation = "spelling" | "form" | "position" | "near" | "ending";
32
36
 
33
37
  type CompanyVariant = { readonly mention: CompanyMention; readonly usual: string; readonly kind: CompanyRelation };
34
38
 
@@ -82,6 +86,18 @@ const SPACES: ReadonlySet<string> = new Set([" ", "\u3000"]);
82
86
  */
83
87
  export type KanaStops = { readonly particles: readonly string[]; readonly openers: readonly string[]; readonly ends: readonly string[] };
84
88
 
89
+ /**
90
+ * 品詞解析が形容詞・動詞・助動詞と読んだ語の終わり(source の上の位置)。い で終わるひらがな(ながい、しおさい)は、ここで終わる
91
+ * なら名前の頭と読まない(ながい食品 の ながい)。名前の頭の い(しおさい の さい)は名詞と読まれる。
92
+ */
93
+ export type PredicateEnds = ReadonlySet<number>;
94
+
95
+ const NO_PREDICATE_ENDS: PredicateEnds = new Set();
96
+ const PREDICATE_TAIL = "い";
97
+
98
+ /** い で終わる名前の頭が、品詞解析の形容詞・動詞・助動詞の終わりか(ながい食品 の ながい)。 */
99
+ const isPredicateHead = (head: string, end: number, predicateEnds: PredicateEnds): boolean => head.endsWith(PREDICATE_TAIL) && predicateEnds.has(end);
100
+
85
101
  /** ひらがなの前に何があるか。word は語や閉じ括弧(当社はこもれび、)により)、form は会社の形の語(株式会社こもれび)、boundary は句読点や行の頭。 */
86
102
  export type KanaLead = "word" | "form" | "boundary";
87
103
 
@@ -117,26 +133,27 @@ const kanaRunStart = (source: string, end: number): number => {
117
133
  };
118
134
 
119
135
  /** 名前の前に続くひらがなのうち、名前の頭と読む所を足した始まり。 */
120
- const withKanaHead = (source: string, start: number, stops: KanaStops): number => {
136
+ const withKanaHead = (source: string, start: number, stops: KanaStops, predicateEnds: PredicateEnds): number => {
121
137
  const kanaStart = kanaRunStart(source, start);
122
138
  if (kanaStart === start) return start;
123
139
  const lead = GLUED.test(source.charAt(kanaStart - 1)) ? "word" : "boundary";
124
- return start - (kanaHeadOf(source.slice(kanaStart, start), lead, stops)?.length ?? 0);
140
+ const head = kanaHeadOf(source.slice(kanaStart, start), lead, stops);
141
+ return head === undefined || isPredicateHead(head, start, predicateEnds) ? start : start - head.length;
125
142
  };
126
143
 
127
144
  /** 漢字・かなの名前: 形の語の隣の、名前に使う字の続き。形の語との間の空白一つは名前の外。 */
128
- const cjkBaseBefore = (source: string, end: number, stops: KanaStops): Span | undefined => {
145
+ const cjkBaseBefore = (source: string, end: number, stops: KanaStops, predicateEnds: PredicateEnds): Span | undefined => {
129
146
  const stop = SPACES.has(source.charAt(end - 1)) ? end - 1 : end;
130
147
  const match = CJK_BEFORE.exec(source.slice(0, stop));
131
- return match === null ? undefined : { start: withKanaHead(source, match.index, stops), end: stop };
148
+ return match === null ? undefined : { start: withKanaHead(source, match.index, stops, predicateEnds), end: stop };
132
149
  };
133
150
 
134
151
  /** 形の語の後ろの名前。ひらがなで始まる名前(株式会社こもれび珈琲)は、ひらがなの後ろに名前に使う字が続くときだけ。 */
135
- const cjkBaseAfter = (source: string, start: number, stops: KanaStops): Span | undefined => {
152
+ const cjkBaseAfter = (source: string, start: number, stops: KanaStops, predicateEnds: PredicateEnds): Span | undefined => {
136
153
  const from = SPACES.has(source.charAt(start)) ? start + 1 : start;
137
154
  const kana = KANA_AFTER.exec(source.slice(from))?.[0] ?? "";
138
155
  const head = kana === "" ? "" : kanaHeadOf(kana, "form", stops);
139
- if (head === undefined) return undefined;
156
+ if (head === undefined || isPredicateHead(head, from + head.length, predicateEnds)) return undefined;
140
157
  const match = CJK_AFTER.exec(source.slice(from + head.length));
141
158
  return match === null ? undefined : { start: from, end: from + head.length + match[0].length };
142
159
  };
@@ -184,23 +201,36 @@ const foreignMentionAt = (source: string, form: CompanyForm, at: number, words:
184
201
  return { ...mentionOf(source, base, { start: at, end: at + form.pattern.length }, form.group), foreign: true };
185
202
  };
186
203
 
187
- const baseBefore = (source: string, at: number, latin: boolean, isProper: IsProper, stops: KanaStops): Span | undefined =>
188
- latin ? latinBaseBefore(source, at, isProper) : cjkBaseBefore(source, at, stops);
204
+ const baseBefore = (source: string, at: number, latin: boolean, isProper: IsProper, stops: KanaStops, predicateEnds: PredicateEnds): Span | undefined =>
205
+ latin ? latinBaseBefore(source, at, isProper) : cjkBaseBefore(source, at, stops, predicateEnds);
189
206
 
190
207
  /** 形の語の一つの現れから、会社の名前の現れ。名前が前にあればそれを、無ければ後ろを取る。 */
191
- const mentionAt = (source: string, form: CompanyForm, at: number, isProper: IsProper, stops: KanaStops): CompanyMention | undefined => {
208
+ const mentionAt = (
209
+ source: string,
210
+ form: CompanyForm,
211
+ at: number,
212
+ isProper: IsProper,
213
+ stops: KanaStops,
214
+ predicateEnds: PredicateEnds,
215
+ ): CompanyMention | undefined => {
192
216
  if (form.foreign !== undefined) return foreignMentionAt(source, form, at, form.foreign.words);
193
217
  const formSpan = { start: at, end: at + form.pattern.length };
194
218
  const latin = LATIN.test(form.pattern);
195
219
  if (latin && CONTINUED.test(source.slice(formSpan.end))) return undefined;
196
- const before = form.position === "before" ? undefined : baseBefore(source, at, latin, isProper, stops);
220
+ const before = form.position === "before" ? undefined : baseBefore(source, at, latin, isProper, stops, predicateEnds);
197
221
  if (before !== undefined && isNameBase(source, before, isProper)) return mentionOf(source, before, formSpan, form.group);
198
- const after = form.position === "after" || latin ? undefined : cjkBaseAfter(source, formSpan.end, stops);
222
+ const after = form.position === "after" || latin ? undefined : cjkBaseAfter(source, formSpan.end, stops, predicateEnds);
199
223
  return after !== undefined && isNameBase(source, after, isProper) ? mentionOf(source, after, formSpan, form.group) : undefined;
200
224
  };
201
225
 
202
226
  /** 文書の中の会社の名前の現れ。長い形の語(Co., Ltd)を先に取り、その中の短い語(Ltd)は数えない。 */
203
- export const companyMentionsIn = (source: string, forms: readonly CompanyForm[], isProper: IsProper, stops: KanaStops): CompanyMention[] => {
227
+ export const companyMentionsIn = (
228
+ source: string,
229
+ forms: readonly CompanyForm[],
230
+ isProper: IsProper,
231
+ stops: KanaStops,
232
+ predicateEnds: PredicateEnds = NO_PREDICATE_ENDS,
233
+ ): CompanyMention[] => {
204
234
  const taken: Span[] = [];
205
235
  return forms
206
236
  .toSorted((left, right) => right.pattern.length - left.pattern.length)
@@ -209,7 +239,7 @@ export const companyMentionsIn = (source: string, forms: readonly CompanyForm[],
209
239
  const end = at + form.pattern.length;
210
240
  if (!standsAsWord(source, form.pattern, at) || taken.some((span) => span.start < end && at < span.end)) return [];
211
241
  taken.push({ start: at, end });
212
- const mention = mentionAt(source, form, at, isProper, stops);
242
+ const mention = mentionAt(source, form, at, isProper, stops, predicateEnds);
213
243
  return mention === undefined ? [] : [mention];
214
244
  }),
215
245
  )
@@ -316,20 +346,46 @@ const talliesOf = (mentions: readonly CompanyMention[]): Tally[] => {
316
346
  /** 多いほうが先。同数なら先に書いたほう。 */
317
347
  const byUsage = (left: Tally, right: Tally): number => right.count - left.count || left.first.offset - right.first.offset;
318
348
 
319
- /** 短い名前のかなの一字違いは、別の会社のこともあるので、相手が二度以上、こちらが一度だけのときに限る。 */
349
+ /**
350
+ * 短い名前のかなの一字違いと、名前の一語の終わりだけの違い(Brightmoor と Brightmore、Water Utility と Water Utilities)は、別の
351
+ * 会社のこともあるので、形も側も同じで、相手が二度以上、こちらが一度だけのときに限る。
352
+ */
320
353
  const relationBetween = (tally: Tally, other: Tally): CompanyRelation | undefined => {
321
354
  const relation = companyRelation(tally.first, other.first);
322
355
  if (relation !== undefined || tally.count !== 1 || other.count < 2) return relation;
323
356
  const [left, right] = [tally.first, other.first];
324
- return left.form === right.form && left.position === right.position && isKanaWordSlip(nameKey(left.base), nameKey(right.base)) ? "near" : undefined;
357
+ if (left.form !== right.form || left.position !== right.position) return undefined;
358
+ if (isKanaWordSlip(nameKey(left.base), nameKey(right.base))) return "near";
359
+ return isNameEndingSlip(left.base, right.base) ? "ending" : undefined;
325
360
  };
326
361
 
327
- /** 同じ会社の、少ないほうの書き方。同じ会社と言える相手のうち一番多いものと比べる。書き方ごとに最初の現れを一つ。 */
362
+ /** 会社のグループと見る、同じ名前の部分に付く形の組の数。 */
363
+ const MIN_GROUP_FORMS = 3;
364
+
365
+ /**
366
+ * 三つ以上の形の組で書いた名前の部分(GitLab Inc、GitLab Ltd、GitLab GmbH)。国ごとの会社を並べたグループで、形の違いは別の会社を
367
+ * 言い分けている。比べる形(nameKey)で。
368
+ */
369
+ export const companyGroupBases = (mentions: readonly CompanyMention[]): Set<string> => {
370
+ const forms = new Map<string, Set<string>>();
371
+ mentions.forEach((mention) => {
372
+ const base = nameKey(mention.base);
373
+ forms.set(base, (forms.get(base) ?? new Set()).add(mention.form));
374
+ });
375
+ return new Set([...forms].flatMap(([base, groups]) => (groups.size >= MIN_GROUP_FORMS ? [base] : [])));
376
+ };
377
+
378
+ /** 同じ会社の、少ないほうの書き方。同じ会社と言える相手のうち一番多いものと比べる。会社のグループの形の違いは比べない。書き方ごとに最初の現れを一つ。 */
328
379
  export const companyVariants = (mentions: readonly CompanyMention[]): CompanyVariant[] => {
329
380
  const tallies = talliesOf(mentions);
381
+ const groups = companyGroupBases(mentions);
382
+ const relationOf = (tally: Tally, other: Tally): CompanyRelation | undefined => {
383
+ const relation = relationBetween(tally, other);
384
+ return relation === "form" && groups.has(nameKey(tally.first.base)) ? undefined : relation;
385
+ };
330
386
  return tallies.flatMap((tally) => {
331
- const [usual] = tallies.filter((other) => other === tally || relationBetween(tally, other) !== undefined).toSorted(byUsage);
332
- const kind = usual === undefined || usual === tally ? undefined : relationBetween(tally, usual);
387
+ const [usual] = tallies.filter((other) => other === tally || relationOf(tally, other) !== undefined).toSorted(byUsage);
388
+ const kind = usual === undefined || usual === tally ? undefined : relationOf(tally, usual);
333
389
  return usual === undefined || kind === undefined ? [] : [{ mention: tally.first, usual: usual.first.surface, kind }];
334
390
  });
335
391
  };
@@ -0,0 +1,2 @@
1
+ /** The variant of a words rule's finding whose word-list entry has no rewrite, so there is no spelling to offer. */
2
+ export const NO_REWRITE = "no-rewrite";
@@ -5,6 +5,7 @@ import { modulePathOf, type ModulePathRefusal } from "./module-path.ts";
5
5
  import type { FieldProblem } from "../rule-fields.ts";
6
6
  import { failed, ok, type Checked } from "./checked.ts";
7
7
  import { describedOf, exampleSides, levelsOf, type Described, type RuleLevels } from "./dsl-fields.ts";
8
+ import { NO_REWRITE } from "./no-rewrite.ts";
8
9
 
9
10
  // custom_rules in chaff.yaml: a team's own deterministic rules, written without code. Each becomes a RuleDefinition like the
10
11
  // built-in ones, so findings, explain, rules --json, stet, the baseline and SARIF treat it the same. Pure: the YAML comes in parsed.
@@ -198,13 +199,28 @@ const languagesOf = (raw: unknown, at: string): Checked<readonly string[] | unde
198
199
  return list.length > 0 && list.every(nonEmpty) ? ok(list.map((entry: string) => entry.trim())) : failed({ kind: "bad-languages", at });
199
200
  };
200
201
 
202
+ /** The rule's name and what was found: the message for a finding with no spelling to use. */
203
+ const namedMessage = (name: Localized): Localized =>
204
+ Object.fromEntries(Object.entries(name).map(([language, text]) => [language, language === "ja" ? `${text}:「{matched}」` : `${text}: "{matched}"`]));
205
+
201
206
  /** The message when a rule does not write one: the replacement for a word list, else the rule's name and what was found. */
202
207
  const defaultMessage = (spec: CustomSpec, name: Localized): Localized => {
203
208
  if (spec.type === "words" && spec.words.every((pair) => pair.use !== ""))
204
209
  return { ja: "「{matched}」は「{preferred}」と書きます", en: 'Write "{preferred}", not "{matched}"' };
205
- return Object.fromEntries(Object.entries(name).map(([language, text]) => [language, language === "ja" ? `${text}:「{matched}」` : `${text}: "{matched}"`]));
210
+ return namedMessage(name);
211
+ };
212
+
213
+ /** In each language, the rule's own message unless it offers {preferred}, else the named message. */
214
+ const noRewriteMessage = (written: Localized | undefined, name: Localized): Localized => {
215
+ const named = namedMessage(name);
216
+ if (written === undefined) return named;
217
+ return Object.fromEntries(Object.entries(written).map(([language, text]) => [language, text.includes("{preferred}") ? (named[language] ?? text) : text]));
206
218
  };
207
219
 
220
+ /** A word-list entry may have no rewrite: that finding must not offer an empty spelling. */
221
+ const defaultMessages = (spec: CustomSpec, written: Localized | undefined, name: Localized): Readonly<Record<string, Localized>> =>
222
+ spec.type === "words" ? { [NO_REWRITE]: noRewriteMessage(written, name) } : {};
223
+
208
224
  const PLACEHOLDERS: Readonly<Record<string, Localized>> = {
209
225
  matched: { ja: "見つけた語句", en: "the text found" },
210
226
  preferred: { ja: "使う書き方", en: "the spelling to use" },
@@ -249,7 +265,7 @@ const definitionOf = (id: string, raw: Record<string, unknown>, parts: Parts, us
249
265
  why: parts.texts.why,
250
266
  how_to_fix: parts.texts.how_to_fix,
251
267
  message: localizedOf(raw["message"]) ?? defaultMessage(parts.spec, parts.texts.name),
252
- messages: {},
268
+ messages: defaultMessages(parts.spec, localizedOf(raw["message"]), parts.texts.name),
253
269
  placeholders: PLACEHOLDERS,
254
270
  levels: parts.levels.table,
255
271
  level_sets: "severity",
@@ -1,14 +1,15 @@
1
- import { escapeRegExp } from "../orthography.ts";
2
1
  import { ROMAN_NUMERAL, romanRangeOf } from "./roman-numeral.ts";
3
2
  import { citationKeySpans } from "./citation-key.ts";
4
3
  import { dottedNameSpans } from "./dotted-name.ts";
5
4
  import { letterJoinedNameSpans } from "./letter-joined-name.ts";
6
5
  import { loneNumeralSpans, nameNumeralSpans } from "./name-numeral.ts";
7
6
  import { placeholderSpans } from "./placeholder.ts";
7
+ import { numeralWordSpans } from "./numeral-word.ts";
8
8
  import { seriesLabelSpans } from "./series-label.ts";
9
+ import { oneOf } from "./acronym-name.ts";
9
10
 
10
11
  /**
11
- * 大文字の語が略語ではなく、決まった書き方の一部として読める所(3:30 PM、1pm ET、USD 1,000、Kansas City, MO 64108)。
12
+ * 大文字の語が略語ではなく、決まった書き方の一部として読める所(3:30 PM、1pm ET、USD 1,000、Kansas City, MO 64108、Fort Lauderdale FL 33304)。
12
13
  * どれも閉じた集合で、しかも隣の数字(州は地名でもよい)があるときだけ認める。PM(project manager)、CT、CA(certificate authority)は
13
14
  * その隣でなければ略語のまま数える。語は言語パッケージの語彙表から読み、書き方の組み立てだけをここに置く。
14
15
  */
@@ -34,9 +35,6 @@ export type NotationWords = {
34
35
  readonly dateTimeUnits: readonly string[];
35
36
  };
36
37
 
37
- // 空の語彙表は「その書き方が無い」。空の選択肢 (?:) は至る所で空文字に当たるので、何にも当たらない形にする。
38
- const oneOf = (words: readonly string[]): string => (words.length === 0 ? "(?!)" : `(?:${words.map(escapeRegExp).join("|")})`);
39
-
40
38
  const MINUTES = String.raw`:[0-5]\d`;
41
39
  const CLOCK_12 = String.raw`(?<![\d:.])(?:1[0-2]|0?[1-9])(?:${MINUTES})?`;
42
40
  const CLOCK_24 = String.raw`(?<![\d:.])(?:[01]?\d|2[0-3])${MINUTES}`;
@@ -88,7 +86,7 @@ const patternsOf = (words: NotationWords): readonly RegExp[] => [
88
86
  new RegExp(String.raw`(?:${CLOCK_24}|${CLOCK_12}\s*${ANY_MERIDIEM})\s*${oneOf(words.timeZones)}`, "gu"),
89
87
  new RegExp(String.raw`${oneOf(words.currencies)}\s*[$€£¥]?${AMOUNT}`, "gu"),
90
88
  new RegExp(String.raw`(?<![\w.,])${AMOUNT}\s*${oneOf(words.currencies)}`, "gu"),
91
- new RegExp(String.raw`,\s+${oneOf(words.usStates)}\s+\d{5}(?:-\d{4})?(?!\d)`, "gu"),
89
+ new RegExp(String.raw`(?:,\s+|(?<=(?<!\p{L})\p{Lu}\p{Ll}+)\s+)${oneOf(words.usStates)}\s+\d{5}(?:-\d{4})?(?!\d)`, "gu"),
92
90
  placeAndState(oneOf(words.usStates)),
93
91
  new RegExp(oneOf(words.emphasis), "gu"),
94
92
  ...numberedPatterns(words),
@@ -113,5 +111,6 @@ export const notAcronymSpansOf = (words: NotationWords): NotAcronymSpans => {
113
111
  ...loneNumeralSpans(text),
114
112
  ...seriesLabelSpans(text),
115
113
  ...placeholderSpans(text, words.dateTimeUnits),
114
+ ...numeralWordSpans(text),
116
115
  ];
117
116
  };