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,55 @@
1
+ // The year a section's heading gives the dates under it: "FY27-Q2 (May 1)", 「2026年度の予定」, 「令和8年の行事」. A yearless
2
+ // date in such a section has its year. Pure.
3
+ import type { StructureNode } from "../plugin.ts";
4
+
5
+ /** A fiscal-year name with its year as a number: "FY{y}" of the language's reporting-period-frame lexicon. */
6
+ export type YearLabel = { readonly before: string; readonly after: string };
7
+
8
+ /** The words that name a year in a heading: era names (令和) and fiscal-year labels ("FY{y}"). */
9
+ export type HeadingYearWords = { readonly eras: readonly string[]; readonly labels: readonly YearLabel[] };
10
+
11
+ /** A year written as figures: 2024年度, "2024 events". */
12
+ const YEAR_FIGURES = /(?<![0-90-9])(?:1[89]|20)\d{2}(?![0-90-9])/u;
13
+ /** An era's year after its name: 8年 of 令和8年, 元年 of 令和元年度 (not 8月). */
14
+ const ERA_YEAR_NUMBER = /^[ \t]?(?:[0-90-9]{1,2}|元)[ \t]?年/u;
15
+ /** A fiscal year's number: two figures (FY27) or four (FY2027). */
16
+ const LABEL_YEAR = /^(?:\d{2}|\d{4})(?!\d)/u;
17
+ const LETTER = /\p{L}/u;
18
+
19
+ /** "FY{y}" as the lexicon writes it: the words before and after the year. A name with no {y} names no year. */
20
+ export const yearLabelOf = (pattern: string): YearLabel | undefined => {
21
+ const at = pattern.indexOf("{y}");
22
+ return at === -1 || pattern.includes("{", at + 1) ? undefined : { before: pattern.slice(0, at).toLowerCase(), after: pattern.slice(at + 3).toLowerCase() };
23
+ };
24
+
25
+ const startsAt = (text: string, index: number): boolean => index === 0 || !LETTER.test(text.charAt(index - 1));
26
+
27
+ const indicesOf = (text: string, word: string, from = 0): number[] => {
28
+ const at = word === "" ? -1 : text.indexOf(word, from);
29
+ return at === -1 ? [] : [at, ...indicesOf(text, word, at + 1)];
30
+ };
31
+
32
+ const namesLabelYear = (heading: string, label: YearLabel): boolean => {
33
+ const text = heading.toLowerCase();
34
+ return indicesOf(text, label.before).some((at) => {
35
+ if (!startsAt(text, at)) return false;
36
+ const year = LABEL_YEAR.exec(text.slice(at + label.before.length))?.[0];
37
+ return year !== undefined && text.startsWith(label.after, at + label.before.length + year.length);
38
+ });
39
+ };
40
+
41
+ const namesEraYear = (heading: string, era: string): boolean => indicesOf(heading, era).some((at) => ERA_YEAR_NUMBER.test(heading.slice(at + era.length)));
42
+
43
+ /** The heading names a year: figures (2026年度), an era's year (令和8年), or a fiscal year (FY27). */
44
+ export const headingNamesYear = (heading: string, words: HeadingYearWords): boolean =>
45
+ YEAR_FIGURES.test(heading) || words.eras.some((era) => namesEraYear(heading, era)) || words.labels.some((label) => namesLabelYear(heading, label));
46
+
47
+ const sectionHeading = (node: StructureNode, current: string): string =>
48
+ node.kind === "section" && node.attrs["heading"] !== undefined ? String(node.attrs["heading"]) : current;
49
+
50
+ /** The offsets of the dates whose own section, the innermost one they are in, has a heading that names a year. */
51
+ export const datesUnderYearHeadings = (tree: StructureNode, words: HeadingYearWords, heading = ""): number[] => {
52
+ const own = sectionHeading(tree, heading);
53
+ if (tree.kind === "date") return headingNamesYear(own, words) ? [tree.span.start] : [];
54
+ return tree.children.flatMap((child) => datesUnderYearHeadings(child, words, own));
55
+ };
@@ -3,15 +3,27 @@
3
3
  import type { Detector, Finding, LexiconEntry, ProseDocument, StructureNode } from "../plugin.ts";
4
4
  import { inDocumentOrder } from "../structure/issues.ts";
5
5
  import { quoteAt } from "./structure-tree.ts";
6
- import { ANY_YEAR_MARKER_LEXICON, YEAR_SPAN_JOINER_LEXICON, anyYearDate, opensSpan, type AnyYearMarker, type MarkerReach } from "./date-any-year.ts";
6
+ import {
7
+ ANY_YEAR_MARKER_LEXICON,
8
+ MARKER_REACHES,
9
+ YEAR_SPAN_JOINER_LEXICON,
10
+ anyYearDate,
11
+ opensSpan,
12
+ type AnyYearMarker,
13
+ type MarkerReach,
14
+ } from "./date-any-year.ts";
15
+ import { datesUnderYearHeadings, yearLabelOf, type HeadingYearWords } from "./date-heading-year.ts";
7
16
 
8
17
  /** The words that make a yearless date any year's (毎年, 例えば, "each") and that join a period's two ends (から, "to"). */
9
18
  export type AnyYearWords = { readonly markers: readonly AnyYearMarker[]; readonly joiners: readonly string[] };
10
19
 
11
20
  const NO_ANY_YEAR_WORDS: AnyYearWords = { markers: [], joiners: [] };
12
21
 
13
- /** A date as the tree reads it: "2026-10-14" with its year, "10-14" without. */
14
- export type DatePoint = { readonly offset: number; readonly end: number; readonly value: string };
22
+ /**
23
+ * A date as the tree reads it: "2026-10-14" with its year, "10-14" without. `yearHeaded`: the heading of its section
24
+ * names a year ("FY27-Q2 (May 1)", 「2026年度の予定」), which the date takes.
25
+ */
26
+ export type DatePoint = { readonly offset: number; readonly end: number; readonly value: string; readonly yearHeaded?: boolean };
15
27
 
16
28
  /** The first and the last year of the document's dated dates. */
17
29
  export type YearSpan = { readonly from: number; readonly to: number };
@@ -106,9 +118,23 @@ const hasYearWord = (point: DatePoint, source: string, yearWords: readonly YearW
106
118
  */
107
119
  const yearGiven = (point: DatePoint, anchors: readonly DatePoint[], source: string, yearWords: readonly YearWord[]): boolean => {
108
120
  const start = lineStart(source, point.offset);
109
- return hasYearWord(point, source, yearWords) || anchors.some((other) => other.offset >= start && other.offset < point.offset);
121
+ return point.yearHeaded === true || hasYearWord(point, source, yearWords) || anchors.some((other) => other.offset >= start && other.offset < point.offset);
110
122
  };
111
123
 
124
+ const DAY_MS = 24 * 60 * 60 * 1000;
125
+ const COMMON_YEAR_MS = 365 * DAY_MS;
126
+ /** A year with no 29 February, so that "03-01" follows "02-28" as it does in most years. */
127
+ const COMMON_YEAR = 2025;
128
+
129
+ const dayOf = (value: string): number => Date.UTC(COMMON_YEAR, Number(value.slice(0, 2)) - 1, Number(value.slice(3, 5)));
130
+
131
+ /**
132
+ * A period of one whole year: its end is the day before its start (January 1 to December 31, 4月1日から3月31日). Without
133
+ * a year it is every year's, like a calendar or a fiscal year.
134
+ */
135
+ export const wholeYear = (start: string, end: string): boolean =>
136
+ MONTH_DAY.test(start) && MONTH_DAY.test(end) && (dayOf(end) + DAY_MS - dayOf(start)) % COMMON_YEAR_MS === 0;
137
+
112
138
  /**
113
139
  * The yearless dates whose year the reader cannot tell. Where most dates carry a year (at least two, and more than the
114
140
  * yearless ones) and those years differ, every yearless one is reported: in a one-year document the year is plain. Where
@@ -124,9 +150,13 @@ export const yearGaps = (
124
150
  const dated = points.filter((point) => FULL.test(point.value));
125
151
  const anchors = [...dated, ...points.filter((point) => hasYearWord(point, source, yearWords))];
126
152
  const nextOf = new Map(points.map((point, index) => [point, points[index + 1]]));
153
+ const previousOf = new Map(points.map((point, index) => [point, points[index - 1]]));
154
+ const yearlySpan = (start: DatePoint | undefined, end: DatePoint | undefined): boolean =>
155
+ start !== undefined && end !== undefined && wholeYear(start.value, end.value) && opensSpan(start, end, source, anyYear.joiners);
127
156
  const yearOfAny = (point: DatePoint): boolean => {
128
157
  const next = nextOf.get(point);
129
158
  if (anyYearDate(point, source, anyYear.markers)) return true;
159
+ if (yearlySpan(point, next) || yearlySpan(previousOf.get(point), point)) return true;
130
160
  return next !== undefined && opensSpan(point, next, source, anyYear.joiners) && hasYearWord(next, source, yearWords);
131
161
  };
132
162
  // A recurring day or an example's date has no year to write, and is not the document's way of writing dates either.
@@ -134,20 +164,35 @@ export const yearGaps = (
134
164
  const span = spanOf(dated);
135
165
  const unclear = dated.length >= 2 && yearless.length < dated.length && span !== undefined && span.to > span.from;
136
166
  const datedSides = new Set(dated.flatMap((point) => sideOf(monthOf(FULL, point.value)) ?? []));
137
- const previousOf = new Map(points.map((point, index) => [point, points[index - 1]]));
138
167
  return yearless.flatMap((point): YearGap[] => {
139
168
  if (unclear) return [{ point, kind: "years", span }];
140
169
  return crossesYear(point, previousOf.get(point), datedSides) ? [{ point, kind: "boundary", span }] : [];
141
170
  });
142
171
  };
143
172
 
144
- export const datePoints = (tree: StructureNode): DatePoint[] =>
145
- inDocumentOrder(tree).flatMap((node) => (node.kind === "date" ? [{ offset: node.span.start, end: node.span.end, value: String(node.attrs["value"]) }] : []));
173
+ const NO_HEADING_YEAR_WORDS: HeadingYearWords = { eras: [], labels: [] };
174
+
175
+ export const datePoints = (tree: StructureNode, headingWords: HeadingYearWords = NO_HEADING_YEAR_WORDS): DatePoint[] => {
176
+ const yearHeaded = new Set(datesUnderYearHeadings(tree, headingWords));
177
+ return inDocumentOrder(tree).flatMap((node) =>
178
+ node.kind === "date"
179
+ ? [{ offset: node.span.start, end: node.span.end, value: String(node.attrs["value"]), yearHeaded: yearHeaded.has(node.span.start) }]
180
+ : [],
181
+ );
182
+ };
146
183
 
147
184
  const yearWordsOf = (doc: ProseDocument): YearWord[] =>
148
185
  (doc.lexicons[YEAR_REFERENCE_LEXICON] ?? []).map((entry: LexiconEntry) => ({ word: entry.pattern, position: entry.position }));
149
186
 
150
- const reachOf = (group: string | undefined): MarkerReach => (group === "adjacent" || group === "label" ? group : "sentence");
187
+ /** The era names (calendar-era) and the fiscal-year names ("FY{y}" of reporting-period-frame) a heading may give a year with. */
188
+ const headingYearWordsOf = (doc: ProseDocument): HeadingYearWords => ({
189
+ eras: (doc.lexicons["calendar-era"] ?? []).map((entry: LexiconEntry) => entry.pattern),
190
+ labels: (doc.lexicons["reporting-period-frame"] ?? []).flatMap((entry: LexiconEntry) =>
191
+ entry.group === "fiscal-year" ? (yearLabelOf(entry.pattern) ?? []) : [],
192
+ ),
193
+ });
194
+
195
+ const reachOf = (group: string | undefined): MarkerReach => MARKER_REACHES.find((reach) => reach === group) ?? "sentence";
151
196
 
152
197
  const anyYearWordsOf = (doc: ProseDocument): AnyYearWords => ({
153
198
  markers: (doc.lexicons[ANY_YEAR_MARKER_LEXICON] ?? []).map((entry: LexiconEntry) => ({ word: entry.pattern, reach: reachOf(entry.group) })),
@@ -157,7 +202,7 @@ const anyYearWordsOf = (doc: ProseDocument): AnyYearWords => ({
157
202
  export const dateWithoutYear: Detector = (doc: ProseDocument): Finding[] =>
158
203
  doc.structure === undefined
159
204
  ? []
160
- : yearGaps(datePoints(doc.structure), doc.source, yearWordsOf(doc), anyYearWordsOf(doc)).map((gap) => ({
205
+ : yearGaps(datePoints(doc.structure, headingYearWordsOf(doc)), doc.source, yearWordsOf(doc), anyYearWordsOf(doc)).map((gap) => ({
161
206
  rule: "date-without-year",
162
207
  severity: "warning",
163
208
  line: 0,
@@ -199,11 +199,31 @@ const MIN_NAME_CHARS = 4;
199
199
  /** In English a long name has two words or more (Acme Corporation); one capitalised word is the term's own kind of word. */
200
200
  const MIN_NAME_WORDS = 2;
201
201
  const LATIN = /\p{Script=Latin}/u;
202
+ const LETTER = /\p{L}/u;
203
+ const JAPANESE = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u;
202
204
 
203
205
  const isNamePart = (token: Token): boolean => NAME_PARTS.has(token.pos) || NAME_MARKS.has(token.surface);
204
206
 
207
+ /**
208
+ * A label for each of several things or for all of them together ((each, a "Certificate"), (collectively, the "Plans"))
209
+ * names the head of the clause before it (a certificate that represented any share of Common Stock), not its last words.
210
+ */
211
+ const LABELS_THE_CLAUSE = /^[((](?:each|collectively)\b/iu;
212
+
213
+ /**
214
+ * Whether the words make a long name. In English, two words with letters, one of them capitalised: a figure is not a word
215
+ * of a name (as amended on January 26, 2015 (the "Indenture"), a par value of $1.00 (the "Preference Stock")), and lower-case
216
+ * words (with respect thereto) are used in their own sense. A name with Japanese in it (株式会社ABC), four characters or more.
217
+ */
218
+ const isLongName = (name: string): boolean => {
219
+ const words = name.split(/\s+/u).filter((word) => LETTER.test(word));
220
+ if (words.length === 0 || [...name].length < MIN_NAME_CHARS) return false;
221
+ return !LATIN.test(name) || JAPANESE.test(name) || (words.length >= MIN_NAME_WORDS && words.some((word) => UPPER_START.test(word)));
222
+ };
223
+
205
224
  /** The long name written right before an inline definition: the run of name words that ends at its opening bracket. */
206
225
  export const nameBefore = (sentence: Sentence, bracket: number): string | undefined => {
226
+ if (LABELS_THE_CLAUSE.test(sentence.text.slice(bracket - sentence.span.start))) return undefined;
207
227
  const tokens = (sentence.tokens ?? []).filter((token) => token.span.end <= bracket);
208
228
  const firstOfRun = tokens.findLastIndex((token) => !isNamePart(token)) + 1;
209
229
  if (isModifier(tokens[firstOfRun - 1])) return undefined;
@@ -212,16 +232,17 @@ export const nameBefore = (sentence: Sentence, bracket: number): string | undefi
212
232
  const end = run.at(-1);
213
233
  if (first === undefined || end === undefined || bracket - end.span.end > 1) return undefined;
214
234
  const name = withoutTrailingMarks(sentence.text.slice(first.span.start - sentence.span.start, end.span.end - sentence.span.start));
215
- const words = name.split(/\s+/u).length;
216
- return [...name].length < MIN_NAME_CHARS || (LATIN.test(name) && words < MIN_NAME_WORDS) ? undefined : name;
235
+ return isLongName(name) ? name : undefined;
217
236
  };
218
237
 
219
238
  /**
220
- * A word that narrows the name before it: an article, an adjective, a verb, or の (妊娠中の女性従業員, the Beta Preview, 本利用規約).
221
- * The words then name a kind of thing the definition picks out, not one party, and are used in their own sense again.
239
+ * A word that narrows the name before it: an article, an adjective, a verb, or a possessive (妊娠中の女性従業員, the Beta
240
+ * Preview, 本利用規約, users of Customer's Web site). The words then name a kind of thing the definition picks out, not one
241
+ * party, and are used in their own sense again.
222
242
  */
223
243
  const MODIFIERS = new Set(["DET", "ADJ", "VERB", "AUX"]);
224
- const isModifier = (token: Token | undefined): boolean => token !== undefined && (MODIFIERS.has(token.pos) || token.surface === "の");
244
+ const POSSESSIVES = new Set(["の", "'s", "’s", "'", "’"]);
245
+ const isModifier = (token: Token | undefined): boolean => token !== undefined && (MODIFIERS.has(token.pos) || POSSESSIVES.has(token.surface));
225
246
 
226
247
  const TRAILING_MARKS = new Set([",", ".", " "]);
227
248
 
@@ -1,6 +1,7 @@
1
1
  // The shape of a document's top: whether the lead says anything the title does not, and whether a title or heading
2
2
  // runs too long to scan. Pure; both read only the sections, paragraphs and tokens chaff has already built.
3
3
  import { newContentMorphemes } from "./content-morphemes.ts";
4
+ import { formValueTokens, isFormBlock } from "./form-line.ts";
4
5
  import { trigrams } from "./heading-overlap.ts";
5
6
  import { findingAt, writtenHeadings } from "./markup-finding.ts";
6
7
  import type { Detector, Finding, LengthUnit, MarkupHeading, Paragraph, ProseDocument, Section } from "../plugin.ts";
@@ -38,6 +39,13 @@ const leadOf = (doc: ProseDocument): Lead | undefined => {
38
39
  const lead = title === undefined ? undefined : leadParagraphOf(doc, title);
39
40
  if (title === undefined || lead === undefined || title.headingTokens === undefined) return undefined;
40
41
  const leadTokens = lead.sentences.flatMap((sentence) => sentence.tokens ?? []);
42
+ // A form or a letter opens with fields or a letterhead, not a lead (Invoice number: INV-2026-0318). A line that only copies the title is still one.
43
+ const leadSource = doc.source.slice(lead.span.start, lead.span.end);
44
+ if (
45
+ isFormBlock(leadSource, lead.span.start, leadTokens) &&
46
+ newContentMorphemes(title.headingTokens, formValueTokens(leadSource, lead.span.start, leadTokens)) > 0
47
+ )
48
+ return undefined;
41
49
  const leadText = lead.sentences.map((sentence) => sentence.text).join(" ");
42
50
  return { title, lead, fresh: newContentMorphemes(title.headingTokens, leadTokens), echo: echoPercent(title.heading, leadText) };
43
51
  };
@@ -1,18 +1,22 @@
1
1
  // due-before-issue: the reading half. The issue-date and due-date words come from the language's lexicons
2
2
  // (issue-date-label, due-date-label, deadline-passed-word), and so do the words of minutes (minutes-title-word, meeting-date-label,
3
3
  // action-section-heading, earlier-section-word, action-due-label, item-done-word) and the other pairs of dates that must come in
4
- // order (dated-pair-label, date-now-word, and dated-span-label for the words whose line states a period, read up to its end;
5
- // a table whose header names both columns of a pair, from dated-pair-label and the header-only dated-column-label);
4
+ // order (dated-pair-label, date-now-word, and dated-span-label for the words whose line states a period, read up to its end,
5
+ // or from its start in the group a dated-span-label entry names;
6
+ // a table whose header names both columns of a pair, from dated-pair-label and the header-only dated-column-label;
7
+ // a signature line giving a pair's later date, from the role words of dated-signer-label;
8
+ // a pair's label naming a version, End of support for 5.0.0 or 3.0.0 のサポート終了日, from dated-pair-version-word);
6
9
  // the dates are the structure tree's, and the lines are read with code masked.
7
10
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
8
11
  import { actionDueBeforeMeeting, type ActionWords } from "../structure/action-due.ts";
9
12
  import { columnDatesOutOfOrder } from "../structure/column-date-order.ts";
10
- import { pairedDatesOutOfOrder, type OrderDate } from "../structure/labelled-date-order.ts";
13
+ import { pairedDatesOutOfOrder, type OrderDate, type PairedIssue } from "../structure/labelled-date-order.ts";
11
14
  import { dueBeforeIssue, type DueWords } from "../structure/due-date.ts";
12
15
  import { inDocumentOrder, type StructureIssue } from "../structure/issues.ts";
13
16
  import { proseAndTablesOf } from "../table-text.ts";
14
17
  import { periodWordsOf } from "./range-words.ts";
15
18
  import { quoteAt } from "./structure-tree.ts";
19
+ import type { VersionWords } from "../structure/versioned-label.ts";
16
20
  import { readableDates, withReadableDates } from "./readable-dates.ts";
17
21
 
18
22
  /** A record's facts table can sit well below its header date (a listing date above the table holding the move-in date). */
@@ -35,6 +39,12 @@ const actionWordsOf = (doc: ProseDocument): ActionWords => ({
35
39
  minutes: patternsOf(doc, "minutes-title-word"),
36
40
  });
37
41
 
42
+ const versionWordsOf = (doc: ProseDocument): VersionWords => {
43
+ const entries = doc.lexicons["dated-pair-version-word"] ?? [];
44
+ const at = (position: "before" | "after"): string[] => entries.filter((entry) => entry.position === position).map((entry) => entry.pattern);
45
+ return { after: at("after"), before: at("before") };
46
+ };
47
+
38
48
  const orderAsidesOf = (doc: ProseDocument): string[] => [...patternsOf(doc, "deadline-passed-word"), ...patternsOf(doc, "date-now-word")];
39
49
 
40
50
  const treeDates = (tree: NonNullable<ProseDocument["structure"]>): OrderDate[] =>
@@ -50,17 +60,26 @@ const findingOf = (doc: ProseDocument, issue: StructureIssue, variant?: string):
50
60
  ...(variant === undefined ? {} : { variant }),
51
61
  });
52
62
 
63
+ const variantOf = (issue: PairedIssue): string => {
64
+ if (issue.fromStart === true) return "period-start";
65
+ return issue.period ? "period" : "order";
66
+ };
67
+
53
68
  export const dueDate: Detector = (doc): Finding[] => {
54
69
  if (doc.structure === undefined) return [];
55
70
  const text = proseAndTablesOf(doc);
56
71
  const dates = treeDates(doc.structure);
57
72
  const pairs = doc.lexicons["dated-pair-label"] ?? [];
58
- const spans = periodWordsOf(doc, patternsOf(doc, "dated-span-label"));
73
+ const spanEntries = doc.lexicons["dated-span-label"] ?? [];
74
+ const spans = { ...periodWordsOf(doc, [...new Set(spanEntries.map((entry) => entry.pattern))]), entries: spanEntries };
59
75
  return [
60
76
  ...dueBeforeIssue(text, dates, wordsOf(doc)).map((issue) => findingOf(doc, issue)),
61
- ...pairedDatesOutOfOrder(text, dates, pairs, orderAsidesOf(doc), MAX_RECORD_LINE_GAP, spans).map((issue) =>
62
- findingOf(doc, issue, issue.period ? "period" : "order"),
63
- ),
77
+ ...pairedDatesOutOfOrder(text, dates, pairs, orderAsidesOf(doc), MAX_RECORD_LINE_GAP, {
78
+ spans,
79
+ whole: doc.source,
80
+ signers: doc.lexicons["dated-signer-label"] ?? [],
81
+ versions: versionWordsOf(doc),
82
+ }).map((issue) => findingOf(doc, issue, variantOf(issue))),
64
83
  ...columnDatesOutOfOrder(text, dates, [...pairs, ...(doc.lexicons["dated-column-label"] ?? [])], orderAsidesOf(doc)).map((issue) =>
65
84
  findingOf(doc, issue, "order"),
66
85
  ),
@@ -1,6 +1,7 @@
1
1
  import { lengthOf } from "../measure.ts";
2
2
  import { isClosed } from "../sentence-shape.ts";
3
3
  import { isTitleCase, minorityCase, pageTitleOf } from "./heading-case.ts";
4
+ import { namesWrittenMidSentence } from "./heading-names.ts";
4
5
  import type { Detector, Finding, Lexicon, ProseDocument, Section, Sentence, Token } from "../plugin.ts";
5
6
  import { entryOpens } from "./lexicon-match.ts";
6
7
 
@@ -137,7 +138,10 @@ const headingsOf = (sections: readonly Section[], fixedCase: ReadonlySet<string>
137
138
  * 見るのは文書の中で揃っているかだけで、少数派のほうを指摘する。題名は指摘しない(minorityCase)。
138
139
  */
139
140
  export const titleCaseMix: Detector = (doc, options): Finding[] => {
140
- const fixedCase = new Set(FIXED_CASE_LISTS.flatMap((id) => (doc.lexicons[id] ?? []).map((entry) => entry.pattern)));
141
+ const fixedCase = new Set([
142
+ ...FIXED_CASE_LISTS.flatMap((id) => (doc.lexicons[id] ?? []).map((entry) => entry.pattern)),
143
+ ...namesWrittenMidSentence(doc.sentences.map((sentence) => sentence.text)),
144
+ ]);
141
145
  const pageTitle = pageTitleOf(doc.sections);
142
146
  const judged = headingsOf(
143
147
  doc.sections.filter((section) => section !== pageTitle),
@@ -2,7 +2,7 @@ import type { Detector, Finding, ProseDocument, StructureNode } from "../plugin.
2
2
  import { countedFacts, countedPhraseAt, type CountedPhrase } from "../facts/counted-facts.ts";
3
3
  import { nameSpans } from "../compare/proper-nouns.ts";
4
4
  import { factValues, type FactValue } from "../facts/fact-values.ts";
5
- import { labelledFacts, type AttributePhrase, type Fact, type FactWords } from "../facts/labelled-facts.ts";
5
+ import { attributePhrasesOf, labelledFacts, type Fact, type FactWords } from "../facts/labelled-facts.ts";
6
6
  import { tableFacts, type TotalColumns } from "../facts/table-facts.ts";
7
7
  import { withCellKeys } from "../facts/cell-keys.ts";
8
8
  import { verbQuantityFacts, type VerbQuantityWords } from "../facts/verb-quantity-facts.ts";
@@ -21,11 +21,13 @@ import { overlapsAny, spanIndex } from "../compare/spans.ts";
21
21
  import { documentTermConflicts, isTermName, termHomes, type TermWord, type TermWords } from "../facts/document-terms.ts";
22
22
  import { termValues, type PlacedWord, type TermValueWords } from "../facts/term-values.ts";
23
23
  import { inDocumentOrder } from "../structure/issues.ts";
24
- import { ageValues, type AgeWord, type AgeWords } from "../facts/age-values.ts";
24
+ import { ageValues } from "../facts/age-values.ts";
25
+ import { ageWordsOf } from "./age-words.ts";
25
26
  import { qualifiedKeyOf, qualifiedKeys, type QualifierWords } from "../facts/qualified-labels.ts";
26
27
  import { rowSentenceFindings } from "./row-sentence-amounts.ts";
27
28
  import type { RateWord, RateWords } from "../facts/rate-values.ts";
28
29
  import { wholeCountFindings } from "./whole-count-findings.ts";
30
+ import { perUnitsOf, perUnitValues } from "./per-unit-words.ts";
29
31
 
30
32
  const patternsOf = (doc: ProseDocument, id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
31
33
 
@@ -51,7 +53,7 @@ export const factWordsOf = (doc: ProseDocument): FactWords => ({
51
53
  leads: patternsOf(doc, "fact-label-lead"),
52
54
  rates: rateWordsOf(doc),
53
55
  readings: { verbs: patternsOf(doc, "fact-reading-verb"), gauges: patternsOf(doc, "fact-reading-gauge"), clauses: patternsOf(doc, "fact-reading-clause") },
54
- attributes: (doc.lexicons["fact-attribute"] ?? []).map((entry): AttributePhrase => ({ pattern: entry.pattern, position: entry.position ?? "before" })),
56
+ attributes: attributePhrasesOf(doc.lexicons["fact-attribute"] ?? []),
55
57
  });
56
58
 
57
59
  const placedWordsOf = (doc: ProseDocument, id: string): PlacedWord[] =>
@@ -71,6 +73,10 @@ const termValueWordsOf = (doc: ProseDocument): TermValueWords => ({
71
73
  selves: placedWordsOf(doc, "fact-term-self"),
72
74
  starts: placedWordsOf(doc, "fact-term-start"),
73
75
  valueEnds: patternsOf(doc, "fact-value-end"),
76
+ restating: patternsOf(doc, "fact-term-restating"),
77
+ frames: patternsOf(doc, "fact-term-frame"),
78
+ conditions: patternsOf(doc, "fact-amount-condition"),
79
+ qualifiers: qualifierWordsOf(doc),
74
80
  });
75
81
 
76
82
  const totalColumnsOf = (doc: ProseDocument): TotalColumns => {
@@ -89,15 +95,6 @@ const durationWordsOf = (doc: ProseDocument): DurationWord[] => [
89
95
  ),
90
96
  ];
91
97
 
92
- const ageWordsAt = (doc: ProseDocument, id: string): AgeWord[] =>
93
- (doc.lexicons[id] ?? []).map((entry): AgeWord => ({ pattern: entry.pattern, position: entry.position ?? "before" }));
94
-
95
- const ageWordsOf = (doc: ProseDocument): AgeWords => ({
96
- marks: ageWordsAt(doc, "fact-age-mark"),
97
- limits: ageWordsAt(doc, "fact-age-limit"),
98
- joiners: patternsOf(doc, "fact-age-joiner"),
99
- });
100
-
101
98
  const qualifierWordsOf = (doc: ProseDocument): QualifierWords => ({
102
99
  templates: patternsOf(doc, "fact-label-qualifier"),
103
100
  determiners: patternsOf(doc, "fact-label-drop"),
@@ -123,6 +120,7 @@ const withQualifiedKeys = <T extends Fact>(doc: ProseDocument, facts: readonly T
123
120
  /**
124
121
  * 単位の語彙表の量(410 g、1.2 kg)と期間(3 months)と年齢(満70歳まで、aged 20 to 70)も値として読む。木が単位を読まない量は、
125
122
  * 数だけでは升や文の値にならない。年齢と重なる期間(30 years old の 30 years)と、期間と重なる量(3 months の 3 m)は読まない。
123
+ * 数量には何あたりか(1kmあたり15円)を付ける。何あたりの値は、それを掛けた金額とは比べない。
126
124
  */
127
125
  const readFacts = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
128
126
  const tagged = factValues(tree, doc.source, nameSpans(doc));
@@ -134,7 +132,7 @@ const readFacts = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
134
132
  durationWordsOf(doc),
135
133
  );
136
134
  const taken = spanIndex([...ages, ...durations]);
137
- const values = valuesWith(tree, doc, [...measuredOf(doc).filter((value) => !overlapsAny(taken, value)), ...ages, ...durations]);
135
+ const values = perUnitsOf(doc, valuesWith(tree, doc, [...measuredOf(doc).filter((value) => !overlapsAny(taken, value)), ...ages, ...durations]));
138
136
  const terms = termValues(doc.source, values, termValueWordsOf(doc));
139
137
  const termed = new Set(terms.map((fact) => fact.value.start));
140
138
  const labelled = labelledFacts(doc.source, values, { ...factWordsOf(doc), qualifiers: qualifierWordsOf(doc) }).filter(
@@ -142,9 +140,10 @@ const readFacts = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
142
140
  );
143
141
  const read = new Set([...termed, ...labelled.map((fact) => fact.value.start)]);
144
142
  const verbs = verbQuantityFacts(doc.source, values, verbQuantityWordsOf(doc)).filter((fact) => !read.has(fact.value.start));
145
- const tabled = tableFacts(doc.source, values, totalColumnsOf(doc), countLabelWordsOf(doc.lexicons));
143
+ const tabled = tableFacts(doc.source, values, totalColumnsOf(doc), countLabelWordsOf(doc.lexicons), { columnGroups: true });
146
144
  const facts = withQualifiedKeys(doc, [...labelled, ...terms, ...verbs, ...tabled]);
147
- return withCellKeys(scopedFacts(facts, tree, doc.source, patternsOf(doc, "summary-heading")), qualifierWordsOf(doc));
145
+ const scoped = scopedFacts(facts, tree, doc.source, patternsOf(doc, "summary-heading"), { paragraphHeads: true });
146
+ return withCellKeys(scoped, qualifierWordsOf(doc));
148
147
  };
149
148
 
150
149
  /** 文書の名前付きの値。二つの rule が読むので、文書ごとに一度だけ読む。 */
@@ -263,8 +262,7 @@ const countedPhrasesOf = (doc: ProseDocument): CountedPhrase[] =>
263
262
  const countedFactsOf = (doc: ProseDocument): ScopedFact[] => {
264
263
  const tree = doc.structure;
265
264
  if (tree === undefined) return [];
266
- const values = factValues(tree, doc.source, nameSpans(doc));
267
- return scopedFacts(countedFacts(doc.source, values, countedPhrasesOf(doc)), tree, doc.source, patternsOf(doc, "summary-heading"));
265
+ return scopedFacts(countedFacts(doc.source, perUnitValues(doc, tree), countedPhrasesOf(doc)), tree, doc.source, patternsOf(doc, "summary-heading"));
268
266
  };
269
267
 
270
268
  const wordsAt = (doc: ProseDocument, id: string): WordAt[] =>
@@ -319,8 +317,7 @@ const pairFinding =
319
317
  const conditionPairFindings = (doc: ProseDocument): Finding[] => {
320
318
  const tree = doc.structure;
321
319
  if (tree === undefined) return [];
322
- const values = factValues(tree, doc.source, nameSpans(doc));
323
- return conditionPairConflicts(doc.source, changeSentencesOf(doc, tree), values, changeWordsOf(doc)).map(pairFinding(doc));
320
+ return conditionPairConflicts(doc.source, changeSentencesOf(doc, tree), perUnitValues(doc, tree), changeWordsOf(doc)).map(pairFinding(doc));
324
321
  };
325
322
 
326
323
  const eventWordsOf = (doc: ProseDocument): EventWord[] =>
@@ -0,0 +1,47 @@
1
+ // Lines at the top of a form or a letter that are not sentences: a field ("Invoice number: INV-2026-0318",
2
+ // 「見積番号:RF-731852」) or a name standing alone (a letterhead, 「有限会社つばめ野リフォーム」). Pure.
3
+ import { labelLine } from "./number-unit.ts";
4
+ import type { Token } from "../plugin.ts";
5
+
6
+ /** Parts of speech a name is made of: no verb, adjective, determiner or particle. */
7
+ const NAME_POS: ReadonlySet<string> = new Set(["NOUN", "PROPN", "NUM", "PUNCT", "SYM", "X"]);
8
+ /** A value with one of these says something ("Note: this page is a sample."); it is a sentence behind a label. */
9
+ const PREDICATE_POS: ReadonlySet<string> = new Set(["VERB", "AUX"]);
10
+
11
+ const isNameOnly = (tokens: readonly Token[]): boolean => tokens.some((token) => token.pos !== "PUNCT") && tokens.every((token) => NAME_POS.has(token.pos));
12
+
13
+ /** "Label: value" whose value states nothing: a number, a date, a name. */
14
+ const isField = (line: string, start: number, tokens: readonly Token[]): boolean => {
15
+ const field = labelLine(line, start);
16
+ return field !== undefined && !tokens.some((token) => token.span.start >= field.at && PREDICATE_POS.has(token.pos));
17
+ };
18
+
19
+ type Line = { readonly text: string; readonly start: number };
20
+
21
+ const linesOf = (text: string, start: number): Line[] =>
22
+ text.split("\n").reduce<Line[]>((lines, line) => {
23
+ const last = lines.at(-1);
24
+ return [...lines, { text: line, start: last === undefined ? start : last.start + last.text.length + 1 }];
25
+ }, []);
26
+
27
+ const isFormLine = (line: Line, tokens: readonly Token[]): boolean => {
28
+ const inLine = tokens.filter((token) => token.span.start >= line.start && token.span.start < line.start + line.text.length);
29
+ return isNameOnly(inLine) || isField(line.text, line.start, inLine);
30
+ };
31
+
32
+ /**
33
+ * Every line of the block gives a field and its value, or only a name: the top of a form or a letterhead, not a sentence.
34
+ * `start` is where the text starts in the coordinates of the tokens' spans. Without tokens no block is read as a form.
35
+ */
36
+ export const isFormBlock = (text: string, start: number, tokens: readonly Token[] | undefined): boolean => {
37
+ const lines = linesOf(text, start).filter((line) => line.text.trim() !== "");
38
+ return tokens !== undefined && lines.length > 0 && lines.every((line) => isFormLine(line, tokens));
39
+ };
40
+
41
+ /** What a form block gives: the tokens after each field's label, and every token of a name line. */
42
+ export const formValueTokens = (text: string, start: number, tokens: readonly Token[]): Token[] =>
43
+ linesOf(text, start).flatMap((line) => {
44
+ const field = labelLine(line.text, line.start);
45
+ const from = field?.at ?? line.start;
46
+ return tokens.filter((token) => token.span.start >= from && token.span.start < line.start + line.text.length);
47
+ });
@@ -4,12 +4,10 @@
4
4
  // currency-notation's, read with amount-multiplier's words of scale. The profile may give the tax rate a document leaves out.
5
5
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
6
6
  import { formulaAmountMismatches, type FormulaWords } from "../structure/formula-amount.ts";
7
- import type { StatedAmount } from "../structure/stated-multiple.ts";
8
7
  import type { TaxPriceRole, TaxPriceWord } from "../structure/tax-price.ts";
9
- import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
10
- import { amountsIn, formsOf } from "./currency-notation.ts";
11
8
  import { proseAndTablesOf } from "../table-text.ts";
12
9
  import { quoteAround } from "./quote-around.ts";
10
+ import { statedAmountsOf } from "./stated-amounts.ts";
13
11
 
14
12
  const TAX_ROLES: readonly string[] = ["excluded", "included", "rate"] satisfies readonly TaxPriceRole[];
15
13
  const isTaxRole = (group: string | undefined): group is TaxPriceRole => group !== undefined && TAX_ROLES.includes(group);
@@ -31,23 +29,9 @@ const wordsOf = (doc: ProseDocument): FormulaWords => ({
31
29
  notIncluded: patternsOf(doc, "formula-amount-word", "not-included"),
32
30
  });
33
31
 
34
- const amountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
35
- const scales = scaleWordsOf(doc);
36
- return amountsIn(
37
- text,
38
- formsOf(doc),
39
- scales.map((scale) => scale.word),
40
- ).flatMap((amount) => {
41
- const read = scaledAmountOf(text, amount, scales);
42
- return read === undefined
43
- ? []
44
- : [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
45
- });
46
- };
47
-
48
32
  export const formulaAmount: Detector = (doc): Finding[] => {
49
33
  const text = proseAndTablesOf(doc);
50
- const input = { text, amounts: amountsOf(text, doc), defaultTaxRate: doc.profile?.taxRate };
34
+ const input = { text, amounts: statedAmountsOf(text, doc), defaultTaxRate: doc.profile?.taxRate };
51
35
  return formulaAmountMismatches(input, wordsOf(doc)).map((issue) => ({
52
36
  rule: "formula-amount-mismatch",
53
37
  severity: "warning",
@@ -0,0 +1,36 @@
1
+ import type { Section, Sentence } from "../plugin.ts";
2
+
3
+ /**
4
+ * 問いの印で終わる見出し。後ろに括弧の注記((updated Nov. 14, 2024))が付いてもよい。
5
+ * 「Q1」の札だけでは問いと見ない。四半期(Q1 2024)の見出しと見分けられない。
6
+ */
7
+ const QUESTION_END = /[??]\s*(?:[((][^()()]*[))])?$/u;
8
+
9
+ export const isQuestionHeading = (heading: string): boolean => QUESTION_END.test(heading.trim());
10
+
11
+ /** 範囲を決めるのに見るのは、見出しと深さと文だけ。 */
12
+ type Heading = Pick<Section, "depth" | "heading" | "sentences">;
13
+
14
+ type Answer = { readonly depth: number; readonly sentences: Sentence[] };
15
+ type Passages = { readonly rest: Sentence[]; readonly answers: Answer[]; readonly open: readonly Answer[] };
16
+
17
+ /** 節は、それを囲む一番内側の問いの答えに入る。同じ深さか浅い見出しが来れば、その問いは閉じている。 */
18
+ const place = (passages: Passages, section: Heading): Passages => {
19
+ const open = passages.open.filter((answer) => answer.depth < section.depth);
20
+ if (isQuestionHeading(section.heading)) {
21
+ const answer = { depth: section.depth, sentences: [...section.sentences] };
22
+ return { ...passages, answers: [...passages.answers, answer], open: [...open, answer] };
23
+ }
24
+ const owner = open.at(-1);
25
+ (owner?.sentences ?? passages.rest).push(...section.sentences);
26
+ return { ...passages, open };
27
+ };
28
+
29
+ /**
30
+ * 言い回しを数える範囲。問いの見出しの下(より深い見出しの「A1」も含む)はそれぞれ一つの答えで、読み手は答えを一つずつ読む。
31
+ * 別の答えで同じ案内(〜をご覧ください)を繰り返しても、書き手が言い直したのではない。問いでない節は、文書全体で一つの範囲。
32
+ */
33
+ export const gramPassagesOf = (sections: readonly Heading[]): Sentence[][] => {
34
+ const passages = sections.reduce<Passages>(place, { rest: [], answers: [], open: [] });
35
+ return [passages.rest, ...passages.answers.map((answer) => answer.sentences)].filter((sentences) => sentences.length > 0);
36
+ };