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
@@ -0,0 +1,64 @@
1
+ import type { Lexicon, Sentence, Token } from "../plugin.ts";
2
+
3
+ // 並べた定義: どの文も違う語を、同じ型(〜を指します、〜といいます)で定義する。同じ文末が続くのは型をそろえたからで、
4
+ // 書き手の調子の繰り返しではない。
5
+
6
+ const TRAILING_POS: ReadonlySet<string> = new Set(["PUNCT", "SYM"]);
7
+ const TAIL_POS: ReadonlySet<string> = new Set(["AUX", "PART"]);
8
+
9
+ export type DefinitionWords = { readonly frames: ReadonlySet<string>; readonly topics: ReadonlySet<string> };
10
+
11
+ const patternsOf = (lexicon: Lexicon | undefined, group: string): ReadonlySet<string> =>
12
+ new Set((lexicon ?? []).filter((entry) => entry.group === group).map((entry) => entry.pattern));
13
+
14
+ export const definitionWordsOf = (lexicon: Lexicon | undefined): DefinitionWords => ({
15
+ frames: patternsOf(lexicon, "frame"),
16
+ topics: patternsOf(lexicon, "topic"),
17
+ });
18
+
19
+ const surfacesOf = (tokens: readonly Token[]): string => tokens.map((token) => token.surface).join("");
20
+
21
+ /** 述語(文末の助動詞の前の語)の位置。助動詞で終わらない文には無い。 */
22
+ const predicateAt = (tokens: readonly Token[]): number | undefined => {
23
+ const last = tokens.findLastIndex((token) => !TRAILING_POS.has(token.pos));
24
+ const head = tokens.slice(0, last + 1).findLastIndex((token) => !TAIL_POS.has(token.pos));
25
+ return head > 0 && head < last ? head : undefined;
26
+ };
27
+
28
+ const PARTICLE_POS = "ADP";
29
+ const TERM_POS: ReadonlySet<string> = new Set(["NOUN", "PROPN"]);
30
+
31
+ /** 定義の文が定義する語と、その型(を指す)。 */
32
+ export type Definition = { readonly term: string; readonly frame: string };
33
+
34
+ /** topic の助詞(は)より前。無ければ、述語の前の助詞の直前の名詞(〜を台風といいます の 台風)。 */
35
+ const termOf = (tokens: readonly Token[], head: number, words: DefinitionWords): string => {
36
+ const topic = tokens.slice(0, head - 1).findIndex((token) => token.pos === PARTICLE_POS && words.topics.has(token.surface));
37
+ if (topic > 0) return surfacesOf(tokens.slice(0, topic));
38
+ const before = tokens[head - 2];
39
+ return before !== undefined && TERM_POS.has(before.pos) ? before.surface : "";
40
+ };
41
+
42
+ /** その文が定義する語と型。型の文(を指す、という)でなければ無い。 */
43
+ export const definitionOf = (sentence: Sentence, words: DefinitionWords): Definition | undefined => {
44
+ const tokens = (sentence.tokens ?? []).filter((token) => token.surface.trim() !== "");
45
+ const head = predicateAt(tokens);
46
+ const particle = head === undefined ? undefined : tokens[head - 1];
47
+ const predicate = head === undefined ? undefined : tokens[head];
48
+ if (head === undefined || particle === undefined || predicate === undefined) return undefined;
49
+ const frame = `${particle.surface}${predicate.lemma ?? predicate.surface}`;
50
+ if (!words.frames.has(frame)) return undefined;
51
+ const term = termOf(tokens, head, words);
52
+ return term === "" ? undefined : { term, frame };
53
+ };
54
+
55
+ const isDefinition = (definition: Definition | undefined): definition is Definition => definition !== undefined;
56
+
57
+ /** どの文も同じ型の定義で、定義する語がみな違う。 */
58
+ export const isParallelDefinition = (sentences: readonly Sentence[], words: DefinitionWords): boolean => {
59
+ const definitions = sentences.map((sentence) => definitionOf(sentence, words));
60
+ if (!definitions.every(isDefinition)) return false;
61
+ const terms = new Set(definitions.map((definition) => definition.term));
62
+ const frames = new Set(definitions.map((definition) => definition.frame));
63
+ return terms.size === definitions.length && frames.size === 1;
64
+ };
@@ -0,0 +1,24 @@
1
+ import type { ProseDocument, StructureNode } from "../plugin.ts";
2
+ import { withPerUnits, type PerUnitMark, type PerUnitTemplate, type PerUnitWords } from "../facts/per-unit.ts";
3
+ import { factValues, type FactValue } from "../facts/fact-values.ts";
4
+ import { nameSpans } from "../compare/proper-nouns.ts";
5
+
6
+ const marksOf = (doc: ProseDocument, id: string): PerUnitMark[] =>
7
+ (doc.lexicons[id] ?? []).map((entry): PerUnitMark => ({ pattern: entry.pattern, group: entry.group ?? entry.pattern }));
8
+
9
+ /** 何あたりかの語: 決まった印(per-unit-mark)、型(fact-per-unit)、単位の語(rate-unit)、読まない百分率(percent-unit)、単価の列の見出し(unit-price-column)。 */
10
+ const perUnitWordsOf = (doc: ProseDocument): PerUnitWords => ({
11
+ marks: marksOf(doc, "per-unit-mark"),
12
+ templates: (doc.lexicons["fact-per-unit"] ?? []).map((entry): PerUnitTemplate => ({ pattern: entry.pattern, position: entry.position ?? "before" })),
13
+ units: marksOf(doc, "rate-unit"),
14
+ percentUnits: (doc.lexicons["percent-unit"] ?? []).map((entry) => entry.pattern),
15
+ priceHeadings: (doc.lexicons["unit-price-column"] ?? []).map((entry) =>
16
+ entry.group === undefined ? { pattern: entry.pattern } : { pattern: entry.pattern, group: entry.group },
17
+ ),
18
+ });
19
+
20
+ /** 文書の値に、何あたりか(1kmあたり15円 の km)を付ける。 */
21
+ export const perUnitsOf = <T extends FactValue>(doc: ProseDocument, values: readonly T[]): T[] => withPerUnits(doc.source, values, perUnitWordsOf(doc));
22
+
23
+ /** 木の数量と日付と固有名詞(factValues)に、何あたりかを付けたもの。 */
24
+ export const perUnitValues = (doc: ProseDocument, tree: StructureNode): FactValue[] => perUnitsOf(doc, factValues(tree, doc.source, nameSpans(doc)));
@@ -4,11 +4,9 @@
4
4
  // number-word (digit), and a range of counts is joined by range-connector or amount-range-word.
5
5
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
6
6
  import { periodMultipleMismatches, type PeriodMultipleWords } from "../structure/period-multiple.ts";
7
- import type { StatedAmount } from "../structure/stated-multiple.ts";
8
- import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
9
- import { amountsIn, formsOf } from "./currency-notation.ts";
10
7
  import { proseAndTablesOf } from "../table-text.ts";
11
8
  import { quoteAround } from "./quote-around.ts";
9
+ import { statedAmountsOf } from "./stated-amounts.ts";
12
10
 
13
11
  const patternsOf = (doc: ProseDocument, lexicon: string, group?: string): string[] =>
14
12
  (doc.lexicons[lexicon] ?? []).filter((entry) => group === undefined || entry.group === group).map((entry) => entry.pattern);
@@ -27,23 +25,9 @@ const wordsOf = (doc: ProseDocument): PeriodMultipleWords => ({
27
25
  numberWords: numberWordsOf(doc),
28
26
  });
29
27
 
30
- const amountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
31
- const scales = scaleWordsOf(doc);
32
- return amountsIn(
33
- text,
34
- formsOf(doc),
35
- scales.map((scale) => scale.word),
36
- ).flatMap((amount) => {
37
- const read = scaledAmountOf(text, amount, scales);
38
- return read === undefined
39
- ? []
40
- : [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
41
- });
42
- };
43
-
44
28
  export const periodMultipleMismatch: Detector = (doc): Finding[] => {
45
29
  const text = proseAndTablesOf(doc);
46
- return periodMultipleMismatches(text, amountsOf(text, doc), wordsOf(doc)).map((issue) => ({
30
+ return periodMultipleMismatches(text, statedAmountsOf(text, doc), wordsOf(doc)).map((issue) => ({
47
31
  rule: "period-multiple-mismatch",
48
32
  severity: "warning",
49
33
  line: 0,
@@ -1,13 +1,14 @@
1
1
  // reference-number-variant: a document's own reference number written with two neighbouring characters swapped somewhere
2
2
  // else in the document, after a label of the same kind (reference-numbers.ts), or with no label where only one labelled
3
- // code swaps to it (unlabelled-references.ts); and the document's one vehicle plate written
3
+ // code swaps to it (unlabelled-references.ts), or as the one code a product document is about (subject-codes.ts); and the document's one vehicle plate written
4
4
  // once with one character of its serial changed (vehicle-plates.ts).
5
- import { labelledReferenceNumbers, referenceVariants, type ReferenceNumber } from "../reference-numbers.ts";
5
+ import { labelledReferenceNumbers, referenceVariants, type ReferenceNumber, type ReferenceVariant } from "../reference-numbers.ts";
6
6
  import { labelledPlates, plateVariants } from "../vehicle-plates.ts";
7
- import { tableCodes, tableLabelledCodes, unlabelledVariants } from "../unlabelled-references.ts";
7
+ import { isCodeWith, tableCodes, tableLabelledCodes, unlabelledVariants } from "../unlabelled-references.ts";
8
+ import { isSubjectCode, MIN_SUBJECT_DIGITS, subjectCodeVariants } from "../subject-codes.ts";
8
9
  import { proseAndTablesOf } from "../table-text.ts";
9
10
  import { quoteAt } from "./structure-tree.ts";
10
- import type { Detector, Finding, OptionValue } from "../plugin.ts";
11
+ import type { Detector, Finding, OptionValue, ProseDocument } from "../plugin.ts";
11
12
 
12
13
  const PLATE_SHAPES = "vehicle-plate";
13
14
  const SUBSTITUTED = "substituted";
@@ -25,6 +26,18 @@ const finding = (number: ReferenceNumber, other: ReferenceNumber, source: string
25
26
  /** Kinds a document lists many of (item codes): two labelled ones are two things, so only a code with no label is compared with them. */
26
27
  const listedKindsOf = (value: OptionValue | undefined): readonly string[] => (typeof value === "object" ? value : []);
27
28
 
29
+ const TITLE_DEPTH = 1;
30
+
31
+ /** The title as the source writes it, where it starts: the prose masks a heading's line. */
32
+ const titleOf = (doc: ProseDocument): { start: number; text: string } | undefined => {
33
+ const title = doc.markup?.headings.find((heading) => heading.depth === TITLE_DEPTH);
34
+ return title === undefined ? undefined : { start: title.start, text: doc.source.slice(title.start, title.end) };
35
+ };
36
+
37
+ /** One finding per place, the first reading kept: a code may be read both as an unlabelled item code and as the document's own. */
38
+ const firstAtEachOffset = (variants: readonly ReferenceVariant[]): ReferenceVariant[] =>
39
+ variants.filter((variant, index) => variants.findIndex((other) => other.number.offset === variant.number.offset) === index);
40
+
28
41
  export const referenceNumberVariant: Detector = (doc, options): Finding[] => {
29
42
  const labels = options.lexicon ?? [];
30
43
  if (labels.length === 0) return [];
@@ -36,9 +49,18 @@ export const referenceNumberVariant: Detector = (doc, options): Finding[] => {
36
49
  const listed = new Set(listedKindsOf(options.settings?.["listed_kinds"]));
37
50
  const withTables = proseAndTablesOf(doc);
38
51
  const labelled = [...numbers, ...tableLabelledCodes(withTables, labels)];
52
+ const subjectCodes = subjectCodeVariants({
53
+ prose: text,
54
+ title: titleOf(doc),
55
+ labels,
56
+ listed,
57
+ tabled: tableLabelledCodes(withTables, labels, isSubjectCode),
58
+ known: tableCodes(withTables, isCodeWith(MIN_SUBJECT_DIGITS)),
59
+ });
60
+ const unlabelled = firstAtEachOffset([...unlabelledVariants(text, labelled, tableCodes(withTables)), ...subjectCodes]);
39
61
  return [
40
62
  ...referenceVariants(numbers.filter((number) => !listed.has(number.label))).map(({ number, other }) => finding(number, other, doc.source)),
41
- ...unlabelledVariants(text, labelled, tableCodes(withTables)).map(({ number, other }) => finding(number, other, doc.source)),
63
+ ...unlabelled.map(({ number, other }) => finding(number, other, doc.source)),
42
64
  ...plateVariants(plates).map(({ number, other }) => finding(number, other, doc.source, SUBSTITUTED)),
43
65
  ].toSorted((a, b) => Number(a.values["offset"]) - Number(b.values["offset"]));
44
66
  };
@@ -17,6 +17,7 @@ const inputOf = (doc: ProseDocument): ReferenceInput | undefined => {
17
17
  asides: patternsOf(doc, "reference-aside"),
18
18
  topicLinks: patternsOf(doc, "reference-topic-link"),
19
19
  vagueTopics: patternsOf(doc, "reference-topic-vague"),
20
+ listJoints: patternsOf(doc, "reference-list-joint"),
20
21
  },
21
22
  };
22
23
  };
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { conditionToki } from "../condition-toki.ts";
3
+
4
+ export const detector: Detector = conditionToki;
@@ -1,4 +1,4 @@
1
1
  import type { Detector } from "../../plugin.ts";
2
- import { unfilledPlaceholder } from "../ai-phrasing.ts";
2
+ import { unfilledPlaceholderOutsideTemplates } from "../unfilled-placeholder.ts";
3
3
 
4
- export const detector: Detector = unfilledPlaceholder;
4
+ export const detector: Detector = unfilledPlaceholderOutsideTemplates;
@@ -1,4 +1,4 @@
1
1
  import type { Detector } from "../../plugin.ts";
2
- import { vagueDensity } from "../lexicon.ts";
2
+ import { vagueDensity } from "../vague-density.ts";
3
3
 
4
4
  export const detector: Detector = vagueDensity;
@@ -4,11 +4,9 @@
4
4
  // range of rent is joined by range-connector or amount-range-word.
5
5
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
6
6
  import { rentMultipleMismatches, type RentMultipleWords } from "../structure/rent-multiple.ts";
7
- import type { StatedAmount } from "../structure/stated-multiple.ts";
8
- import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
9
- import { amountsIn, formsOf } from "./currency-notation.ts";
10
7
  import { proseAndTablesOf } from "../table-text.ts";
11
8
  import { quoteAround } from "./quote-around.ts";
9
+ import { statedAmountsOf } from "./stated-amounts.ts";
12
10
 
13
11
  const patternsOf = (doc: ProseDocument, lexicon: string, group?: string): string[] =>
14
12
  (doc.lexicons[lexicon] ?? []).filter((entry) => group === undefined || entry.group === group).map((entry) => entry.pattern);
@@ -30,23 +28,9 @@ const wordsOf = (doc: ProseDocument): RentMultipleWords => ({
30
28
  numberWords: numberWordsOf(doc),
31
29
  });
32
30
 
33
- const amountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
34
- const scales = scaleWordsOf(doc);
35
- return amountsIn(
36
- text,
37
- formsOf(doc),
38
- scales.map((scale) => scale.word),
39
- ).flatMap((amount) => {
40
- const read = scaledAmountOf(text, amount, scales);
41
- return read === undefined
42
- ? []
43
- : [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
44
- });
45
- };
46
-
47
31
  export const rentMultipleMismatch: Detector = (doc): Finding[] => {
48
32
  const text = proseAndTablesOf(doc);
49
- return rentMultipleMismatches(text, amountsOf(text, doc), wordsOf(doc)).map((issue) => ({
33
+ return rentMultipleMismatches(text, statedAmountsOf(text, doc), wordsOf(doc)).map((issue) => ({
50
34
  rule: "rent-multiple-mismatch",
51
35
  severity: "warning",
52
36
  line: 0,
@@ -1,6 +1,6 @@
1
1
  // A request for an action (「資料をご確認ください」 "Please send the report.") with no deadline and no person or role,
2
2
  // in its own sentence or the next. The words come from the language's lexicons; the code only combines them.
3
- import type { Detector, Finding, Lexicon, ProseDocument, Sentence, Span, StructureNode } from "../plugin.ts";
3
+ import type { Detector, Finding, Lexicon, ProseDocument, Section, Sentence, Span, StructureNode } from "../plugin.ts";
4
4
  import { proseText } from "../measure.ts";
5
5
  import { comparableWords } from "./lexicon-match.ts";
6
6
  import { escapeRegExp } from "../orthography.ts";
@@ -15,6 +15,9 @@ export const REQUEST_LEXICONS = {
15
15
  owner: "request-owner",
16
16
  pointer: "request-pointer",
17
17
  offer: "request-offer",
18
+ timing: "request-timing",
19
+ invitation: "request-invitation",
20
+ contact: "request-contact",
18
21
  } as const;
19
22
 
20
23
  type Words = Readonly<Record<keyof typeof REQUEST_LEXICONS, readonly string[]>>;
@@ -32,6 +35,9 @@ const wordsOf = (doc: ProseDocument): Words => ({
32
35
  owner: patternsOf(doc.lexicons[REQUEST_LEXICONS.owner]),
33
36
  pointer: patternsOf(doc.lexicons[REQUEST_LEXICONS.pointer]),
34
37
  offer: patternsOf(doc.lexicons[REQUEST_LEXICONS.offer]),
38
+ timing: patternsOf(doc.lexicons[REQUEST_LEXICONS.timing]),
39
+ invitation: patternsOf(doc.lexicons[REQUEST_LEXICONS.invitation]),
40
+ contact: patternsOf(doc.lexicons[REQUEST_LEXICONS.contact]),
35
41
  });
36
42
 
37
43
  /** How far apart, in characters, the action word and the request ending may be: the action must be what is requested. */
@@ -57,16 +63,43 @@ export const containsAny = (text: string, patterns: readonly string[]): boolean
57
63
 
58
64
  const gapBetween = (left: Place, right: Place): number => Math.max(left.start - right.end, right.start - left.end, 0);
59
65
 
66
+ /** An invitation verb right at the request ending (「ご相談ください」 "please come"): the reader may come, nothing is to be finished. */
67
+ const INVITATION_REACH = 1;
68
+
69
+ /** A comma or semicolon between an action and the invitation: the action is a request of its own (「申請書を提出し、会場へお越しください」). */
70
+ const CLAUSE_BREAK = /[、,,;;]/u;
71
+
72
+ /** A label and a colon (「電話:」 "Fax:"): a contact line, whose request is how to reach the writer. */
73
+ const LABEL_COLON = /^\s*[::]/u;
74
+
75
+ /** Whether the action is what the invitation is for (「登録をしにお越しください」「入力用にご使用ください」), not a request beside it. */
76
+ const invitedTo = (comparable: string, action: Place, invitation: Place): boolean => {
77
+ const [left, right] = action.start <= invitation.start ? [action, invitation] : [invitation, action];
78
+ return !CLAUSE_BREAK.test(comparable.slice(left.end, right.start));
79
+ };
80
+
81
+ const holdsContactLine = (text: string, words: Words): boolean => {
82
+ const comparable = comparableWords(text);
83
+ return placesOf(comparable, words.contact).some((label) => LABEL_COLON.test(comparable.slice(label.end)));
84
+ };
85
+
60
86
  /**
61
87
  * A request for an action: an action word next to a request ending (「確認してください」「please send」), not a condition
62
88
  * (「ご不明な点があれば…ください」 is an offer), not an open offer to take the reader's questions (「ご質問はメールでお送りください」),
63
- * and not a pointer to where to read more (「詳細は資料をご確認ください」).
89
+ * not a pointer to where to read more (「詳細は資料をご確認ください」), not what an invitation is for (「登録をしにお越しください」),
90
+ * and not the way to reach the writer on a contact line (「ファックス番号:… 送信後、ご連絡ください」).
64
91
  * The action has to be close to the ending, or a noun like 検討会 or 履修登録 earlier in the sentence would make one.
65
92
  */
66
93
  export const isRequest = (text: string, words: Words): boolean => {
94
+ const comparable = comparableWords(text);
67
95
  const endings = placesOf(text, words.ending);
68
- const asked = placesOf(text, words.action).some((action) => endings.some((ending) => gapBetween(action, ending) <= ACTION_REACH));
69
- return asked && ![words.condition, words.offer, words.pointer].some((patterns) => containsAny(text, patterns));
96
+ const invitations = placesOf(text, words.invitation).filter((invitation) => endings.some((ending) => gapBetween(invitation, ending) <= INVITATION_REACH));
97
+ const asked = placesOf(text, words.action).some(
98
+ (action) =>
99
+ endings.some((ending) => gapBetween(action, ending) <= ACTION_REACH) && !invitations.some((invitation) => invitedTo(comparable, action, invitation)),
100
+ );
101
+ if (!asked || holdsContactLine(text, words)) return false;
102
+ return ![words.condition, words.offer, words.pointer].some((patterns) => containsAny(text, patterns));
70
103
  };
71
104
 
72
105
  const NAMED = new Set(["PROPN"]);
@@ -105,13 +138,16 @@ const holdsWord = (sentence: Sentence, patterns: readonly string[]): boolean =>
105
138
  return placesOf(comparable, patterns).some((place) => bounds === undefined || (bounds.starts.has(place.start) && bounds.ends.has(place.end)));
106
139
  };
107
140
 
108
- /** Whether a sentence says when (a date, a clock time, a deadline word) or who (a role; a name in the request itself). */
141
+ /**
142
+ * Whether a sentence says when or who (a role). The request itself may also say when relative to something else
143
+ * (「提出いただく前に」 "before you submit") or name the person; the next sentence's timing or name may be about something else.
144
+ */
109
145
  const saysWhenOrWho = (sentence: Sentence, words: Words, dates: readonly Span[], isRequestItself: boolean): boolean =>
110
146
  datedWithin(dates, sentence.span) ||
111
147
  CLOCK.test(proseText(sentence)) ||
112
148
  holdsWord(sentence, words.deadline) ||
113
149
  holdsWord(sentence, words.owner) ||
114
- (isRequestItself && namesSomeone(sentence));
150
+ (isRequestItself && (holdsWord(sentence, words.timing) || namesSomeone(sentence)));
115
151
 
116
152
  /** A paragraph break or a new list item between two sentences: the second does not continue the first. */
117
153
  const BREAK = /\n[^\S\n]*\n|\n[^\S\n]*(?:[-*+]|\d+[.)])[^\S\n]/u;
@@ -122,14 +158,41 @@ const continues = (source: string, sentence: Sentence, next: Sentence | undefine
122
158
  const dateSpans = (tree: StructureNode | undefined): Span[] =>
123
159
  tree === undefined ? [] : inDocumentOrder(tree).flatMap((node) => (node.kind === "date" ? [node.span] : []));
124
160
 
125
- /** The request sentences with neither a deadline nor a person in them or in the sentence after, in the same paragraph or item. */
161
+ /** A section's heading, read as a sentence so the deadline words match it the same way. */
162
+ const headingOf = (section: Section): Sentence => ({
163
+ span: section.span,
164
+ text: section.heading,
165
+ ...(section.headingTokens === undefined ? {} : { tokens: section.headingTokens }),
166
+ });
167
+
168
+ /** The headings an offset sits under: its own section's, then each enclosing one's up to the title. */
169
+ const enclosingHeadings = (sections: readonly Section[], offset: number): Sentence[] => {
170
+ const own = sections.findLastIndex((section) => section.span.start <= offset);
171
+ const chain = sections
172
+ .slice(0, own + 1)
173
+ .reduceRight<{ depth: number; found: Section[] }>(
174
+ (walk, section) => (section.depth < walk.depth ? { depth: section.depth, found: [...walk.found, section] } : walk),
175
+ { depth: Number.POSITIVE_INFINITY, found: [] },
176
+ ).found;
177
+ return chain.filter((section) => section.depth > 0 && section.heading.trim() !== "").map(headingOf);
178
+ };
179
+
180
+ /**
181
+ * A notice whose heading names its deadline (「見積提出期限:10月26日」「【随時受付】」): every request under it inherits it.
182
+ * A date alone in a heading is more often the day the notice was issued or the event it announces, so it is not enough.
183
+ */
184
+ const underDeadlineHeading = (sections: readonly Section[], sentence: Sentence, words: Words): boolean =>
185
+ enclosingHeadings(sections, sentence.span.start).some((heading) => holdsWord(heading, words.deadline));
186
+
187
+ /** The request sentences with neither a deadline nor a person in them, in the sentence after (same paragraph or item), or in a heading above. */
126
188
  export const ownerlessRequests = (doc: ProseDocument): Sentence[] => {
127
189
  const words = wordsOf(doc);
128
190
  const dates = dateSpans(doc.structure);
129
191
  return doc.sentences.filter((sentence, index) => {
130
192
  if (!isRequest(proseText(sentence), words) || saysWhenOrWho(sentence, words, dates, true)) return false;
131
193
  const next = doc.sentences[index + 1];
132
- return !continues(doc.source, sentence, next) || !saysWhenOrWho(next, words, dates, false);
194
+ if (continues(doc.source, sentence, next) && saysWhenOrWho(next, words, dates, false)) return false;
195
+ return !underDeadlineHeading(doc.sections, sentence, words);
133
196
  });
134
197
  };
135
198
 
@@ -1,16 +1,20 @@
1
1
  import type { Detector, Finding, Lexicon, LexiconEntry, ProseDocument, Sentence } from "../plugin.ts";
2
2
  import { entryCloses, entryIn, entryRanges } from "./lexicon-match.ts";
3
3
  import { openEndAt, openEndNames, type OpenEndNames } from "./open-end-names.ts";
4
+ import { statesConcrete } from "./vague-deadline.ts";
4
5
 
5
6
  // Requirements smells (Femmer et al. 2017; Berry et al. 2003; ISO/IEC/IEEE 29148): a loophole, an open-ended list and
6
7
  // "and/or", in a sentence that states a requirement. What makes a sentence a requirement, and each smell's words, come
7
8
  // from the language's lexicons; this file knows neither language.
8
9
 
9
10
  const OPEN_END = "requirement-open-end";
11
+ const LOOPHOLE = "requirement-loophole";
12
+ const TIME = "time";
13
+ const CONCRETE_DEADLINE = "concrete-deadline";
10
14
 
11
15
  /** Each smell: the lexicon of its words, and the finding's variant (the rule's messages). */
12
16
  const SMELLS = [
13
- { lexicon: "requirement-loophole", variant: "loophole" },
17
+ { lexicon: LOOPHOLE, variant: "loophole" },
14
18
  { lexicon: OPEN_END, variant: "open-end" },
15
19
  { lexicon: "requirement-either", variant: "either" },
16
20
  ] as const;
@@ -43,9 +47,18 @@ const findingOf = (sentence: Sentence, entry: LexiconEntry, variant: string, off
43
47
  values: { matched: entry.pattern, offset },
44
48
  });
45
49
 
50
+ /** A loophole about when (group: time) that the sentence bounds with a stated limit ("as soon as possible, but no later than two days after"). */
51
+ const boundedInTime = (doc: ProseDocument, sentence: Sentence, entry: LexiconEntry, lexicon: string): boolean =>
52
+ lexicon === LOOPHOLE &&
53
+ entry.group === TIME &&
54
+ statesConcrete(
55
+ { start: sentence.span.start, text: sentence.text },
56
+ (doc.lexicons[CONCRETE_DEADLINE] ?? []).map((limit) => limit.pattern),
57
+ );
58
+
46
59
  /** Where the word stands as a smell. An open-end word inside a name the document gives (業務執行取締役等) is none; without tokens it cannot be told apart. */
47
60
  const smellAt = (doc: ProseDocument, sentence: Sentence, entry: LexiconEntry, lexicon: string, names: () => OpenEndNames): number | undefined => {
48
- if (!entryIn(sentence, entry)) return undefined;
61
+ if (!entryIn(sentence, entry) || boundedInTime(doc, sentence, entry, lexicon)) return undefined;
49
62
  const tokenized = sentence.tokens !== undefined && (entry.tokens?.length ?? 0) > 0;
50
63
  return lexicon === OPEN_END && tokenized ? openEndAt(doc, sentence, entry, names()) : offsetOf(sentence, entry);
51
64
  };
@@ -4,15 +4,8 @@ import { factValues, type FactValue } from "../facts/fact-values.ts";
4
4
  import { cellsOf, tablesOf } from "../facts/table-facts.ts";
5
5
  import { scopedFacts, type ScopedFact } from "../facts/fact-scope.ts";
6
6
  import { withoutEdgeMarks } from "../facts/trim-marks.ts";
7
- import {
8
- periodOf,
9
- rowSentenceConflicts,
10
- type Amount,
11
- type AmountRow,
12
- type PeriodMark,
13
- type SubjectSentence,
14
- type SubjectWords,
15
- } from "../facts/row-sentence-amounts.ts";
7
+ import { rowSentenceConflicts, type Amount, type AmountRow, type SubjectSentence, type SubjectWords } from "../facts/row-sentence-amounts.ts";
8
+ import { perUnitsOf } from "./per-unit-words.ts";
16
9
  import { linesOf, type Line } from "../structure/lines.ts";
17
10
  import { quoteAt } from "./structure-tree.ts";
18
11
 
@@ -57,19 +50,11 @@ const subjectWordsOf = (doc: ProseDocument): SubjectWords => ({
57
50
  conditions: patternsOf(doc, "fact-amount-condition"),
58
51
  });
59
52
 
60
- const periodMarksOf = (doc: ProseDocument): PeriodMark[] =>
61
- (doc.lexicons["per-unit-mark"] ?? []).map((entry): PeriodMark => ({ pattern: entry.pattern, group: entry.group ?? entry.pattern }));
62
-
63
- /** 金額: 通貨の語彙表の印を単位に書いた数量。前後に期間あたりの印があれば、その期間も。 */
53
+ /** 金額: 通貨の語彙表の印を単位に書いた数量。何あたりの金額(日額、1kmあたり)は、その単位も。 */
64
54
  const amountsOf = (doc: ProseDocument, tree: StructureNode): Amount[] => {
65
55
  const currencies = new Set(patternsOf(doc, "currency-notation").map((pattern) => pattern.normalize("NFKC")));
66
- const marks = periodMarksOf(doc);
67
- return factValues(tree, doc.source, nameSpans(doc))
68
- .filter((value) => value.kind === "quantity" && currencies.has(value.unit))
69
- .map((value): Amount => {
70
- const period = periodOf(doc.source, value, marks);
71
- return period === undefined ? value : { ...value, period };
72
- });
56
+ const amounts = factValues(tree, doc.source, nameSpans(doc)).filter((value) => value.kind === "quantity" && currencies.has(value.unit));
57
+ return perUnitsOf(doc, amounts);
73
58
  };
74
59
 
75
60
  /** 表の行の金額と、その行の見出しを主語にした文の金額の食い違い。名前付きの値として読めた文の値は、ほかの読みが比べる。 */
@@ -1,19 +1,26 @@
1
1
  import { lengthOf, proseText } from "../measure.ts";
2
2
  import type { Detector, DetectorOptions, Finding, LengthUnit, Sentence } from "../plugin.ts";
3
+ import { pageMarkerPattern, pageMarkerSize } from "./page-marker.ts";
3
4
 
4
5
  type Measure = { readonly size: number; readonly limit: number; readonly variant?: string };
5
6
 
6
- /** 文書と違う言語の文(和文の中の英文)は、その言語の単位と上限で測る。rule がその言語の段を持たなければ文書のもので。 */
7
- const measureOf = (sentence: Sentence, unit: LengthUnit, options: DetectorOptions): Measure => {
7
+ /**
8
+ * 文書と違う言語の文(和文の中の英文)は、その言語の単位と上限で測る。rule がその言語の段を持たなければ文書のもので。
9
+ * 印刷版のページの印(( printed page 52044))は文の言葉ではないので数えない。
10
+ */
11
+ const measureOf = (sentence: Sentence, unit: LengthUnit, options: DetectorOptions, markers: RegExp | undefined): Measure => {
8
12
  const embedded = sentence.embeddedLanguage;
9
13
  const limit = embedded === undefined ? undefined : options.embeddedLimits?.[embedded.id];
10
- if (embedded === undefined || limit === undefined) return { size: lengthOf(sentence, unit), limit: options.limit };
14
+ if (embedded === undefined || limit === undefined) {
15
+ return { size: lengthOf(sentence, unit) - pageMarkerSize(proseText(sentence), markers, unit), limit: options.limit };
16
+ }
11
17
  return { size: lengthOf(sentence, embedded.lengthUnit), limit, variant: `embedded-${embedded.id}` };
12
18
  };
13
19
 
14
- export const sentenceLength: Detector = (doc, options): Finding[] =>
15
- doc.sentences
16
- .map((sentence) => ({ sentence, measure: measureOf(sentence, doc.lengthUnit, options) }))
20
+ export const sentenceLength: Detector = (doc, options): Finding[] => {
21
+ const markers = pageMarkerPattern((options.lexicon ?? []).map((entry) => entry.pattern));
22
+ return doc.sentences
23
+ .map((sentence) => ({ sentence, measure: measureOf(sentence, doc.lengthUnit, options, markers) }))
17
24
  .filter(({ measure }) => measure.size > measure.limit)
18
25
  .map(({ sentence, measure }) => ({
19
26
  rule: "max-sentence-length",
@@ -24,3 +31,4 @@ export const sentenceLength: Detector = (doc, options): Finding[] =>
24
31
  values: { count: measure.size, limit: measure.limit, offset: sentence.span.start },
25
32
  ...(measure.variant === undefined ? {} : { variant: measure.variant }),
26
33
  }));
34
+ };
@@ -1,5 +1,5 @@
1
1
  import { charLength, proseText } from "../measure.ts";
2
- import type { Detector, Finding } from "../plugin.ts";
2
+ import type { Detector, Finding, ProseDocument, Sentence } from "../plugin.ts";
3
3
 
4
4
  /** 文が少ないと変動係数は当てにならない。ここを下回る文書は見ない。 */
5
5
  const MIN_SENTENCES = 8;
@@ -11,8 +11,12 @@ const coefficientOfVariation = (sizes: readonly number[]): number => {
11
11
  return Math.sqrt(variance) / mean;
12
12
  };
13
13
 
14
+ /** 箇条書きの項目は揃えて書くのが正しい形なので、地の文の文だけを測る。 */
15
+ const proseSentences = (doc: ProseDocument): readonly Sentence[] => doc.paragraphs.flatMap((paragraph) => paragraph.sentences);
16
+
14
17
  export const sentenceRhythm: Detector = (doc, options): Finding[] => {
15
- const sizes = doc.sentences.map((sentence) => charLength(sentence));
18
+ const sentences = proseSentences(doc);
19
+ const sizes = sentences.map((sentence) => charLength(sentence));
16
20
  if (sizes.length < MIN_SENTENCES) return [];
17
21
  const spread = Math.round(coefficientOfVariation(sizes) * 100);
18
22
  if (spread >= options.limit) return [];
@@ -22,8 +26,8 @@ export const sentenceRhythm: Detector = (doc, options): Finding[] => {
22
26
  severity: "warning",
23
27
  line: 0,
24
28
  column: 0,
25
- quote: doc.sentences[0] === undefined ? "" : proseText(doc.sentences[0]),
26
- values: { count: spread, limit: options.limit, offset: doc.sentences[0]?.span.start ?? 0 },
29
+ quote: sentences[0] === undefined ? "" : proseText(sentences[0]),
30
+ values: { count: spread, limit: options.limit, offset: sentences[0]?.span.start ?? 0 },
27
31
  },
28
32
  ];
29
33
  };
@@ -1,13 +1,22 @@
1
1
  /**
2
- * - で区切った文書番号のすぐ前の大文字の語(NIST SP 800-61 の SP、NSF 19-582、IEC 19757-2)。番号の一部で、略語ではない。
2
+ * - で区切った文書番号のすぐ前の大文字の語(NIST SP 800-61 の SP、NSF 19-582、IEC 19757-2、XRIN 0693-XC139、
3
+ * FR Doc. 2026-16371 の FR)。番号の一部で、略語ではない。
3
4
  * 空白で離して書くほかは、- で繋いだ識別子(AC-2)と同じ。番号の直前の 1 語だけで、その前の語(NIST)は略語のまま数える。
4
5
  * 区切りの無い番号(RFC 9110)、. で区切る版(SDK 3.1)、年の範囲(FY 2024-25)の前の語も略語のまま数える。
5
6
  */
6
7
 
7
8
  type Span = { readonly start: number; readonly end: number };
8
9
 
9
- const YEAR_RANGE = String.raw`(?:19|20)\d\d-\d`;
10
- const SERIES_LABEL = new RegExp(String.raw`(?<![A-Za-z0-9_&.-])[A-Z]+ (?!${YEAR_RANGE})(?<number>\d+(?:-\d+)+)[A-Za-z0-9]*(?![A-Za-z0-9_&-])`, "gu");
10
+ /** 年の範囲(2024-25、1999-2000)。後ろが 3 桁や 5 桁の番号(FR Doc. 2026-16371)は年ではない。 */
11
+ const YEAR_RANGE = String.raw`(?:19|20)\d\d-(?:(?:19|20)\d\d|\d\d)(?![A-Za-z0-9_&-])`;
12
+ /** 語と番号の間に置く、点で終わる 2〜3 文字の略し(FR Doc. 2026-16371、EO No. 14028-1)。 */
13
+ const NUMBER_WORD = String.raw`(?:[A-Z][a-z]{1,2}\. )?`;
14
+ /** 2 つめからの区切りは、2 文字までの英字の頭を持てる(RIN の 0693-XC139)。英字の後ろは 3 桁以上の通し番号。 */
15
+ const LATER_GROUP = String.raw`-(?:[A-Z]{1,2}\d{3,}|\d+)`;
16
+ const SERIES_LABEL = new RegExp(
17
+ String.raw`(?<![A-Za-z0-9_&.-])[A-Z]+ ${NUMBER_WORD}(?!${YEAR_RANGE})(?<number>\d+(?:${LATER_GROUP})+)[A-Za-z0-9]*(?![A-Za-z0-9_&-])`,
18
+ "gu",
19
+ );
11
20
 
12
21
  /**
13
22
  * 文書番号は長い通し番号を持つ(800-61、19757-2)。2 桁ずつの番号(BOD 25-01)は範囲・得点・日付(SRE 1-2、NFL 3-1、
@@ -23,7 +32,7 @@ const isRange = (groups: readonly string[]): boolean => {
23
32
 
24
33
  const isDocumentNumber = (number: string): boolean => {
25
34
  const groups = number.split("-");
26
- return groups.some((group) => group.length >= SERIAL_DIGITS) && !isRange(groups);
35
+ return groups.some((group) => group.replace(/\D/gu, "").length >= SERIAL_DIGITS) && !isRange(groups);
27
36
  };
28
37
 
29
38
  /** 文の中の、番号と、その前の大文字の語の範囲。 */