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
package/src/grade/text.ts CHANGED
@@ -11,7 +11,11 @@ export type GradeText = {
11
11
  readonly contextsUnread: (kind: string, reason: string) => string;
12
12
  readonly uncheckedSentences: (count: number) => string;
13
13
  readonly unknownRule: string;
14
- readonly rubricProblem: (problem: RubricProblem) => string;
14
+ /** A problem under chaff.yaml's `grade:`, or, given `file`, under a --rubric file's top level. */
15
+ readonly rubricProblem: (problem: RubricProblem, file?: string) => string;
16
+ /** A --rubric file whose extension is none of .yaml, .yml, .json. */
17
+ readonly rubricFormat: (file: string) => string;
18
+ readonly rubricSyntax: (file: string, why: string) => string;
15
19
  readonly penalty: (total: number) => string;
16
20
  /** The outputs at each level of the AI-likeness quick score. */
17
21
  readonly aiScore: (low: number, medium: number, high: number, notScored: number) => string;
@@ -55,6 +59,12 @@ const PROBLEM_JA: Readonly<Record<ItemProblemKind, (problem: ItemProblem) => str
55
59
  "which-source": (problem) => `${lineJa(problem)}番地 ${problem.detail ?? ""} の引用に source がありません。原文が二つ以上あるときは名前を書いてください`,
56
60
  "unknown-language": (problem) => `${lineJa(problem)}language "${problem.detail ?? ""}" は読めません`,
57
61
  "unknown-genre": (problem) => `${lineJa(problem)}genre "${problem.detail ?? ""}" は chaff の知らないジャンルです(chaff genres で一覧)`,
62
+ "not-expect": (problem) => `${lineJa(problem)}${problem.detail ?? ""} は { "facts": ["…"], "absent": ["…"] } の形で、空でない文字列の並びを書いてください`,
63
+ "expect-no-fact": (problem) =>
64
+ `${lineJa(problem)}${problem.detail ?? ""} から事実を読めません(数・日付・時刻・URL・コード・名前・引用のどれか 1 つを書いてください)`,
65
+ "expect-several-facts": (problem) =>
66
+ `${lineJa(problem)}${problem.detail ?? ""} は事実を 2 つ以上含みます(compare が 1 つの事実と読む書き方で、1 項目に 1 つ書いてください)`,
67
+ "unknown-task": (problem) => `${lineJa(problem)}task "${problem.detail ?? ""}" は採点基準の tasks にありません`,
58
68
  empty: () => "採点する出力が 1 行もありません",
59
69
  };
60
70
 
@@ -74,6 +84,12 @@ const PROBLEM_EN: typeof PROBLEM_JA = {
74
84
  "which-source": (problem) => `${lineEn(problem)}the citation of ${problem.detail ?? ""} names no source; with two or more sources, name one`,
75
85
  "unknown-language": (problem) => `${lineEn(problem)}language "${problem.detail ?? ""}" cannot be read`,
76
86
  "unknown-genre": (problem) => `${lineEn(problem)}genre "${problem.detail ?? ""}" is not one chaff knows (chaff genres lists them)`,
87
+ "not-expect": (problem) => `${lineEn(problem)}${problem.detail ?? ""} must be { "facts": ["…"], "absent": ["…"] } with non-empty strings`,
88
+ "expect-no-fact": (problem) =>
89
+ `${lineEn(problem)}${problem.detail ?? ""} states no fact chaff can read (write one number, date, time, URL, code, name or quotation)`,
90
+ "expect-several-facts": (problem) =>
91
+ `${lineEn(problem)}${problem.detail ?? ""} states more than one fact (write one per entry, in a form compare reads as one fact)`,
92
+ "unknown-task": (problem) => `${lineEn(problem)}task "${problem.detail ?? ""}" is not among the rubric's tasks`,
77
93
  empty: () => "no output to grade: the file has no item",
78
94
  };
79
95
 
@@ -103,14 +119,17 @@ const aside = (open: string, inner: string, close: string): string => (inner ===
103
119
  export const GRADE_TEXT: Texts<GradeText> = {
104
120
  ja: {
105
121
  usage:
106
- "使い方: chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <前の results.jsonl>] [--allow-stamp-mismatch] [--variant-key <欄の名前>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <ジャンル>]",
122
+ "使い方: chaff grade <items.jsonl> [--rubric <rubric.yaml|.json>] [--out <results.jsonl>] [--baseline <前の results.jsonl>] [--allow-stamp-mismatch] [--variant-key <欄の名前>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <ジャンル>]",
107
123
  noReference: "reference が無い(事実は reference と照らす)",
108
124
  noCitations: "citations が無い(chaff は出力から引用を推測しない)",
109
125
  noContexts: "contexts が無い(回答の事実は、検索で取った一節と照らす)",
110
126
  contextsUnread: (kind, reason) => `contexts と照らすとき、${kind} を読み切れなかった(${reason})。その種類の事実は、一節にあっても見つからないことがある`,
111
127
  uncheckedSentences: (count) => `数・日付・名前・引用の無い文 ${String(count)} 件は、contexts に支えられているかを照らしていない(意味を読む必要がある)`,
112
128
  unknownRule: "grade: に書かれているが、chaff の知らないルール",
113
- rubricProblem: (problem) => `chaff.yaml の ${problem.path} は${EXPECTED_JA[problem.expected]}で書いてください(書かれていたのは ${problem.written})`,
129
+ rubricProblem: (problem, file) =>
130
+ `${file ?? "chaff.yaml"} の ${problem.path === "" ? "最上位" : problem.path} は${EXPECTED_JA[problem.expected]}で書いてください(書かれていたのは ${problem.written})`,
131
+ rubricFormat: (file) => `${file}: --rubric のファイルは .yaml・.yml・.json のどれかにしてください`,
132
+ rubricSyntax: (file, why) => `${file} を採点の基準として読めませんでした: ${why}`,
114
133
  penalty: (total) => `減点の和: ${String(total)}`,
115
134
  aiScore: (low, medium, high, notScored) =>
116
135
  `AI らしさ: 低 ${String(low)}、中 ${String(medium)}、高 ${String(high)}、測っていない ${String(notScored)}(書いたのが AI かどうかの判定ではありません。合否には入りません)`,
@@ -135,7 +154,7 @@ export const GRADE_TEXT: Texts<GradeText> = {
135
154
  },
136
155
  en: {
137
156
  usage:
138
- "usage: chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <earlier results.jsonl>] [--allow-stamp-mismatch] [--variant-key <field>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <genre>]",
157
+ "usage: chaff grade <items.jsonl> [--rubric <rubric.yaml|.json>] [--out <results.jsonl>] [--baseline <earlier results.jsonl>] [--allow-stamp-mismatch] [--variant-key <field>] [--format text|json|markdown] [--json] [--compact] [--experimental] [--genre <genre>]",
139
158
  noReference: "no reference given (facts are checked against a reference)",
140
159
  noCitations: "no citations given (chaff does not guess quotations from the output)",
141
160
  noContexts: "no contexts given (the output's facts are checked against retrieved passages)",
@@ -144,7 +163,10 @@ export const GRADE_TEXT: Texts<GradeText> = {
144
163
  uncheckedSentences: (count) =>
145
164
  `${String(count)} ${count === 1 ? "sentence states" : "sentences state"} no number, date, name or quotation, so their support by contexts is not checked (it needs reading)`,
146
165
  unknownRule: "named under grade: but not a rule chaff knows",
147
- rubricProblem: (problem) => `chaff.yaml: ${problem.path} must be ${EXPECTED_EN[problem.expected]} (found ${problem.written})`,
166
+ rubricProblem: (problem, file) =>
167
+ `${file ?? "chaff.yaml"}: ${problem.path === "" ? "the top level" : problem.path} must be ${EXPECTED_EN[problem.expected]} (found ${problem.written})`,
168
+ rubricFormat: (file) => `${file}: a --rubric file must end in .yaml, .yml or .json`,
169
+ rubricSyntax: (file, why) => `Could not read ${file} as a rubric: ${why}`,
148
170
  penalty: (total) => `Penalty points: ${String(total)}`,
149
171
  aiScore: (low, medium, high, notScored) =>
150
172
  `AI-likeness: low ${String(low)}, medium ${String(medium)}, high ${String(high)}, not scored ${String(notScored)} (not a verdict on whether AI wrote them; not part of pass or fail)`,
package/src/grade-api.ts CHANGED
@@ -11,10 +11,13 @@ import { withStyle } from "./config/style.ts";
11
11
  import { withExtensions } from "./extension/load.ts";
12
12
  import { GENRES } from "./genre.ts";
13
13
  import { gradeItem, type GradeSetup } from "./grade/grade-item.ts";
14
- import { readItem } from "./grade/item.ts";
14
+ import { expectProblems } from "./grade/expect-read.ts";
15
+ import type { GradeExpect } from "./grade/expect.ts";
16
+ import { readItem, type GradeItem } from "./grade/item.ts";
15
17
  import type { GradeResult } from "./grade/result.ts";
16
18
  import { parseRubric, type Rubric } from "./grade/rubric.ts";
17
19
  import { gradeSetup } from "./grade/setup.ts";
20
+ import { taskNamesOf } from "./grade/task-rubric.ts";
18
21
  import { GRADE_TEXT } from "./grade/text.ts";
19
22
  import { compareVariantGroups, type VariantComparison } from "./grade/variants.ts";
20
23
  import { variantGroupsOf, type VariantInput } from "./grade/variants-input.ts";
@@ -36,6 +39,7 @@ export type {
36
39
  SupportedFact,
37
40
  } from "./grade/result.ts";
38
41
  export type { OutputSize } from "./grade/rates.ts";
42
+ export type { GradeExpect } from "./grade/expect.ts";
39
43
  export type { AiLevelCounts, GradeAiScore } from "./grade/ai-score.ts";
40
44
  export { toScorer, type ChaffScore } from "./grade/scorer.ts";
41
45
  export type { Disagreement, VariantColumn, VariantComparison, VariantRates } from "./grade/variants.ts";
@@ -56,6 +60,10 @@ export type GradeOptions = {
56
60
  readonly genre?: string;
57
61
  /** The prompt, model or setting that produced the output, kept on the result for compareVariants(). */
58
62
  readonly variant?: string;
63
+ /** The rubric task to grade under: one of chaff.yaml's `grade.tasks`. The top-level rubric when left out. */
64
+ readonly task?: string;
65
+ /** Facts the output must state (`facts`) and must not (`absent`), each one fact as `chaff compare` reads it. */
66
+ readonly expect?: Partial<GradeExpect>;
59
67
  /** Run the experimental rules too, as --experimental does. chaff.yaml's `experimental` when left out. */
60
68
  readonly experimental?: boolean;
61
69
  /** chaff.yaml's path, or settings already read. Without it chaff's defaults apply and no file is read. */
@@ -125,36 +133,32 @@ const rubricOf = (config: Config): Rubric | undefined => {
125
133
  */
126
134
  const setups = new WeakMap<Config, Map<string, Promise<GradeSetup>>>();
127
135
 
128
- const setupFor = (config: Config, experimental: boolean, languages: readonly string[]): Promise<GradeSetup> => {
136
+ const setupFor = (config: Config, rubric: Rubric | undefined, experimental: boolean, languages: readonly string[]): Promise<GradeSetup> => {
129
137
  const run = { experimental, genre: undefined };
130
138
  const own = setups.get(config) ?? new Map<string, Promise<GradeSetup>>();
131
139
  setups.set(config, own);
132
- const key = `${String(experimental)}\n${languages.join(",")}`;
140
+ // The rubric is in the key: an item's task was checked against this rubric, so the setup must grade by the same one.
141
+ const key = `${String(experimental)}\n${languages.join(",")}\n${JSON.stringify(rubric) ?? ""}`;
133
142
  const known = own.get(key);
134
143
  if (known !== undefined) return known;
135
- const made = remember(own, key, gradeSetup(config, run, languages, rubricOf(config)));
144
+ const made = remember(own, key, gradeSetup(config, run, languages, rubric));
136
145
  // A language package that failed to load may be installed before the next call: do not keep the failure.
137
146
  made.catch(() => own.delete(key));
138
147
  return made;
139
148
  };
140
149
 
141
150
  /** The setup, or GradeInputError when a language package cannot be loaded, as `chaff grade` ends with 2 then. */
142
- const loadedSetup = async (config: Config, experimental: boolean, languages: readonly string[]): Promise<GradeSetup> => {
151
+ const loadedSetup = async (config: Config, rubric: Rubric | undefined, experimental: boolean, languages: readonly string[]): Promise<GradeSetup> => {
143
152
  try {
144
- return await setupFor(config, experimental, languages);
153
+ return await setupFor(config, rubric, experimental, languages);
145
154
  } catch (error) {
146
155
  if (error instanceof GradeInputError) throw error;
147
156
  throw new GradeInputError([TEXT.cannotLoad(error instanceof Error ? error.message : String(error))]);
148
157
  }
149
158
  };
150
159
 
151
- /**
152
- * Grades one output (spec §29.6): its findings and rates, its facts against `reference`, its `citations` against
153
- * `sources`, and pass or fail by chaff.yaml's `grade:` or the default. Reads a file only when `config` is a path, and
154
- * never writes one. Throws GradeInputError for an input or a chaff.yaml `chaff grade` would refuse with exit 2.
155
- */
156
- export const grade = async (output: string, options: GradeOptions = {}): Promise<GradeResult> => {
157
- const config = await configOf(options.config);
160
+ /** The options read as one line of `chaff grade`'s input, refused as that line would be. `tasks`: those the rubric defines. */
161
+ const itemOf = (output: string, options: GradeOptions, tasks: readonly string[]): GradeItem => {
158
162
  const raw = {
159
163
  id: options.id ?? "output",
160
164
  output,
@@ -165,11 +169,29 @@ export const grade = async (output: string, options: GradeOptions = {}): Promise
165
169
  language: options.language,
166
170
  genre: options.genre,
167
171
  variant: options.variant,
172
+ task: options.task,
173
+ expect: options.expect,
168
174
  };
169
- const read = readItem(raw, { isLanguage: (language) => packageFor(language) !== undefined, genres: GENRES });
175
+ const read = readItem(raw, { isLanguage: (language) => packageFor(language) !== undefined, genres: GENRES, tasks });
170
176
  if ("problem" in read) throw new GradeInputError([TEXT.problem(read.problem)]);
171
- const languages = read.item.language === undefined ? [] : [read.item.language];
172
- return gradeItem(read.item, await loadedSetup(config, options.experimental ?? config.experimental, languages));
177
+ return read.item;
178
+ };
179
+
180
+ /**
181
+ * Grades one output (spec §29.6): its findings and rates, its facts against `reference`, its `citations` against
182
+ * `sources`, its `expect` facts, and pass or fail by chaff.yaml's `grade:` (its `task`'s rubric when named) or the
183
+ * default. Reads a file only when `config` is a path, and never writes one. Throws GradeInputError for an input or a
184
+ * chaff.yaml `chaff grade` would refuse with exit 2, an unknown `task` or an `expect` entry that is not one fact among them.
185
+ */
186
+ export const grade = async (output: string, options: GradeOptions = {}): Promise<GradeResult> => {
187
+ const config = await configOf(options.config);
188
+ const rubric = rubricOf(config);
189
+ const item = itemOf(output, options, taskNamesOf(rubric));
190
+ const languages = item.language === undefined ? [] : [item.language];
191
+ const setup = await loadedSetup(config, rubric, options.experimental ?? config.experimental, languages);
192
+ const problems = await expectProblems(item, 0, setup);
193
+ if (problems.length > 0) throw new GradeInputError(problems.map((problem) => TEXT.problem(problem)));
194
+ return gradeItem(item, setup);
173
195
  };
174
196
 
175
197
  /**
@@ -41,16 +41,31 @@ const labelPattern = (label: NumberLabel): RegExp =>
41
41
  /** 見出しの頭の強調の印と空白。「**1. 概要**」も「1. 概要」と読む。 */
42
42
  const LEAD = /^[\s*_]+/u;
43
43
 
44
- /** 見出しの言葉から、番号の書き方を読む。番号を持つ語(第1章)を先に、字だけの形(1.)を後に見る。 */
45
- export const numberingStyleOf = (heading: string, labels: readonly NumberLabel[]): string => {
44
+ type NumberMark = { readonly style: string; readonly mark: string };
45
+
46
+ const markOf = (heading: string, labels: readonly NumberLabel[]): NumberMark => {
46
47
  const text = heading.replace(LEAD, "");
47
48
  const label = labels.find((candidate) => labelPattern(candidate).test(text));
48
- if (label !== undefined) return `label:${label.word.toLowerCase()}`;
49
- return SHAPES.find(([, shape]) => shape.test(text))?.[0] ?? UNNUMBERED;
49
+ if (label !== undefined) return { style: `label:${label.word.toLowerCase()}`, mark: labelPattern(label).exec(text)?.[0] ?? "" };
50
+ const shape = SHAPES.find(([, pattern]) => pattern.test(text));
51
+ return shape === undefined ? { style: UNNUMBERED, mark: "" } : { style: shape[0], mark: shape[1].exec(text)?.[0] ?? "" };
52
+ };
53
+
54
+ /** 見出しの言葉から、番号の書き方を読む。番号を持つ語(第1章)を先に、字だけの形(1.)を後に見る。 */
55
+ export const numberingStyleOf = (heading: string, labels: readonly NumberLabel[]): string => markOf(heading, labels).style;
56
+
57
+ /** 番号の中の数の一つ一つ(「7.1」の 7 と 1、「Chapter II」の II)。番号は印の最後に来るので、語の頭の大文字(Chapter の C)は最後にならない。 */
58
+ const NUMBER_TOKEN = /[0-90-9]+|[A-ZⅠ-Ⅻ①-⑳一二三四五六七八九十百]+/gu;
59
+ const FIRST_NUMBERS: ReadonlySet<string> = new Set(["1", "1", "I", "Ⅰ", "A", "①", "一"]);
60
+
61
+ /** 番号が並びの最初(1.、1.1、第1章、A.、①)か。最後の数が最初の数のときで、番号の無い見出しは並びを始めない。 */
62
+ export const opensNumbering = (heading: string, labels: readonly NumberLabel[]): boolean => {
63
+ const last = markOf(heading, labels).mark.match(NUMBER_TOKEN)?.at(-1);
64
+ return last !== undefined && FIRST_NUMBERS.has(last);
50
65
  };
51
66
 
52
- /** 見出し 1 つ。depth は深さ(#の数)、style は番号の書き方、skipped は番号を付けない前後の見出し(目次・参考文献)。 */
53
- export type NumberedHeading = { readonly depth: number; readonly style: string; readonly skipped: boolean };
67
+ /** 見出し 1 つ。depth は深さ(#の数)、style は番号の書き方、skipped は番号を付けない前後の見出し(目次・参考文献)、opens は番号が 1 から始まるか。 */
68
+ export type NumberedHeading = { readonly depth: number; readonly style: string; readonly skipped: boolean; readonly opens: boolean };
54
69
 
55
70
  /** 親(直前の浅い見出し)と深さが同じ見出しの組。番号は兄弟の見出しのあいだで揃える。位置は渡した並びの添え字。 */
56
71
  export const siblingGroups = (headings: readonly NumberedHeading[]): number[][] => {
@@ -87,13 +102,25 @@ const minorityBy = (members: readonly number[], keyOf: (at: number) => string):
87
102
  const minoritiesOf = (split: Split | undefined, kind: NumberingMinority["kind"]): NumberingMinority[] =>
88
103
  split === undefined ? [] : split.minority.map((at) => ({ at, kind, majority: split.majority, count: split.count, example: split.example }));
89
104
 
105
+ /** 番号の並びの最初の兄弟が 1 から始まるとき、その前の番号の無い兄弟(文書の題、「Applies to England」)は並びの外。番号付きの兄弟が二つ以上あるときだけ。 */
106
+ const MIN_NUMBERED_RUN = 2;
107
+
108
+ const leadingFrontMatter = (members: readonly number[], headings: readonly NumberedHeading[]): ReadonlySet<number> => {
109
+ const numbered = members.filter((at) => (headings[at]?.style ?? UNNUMBERED) !== UNNUMBERED);
110
+ const first = numbered[0];
111
+ if (first === undefined || numbered.length < MIN_NUMBERED_RUN || headings[first]?.opens !== true) return new Set();
112
+ return new Set(members.filter((at) => at < first));
113
+ };
114
+
90
115
  /**
91
116
  * 兄弟の見出しのうち、少ないほうの書き方のもの。先に番号の有無を比べ(「1. 概要」「2. 手順」「まとめ」の「まとめ」)、
92
- * 番号の付いた見出しのあいだで書き方を比べる(「1.」「2.」「3)」の「3)」)。同じ数なら言わない(二つだけの兄弟は必ず同じ数か一つの書き方)。前後の見出し(目次・参考文献)は数えない。
117
+ * 番号の付いた見出しのあいだで書き方を比べる(「1.」「2.」「3)」の「3)」)。同じ数なら言わない(二つだけの兄弟は必ず同じ数か一つの書き方)。前後の見出し(目次・参考文献)と、1 から始まる番号の前の見出しは数えない。
93
118
  */
94
119
  export const numberingMinorities = (headings: readonly NumberedHeading[]): NumberingMinority[] =>
95
120
  siblingGroups(headings).flatMap((group) => {
96
- const members = group.filter((at) => headings[at]?.skipped !== true);
121
+ const listed = group.filter((at) => headings[at]?.skipped !== true);
122
+ const front = leadingFrontMatter(listed, headings);
123
+ const members = listed.filter((at) => !front.has(at));
97
124
  const styleOf = (at: number): string => headings[at]?.style ?? UNNUMBERED;
98
125
  const numbered = members.filter((at) => styleOf(at) !== UNNUMBERED);
99
126
  return [
@@ -22,3 +22,19 @@ export const readingOfWords = (words: readonly ReadToken[], chars: CharReadings)
22
22
  const readings = words.map((token) => tokenReadingOf(token, chars));
23
23
  return words.length > 0 && readings.every(isRead) ? readings.join("") : undefined;
24
24
  };
25
+
26
+ /** 名の字の読みで読み直す、名の字数の下限。一字の名(太 を フトシ)は、二字の名の中の読み(健太 の タ)で読まない。 */
27
+ const MIN_GIVEN_LETTERS = 2;
28
+
29
+ /**
30
+ * 名をもう一通りに読んだもの。解析器は名を別の読みに切ることがある(建太 を タテ と フトシ)。字がどれも givenChars(名の中での
31
+ * 字の読み)にある語はその字の読みをつなぎ、ほかの語は tokenReadingOf で読む。一字の名と、読めない語のある名は読まない。
32
+ */
33
+ export const givenNameReadingOf = (words: readonly ReadToken[], givenChars: CharReadings, chars: CharReadings): string | undefined => {
34
+ if (words.reduce((letters, token) => letters + [...token.surface].length, 0) < MIN_GIVEN_LETTERS) return undefined;
35
+ const readings = words.map((token) => {
36
+ const letters = [...token.surface].map((letter) => givenChars.get(letter));
37
+ return letters.length > 0 && letters.every(isRead) ? letters.join("") : tokenReadingOf(token, chars);
38
+ });
39
+ return readings.every(isRead) ? readings.join("") : undefined;
40
+ };
@@ -0,0 +1,61 @@
1
+ // 名前の語の終わりの一字の抜けか足し(Whitmore と Whitmor、Hollybrook と Hollybrooke)。ふつうの語なら語の形の違い
2
+ // (Service と Services、America と American)なので、どちらも名前にしか使わない語に限る。
3
+
4
+ const LATIN_WORD = /^[a-z]+$/u;
5
+ const VOWEL = /[aeiouy]$/u;
6
+
7
+ /** 足すと別の語の形になる字。s は複数と所有(Rental と Rentals)。 */
8
+ const PLURAL_LETTER = "s";
9
+ /** 母音で終わる語に足すと、その土地の人や言葉の語になる字(Korea と Korean、Rica と Rican)。 */
10
+ const DEMONYM_LETTER = "n";
11
+
12
+ /** 比べる語の長さ。三字の語(Ann と Anne)は別の名前のことが多い。 */
13
+ const MIN_END_LETTER_LENGTH = 4;
14
+ /** 終わりの一字の抜けか足しを、名前の最後でない語で見る長さ(Hollybrook と Hollybrooke)。 */
15
+ const MIN_END_SLIP_ANYWHERE = 8;
16
+
17
+ const isFormLetter = (shorter: string, added: string): boolean => added === PLURAL_LETTER || (added === DEMONYM_LETTER && VOWEL.test(shorter));
18
+
19
+ /** 二つの英字の語が、終わりの一字の抜けか足しだけ違うか。足した字が語の形を作る字(s、母音の後ろの n)なら違うと見ない。 */
20
+ export const isEndLetterApart = (left: string, right: string): boolean => {
21
+ const [shorter, longer] = left.length < right.length ? [left, right] : [right, left];
22
+ if (!LATIN_WORD.test(shorter) || !LATIN_WORD.test(longer) || shorter.length < MIN_END_LETTER_LENGTH) return false;
23
+ return longer.length === shorter.length + 1 && longer.startsWith(shorter) && !isFormLetter(shorter, longer.slice(shorter.length));
24
+ };
25
+
26
+ /**
27
+ * 文書での語の使い方(小文字で)。ordinary は名前と読んだ語のうち小文字で書けばふつうの語(Rental、Green)、common は文書が
28
+ * 小文字で書くか、品詞解析が普通名詞と読む語(hurricane、lake)。
29
+ */
30
+ export type WordUse = { readonly ordinary: ReadonlySet<string>; readonly common: ReadonlySet<string> };
31
+
32
+ export const NO_WORD_USE: WordUse = { ordinary: new Set(), common: new Set() };
33
+
34
+ /**
35
+ * 終わりの重なった字の一つの抜け(Licensee と License、Bennett と Bennet)で、どちらかを文書が小文字か普通名詞で書く(license)。
36
+ * 語の終わりの抜けと同じく、語の形の違い(License と、その許諾を受ける Licensee)。
37
+ */
38
+ export const isWordFormOf = (left: string, right: string, use: WordUse): boolean => {
39
+ const [longer, shorter] = left.length > right.length ? [left, right] : [right, left];
40
+ return longer.slice(0, -1) === shorter && (use.common.has(longer) || use.common.has(shorter));
41
+ };
42
+
43
+ /**
44
+ * 名前の語(words、小文字)の at の語を usual と書いた名前があるとき、その違いを書き損じと見るか。違う語が最後の語(姓)なら、
45
+ * 終わりの一字の抜けか足しか、四字以上の一字違い(oneLetterApart)で、前の語がどれも文書の中で普通名詞として書かない語(Rachel、Mr)
46
+ * のとき。Hurricane Hanna と Hurricane Hannah は名前の違う二つの嵐。最後でない語なら、八字以上の終わりの一字の抜けか足しで、名前の
47
+ * 最後の語がふつうの語(Residences、Products)のとき。人の名の終わりの一字だけ違う名前(Christian と Christiane)は別の人のことが多い。
48
+ */
49
+ export const isEndWordSlip = (
50
+ words: readonly string[],
51
+ at: number,
52
+ usual: string,
53
+ use: WordUse,
54
+ oneLetterApart: (left: string, right: string) => boolean,
55
+ ): boolean => {
56
+ const word = words[at] ?? "";
57
+ const shorter = Math.min(word.length, usual.length);
58
+ if (at < words.length - 1) return shorter >= MIN_END_SLIP_ANYWHERE && use.ordinary.has(words.at(-1) ?? "") && isEndLetterApart(word, usual);
59
+ if (words.slice(0, at).some((before) => use.common.has(before))) return false;
60
+ return isEndLetterApart(word, usual) || (shorter >= MIN_END_LETTER_LENGTH && oneLetterApart(word, usual));
61
+ };
@@ -0,0 +1,40 @@
1
+ import type { Token } from "./plugin.ts";
2
+
3
+ // 姓のすぐ前に書いた名(Jeffrey D. Walker の Jeffrey)。名の違う二人(Jeffrey D. Walker と Christopher J. Waller)は、姓が一字違いでも
4
+ // 別の人で、書き損じではない。
5
+
6
+ const GIVEN_NAME = /^\p{Lu}\p{Ll}+$/u;
7
+ const INITIAL = /^\p{Lu}$/u;
8
+ const NEWLINE = /\n/u;
9
+
10
+ const isInitial = (token: Token | undefined): boolean => INITIAL.test(token?.surface ?? "");
11
+
12
+ /** 名と名前のあいだの頭文字(D.、D)を飛ばした、名の語の添字。 */
13
+ const givenIndexOf = (tokens: readonly Token[], index: number): number => {
14
+ if (tokens[index - 1]?.surface === "." && isInitial(tokens[index - 2])) return index - 3;
15
+ return isInitial(tokens[index - 1]) ? index - 2 : index - 1;
16
+ };
17
+
18
+ /** 名前の書き方ごとの、すぐ前に書いた名のすべて。 */
19
+ export type GivenNames = ReadonlyMap<string, readonly string[]>;
20
+
21
+ export const givenNamesBySurface = (mentions: readonly { readonly surface: string; readonly givenName?: string | undefined }[]): GivenNames =>
22
+ mentions.reduce((names, { surface, givenName }) => {
23
+ const known = names.get(surface) ?? [];
24
+ return givenName === undefined || known.includes(givenName) ? names : names.set(surface, [...known, givenName]);
25
+ }, new Map<string, string[]>());
26
+
27
+ /** どちらの書き方にも名前のすぐ前の名があり、一つも同じでない(Jeffrey D. Walker と Christopher J. Waller)。別の人。 */
28
+ export const areOtherPeople = (left: readonly string[] = [], right: readonly string[] = []): boolean =>
29
+ left.length > 0 && right.length > 0 && !left.some((name) => right.includes(name));
30
+
31
+ /**
32
+ * tokens[index] で始まる名前のすぐ前の名。解析器が固有名詞と読んだ、大文字一字に小文字の続く語で、あいだに頭文字一つを挟んでよい。
33
+ * 行を越えては読まない(一行に一人ずつ並べた出席者の名簿)。
34
+ */
35
+ export const givenNameBefore = (tokens: readonly Token[], index: number, source: string): string | undefined => {
36
+ const name = tokens[index];
37
+ const given = tokens[givenIndexOf(tokens, index)];
38
+ if (name === undefined || given === undefined || given.pos !== "PROPN" || !GIVEN_NAME.test(given.surface)) return undefined;
39
+ return NEWLINE.test(source.slice(given.span.end, name.span.start)) ? undefined : given.surface;
40
+ };
@@ -47,11 +47,12 @@ export const withKnownNeighbours = (mentions: readonly NameMention[], source: st
47
47
  surface: `${before} ${mention.surface}`,
48
48
  offset: mention.offset - 1 - before.length,
49
49
  reading: undefined,
50
+ givenNameReading: undefined,
50
51
  words: [before, ...mention.words],
51
52
  };
52
53
  }
53
54
  if (after !== undefined && known.has(`${mention.surface} ${after}`) && !taken(end + 1, end + 1 + after.length)) {
54
- return { ...mention, surface: `${mention.surface} ${after}`, reading: undefined, words: [...mention.words, after] };
55
+ return { ...mention, surface: `${mention.surface} ${after}`, reading: undefined, givenNameReading: undefined, words: [...mention.words, after] };
55
56
  }
56
57
  return mention;
57
58
  });
@@ -34,6 +34,99 @@ const isNameLine = (lineTokens: readonly Token[]): boolean => lineTokens.length
34
34
  const isOrganizationName = (word: string, wordTokens: readonly Token[], words: OrganizationWords): boolean =>
35
35
  words.units.has(wordTokens.at(-1)?.surface ?? "") || words.forms.some((form) => word.length > form.length && (word.startsWith(form) || word.endsWith(form)));
36
36
 
37
+ /** 行の頭の項目名とコロン(所属:、振込先:)。項目名は空白も数字も含まない短い語。 */
38
+ const FIELD_LABEL = /^[ \t]*(?:[-*+][ \t]+)?[^\s::。\d]{1,12}[::][ \t\u3000]*/u;
39
+
40
+ /** 文の終わり。値を文で書いた行(会場:本社 5階で行います。)の空白は、文の中の空け方として数える。 */
41
+ const SENTENCE_END = /[。!?]/u;
42
+
43
+ /** 値を句で書いた行(目標:参加者 100人を想定)に出る品詞。名前と番号を並べた値には出ない。 */
44
+ const CLAUSE_POS = new Set(["VERB", "AUX", "ADP"]);
45
+
46
+ /** 数の前に書いて量の一部になる語(約 3 か月、およそ 3 日、全 5 店舗)や、文の中の語(本社は 5階)の品詞。 */
47
+ const QUANTITY_LEAD_POS = new Set(["ADJ", "ADV", "ADP", "AUX", "VERB", "SCONJ", "PART"]);
48
+
49
+ /** 値の組の最も短い長さ。1 字の語(計 5件)は量の前置き。 */
50
+ const MIN_PART_LENGTH = 2;
51
+
52
+ /** 組を囲む字(括弧・表の升目の線)。組が囲みの中で読点で並ぶこともある(電話 03-1234-5678、内線 3839)。 */
53
+ const LAST_ENCLOSURE_OPEN = /[((||][^((||]*$/u;
54
+ const ENCLOSURE_CLOSE = /[))||]/u;
55
+
56
+ /** 組と組を分ける読点。数の桁の区切り(1,000)のコンマは除く。 */
57
+ const PAIR_COMMA = /[、,]|(?<!\d),|,(?!\d)/gu;
58
+
59
+ /** 行の頭の字下げと箇条書きの印(「- 」「1. 」)。 */
60
+ const PAIR_LEAD = /^[ \t\u3000]*(?:(?:[-*+]|\d{1,3}[..))])[ \t\u3000]+)?/u;
61
+
62
+ /** 項目名: 空白・数字・区切りの字を含まない短い語。値: 数字で始まり、空白も区切りも文の終わりも含まない一続き(桁の区切りのコンマは含む)。 */
63
+ const PAIR_LABEL = /^[^\s\d、,,()()||::。!?]{2,12}$/u;
64
+ const PAIR_VALUE = /^\d(?:[^\s、,,()()||。!?]|(?<=\d),(?=\d))*$/u;
65
+
66
+ /** 項目名に出る品詞。名詞だけで、助詞・副詞(およそ)・接頭の語(約)を含めば、量の前置きか文。 */
67
+ const PAIR_LABEL_POS = new Set(["NOUN", "PROPN"]);
68
+
69
+ const SPACE_RUN = /^[ \t\u3000]*/u;
70
+
71
+ /** at を含む囲み: 括弧か表の升目の線の内側、無ければ行(字下げと箇条書きの印の後ろ)。 */
72
+ const enclosureAround = (text: string, line: Span, at: number): Span => {
73
+ const open = LAST_ENCLOSURE_OPEN.exec(text.slice(line.start, at));
74
+ const start = open === null ? line.start + (PAIR_LEAD.exec(text.slice(line.start, line.end))?.[0].length ?? 0) : line.start + open.index + 1;
75
+ const close = text.slice(at, line.end).search(ENCLOSURE_CLOSE);
76
+ return { start, end: close === -1 ? line.end : at + close };
77
+ };
78
+
79
+ /** 囲みの中で at を含む組。読点で区切り、前後の空白を除く。 */
80
+ const pairAround = (text: string, enclosure: Span, at: number): Span => {
81
+ const commas = [...text.slice(enclosure.start, enclosure.end).matchAll(PAIR_COMMA)].map((match) => enclosure.start + match.index);
82
+ const rawStart = (commas.filter((comma) => comma < at).at(-1) ?? enclosure.start - 1) + 1;
83
+ const rawEnd = commas.find((comma) => comma > at) ?? enclosure.end;
84
+ const start = rawStart + (SPACE_RUN.exec(text.slice(rawStart, at))?.[0].length ?? 0);
85
+ return { start, end: rawStart + text.slice(rawStart, rawEnd).trimEnd().length };
86
+ };
87
+
88
+ /**
89
+ * 「最高速度 40km/h」「(内線 3839~40)」「- 定員 30名」のように、短い項目名と、それが名指す値を空白一つで並べただけの組の、名と値のあいだの空白。
90
+ * 組は行・括弧の中・表の升目にそれだけで書くか、読点で並べる。項目の区切りで、文の中の空け方ではない。
91
+ * 囲みの中に助詞や動詞がある(定員 30名で行います、参加者 30名、来場者50名を見込みます)、値の後ろに語が続く(内線 3839 まで)、
92
+ * 項目名が 1 字(約 30名)か名詞でない語を含む組は、文の中の空白として数える。
93
+ */
94
+ const isLabelledValue = (text: string, boundary: Boundary, tokens: readonly Token[], base: number): boolean => {
95
+ const enclosure = enclosureAround(text, lineAround(text, boundary.offset), boundary.offset);
96
+ const pair = pairAround(text, enclosure, boundary.offset);
97
+ const label = { start: pair.start, end: boundary.offset };
98
+ if (!PAIR_LABEL.test(text.slice(label.start, label.end)) || !PAIR_VALUE.test(text.slice(boundary.offset + 1, pair.end))) return false;
99
+ if (SENTENCE_END.test(text.slice(enclosure.start, enclosure.end))) return false;
100
+ const labelTokens = tokensIn(tokens, label, base);
101
+ return (
102
+ labelTokens.length > 0 &&
103
+ labelTokens.every((token) => PAIR_LABEL_POS.has(token.pos)) &&
104
+ !tokensIn(tokens, enclosure, base).some((token) => CLAUSE_POS.has(token.pos))
105
+ );
106
+ };
107
+
108
+ /** 項目名とコロンの後ろに値の組を並べた行の、組と、数で始まる次の組のあいだの空白か。 */
109
+ const isColonFieldPart = (text: string, boundary: Boundary, tokens: readonly Token[], base: number): boolean => {
110
+ const line = lineAround(text, boundary.offset);
111
+ const label = FIELD_LABEL.exec(text.slice(line.start, line.end));
112
+ if (label === null || SENTENCE_END.test(text.slice(line.start, line.end))) return false;
113
+ const valueStart = line.start + label[0].length;
114
+ if (tokensIn(tokens, { start: valueStart, end: line.end }, base).some((token) => CLAUSE_POS.has(token.pos))) return false;
115
+ const partStart = Math.max(wordStart(text, boundary.offset), valueStart);
116
+ const partEnd = tokens.find((token) => token.span.end === base + boundary.offset);
117
+ return boundary.offset - partStart >= MIN_PART_LENGTH && partEnd !== undefined && !QUANTITY_LEAD_POS.has(partEnd.pos);
118
+ };
119
+
120
+ /**
121
+ * 項目と値を分ける空白。「所属:経済学部 経済学科 1年」「振込先:みなと銀行 普通 1234567」のように項目名とコロンの後ろに値の組を並べた行の組と組のあいだか、
122
+ * 「最高速度 40km/h」「(内線 3839)」のように短い項目名と値を並べただけの組の、名と値のあいだ。値の区切りで、日本語と数字のあいだの空け方ではない。
123
+ * boundary は空けた数字の前の境目(text[offset] が空白)。tokens は文書全体の座標で、base は text の先頭の位置。
124
+ */
125
+ export const isFieldSeparator = (text: string, boundary: Boundary, tokens: readonly Token[] | undefined, base: number): boolean => {
126
+ if (tokens === undefined || boundary.kind !== "before-digit" || !boundary.spaced) return false;
127
+ return isColonFieldPart(text, boundary, tokens, base) || isLabelledValue(text, boundary, tokens, base);
128
+ };
129
+
37
130
  /**
38
131
  * 「株式会社あおば電子 経営企画部 IR担当」「東京本社 PR室」のように、名前だけを空白で並べた行で、空白の両側がどちらも組織の名前のときの空白。
39
132
  * 名前と名前の区切りで、英字の前後の空け方ではない。文の中の空白(この IT システムは)や、組織の名前でない語のあいだ(生成AI 活用事例、Patch リリース)は区切りと読まない。