chaffjs 0.33.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. package/dist/api.d.ts +7 -1
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js.map +1 -1
  4. package/dist/capitals-passage.d.ts +3 -0
  5. package/dist/capitals-passage.d.ts.map +1 -0
  6. package/dist/capitals-passage.js +26 -0
  7. package/dist/capitals-passage.js.map +1 -0
  8. package/dist/cli-text.d.ts.map +1 -1
  9. package/dist/cli-text.js +4 -2
  10. package/dist/cli-text.js.map +1 -1
  11. package/dist/coined-hyphen-name.d.ts +13 -0
  12. package/dist/coined-hyphen-name.d.ts.map +1 -0
  13. package/dist/coined-hyphen-name.js +21 -0
  14. package/dist/coined-hyphen-name.js.map +1 -0
  15. package/dist/commands/grade.d.ts.map +1 -1
  16. package/dist/commands/grade.js +66 -21
  17. package/dist/commands/grade.js.map +1 -1
  18. package/dist/company-kana-spelling.d.ts +6 -1
  19. package/dist/company-kana-spelling.d.ts.map +1 -1
  20. package/dist/company-kana-spelling.js +19 -2
  21. package/dist/company-kana-spelling.js.map +1 -1
  22. package/dist/company-name-ending.d.ts +7 -0
  23. package/dist/company-name-ending.d.ts.map +1 -0
  24. package/dist/company-name-ending.js +44 -0
  25. package/dist/company-name-ending.js.map +1 -0
  26. package/dist/company-names.d.ts +17 -4
  27. package/dist/company-names.d.ts.map +1 -1
  28. package/dist/company-names.js +49 -17
  29. package/dist/company-names.js.map +1 -1
  30. package/dist/custom/no-rewrite.d.ts +3 -0
  31. package/dist/custom/no-rewrite.d.ts.map +1 -0
  32. package/dist/custom/no-rewrite.js +3 -0
  33. package/dist/custom/no-rewrite.js.map +1 -0
  34. package/dist/custom/parse.d.ts.map +1 -1
  35. package/dist/custom/parse.js +14 -2
  36. package/dist/custom/parse.js.map +1 -1
  37. package/dist/detectors/acronym-context.d.ts +1 -1
  38. package/dist/detectors/acronym-context.d.ts.map +1 -1
  39. package/dist/detectors/acronym-context.js +4 -4
  40. package/dist/detectors/acronym-context.js.map +1 -1
  41. package/dist/detectors/acronym-definition.d.ts +13 -0
  42. package/dist/detectors/acronym-definition.d.ts.map +1 -0
  43. package/dist/detectors/acronym-definition.js +90 -0
  44. package/dist/detectors/acronym-definition.js.map +1 -0
  45. package/dist/detectors/acronym-lone.d.ts +13 -0
  46. package/dist/detectors/acronym-lone.d.ts.map +1 -0
  47. package/dist/detectors/acronym-lone.js +22 -0
  48. package/dist/detectors/acronym-lone.js.map +1 -0
  49. package/dist/detectors/acronym-name.d.ts +55 -0
  50. package/dist/detectors/acronym-name.d.ts.map +1 -0
  51. package/dist/detectors/acronym-name.js +75 -0
  52. package/dist/detectors/acronym-name.js.map +1 -0
  53. package/dist/detectors/age-words.d.ts +5 -0
  54. package/dist/detectors/age-words.d.ts.map +1 -0
  55. package/dist/detectors/age-words.js +8 -0
  56. package/dist/detectors/age-words.js.map +1 -0
  57. package/dist/detectors/annual-pay-mismatch.d.ts.map +1 -1
  58. package/dist/detectors/annual-pay-mismatch.js +2 -12
  59. package/dist/detectors/annual-pay-mismatch.js.map +1 -1
  60. package/dist/detectors/blank-structure.d.ts.map +1 -1
  61. package/dist/detectors/blank-structure.js +4 -3
  62. package/dist/detectors/blank-structure.js.map +1 -1
  63. package/dist/detectors/capitalised-term.d.ts +14 -2
  64. package/dist/detectors/capitalised-term.d.ts.map +1 -1
  65. package/dist/detectors/capitalised-term.js +115 -4
  66. package/dist/detectors/capitalised-term.js.map +1 -1
  67. package/dist/detectors/caps-caption.d.ts +11 -0
  68. package/dist/detectors/caps-caption.d.ts.map +1 -0
  69. package/dist/detectors/caps-caption.js +51 -0
  70. package/dist/detectors/caps-caption.js.map +1 -0
  71. package/dist/detectors/char-shape.d.ts.map +1 -1
  72. package/dist/detectors/char-shape.js +47 -18
  73. package/dist/detectors/char-shape.js.map +1 -1
  74. package/dist/detectors/clause-shape.d.ts +1 -1
  75. package/dist/detectors/clause-shape.d.ts.map +1 -1
  76. package/dist/detectors/clause-shape.js +9 -4
  77. package/dist/detectors/clause-shape.js.map +1 -1
  78. package/dist/detectors/closing-balance-mismatch.d.ts.map +1 -1
  79. package/dist/detectors/closing-balance-mismatch.js +1 -0
  80. package/dist/detectors/closing-balance-mismatch.js.map +1 -1
  81. package/dist/detectors/code-fences.d.ts +5 -0
  82. package/dist/detectors/code-fences.d.ts.map +1 -1
  83. package/dist/detectors/code-fences.js +9 -0
  84. package/dist/detectors/code-fences.js.map +1 -1
  85. package/dist/detectors/concrete-evidence.d.ts +13 -1
  86. package/dist/detectors/concrete-evidence.d.ts.map +1 -1
  87. package/dist/detectors/concrete-evidence.js +59 -0
  88. package/dist/detectors/concrete-evidence.js.map +1 -1
  89. package/dist/detectors/condition-toki.d.ts +16 -0
  90. package/dist/detectors/condition-toki.d.ts.map +1 -0
  91. package/dist/detectors/condition-toki.js +42 -0
  92. package/dist/detectors/condition-toki.js.map +1 -0
  93. package/dist/detectors/conjugated-entry.d.ts +17 -0
  94. package/dist/detectors/conjugated-entry.d.ts.map +1 -0
  95. package/dist/detectors/conjugated-entry.js +50 -0
  96. package/dist/detectors/conjugated-entry.js.map +1 -0
  97. package/dist/detectors/content-morphemes.d.ts +2 -0
  98. package/dist/detectors/content-morphemes.d.ts.map +1 -1
  99. package/dist/detectors/content-morphemes.js +1 -1
  100. package/dist/detectors/content-morphemes.js.map +1 -1
  101. package/dist/detectors/contraction-minority.d.ts +11 -0
  102. package/dist/detectors/contraction-minority.d.ts.map +1 -0
  103. package/dist/detectors/contraction-minority.js +10 -0
  104. package/dist/detectors/contraction-minority.js.map +1 -0
  105. package/dist/detectors/counter-edge.d.ts +5 -0
  106. package/dist/detectors/counter-edge.d.ts.map +1 -1
  107. package/dist/detectors/counter-edge.js +23 -0
  108. package/dist/detectors/counter-edge.js.map +1 -1
  109. package/dist/detectors/cross-facts.d.ts.map +1 -1
  110. package/dist/detectors/cross-facts.js +2 -1
  111. package/dist/detectors/cross-facts.js.map +1 -1
  112. package/dist/detectors/custom.d.ts.map +1 -1
  113. package/dist/detectors/custom.js +8 -2
  114. package/dist/detectors/custom.js.map +1 -1
  115. package/dist/detectors/date-any-year.d.ts +6 -3
  116. package/dist/detectors/date-any-year.d.ts.map +1 -1
  117. package/dist/detectors/date-any-year.js +47 -10
  118. package/dist/detectors/date-any-year.js.map +1 -1
  119. package/dist/detectors/date-heading-year.d.ts +18 -0
  120. package/dist/detectors/date-heading-year.d.ts.map +1 -0
  121. package/dist/detectors/date-heading-year.js +38 -0
  122. package/dist/detectors/date-heading-year.js.map +1 -0
  123. package/dist/detectors/date-year.d.ts +12 -2
  124. package/dist/detectors/date-year.d.ts.map +1 -1
  125. package/dist/detectors/date-year.js +31 -6
  126. package/dist/detectors/date-year.js.map +1 -1
  127. package/dist/detectors/defined-term-form.d.ts.map +1 -1
  128. package/dist/detectors/defined-term-form.js +26 -5
  129. package/dist/detectors/defined-term-form.js.map +1 -1
  130. package/dist/detectors/document-shape.d.ts.map +1 -1
  131. package/dist/detectors/document-shape.js +6 -0
  132. package/dist/detectors/document-shape.js.map +1 -1
  133. package/dist/detectors/due-date.d.ts.map +1 -1
  134. package/dist/detectors/due-date.js +18 -2
  135. package/dist/detectors/due-date.js.map +1 -1
  136. package/dist/detectors/en-shape.d.ts.map +1 -1
  137. package/dist/detectors/en-shape.js +5 -1
  138. package/dist/detectors/en-shape.js.map +1 -1
  139. package/dist/detectors/fact-consistency.d.ts.map +1 -1
  140. package/dist/detectors/fact-consistency.js +15 -15
  141. package/dist/detectors/fact-consistency.js.map +1 -1
  142. package/dist/detectors/form-line.d.ts +9 -0
  143. package/dist/detectors/form-line.d.ts.map +1 -0
  144. package/dist/detectors/form-line.js +36 -0
  145. package/dist/detectors/form-line.js.map +1 -0
  146. package/dist/detectors/formula-amount.d.ts.map +1 -1
  147. package/dist/detectors/formula-amount.js +2 -12
  148. package/dist/detectors/formula-amount.js.map +1 -1
  149. package/dist/detectors/gram-passages.d.ts +11 -0
  150. package/dist/detectors/gram-passages.d.ts.map +1 -0
  151. package/dist/detectors/gram-passages.js +26 -0
  152. package/dist/detectors/gram-passages.js.map +1 -0
  153. package/dist/detectors/heading-claim.d.ts +14 -0
  154. package/dist/detectors/heading-claim.d.ts.map +1 -0
  155. package/dist/detectors/heading-claim.js +49 -0
  156. package/dist/detectors/heading-claim.js.map +1 -0
  157. package/dist/detectors/heading-echo.d.ts.map +1 -1
  158. package/dist/detectors/heading-echo.js +29 -1
  159. package/dist/detectors/heading-echo.js.map +1 -1
  160. package/dist/detectors/heading-end-mark.d.ts +8 -3
  161. package/dist/detectors/heading-end-mark.d.ts.map +1 -1
  162. package/dist/detectors/heading-end-mark.js +18 -8
  163. package/dist/detectors/heading-end-mark.js.map +1 -1
  164. package/dist/detectors/heading-names.d.ts +7 -0
  165. package/dist/detectors/heading-names.d.ts.map +1 -0
  166. package/dist/detectors/heading-names.js +24 -0
  167. package/dist/detectors/heading-names.js.map +1 -0
  168. package/dist/detectors/heading-numbering.d.ts.map +1 -1
  169. package/dist/detectors/heading-numbering.js +7 -2
  170. package/dist/detectors/heading-numbering.js.map +1 -1
  171. package/dist/detectors/inch-mark.d.ts +10 -0
  172. package/dist/detectors/inch-mark.d.ts.map +1 -0
  173. package/dist/detectors/inch-mark.js +48 -0
  174. package/dist/detectors/inch-mark.js.map +1 -0
  175. package/dist/detectors/installment-total-mismatch.d.ts.map +1 -1
  176. package/dist/detectors/installment-total-mismatch.js +2 -12
  177. package/dist/detectors/installment-total-mismatch.js.map +1 -1
  178. package/dist/detectors/lexicon.d.ts +0 -1
  179. package/dist/detectors/lexicon.d.ts.map +1 -1
  180. package/dist/detectors/lexicon.js +29 -23
  181. package/dist/detectors/lexicon.js.map +1 -1
  182. package/dist/detectors/list-parallel.d.ts +5 -2
  183. package/dist/detectors/list-parallel.d.ts.map +1 -1
  184. package/dist/detectors/list-parallel.js +45 -7
  185. package/dist/detectors/list-parallel.js.map +1 -1
  186. package/dist/detectors/mark-shape.d.ts +6 -3
  187. package/dist/detectors/mark-shape.d.ts.map +1 -1
  188. package/dist/detectors/mark-shape.js +12 -6
  189. package/dist/detectors/mark-shape.js.map +1 -1
  190. package/dist/detectors/name-variant-apart.d.ts +27 -0
  191. package/dist/detectors/name-variant-apart.d.ts.map +1 -0
  192. package/dist/detectors/name-variant-apart.js +51 -0
  193. package/dist/detectors/name-variant-apart.js.map +1 -0
  194. package/dist/detectors/name-variant.d.ts.map +1 -1
  195. package/dist/detectors/name-variant.js +51 -17
  196. package/dist/detectors/name-variant.js.map +1 -1
  197. package/dist/detectors/number-unit.d.ts +10 -0
  198. package/dist/detectors/number-unit.d.ts.map +1 -1
  199. package/dist/detectors/number-unit.js +28 -8
  200. package/dist/detectors/number-unit.js.map +1 -1
  201. package/dist/detectors/numeral-word.d.ts +15 -0
  202. package/dist/detectors/numeral-word.d.ts.map +1 -0
  203. package/dist/detectors/numeral-word.js +26 -0
  204. package/dist/detectors/numeral-word.js.map +1 -0
  205. package/dist/detectors/organisation-run.d.ts +14 -0
  206. package/dist/detectors/organisation-run.d.ts.map +1 -0
  207. package/dist/detectors/organisation-run.js +73 -0
  208. package/dist/detectors/organisation-run.js.map +1 -0
  209. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  210. package/dist/detectors/orthographic-variant.js +13 -5
  211. package/dist/detectors/orthographic-variant.js.map +1 -1
  212. package/dist/detectors/orthography.d.ts.map +1 -1
  213. package/dist/detectors/orthography.js +16 -7
  214. package/dist/detectors/orthography.js.map +1 -1
  215. package/dist/detectors/outline-label.d.ts +14 -0
  216. package/dist/detectors/outline-label.d.ts.map +1 -0
  217. package/dist/detectors/outline-label.js +32 -0
  218. package/dist/detectors/outline-label.js.map +1 -0
  219. package/dist/detectors/page-marker.d.ts +6 -0
  220. package/dist/detectors/page-marker.d.ts.map +1 -0
  221. package/dist/detectors/page-marker.js +19 -0
  222. package/dist/detectors/page-marker.js.map +1 -0
  223. package/dist/detectors/parallel-definition.d.ts +16 -0
  224. package/dist/detectors/parallel-definition.d.ts.map +1 -0
  225. package/dist/detectors/parallel-definition.js +51 -0
  226. package/dist/detectors/parallel-definition.js.map +1 -0
  227. package/dist/detectors/per-unit-words.d.ts +7 -0
  228. package/dist/detectors/per-unit-words.d.ts.map +1 -0
  229. package/dist/detectors/per-unit-words.js +17 -0
  230. package/dist/detectors/per-unit-words.js.map +1 -0
  231. package/dist/detectors/period-multiple-mismatch.d.ts.map +1 -1
  232. package/dist/detectors/period-multiple-mismatch.js +2 -12
  233. package/dist/detectors/period-multiple-mismatch.js.map +1 -1
  234. package/dist/detectors/reference-number-variant.d.ts.map +1 -1
  235. package/dist/detectors/reference-number-variant.js +21 -3
  236. package/dist/detectors/reference-number-variant.js.map +1 -1
  237. package/dist/detectors/reference-text.d.ts.map +1 -1
  238. package/dist/detectors/reference-text.js +1 -0
  239. package/dist/detectors/reference-text.js.map +1 -1
  240. package/dist/detectors/registry/condition-toki.d.ts +3 -0
  241. package/dist/detectors/registry/condition-toki.d.ts.map +1 -0
  242. package/dist/detectors/registry/condition-toki.js +3 -0
  243. package/dist/detectors/registry/condition-toki.js.map +1 -0
  244. package/dist/detectors/registry/unfilled-placeholder.d.ts.map +1 -1
  245. package/dist/detectors/registry/unfilled-placeholder.js +2 -2
  246. package/dist/detectors/registry/unfilled-placeholder.js.map +1 -1
  247. package/dist/detectors/registry/vague-density.js +1 -1
  248. package/dist/detectors/registry/vague-density.js.map +1 -1
  249. package/dist/detectors/rent-multiple-mismatch.d.ts.map +1 -1
  250. package/dist/detectors/rent-multiple-mismatch.js +2 -12
  251. package/dist/detectors/rent-multiple-mismatch.js.map +1 -1
  252. package/dist/detectors/request-owner.d.ts +6 -2
  253. package/dist/detectors/request-owner.d.ts.map +1 -1
  254. package/dist/detectors/request-owner.js +57 -7
  255. package/dist/detectors/request-owner.js.map +1 -1
  256. package/dist/detectors/requirement-smell.d.ts.map +1 -1
  257. package/dist/detectors/requirement-smell.js +10 -2
  258. package/dist/detectors/requirement-smell.js.map +1 -1
  259. package/dist/detectors/row-sentence-amounts.d.ts.map +1 -1
  260. package/dist/detectors/row-sentence-amounts.js +5 -10
  261. package/dist/detectors/row-sentence-amounts.js.map +1 -1
  262. package/dist/detectors/sentence-length.d.ts.map +1 -1
  263. package/dist/detectors/sentence-length.js +24 -16
  264. package/dist/detectors/sentence-length.js.map +1 -1
  265. package/dist/detectors/sentence-rhythm.d.ts.map +1 -1
  266. package/dist/detectors/sentence-rhythm.js +6 -3
  267. package/dist/detectors/sentence-rhythm.js.map +1 -1
  268. package/dist/detectors/series-label.d.ts +2 -1
  269. package/dist/detectors/series-label.d.ts.map +1 -1
  270. package/dist/detectors/series-label.js +10 -4
  271. package/dist/detectors/series-label.js.map +1 -1
  272. package/dist/detectors/signals.d.ts +4 -0
  273. package/dist/detectors/signals.d.ts.map +1 -1
  274. package/dist/detectors/signals.js +95 -36
  275. package/dist/detectors/signals.js.map +1 -1
  276. package/dist/detectors/stated-amounts.d.ts +4 -0
  277. package/dist/detectors/stated-amounts.d.ts.map +1 -0
  278. package/dist/detectors/stated-amounts.js +12 -0
  279. package/dist/detectors/stated-amounts.js.map +1 -0
  280. package/dist/detectors/step-time-sum.d.ts.map +1 -1
  281. package/dist/detectors/step-time-sum.js +2 -1
  282. package/dist/detectors/step-time-sum.js.map +1 -1
  283. package/dist/detectors/structure-tree.d.ts.map +1 -1
  284. package/dist/detectors/structure-tree.js +11 -7
  285. package/dist/detectors/structure-tree.js.map +1 -1
  286. package/dist/detectors/team.d.ts.map +1 -1
  287. package/dist/detectors/team.js +10 -6
  288. package/dist/detectors/team.js.map +1 -1
  289. package/dist/detectors/template-sections.d.ts +14 -0
  290. package/dist/detectors/template-sections.d.ts.map +1 -0
  291. package/dist/detectors/template-sections.js +25 -0
  292. package/dist/detectors/template-sections.js.map +1 -0
  293. package/dist/detectors/time-order.d.ts.map +1 -1
  294. package/dist/detectors/time-order.js +17 -13
  295. package/dist/detectors/time-order.js.map +1 -1
  296. package/dist/detectors/titled-run.d.ts +22 -0
  297. package/dist/detectors/titled-run.d.ts.map +1 -0
  298. package/dist/detectors/titled-run.js +34 -0
  299. package/dist/detectors/titled-run.js.map +1 -0
  300. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
  301. package/dist/detectors/unbalanced-bracket.js +4 -0
  302. package/dist/detectors/unbalanced-bracket.js.map +1 -1
  303. package/dist/detectors/undefined-term.d.ts.map +1 -1
  304. package/dist/detectors/undefined-term.js +8 -0
  305. package/dist/detectors/undefined-term.js.map +1 -1
  306. package/dist/detectors/unfilled-placeholder.d.ts +4 -0
  307. package/dist/detectors/unfilled-placeholder.d.ts.map +1 -0
  308. package/dist/detectors/unfilled-placeholder.js +9 -0
  309. package/dist/detectors/unfilled-placeholder.js.map +1 -0
  310. package/dist/detectors/unknown-word.d.ts +4 -1
  311. package/dist/detectors/unknown-word.d.ts.map +1 -1
  312. package/dist/detectors/unknown-word.js +18 -2
  313. package/dist/detectors/unknown-word.js.map +1 -1
  314. package/dist/detectors/use-interval.d.ts +1 -0
  315. package/dist/detectors/use-interval.d.ts.map +1 -1
  316. package/dist/detectors/use-interval.js +15 -10
  317. package/dist/detectors/use-interval.js.map +1 -1
  318. package/dist/detectors/use-maximum.d.ts.map +1 -1
  319. package/dist/detectors/use-maximum.js +3 -1
  320. package/dist/detectors/use-maximum.js.map +1 -1
  321. package/dist/detectors/vague-density.d.ts +5 -0
  322. package/dist/detectors/vague-density.d.ts.map +1 -0
  323. package/dist/detectors/vague-density.js +52 -0
  324. package/dist/detectors/vague-density.js.map +1 -0
  325. package/dist/extension/document-view.d.ts +2 -2
  326. package/dist/extension/document-view.d.ts.map +1 -1
  327. package/dist/extension/document-view.js +17 -8
  328. package/dist/extension/document-view.js.map +1 -1
  329. package/dist/extension/entry-genres.d.ts +5 -0
  330. package/dist/extension/entry-genres.d.ts.map +1 -0
  331. package/dist/extension/entry-genres.js +13 -0
  332. package/dist/extension/entry-genres.js.map +1 -0
  333. package/dist/extension/module-detector.d.ts.map +1 -1
  334. package/dist/extension/module-detector.js +4 -4
  335. package/dist/extension/module-detector.js.map +1 -1
  336. package/dist/extension/plugin-parse.d.ts +1 -1
  337. package/dist/extension/plugin-parse.d.ts.map +1 -1
  338. package/dist/extension/plugin-parse.js +24 -7
  339. package/dist/extension/plugin-parse.js.map +1 -1
  340. package/dist/extension/problem-text.d.ts.map +1 -1
  341. package/dist/extension/problem-text.js +2 -0
  342. package/dist/extension/problem-text.js.map +1 -1
  343. package/dist/facts/age-values.d.ts.map +1 -1
  344. package/dist/facts/age-values.js +20 -2
  345. package/dist/facts/age-values.js.map +1 -1
  346. package/dist/facts/column-units.d.ts +31 -0
  347. package/dist/facts/column-units.d.ts.map +1 -0
  348. package/dist/facts/column-units.js +37 -0
  349. package/dist/facts/column-units.js.map +1 -0
  350. package/dist/facts/fact-scope.d.ts +10 -1
  351. package/dist/facts/fact-scope.d.ts.map +1 -1
  352. package/dist/facts/fact-scope.js +34 -3
  353. package/dist/facts/fact-scope.js.map +1 -1
  354. package/dist/facts/fact-values.d.ts +4 -0
  355. package/dist/facts/fact-values.d.ts.map +1 -1
  356. package/dist/facts/fact-values.js +3 -1
  357. package/dist/facts/fact-values.js.map +1 -1
  358. package/dist/facts/labelled-facts.d.ts +10 -0
  359. package/dist/facts/labelled-facts.d.ts.map +1 -1
  360. package/dist/facts/labelled-facts.js +6 -1
  361. package/dist/facts/labelled-facts.js.map +1 -1
  362. package/dist/facts/per-unit.d.ts +36 -0
  363. package/dist/facts/per-unit.d.ts.map +1 -0
  364. package/dist/facts/per-unit.js +56 -0
  365. package/dist/facts/per-unit.js.map +1 -0
  366. package/dist/facts/row-sentence-amounts.d.ts +3 -12
  367. package/dist/facts/row-sentence-amounts.d.ts.map +1 -1
  368. package/dist/facts/row-sentence-amounts.js +1 -15
  369. package/dist/facts/row-sentence-amounts.js.map +1 -1
  370. package/dist/facts/table-facts.d.ts +13 -3
  371. package/dist/facts/table-facts.d.ts.map +1 -1
  372. package/dist/facts/table-facts.js +35 -13
  373. package/dist/facts/table-facts.js.map +1 -1
  374. package/dist/facts/term-values.d.ts +13 -1
  375. package/dist/facts/term-values.d.ts.map +1 -1
  376. package/dist/facts/term-values.js +71 -12
  377. package/dist/facts/term-values.js.map +1 -1
  378. package/dist/grade/baseline.d.ts +4 -2
  379. package/dist/grade/baseline.d.ts.map +1 -1
  380. package/dist/grade/baseline.js +13 -11
  381. package/dist/grade/baseline.js.map +1 -1
  382. package/dist/grade/expect-read.d.ts +16 -0
  383. package/dist/grade/expect-read.d.ts.map +1 -0
  384. package/dist/grade/expect-read.js +52 -0
  385. package/dist/grade/expect-read.js.map +1 -0
  386. package/dist/grade/expect.d.ts +50 -0
  387. package/dist/grade/expect.d.ts.map +1 -0
  388. package/dist/grade/expect.js +53 -0
  389. package/dist/grade/expect.js.map +1 -0
  390. package/dist/grade/grade-item.d.ts +1 -1
  391. package/dist/grade/grade-item.d.ts.map +1 -1
  392. package/dist/grade/grade-item.js +13 -3
  393. package/dist/grade/grade-item.js.map +1 -1
  394. package/dist/grade/item.d.ts +9 -1
  395. package/dist/grade/item.d.ts.map +1 -1
  396. package/dist/grade/item.js +32 -7
  397. package/dist/grade/item.js.map +1 -1
  398. package/dist/grade/result.d.ts +5 -0
  399. package/dist/grade/result.d.ts.map +1 -1
  400. package/dist/grade/results-read.d.ts.map +1 -1
  401. package/dist/grade/results-read.js +4 -2
  402. package/dist/grade/results-read.js.map +1 -1
  403. package/dist/grade/rubric-file.d.ts +23 -0
  404. package/dist/grade/rubric-file.d.ts.map +1 -0
  405. package/dist/grade/rubric-file.js +35 -0
  406. package/dist/grade/rubric-file.js.map +1 -0
  407. package/dist/grade/rubric.d.ts +2 -0
  408. package/dist/grade/rubric.d.ts.map +1 -1
  409. package/dist/grade/rubric.js +75 -47
  410. package/dist/grade/rubric.js.map +1 -1
  411. package/dist/grade/setup.d.ts +2 -1
  412. package/dist/grade/setup.d.ts.map +1 -1
  413. package/dist/grade/setup.js +2 -2
  414. package/dist/grade/setup.js.map +1 -1
  415. package/dist/grade/stamp.d.ts +2 -0
  416. package/dist/grade/stamp.d.ts.map +1 -1
  417. package/dist/grade/stamp.js +8 -2
  418. package/dist/grade/stamp.js.map +1 -1
  419. package/dist/grade/task-rubric.d.ts +16 -0
  420. package/dist/grade/task-rubric.d.ts.map +1 -0
  421. package/dist/grade/task-rubric.js +34 -0
  422. package/dist/grade/task-rubric.js.map +1 -0
  423. package/dist/grade/text.d.ts +5 -1
  424. package/dist/grade/text.d.ts.map +1 -1
  425. package/dist/grade/text.js +16 -4
  426. package/dist/grade/text.js.map +1 -1
  427. package/dist/grade-api.d.ts +9 -2
  428. package/dist/grade-api.d.ts.map +1 -1
  429. package/dist/grade-api.js +31 -15
  430. package/dist/grade-api.js.map +1 -1
  431. package/dist/heading-numbering.d.ts +5 -2
  432. package/dist/heading-numbering.d.ts.map +1 -1
  433. package/dist/heading-numbering.js +27 -6
  434. package/dist/heading-numbering.js.map +1 -1
  435. package/dist/name-char-reading.d.ts +5 -0
  436. package/dist/name-char-reading.d.ts.map +1 -1
  437. package/dist/name-char-reading.js +15 -0
  438. package/dist/name-char-reading.js.map +1 -1
  439. package/dist/name-end-letter.d.ts +24 -0
  440. package/dist/name-end-letter.d.ts.map +1 -0
  441. package/dist/name-end-letter.js +45 -0
  442. package/dist/name-end-letter.js.map +1 -0
  443. package/dist/name-given-before.d.ts +15 -0
  444. package/dist/name-given-before.d.ts.map +1 -0
  445. package/dist/name-given-before.js +30 -0
  446. package/dist/name-given-before.js.map +1 -0
  447. package/dist/name-neighbours.d.ts.map +1 -1
  448. package/dist/name-neighbours.js +2 -1
  449. package/dist/name-neighbours.js.map +1 -1
  450. package/dist/name-separator.d.ts +6 -0
  451. package/dist/name-separator.d.ts.map +1 -1
  452. package/dist/name-separator.js +80 -0
  453. package/dist/name-separator.js.map +1 -1
  454. package/dist/name-variants.d.ts +8 -3
  455. package/dist/name-variants.d.ts.map +1 -1
  456. package/dist/name-variants.js +40 -12
  457. package/dist/name-variants.js.map +1 -1
  458. package/dist/name-word-order.d.ts +9 -5
  459. package/dist/name-word-order.d.ts.map +1 -1
  460. package/dist/name-word-order.js +47 -15
  461. package/dist/name-word-order.js.map +1 -1
  462. package/dist/nominal-stem.d.ts +13 -0
  463. package/dist/nominal-stem.d.ts.map +1 -0
  464. package/dist/nominal-stem.js +32 -0
  465. package/dist/nominal-stem.js.map +1 -0
  466. package/dist/number-name.d.ts.map +1 -1
  467. package/dist/number-name.js +11 -2
  468. package/dist/number-name.js.map +1 -1
  469. package/dist/profile/cue-lines.d.ts +6 -0
  470. package/dist/profile/cue-lines.d.ts.map +1 -0
  471. package/dist/profile/cue-lines.js +13 -0
  472. package/dist/profile/cue-lines.js.map +1 -0
  473. package/dist/profile/parse.d.ts +1 -1
  474. package/dist/profile/parse.d.ts.map +1 -1
  475. package/dist/profile/parse.js +3 -2
  476. package/dist/profile/parse.js.map +1 -1
  477. package/dist/reference-numbers.d.ts +2 -0
  478. package/dist/reference-numbers.d.ts.map +1 -1
  479. package/dist/reference-numbers.js +1 -1
  480. package/dist/reference-numbers.js.map +1 -1
  481. package/dist/sentence-load.d.ts +2 -1
  482. package/dist/sentence-load.d.ts.map +1 -1
  483. package/dist/sentence-load.js +6 -2
  484. package/dist/sentence-load.js.map +1 -1
  485. package/dist/spaced-person-name.d.ts.map +1 -1
  486. package/dist/spaced-person-name.js +26 -1
  487. package/dist/spaced-person-name.js.map +1 -1
  488. package/dist/spacing-code.d.ts.map +1 -1
  489. package/dist/spacing-code.js +10 -1
  490. package/dist/spacing-code.js.map +1 -1
  491. package/dist/spacing-minority.d.ts +7 -0
  492. package/dist/spacing-minority.d.ts.map +1 -1
  493. package/dist/spacing-minority.js +14 -0
  494. package/dist/spacing-minority.js.map +1 -1
  495. package/dist/structure/cited-document-section.d.ts +7 -0
  496. package/dist/structure/cited-document-section.d.ts.map +1 -0
  497. package/dist/structure/cited-document-section.js +33 -0
  498. package/dist/structure/cited-document-section.js.map +1 -0
  499. package/dist/structure/closing-balance.d.ts +9 -0
  500. package/dist/structure/closing-balance.d.ts.map +1 -1
  501. package/dist/structure/closing-balance.js +34 -7
  502. package/dist/structure/closing-balance.js.map +1 -1
  503. package/dist/structure/definition-use.d.ts.map +1 -1
  504. package/dist/structure/definition-use.js +20 -1
  505. package/dist/structure/definition-use.js.map +1 -1
  506. package/dist/structure/document-context.d.ts +2 -0
  507. package/dist/structure/document-context.d.ts.map +1 -0
  508. package/dist/structure/document-context.js +42 -0
  509. package/dist/structure/document-context.js.map +1 -0
  510. package/dist/structure/fenced-lines.d.ts +7 -0
  511. package/dist/structure/fenced-lines.d.ts.map +1 -0
  512. package/dist/structure/fenced-lines.js +27 -0
  513. package/dist/structure/fenced-lines.js.map +1 -0
  514. package/dist/structure/html-text-blocks.d.ts +8 -0
  515. package/dist/structure/html-text-blocks.d.ts.map +1 -0
  516. package/dist/structure/html-text-blocks.js +47 -0
  517. package/dist/structure/html-text-blocks.js.map +1 -0
  518. package/dist/structure/issues.d.ts +1 -1
  519. package/dist/structure/issues.d.ts.map +1 -1
  520. package/dist/structure/issues.js +19 -4
  521. package/dist/structure/issues.js.map +1 -1
  522. package/dist/structure/labelled-date-order.d.ts +34 -9
  523. package/dist/structure/labelled-date-order.d.ts.map +1 -1
  524. package/dist/structure/labelled-date-order.js +60 -15
  525. package/dist/structure/labelled-date-order.js.map +1 -1
  526. package/dist/structure/labelled-order.d.ts +10 -1
  527. package/dist/structure/labelled-order.d.ts.map +1 -1
  528. package/dist/structure/labelled-order.js +18 -6
  529. package/dist/structure/labelled-order.js.map +1 -1
  530. package/dist/structure/line-amount-label.d.ts.map +1 -1
  531. package/dist/structure/line-amount-label.js +2 -1
  532. package/dist/structure/line-amount-label.js.map +1 -1
  533. package/dist/structure/line-amount.d.ts +0 -5
  534. package/dist/structure/line-amount.d.ts.map +1 -1
  535. package/dist/structure/line-amount.js +1 -10
  536. package/dist/structure/line-amount.js.map +1 -1
  537. package/dist/structure/list-numbering.d.ts +20 -4
  538. package/dist/structure/list-numbering.d.ts.map +1 -1
  539. package/dist/structure/list-numbering.js +65 -9
  540. package/dist/structure/list-numbering.js.map +1 -1
  541. package/dist/structure/listed-paragraph.d.ts +16 -0
  542. package/dist/structure/listed-paragraph.d.ts.map +1 -0
  543. package/dist/structure/listed-paragraph.js +37 -0
  544. package/dist/structure/listed-paragraph.js.map +1 -0
  545. package/dist/structure/numbering.d.ts +3 -2
  546. package/dist/structure/numbering.d.ts.map +1 -1
  547. package/dist/structure/numbering.js +31 -6
  548. package/dist/structure/numbering.js.map +1 -1
  549. package/dist/structure/prose-total.d.ts +8 -0
  550. package/dist/structure/prose-total.d.ts.map +1 -1
  551. package/dist/structure/prose-total.js +70 -2
  552. package/dist/structure/prose-total.js.map +1 -1
  553. package/dist/structure/reference-text.d.ts +9 -1
  554. package/dist/structure/reference-text.d.ts.map +1 -1
  555. package/dist/structure/reference-text.js +21 -3
  556. package/dist/structure/reference-text.js.map +1 -1
  557. package/dist/structure/runs.d.ts.map +1 -1
  558. package/dist/structure/runs.js +9 -1
  559. package/dist/structure/runs.js.map +1 -1
  560. package/dist/structure/section-names.d.ts +12 -0
  561. package/dist/structure/section-names.d.ts.map +1 -0
  562. package/dist/structure/section-names.js +26 -0
  563. package/dist/structure/section-names.js.map +1 -0
  564. package/dist/structure/signed-date-line.d.ts +15 -0
  565. package/dist/structure/signed-date-line.d.ts.map +1 -0
  566. package/dist/structure/signed-date-line.js +68 -0
  567. package/dist/structure/signed-date-line.js.map +1 -0
  568. package/dist/structure/tax.d.ts.map +1 -1
  569. package/dist/structure/tax.js +5 -3
  570. package/dist/structure/tax.js.map +1 -1
  571. package/dist/structure/total-line.d.ts.map +1 -1
  572. package/dist/structure/total-line.js +10 -6
  573. package/dist/structure/total-line.js.map +1 -1
  574. package/dist/structure/total.d.ts +2 -0
  575. package/dist/structure/total.d.ts.map +1 -1
  576. package/dist/structure/total.js +34 -3
  577. package/dist/structure/total.js.map +1 -1
  578. package/dist/structure/versioned-label.d.ts +16 -0
  579. package/dist/structure/versioned-label.d.ts.map +1 -0
  580. package/dist/structure/versioned-label.js +48 -0
  581. package/dist/structure/versioned-label.js.map +1 -0
  582. package/dist/structure/written-headings.d.ts +31 -0
  583. package/dist/structure/written-headings.d.ts.map +1 -0
  584. package/dist/structure/written-headings.js +119 -0
  585. package/dist/structure/written-headings.js.map +1 -0
  586. package/dist/structure/written-resolve.d.ts +12 -0
  587. package/dist/structure/written-resolve.d.ts.map +1 -0
  588. package/dist/structure/written-resolve.js +49 -0
  589. package/dist/structure/written-resolve.js.map +1 -0
  590. package/dist/subject-codes.d.ts +21 -0
  591. package/dist/subject-codes.d.ts.map +1 -0
  592. package/dist/subject-codes.js +79 -0
  593. package/dist/subject-codes.js.map +1 -0
  594. package/dist/unlabelled-references.d.ts +6 -2
  595. package/dist/unlabelled-references.d.ts.map +1 -1
  596. package/dist/unlabelled-references.js +11 -10
  597. package/dist/unlabelled-references.js.map +1 -1
  598. package/genres.yaml +17 -0
  599. package/package.json +3 -3
  600. package/profiles/listing.yaml +1 -1
  601. package/rules/all-caps-shouting.yaml +2 -2
  602. package/rules/closing-balance-mismatch.yaml +3 -3
  603. package/rules/concrete-evidence-density.yaml +2 -2
  604. package/rules/contraction-consistency.yaml +13 -13
  605. package/rules/dangling-reference.yaml +2 -2
  606. package/rules/date-without-year.yaml +2 -2
  607. package/rules/defined-name-repeated.yaml +2 -2
  608. package/rules/due-before-issue.yaml +9 -5
  609. package/rules/fact-conflict.yaml +2 -2
  610. package/rules/heading-echo.yaml +2 -2
  611. package/rules/heading-end-punctuation-mix.yaml +2 -2
  612. package/rules/heading-numbering-mix.yaml +2 -2
  613. package/rules/internal-jargon.yaml +2 -2
  614. package/rules/latin-spacing.yaml +4 -4
  615. package/rules/list-item-form-mix.yaml +1 -1
  616. package/rules/max-kanji-continuous.yaml +5 -3
  617. package/rules/max-sentence-length.yaml +3 -2
  618. package/rules/name-variant.yaml +5 -2
  619. package/rules/ngram-repetition.yaml +2 -2
  620. package/rules/no-lead.yaml +2 -2
  621. package/rules/number-without-unit.yaml +2 -2
  622. package/rules/numbering-gap.yaml +2 -2
  623. package/rules/orthographic-variant.yaml +2 -2
  624. package/rules/reference-number-variant.yaml +3 -3
  625. package/rules/reference-title-mismatch.yaml +2 -2
  626. package/rules/repeated-sentence-ending.yaml +3 -2
  627. package/rules/request-without-deadline.yaml +2 -2
  628. package/rules/requirement-smell.yaml +2 -2
  629. package/rules/sentence-rhythm.yaml +2 -2
  630. package/rules/title-case-consistency.yaml +2 -2
  631. package/rules/toki-as-condition.yaml +71 -0
  632. package/rules/total-mismatch.yaml +4 -4
  633. package/rules/unbalanced-bracket.yaml +2 -2
  634. package/rules/undefined-acronym.yaml +11 -2
  635. package/rules/undefined-term.yaml +2 -2
  636. package/rules/unfilled-placeholder.yaml +2 -2
  637. package/rules/unknown-word.yaml +2 -2
  638. package/rules/use-before-definition.yaml +2 -2
  639. package/rules/vague-word-density.yaml +2 -2
  640. package/src/api.ts +11 -2
  641. package/src/capitals-passage.ts +31 -0
  642. package/src/cli-text.ts +4 -2
  643. package/src/coined-hyphen-name.ts +27 -0
  644. package/src/commands/grade.ts +75 -23
  645. package/src/company-kana-spelling.ts +22 -2
  646. package/src/company-name-ending.ts +50 -0
  647. package/src/company-names.ts +76 -20
  648. package/src/custom/no-rewrite.ts +2 -0
  649. package/src/custom/parse.ts +18 -2
  650. package/src/detectors/acronym-context.ts +5 -6
  651. package/src/detectors/acronym-definition.ts +123 -0
  652. package/src/detectors/acronym-lone.ts +26 -0
  653. package/src/detectors/acronym-name.ts +117 -0
  654. package/src/detectors/age-words.ts +12 -0
  655. package/src/detectors/annual-pay-mismatch.ts +3 -18
  656. package/src/detectors/blank-structure.ts +4 -3
  657. package/src/detectors/capitalised-term.ts +154 -4
  658. package/src/detectors/caps-caption.ts +61 -0
  659. package/src/detectors/char-shape.ts +74 -22
  660. package/src/detectors/clause-shape.ts +14 -4
  661. package/src/detectors/closing-balance-mismatch.ts +1 -0
  662. package/src/detectors/code-fences.ts +10 -0
  663. package/src/detectors/concrete-evidence.ts +77 -1
  664. package/src/detectors/condition-toki.ts +60 -0
  665. package/src/detectors/conjugated-entry.ts +53 -0
  666. package/src/detectors/content-morphemes.ts +2 -1
  667. package/src/detectors/contraction-minority.ts +11 -0
  668. package/src/detectors/counter-edge.ts +23 -0
  669. package/src/detectors/cross-facts.ts +2 -1
  670. package/src/detectors/custom.ts +9 -2
  671. package/src/detectors/date-any-year.ts +56 -10
  672. package/src/detectors/date-heading-year.ts +55 -0
  673. package/src/detectors/date-year.ts +54 -9
  674. package/src/detectors/defined-term-form.ts +26 -5
  675. package/src/detectors/document-shape.ts +8 -0
  676. package/src/detectors/due-date.ts +26 -7
  677. package/src/detectors/en-shape.ts +5 -1
  678. package/src/detectors/fact-consistency.ts +16 -19
  679. package/src/detectors/form-line.ts +47 -0
  680. package/src/detectors/formula-amount.ts +2 -18
  681. package/src/detectors/gram-passages.ts +36 -0
  682. package/src/detectors/heading-claim.ts +76 -0
  683. package/src/detectors/heading-echo.ts +32 -1
  684. package/src/detectors/heading-end-mark.ts +23 -10
  685. package/src/detectors/heading-names.ts +31 -0
  686. package/src/detectors/heading-numbering.ts +7 -2
  687. package/src/detectors/inch-mark.ts +49 -0
  688. package/src/detectors/installment-total-mismatch.ts +3 -18
  689. package/src/detectors/lexicon.ts +32 -21
  690. package/src/detectors/list-parallel.ts +46 -7
  691. package/src/detectors/mark-shape.ts +12 -6
  692. package/src/detectors/name-variant-apart.ts +63 -0
  693. package/src/detectors/name-variant.ts +73 -18
  694. package/src/detectors/number-unit.ts +35 -9
  695. package/src/detectors/numeral-word.ts +33 -0
  696. package/src/detectors/organisation-run.ts +86 -0
  697. package/src/detectors/orthographic-variant.ts +22 -6
  698. package/src/detectors/orthography.ts +17 -8
  699. package/src/detectors/outline-label.ts +48 -0
  700. package/src/detectors/page-marker.ts +26 -0
  701. package/src/detectors/parallel-definition.ts +64 -0
  702. package/src/detectors/per-unit-words.ts +24 -0
  703. package/src/detectors/period-multiple-mismatch.ts +2 -18
  704. package/src/detectors/reference-number-variant.ts +27 -5
  705. package/src/detectors/reference-text.ts +1 -0
  706. package/src/detectors/registry/condition-toki.ts +4 -0
  707. package/src/detectors/registry/unfilled-placeholder.ts +2 -2
  708. package/src/detectors/registry/vague-density.ts +1 -1
  709. package/src/detectors/rent-multiple-mismatch.ts +2 -18
  710. package/src/detectors/request-owner.ts +71 -8
  711. package/src/detectors/requirement-smell.ts +15 -2
  712. package/src/detectors/row-sentence-amounts.ts +5 -20
  713. package/src/detectors/sentence-length.ts +14 -6
  714. package/src/detectors/sentence-rhythm.ts +8 -4
  715. package/src/detectors/series-label.ts +13 -4
  716. package/src/detectors/signals.ts +94 -26
  717. package/src/detectors/stated-amounts.ts +20 -0
  718. package/src/detectors/step-time-sum.ts +2 -1
  719. package/src/detectors/structure-tree.ts +13 -8
  720. package/src/detectors/team.ts +13 -7
  721. package/src/detectors/template-sections.ts +37 -0
  722. package/src/detectors/time-order.ts +6 -3
  723. package/src/detectors/titled-run.ts +43 -0
  724. package/src/detectors/unbalanced-bracket.ts +3 -0
  725. package/src/detectors/undefined-term.ts +8 -0
  726. package/src/detectors/unfilled-placeholder.ts +10 -0
  727. package/src/detectors/unknown-word.ts +20 -2
  728. package/src/detectors/use-interval.ts +8 -4
  729. package/src/detectors/use-maximum.ts +3 -1
  730. package/src/detectors/vague-density.ts +68 -0
  731. package/src/extension/document-view.ts +18 -9
  732. package/src/extension/entry-genres.ts +15 -0
  733. package/src/extension/module-detector.ts +9 -4
  734. package/src/extension/plugin-parse.ts +29 -7
  735. package/src/extension/problem-text.ts +4 -0
  736. package/src/facts/age-values.ts +24 -2
  737. package/src/facts/column-units.ts +67 -0
  738. package/src/facts/fact-scope.ts +53 -4
  739. package/src/facts/fact-values.ts +11 -1
  740. package/src/facts/labelled-facts.ts +16 -2
  741. package/src/facts/per-unit.ts +105 -0
  742. package/src/facts/row-sentence-amounts.ts +4 -26
  743. package/src/facts/table-facts.ts +50 -10
  744. package/src/facts/term-values.ts +94 -13
  745. package/src/grade/baseline.ts +20 -12
  746. package/src/grade/expect-read.ts +65 -0
  747. package/src/grade/expect.ts +74 -0
  748. package/src/grade/grade-item.ts +14 -3
  749. package/src/grade/item.ts +48 -8
  750. package/src/grade/result.ts +5 -0
  751. package/src/grade/results-read.ts +7 -2
  752. package/src/grade/rubric-file.ts +46 -0
  753. package/src/grade/rubric.ts +77 -47
  754. package/src/grade/setup.ts +3 -3
  755. package/src/grade/stamp.ts +10 -2
  756. package/src/grade/task-rubric.ts +39 -0
  757. package/src/grade/text.ts +27 -5
  758. package/src/grade-api.ts +38 -16
  759. package/src/heading-numbering.ts +35 -8
  760. package/src/name-char-reading.ts +16 -0
  761. package/src/name-end-letter.ts +61 -0
  762. package/src/name-given-before.ts +40 -0
  763. package/src/name-neighbours.ts +2 -1
  764. package/src/name-separator.ts +93 -0
  765. package/src/name-variants.ts +69 -18
  766. package/src/name-word-order.ts +62 -17
  767. package/src/nominal-stem.ts +36 -0
  768. package/src/number-name.ts +12 -3
  769. package/src/profile/cue-lines.ts +14 -0
  770. package/src/profile/parse.ts +3 -2
  771. package/src/reference-numbers.ts +1 -1
  772. package/src/sentence-load.ts +7 -2
  773. package/src/spaced-person-name.ts +27 -2
  774. package/src/spacing-code.ts +13 -2
  775. package/src/spacing-minority.ts +17 -0
  776. package/src/structure/cited-document-section.ts +42 -0
  777. package/src/structure/closing-balance.ts +46 -8
  778. package/src/structure/definition-use.ts +24 -1
  779. package/src/structure/document-context.ts +46 -0
  780. package/src/structure/fenced-lines.ts +28 -0
  781. package/src/structure/html-text-blocks.ts +45 -0
  782. package/src/structure/issues.ts +19 -4
  783. package/src/structure/labelled-date-order.ts +108 -21
  784. package/src/structure/labelled-order.ts +33 -13
  785. package/src/structure/line-amount-label.ts +2 -1
  786. package/src/structure/line-amount.ts +1 -11
  787. package/src/structure/list-numbering.ts +100 -11
  788. package/src/structure/listed-paragraph.ts +45 -0
  789. package/src/structure/numbering.ts +48 -19
  790. package/src/structure/prose-total.ts +81 -2
  791. package/src/structure/reference-text.ts +25 -3
  792. package/src/structure/runs.ts +10 -1
  793. package/src/structure/section-names.ts +32 -0
  794. package/src/structure/signed-date-line.ts +78 -0
  795. package/src/structure/tax.ts +6 -3
  796. package/src/structure/total-line.ts +12 -6
  797. package/src/structure/total.ts +42 -3
  798. package/src/structure/versioned-label.ts +52 -0
  799. package/src/structure/written-headings.ts +137 -0
  800. package/src/structure/written-resolve.ts +57 -0
  801. package/src/subject-codes.ts +105 -0
  802. package/src/unlabelled-references.ts +24 -16
@@ -1,12 +1,13 @@
1
1
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
2
2
  import { cuedNamesIn, mentionsIn, nameVariants, suffixedNamesIn, type NameMention, type VariantChars } from "../name-variants.ts";
3
+ import type { WordUse } from "../name-end-letter.ts";
3
4
  import { withKnownNeighbours } from "../name-neighbours.ts";
4
5
  import type { SpellingInput } from "../name-spelling-chars.ts";
5
6
  import { lookalikeSlipsIn, type LookalikeChars } from "../name-lookalike-chars.ts";
6
- import { readingOfWords, type CharReadings } from "../name-char-reading.ts";
7
+ import { givenNameReadingOf, readingOfWords, type CharReadings } from "../name-char-reading.ts";
7
8
  import { nameCueAt, type NameCues } from "../name-cue.ts";
8
9
  import { quoteAt } from "./structure-tree.ts";
9
- import { companyMentionsIn, companyVariants, type CompanyForm, type IsProper } from "../company-names.ts";
10
+ import { companyMentionsIn, companyVariants, type CompanyForm, type CompanyMention, type IsProper, type PredicateEnds } from "../company-names.ts";
10
11
  import { kanaSpelledCompanies, type ReadWord } from "../company-kana-spelling.ts";
11
12
  import { proseAndTablesOf } from "../table-text.ts";
12
13
  import { tableBodyCells } from "../facts/table-facts.ts";
@@ -22,6 +23,7 @@ import { spacedPersonNamesIn } from "../spaced-person-name.ts";
22
23
  import { isOrdinaryToken, withOrdinaryWords } from "../name-ordinary-word.ts";
23
24
  import { isInPersonField } from "../person-field.ts";
24
25
  import { labelledSpans, orderNamesOf, quotedSpans, stemOf, titleCaseSpans, wordOrderVariants, type OrderWord } from "../name-word-order.ts";
26
+ import { isGroupPairOf, notDefinedTerms, outsideCapitals, sentenceIndexOf, withGivenNames } from "./name-variant-apart.ts";
25
27
 
26
28
  // 人の名前と読ませる敬称(様、さん)は語彙表 person-suffix、人を指す前置き(担当の)は person-lead、名前のすぐ後ろに来る語
27
29
  // (です、まで)は name-particle、字体の違う同じ字(斎・斉・齋)は name-variant-char が組(group)ごとに言う。
@@ -33,6 +35,18 @@ const variantCharsOf = (doc: ProseDocument): VariantChars =>
33
35
  const charReadingsOf = (doc: ProseDocument): CharReadings =>
34
36
  new Map((doc.lexicons["name-char-reading"] ?? []).flatMap((entry): [string, string][] => (entry.group === undefined ? [] : [[entry.pattern, entry.group]])));
35
37
 
38
+ /**
39
+ * 名の中での字の読み(建太 の 建 を ケン)は、語彙表 given-name-char-reading が組(group)に言う。解析器が読めない字の読み
40
+ * (name-char-reading)も名の中で同じに読む。
41
+ */
42
+ const givenCharReadingsOf = (doc: ProseDocument, chars: CharReadings): CharReadings =>
43
+ new Map([
44
+ ...chars,
45
+ ...(doc.lexicons["given-name-char-reading"] ?? []).flatMap((entry): [string, string][] =>
46
+ entry.group === undefined ? [] : [[entry.pattern, entry.group]],
47
+ ),
48
+ ]);
49
+
36
50
  const patternsOf = (doc: ProseDocument, id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
37
51
 
38
52
  /** 会社の形の語(株式会社、Inc)は語彙表 company-form が、同じ形の組(group)と名前のどちら側に立つか(position)とともに言う。 */
@@ -124,23 +138,30 @@ const kanaStopsOf = (doc: ProseDocument): Parameters<typeof companyMentionsIn>[3
124
138
  return { particles: inGroup("particle"), openers: inGroup("opener"), ends: inGroup("end") };
125
139
  };
126
140
 
141
+ /** 品詞解析が形容詞・動詞・助動詞と読んだ語の終わり。い で終わるひらがな(ながい食品)を会社の名前の頭に入れないため。 */
142
+ const PREDICATE_POS: ReadonlySet<string> = new Set(["ADJ", "VERB", "AUX"]);
143
+ const predicateEndsOf = (doc: ProseDocument): PredicateEnds =>
144
+ new Set(tokensOf(doc).flatMap((token) => (PREDICATE_POS.has(token.pos) ? [token.span.end] : [])));
145
+
127
146
  const readWordsOf = (doc: ProseDocument): ReadWord[] =>
128
147
  tokensOf(doc).map((token) => ({ start: token.span.start, end: token.span.end, surface: token.surface, reading: token.reading }));
129
148
 
149
+ /** 会社の名前の現れ。大文字で書いた一節の中のものは除く。 */
150
+ const companyMentionsOf = (doc: ProseDocument, prose: string): CompanyMention[] =>
151
+ outsideCapitals(prose, companyMentionsIn(prose, [...companyFormsOf(doc), ...foreignFormsOf(doc)], properOf(doc), kanaStopsOf(doc), predicateEndsOf(doc)));
152
+
130
153
  /**
131
154
  * 会社の名前の書き分けと、名前の漢字一字をその読みのかなで書いた所(みどり野 と みどりの)。名前の見方がすでに指した所と重なる
132
155
  * ものは除く。
133
156
  */
134
- const companyFindings = (doc: ProseDocument, prose: string, reported: readonly Reported[]): Reported[] => {
135
- const stops = kanaStopsOf(doc);
136
- const mentions = companyMentionsIn(prose, [...companyFormsOf(doc), ...foreignFormsOf(doc)], properOf(doc), stops);
157
+ const companyFindings = (doc: ProseDocument, prose: string, mentions: readonly CompanyMention[], reported: readonly Reported[]): Reported[] => {
137
158
  const variants = companyVariants(mentions).map(({ mention, usual, kind }) => ({
138
159
  offset: mention.offset,
139
160
  name: mention.surface,
140
161
  usual,
141
162
  kind: kind === "spelling" ? kind : `company-${kind}`,
142
163
  }));
143
- const kana = kanaSpelledCompanies(prose, mentions, readWordsOf(doc), stops.particles)
164
+ const kana = kanaSpelledCompanies(prose, mentions, readWordsOf(doc), kanaStopsOf(doc).particles)
144
165
  .map(({ surface, offset, usual }) => ({ offset, name: surface, usual, kind: "company-kana" }))
145
166
  .filter((found) => !overlapsAny(variants, found.offset, found.name.length));
146
167
  return [...variants, ...kana].filter(({ offset, name }) => !overlapsAny(reported, offset, name.length));
@@ -189,6 +210,9 @@ const orderWordsOf = (doc: ProseDocument): OrderWord[] => {
189
210
  .map((token) => ({ start: token.span.start, end: token.span.end, key: stemOf(token.surface, suffixes) }));
190
211
  };
191
212
 
213
+ /** 語彙表 name-title-joiner の、前置詞の後ろにだけ立つ冠詞(the)の組。 */
214
+ const ARTICLE = "article";
215
+
192
216
  /**
193
217
  * 語の順を入れ替えて書いた同じ名前(統計学基礎 と 基礎統計学)。名前と読める所は、括弧の中(name-quote)、大文字で始まる語の並び
194
218
  * (name-title-joiner を挟んでよい)、名前を書く欄の後ろ(name-label)。大文字の語の並びどうしは、片方が表の升まるごとに
@@ -196,13 +220,20 @@ const orderWordsOf = (doc: ProseDocument): OrderWord[] => {
196
220
  */
197
221
  const orderFindings = (doc: ProseDocument, prose: string, reported: readonly Reported[]): Reported[] => {
198
222
  const starts = sentenceStartsOf(doc);
223
+ const joiners = doc.lexicons["name-title-joiner"] ?? [];
199
224
  const spans = [
200
225
  ...quotedSpans(prose, patternsOf(doc, "name-quote")),
201
- ...titleCaseSpans(prose, patternsOf(doc, "name-title-joiner"), (offset) => starts.has(offset)),
226
+ ...titleCaseSpans(
227
+ prose,
228
+ joiners.filter((entry) => entry.group !== ARTICLE).map((entry) => entry.pattern),
229
+ (offset) => starts.has(offset),
230
+ joiners.filter((entry) => entry.group === ARTICLE).map((entry) => entry.pattern),
231
+ ),
202
232
  ...labelledSpans(prose, patternsOf(doc, "name-label")),
203
233
  ];
204
234
  const cells = new Set(tableBodyCells(proseAndTablesOf(doc)).map((cell) => cell.text.trim()));
205
- return wordOrderVariants(orderNamesOf(doc.source, spans, orderWordsOf(doc), orderStopsOf(doc)), cells)
235
+ const names = notDefinedTerms(doc, orderNamesOf(doc.source, spans, orderWordsOf(doc), orderStopsOf(doc)));
236
+ return wordOrderVariants(names, cells, sentenceIndexOf(doc))
206
237
  .filter(({ name }) => !overlapsAny(reported, name.offset, name.surface.length))
207
238
  .map(({ name, usual }) => ({ offset: name.offset, name: name.surface, usual, kind: "order" }));
208
239
  };
@@ -220,21 +251,25 @@ const wordsCovering = (tokens: readonly Token[], startAt: ReadonlyMap<number, nu
220
251
 
221
252
  /**
222
253
  * 空白を挟んだ姓と名で、敬称か肩書きが付くか、人を書く欄にあるもの(高瀬 誠部長、氏名:森川 大輔)。語は解析器の切り方のまま、
223
- * 読みは語の読みをつなぐ。解析器の語の切れ目と姓・名の端が合わないものは読まない。
254
+ * 読みは語の読みをつなぐ。名を名の中での字の読みで読み直した読みも持つ(givenNameReading)。解析器の語の切れ目と姓・名の端が
255
+ * 合わないものは読まない。
224
256
  */
225
257
  const spacedNameMentionsOf = (doc: ProseDocument, prose: string, charReadings: CharReadings): NameMention[] => {
226
258
  const cues = { suffixes: patternsOf(doc, "person-suffix"), titles: patternsOf(doc, "person-title"), labels: patternsOf(doc, "person-label") };
227
259
  const tokens = tokensOf(doc);
228
260
  const startAt = new Map(tokens.map((token, index) => [token.span.start, index]));
261
+ const givenChars = givenCharReadingsOf(doc, charReadings);
229
262
  return spacedPersonNamesIn(prose, cues).flatMap(({ surname, given }): NameMention[] => {
230
263
  const surnameWords = wordsCovering(tokens, startAt, surname);
231
264
  const givenWords = wordsCovering(tokens, startAt, given);
232
265
  if (surnameWords === undefined || givenWords === undefined) return [];
233
266
  const words = [...surnameWords, ...givenWords];
234
267
  const surface = `${prose.slice(surname.start, surname.end)} ${prose.slice(given.start, given.end)}`;
235
- return [
236
- { surface, offset: surname.start, reading: readingOfWords(words, charReadings), words: words.map((word) => word.surface), person: true, cue: "person" },
237
- ];
268
+ const surnameReading = readingOfWords(surnameWords, charReadings);
269
+ const givenReading = givenNameReadingOf(givenWords, givenChars, charReadings);
270
+ const givenNameReading = surnameReading === undefined || givenReading === undefined ? undefined : surnameReading + givenReading;
271
+ const reading = readingOfWords(words, charReadings);
272
+ return [{ surface, offset: surname.start, reading, givenNameReading, words: words.map((word) => word.surface), person: true, cue: "person" }];
238
273
  });
239
274
  };
240
275
 
@@ -248,7 +283,7 @@ const tokenRunsOf = (sentence: Sentence): readonly (readonly Token[])[] => {
248
283
  const nameMentionsOf = (doc: ProseDocument, prose: string, chars: VariantChars): NameMention[] => {
249
284
  const cues: NameCues = { leads: patternsOf(doc, "person-lead"), suffixes: patternsOf(doc, "person-suffix"), particles: patternsOf(doc, "name-particle") };
250
285
  const charReadings = charReadingsOf(doc);
251
- const tagged = doc.sentences.flatMap((sentence) => tokenRunsOf(sentence).flatMap((tokens) => mentionsIn(tokens, doc.source, cues.suffixes, charReadings)));
286
+ const tagged = doc.sentences.flatMap((sentence) => tokenRunsOf(sentence).flatMap((tokens) => mentionsIn(tokens, prose, cues.suffixes, charReadings)));
252
287
  const taggedOrSuffixed = [...tagged, ...suffixedNamesIn(prose, cues.suffixes, chars, tagged)];
253
288
  const cued = [...taggedOrSuffixed, ...cuedNamesIn(prose, cues, chars, taggedOrSuffixed)].map((mention): NameMention => {
254
289
  const cue = mention.cue ?? nameCueAt(prose, mention.offset, mention.surface, cues);
@@ -259,7 +294,7 @@ const nameMentionsOf = (doc: ProseDocument, prose: string, chars: VariantChars):
259
294
  const outside = joined.filter(
260
295
  (mention) => !spaced.some((name) => name.offset < mention.offset + mention.surface.length && mention.offset < name.offset + name.surface.length),
261
296
  );
262
- return withKnownNeighbours([...outside, ...spaced], prose).toSorted((left, right) => left.offset - right.offset);
297
+ return outsideCapitals(prose, withKnownNeighbours([...outside, ...spaced], prose)).toSorted((left, right) => left.offset - right.offset);
263
298
  };
264
299
 
265
300
  /** 人の名前で形の似た別の字(太 と 大)は語彙表 name-lookalike-char が組(group)ごとに言う。 */
@@ -311,14 +346,34 @@ const labelledNamesOf = (doc: ProseDocument, mentions: readonly NameMention[]):
311
346
  );
312
347
  };
313
348
 
349
+ const LATIN_WORD = /^[A-Za-z]+$/u;
350
+ const LOWERCASE_WORD = /^[a-z]+$/u;
351
+
352
+ /** 文書が小文字で書くか、品詞解析が普通名詞と読む英字の語(文頭の Hurricane)。 */
353
+ const isCommonToken = (token: Token): boolean => LOWERCASE_WORD.test(token.surface) || (token.pos === "NOUN" && LATIN_WORD.test(token.surface));
354
+
355
+ /** 文書での英字の語の使い方。名前と読んだ語のうち小文字で書けばふつうの語と、普通名詞として書いた語。 */
356
+ const wordUseOf = (doc: ProseDocument): WordUse => {
357
+ const tokens = tokensOf(doc);
358
+ return {
359
+ ordinary: new Set(tokens.flatMap((token) => (isOrdinaryToken(token) ? [token.surface.toLowerCase()] : []))),
360
+ common: new Set(tokens.flatMap((token) => (isCommonToken(token) ? [token.surface.toLowerCase()] : []))),
361
+ };
362
+ };
363
+
314
364
  /** 同じ名前を、文書の中で少しだけ違う形に書いた所(GitHub と Github、山田太郎 と 山田太朗)。少ないほうを指す。 */
315
365
  export const nameVariant: Detector = (doc): Finding[] => {
316
366
  const prose = doc.prose ?? doc.source;
317
367
  const chars = variantCharsOf(doc);
318
- const mentions = labelledNamesOf(doc, ordinaryNamesOf(doc, nameMentionsOf(doc, prose, chars)));
319
- const variants = nameVariants(mentions, chars, spellingInputOf(doc))
368
+ const mentions = labelledNamesOf(doc, ordinaryNamesOf(doc, withGivenNames(tokensOf(doc), doc.source, nameMentionsOf(doc, prose, chars))));
369
+ const companies = companyMentionsOf(doc, prose);
370
+ const inGroup = isGroupPairOf(
371
+ companies,
372
+ companyFormsOf(doc).map((form) => form.pattern),
373
+ );
374
+ const variants = nameVariants(mentions, chars, spellingInputOf(doc), wordUseOf(doc))
320
375
  .map(({ mention, usual, kind }): Reported => ({ offset: mention.offset, name: mention.surface, usual, kind }))
321
- .filter(notSpacingOnly);
376
+ .filter((found) => notSpacingOnly(found) && !inGroup(found));
322
377
  const lookalikes = lookalikeSlipsIn(mentions, lookalikeCharsOf(doc)).map(({ mention, usual }) => ({
323
378
  offset: mention.offset,
324
379
  name: mention.surface,
@@ -326,7 +381,7 @@ export const nameVariant: Detector = (doc): Finding[] => {
326
381
  kind: "lookalike",
327
382
  }));
328
383
  const names = [...variants, ...lookalikes.filter((found) => !overlapsAny(variants, found.offset, found.name.length))];
329
- const namesAndCompanies = [...names, ...companyFindings(doc, prose, names)];
384
+ const namesAndCompanies = [...names, ...companyFindings(doc, prose, companies, names)];
330
385
  const withTables = [...namesAndCompanies, ...tableFindings(doc, prose, mentions, namesAndCompanies).filter(notSpacingOnly)];
331
386
  const withPlaces = [...withTables, ...placeFindings(doc, prose, withTables, chars)];
332
387
  const withProducts = [...withPlaces, ...productFindings(doc, prose, withPlaces)];
@@ -135,12 +135,38 @@ export const unitGaps = (values: readonly Measured[]): UnitGap[] => {
135
135
  const unitsOf = (doc: ProseDocument): Set<string> =>
136
136
  new Set(UNIT_LEXICONS.flatMap((name) => (doc.lexicons[name] ?? []).flatMap((entry) => [entry.pattern, entry.pattern.toLowerCase()])));
137
137
 
138
- export const numberWithoutUnit: Detector = (doc: ProseDocument): Finding[] =>
139
- unitGaps(measuredValues(doc.source, doc.prose ?? doc.source, unitsOf(doc))).map((gap) => ({
140
- rule: "number-without-unit",
141
- severity: "warning",
142
- line: 0,
143
- column: 0,
144
- quote: quoteAt(doc.source, gap.value.offset),
145
- values: { value: gap.value.written, name: gap.value.name, unit: gap.unit, offset: gap.value.offset },
146
- }));
138
+ /** Lexicon piece-count-column: the headings of a column that counts whatever its row is, and the units of a hired period. */
139
+ export type PieceCount = { readonly columns: ReadonlySet<string>; readonly periods: ReadonlySet<string> };
140
+
141
+ const WHOLE_NUMBER = /^\d[\d,]*$/u;
142
+ const TABLE_KIND = /^table \d+: /u;
143
+
144
+ /**
145
+ * A bare whole number in a quantity column whose other rows count a hired period (4 days, 2 nights): the count of a
146
+ * piece the row hires or buys (Child seat | 1), which has no unit to lose.
147
+ */
148
+ export const isPieceCount = (gap: UnitGap, count: PieceCount): boolean =>
149
+ TABLE_KIND.test(gap.value.kind) &&
150
+ count.columns.has(gap.value.name.toLowerCase()) &&
151
+ count.periods.has(gap.unit.toLowerCase()) &&
152
+ WHOLE_NUMBER.test(gap.value.written.normalize("NFKC"));
153
+
154
+ const pieceCountOf = (doc: ProseDocument): PieceCount => {
155
+ const entries = doc.lexicons["piece-count-column"] ?? [];
156
+ const patterns = (group: string): Set<string> => new Set(entries.filter((entry) => entry.group === group).map((entry) => entry.pattern.toLowerCase()));
157
+ return { columns: patterns("column"), periods: patterns("period") };
158
+ };
159
+
160
+ export const numberWithoutUnit: Detector = (doc: ProseDocument): Finding[] => {
161
+ const count = pieceCountOf(doc);
162
+ return unitGaps(measuredValues(doc.source, doc.prose ?? doc.source, unitsOf(doc)))
163
+ .filter((gap) => !isPieceCount(gap, count))
164
+ .map((gap) => ({
165
+ rule: "number-without-unit",
166
+ severity: "warning",
167
+ line: 0,
168
+ column: 0,
169
+ quote: quoteAt(doc.source, gap.value.offset),
170
+ values: { value: gap.value.written, name: gap.value.name, unit: gap.unit, offset: gap.value.offset },
171
+ }));
172
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 大文字の並びでも略語として書かれないもの。どれも字の形だけで決まる。
3
+ * - I だけのローマ数字(II、III)。名前の後ろでなくても番号で(Doswell, III、1964: II Structure)、この形の略語は使われない。
4
+ * IV や VI のように V・X を含む数字は略語(静脈注射の IV)でもあるので、名前の番号(name-numeral.ts)の位置でだけ外す。
5
+ * - 大文字で始まる語に - で繋いだ I・V・X の数字(Association-IV)。名前の番号を空白でなく - で書いた形。
6
+ * - X を 3 つ以上並べた伏せ字(the Secretary of State for XXX)や X の数で書く染色体の型(XXX症候群)。KKK や WWW のような他の字の繰り返しは略語のまま数える。
7
+ */
8
+
9
+ type Span = { readonly start: number; readonly end: number };
10
+
11
+ // 略語の切り出しと同じ境目。日本語の文字(XXX症候群)は語の続きではない。
12
+ const NOT_BEFORE = String.raw`(?<![A-Za-z0-9_&])`;
13
+ const NOT_AFTER = String.raw`(?![A-Za-z0-9_&])`;
14
+
15
+ const ONES_NUMERAL = new RegExp(`${NOT_BEFORE}I{2,3}${NOT_AFTER}`, "gu");
16
+ const MASK = new RegExp(`${NOT_BEFORE}X{3,}${NOT_AFTER}`, "gu");
17
+ const SMALL_NUMERAL = "(?=[IVX])X{0,3}(?:IX|IV|V?I{0,3})";
18
+ const JOINED_NUMERAL = new RegExp(String.raw`(?<![A-Za-z0-9_-])\p{Lu}\p{Ll}+-(?<numeral>${SMALL_NUMERAL})${NOT_AFTER}`, "gu");
19
+
20
+ const spanOf = (match: RegExpExecArray): Span => ({ start: match.index, end: match.index + match[0].length });
21
+
22
+ const joinedSpans = (text: string): Span[] =>
23
+ [...text.matchAll(JOINED_NUMERAL)].map((match) => {
24
+ const end = match.index + match[0].length;
25
+ return { start: end - (match.groups?.["numeral"] ?? "").length, end };
26
+ });
27
+
28
+ /** 文の中の、番号か伏せ字と読む大文字の範囲。 */
29
+ export const numeralWordSpans = (text: string): Span[] => [
30
+ ...[...text.matchAll(ONES_NUMERAL)].map(spanOf),
31
+ ...[...text.matchAll(MASK)].map(spanOf),
32
+ ...joinedSpans(text),
33
+ ];
@@ -0,0 +1,86 @@
1
+ import type { Token } from "../plugin.ts";
2
+
3
+ /** 組織の名前の前に立つ形(語彙表 organisation-form)と、組織や単位の名前を閉じる語(organisation-unit)。 */
4
+ export type OrganisationWords = { readonly forms: readonly string[]; readonly units: readonly string[] };
5
+
6
+ /** 区切りの前に要る字数。1 字なら、普通の語の一部(外部・本部・課題)と見分けられない。 */
7
+ const MIN_BODY_LENGTH = 2;
8
+ const KANJI = /[一-鿿]/u;
9
+
10
+ const surfaceOf = (tokens: readonly Token[]): string => tokens.map((token) => token.surface).join("");
11
+ const isNumber = (token: Token): boolean => token.features?.["NumType"] === "Card";
12
+ const isProperPiece = (token: Token): boolean => token.pos === "PROPN" || token.features?.["NameType"] === "GeoUnit";
13
+
14
+ /** covering の語が、隙間なく続いて並ぶときだけ、その語の並び。改行などで割れていれば読まない。 */
15
+ const contiguous = (tokens: readonly Token[], covering: readonly number[]): Token[] | undefined => {
16
+ const run = covering.flatMap((index) => tokens.slice(index, index + 1));
17
+ const joined = run.every((token, at) => at === 0 || run[at - 1]?.span.end === token.span.start);
18
+ return run.length === covering.length && joined ? run : undefined;
19
+ };
20
+
21
+ /**
22
+ * 連なりのすぐ後ろの語が組織の語そのもの(幼稚園運営企画グループのグループ)なら、それも足した語の並び。
23
+ * 漢字でない組織の語は漢字の連なりの外にあるが、名前はそこで閉じる。
24
+ */
25
+ const withClosingUnit = (tokens: readonly Token[], covering: readonly number[], units: readonly string[]): number[] => {
26
+ const next = (covering.at(-1) ?? -1) + 1;
27
+ const [last, closing] = [tokens[next - 1], tokens[next]];
28
+ const closes =
29
+ covering.length > 0 &&
30
+ last !== undefined &&
31
+ closing !== undefined &&
32
+ last.span.end === closing.span.start &&
33
+ !KANJI.test(closing.surface) &&
34
+ units.includes(closing.surface);
35
+ return closes ? [...covering, next] : [...covering];
36
+ };
37
+
38
+ /** 頭の、語の切れ目で終わる組織の形(国立研究開発法人)の語数。無ければ 0。 */
39
+ const formLength = (run: readonly Token[], forms: ReadonlySet<string>): number =>
40
+ run.reduce((found, _, at) => (forms.has(surfaceOf(run.slice(0, at + 1))) ? at + 1 : found), 0);
41
+
42
+ /** 頭の、固有名詞と地名の単位だけの並び(紀美野町、下神野地区、気象庁)の語数。固有名詞が無ければ 0。 */
43
+ const properLength = (run: readonly Token[]): number => {
44
+ const length = run.findIndex((token) => !isProperPiece(token));
45
+ const stretch = length === -1 ? run.length : length;
46
+ return run.slice(0, stretch).some((token) => token.pos === "PROPN") ? stretch : 0;
47
+ };
48
+
49
+ /** 1 つの区切り(総務課、産業技術総合研究所)か。組織の語で閉じ、その前に 2 字以上の語があり、数を含まない。 */
50
+ const isSegment = (part: readonly Token[], units: readonly string[]): boolean => {
51
+ const text = [...surfaceOf(part)];
52
+ const closing = units.filter((unit) => text.join("").endsWith(unit));
53
+ return !part.some(isNumber) && closing.some((unit) => text.length - [...unit].length >= MIN_BODY_LENGTH);
54
+ };
55
+
56
+ /**
57
+ * run を区切りだけに割ったときの区切りの数の最大。割れなければ 0。
58
+ * 後ろから、各位置から終わりまでを割れる数を一度ずつ決める(長い連なりでも語数の二乗で済む)。
59
+ */
60
+ const segmentCount = (run: readonly Token[], units: readonly string[]): number => {
61
+ const counts = run.reduceRight<number[]>((after, _, start) => {
62
+ const best = run.slice(start).reduce((most, __, offset) => {
63
+ const end = start + offset + 1;
64
+ const rest = after[end - start - 1] ?? 0;
65
+ const closesRun = end === run.length;
66
+ return isSegment(run.slice(start, end), units) && (closesRun || rest > 0) ? Math.max(most, 1 + rest) : most;
67
+ }, 0);
68
+ return [best, ...after];
69
+ }, []);
70
+ return counts[0] ?? 0;
71
+ };
72
+
73
+ /**
74
+ * 漢字の連なりの語(covering: tokens の添字)が 1 つの組織の名前か。名前は書き手が変えられない。
75
+ * 法人格か地名・固有名詞で始まって組織の語で閉じるもの(国立研究開発法人産業技術総合研究所、紀美野町青少年育成町民会議)、
76
+ * または組織の語で閉じる区切りが 2 つ以上続くもの(国土交通省鉄道局総務課)。
77
+ * 組織の語で閉じない連なり(情報処理推進機構認定試験、総務課長)や、頭に名前の無い 1 区切り(個人情報保護法施行規則改正案検討会)は名前ではない。
78
+ */
79
+ export const isOrganisationRun = (tokens: readonly Token[], covering: readonly number[], words: OrganisationWords): boolean => {
80
+ const run = contiguous(tokens, withClosingUnit(tokens, covering, words.units));
81
+ if (run === undefined || run.length === 0) return false;
82
+ const form = formLength(run, new Set(words.forms));
83
+ const head = form > 0 ? form : properLength(run);
84
+ const segments = segmentCount(run.slice(head), words.units);
85
+ return head > 0 ? segments >= 1 : segments >= 2;
86
+ };
@@ -7,8 +7,11 @@ import { nameSpans, touchesAny } from "../team-names.ts";
7
7
  import { furiganaSpans } from "../furigana.ts";
8
8
  import { acronymsIn, isCapitalsNotSpelling } from "../capitals-with-small.ts";
9
9
  import { isPartOfAddress } from "./address-word.ts";
10
+ import { isInCapitalsPassage } from "../capitals-passage.ts";
11
+ import { withoutCoinedNames } from "../coined-hyphen-name.ts";
10
12
  import { wholeWordRuns, type WholeWordRun } from "../whole-word-runs.ts";
11
13
  import { entriesForGenre } from "../lexicon-genres.ts";
14
+ import { asNounWhereNominal } from "../nominal-stem.ts";
12
15
 
13
16
  /**
14
17
  * A word found in the document: where it is, which sentence it is in, its key and spelling, how it is written when that differs, and
@@ -41,6 +44,8 @@ const FUKUSHI = "hiragana-fukushi";
41
44
  const IDIOM = "orthographic-variant-idiom";
42
45
  /** Lexicon: words the tokenizer cuts in one spelling and not the other (お客様, お客 and さま). Each is read whole, keyed by its group. */
43
46
  const WHOLE_WORD = "orthographic-variant-whole-word";
47
+ /** Lexicon: suffixes written onto a word that do not make a compound of it (割当て等, 引受け後): the word keeps its okurigana there. */
48
+ const PHRASE_SUFFIX = "orthographic-variant-phrase-suffix";
44
49
 
45
50
  const patternsOf = (doc: ProseDocument, id: string, genre: string | undefined): string[] =>
46
51
  entriesForGenre(doc.lexicons[id] ?? [], genre).map((entry) => entry.pattern);
@@ -121,7 +126,12 @@ const isCutFromKatakana = ({ token, previous }: InContext): boolean =>
121
126
  const isCopulaReadAsVerb = ({ token, previous }: InContext): boolean =>
122
127
  token.pos === "VERB" && token.surface === "で" && previous !== undefined && previous.pos !== "ADP";
123
128
 
124
- type Skips = { readonly skip: ReadonlySet<string>; readonly idioms: ReadonlySet<string>; readonly wholeWords: ReadonlyMap<string, string> };
129
+ type Skips = {
130
+ readonly skip: ReadonlySet<string>;
131
+ readonly idioms: ReadonlySet<string>;
132
+ readonly wholeWords: ReadonlyMap<string, string>;
133
+ readonly phraseSuffixes: ReadonlySet<string>;
134
+ };
125
135
 
126
136
  const readingKeyOf = (word: InContext, { skip, idioms }: Skips): string | undefined => {
127
137
  const { token } = word;
@@ -156,13 +166,14 @@ const readingWords = (sentence: Sentence, isOpen: IsOpen, skips: Skips): Placed[
156
166
  const whole = runs.flatMap((run) => wholeWordOf(sentence, tokens, run, isOpen, skips.wholeWords));
157
167
  return [
158
168
  ...whole,
159
- ...tokens.flatMap((token, at): Placed[] => {
169
+ ...tokens.flatMap((written, at): Placed[] => {
160
170
  if (inRun.has(at)) return [];
171
+ const next = tokens[at + 1];
172
+ const token = asNounWhereNominal(written, next, skips.phraseSuffixes);
161
173
  const key = readingKeyOf({ token, previous: tokens[at - 1], before: tokens[at - 2] }, skips);
162
174
  const local = token.span.start - sentence.span.start;
163
175
  if (key === undefined || token.lemma === undefined || !isOpen(local, local + token.surface.length)) return [];
164
- const next = tokens[at + 1];
165
- const compoundHead = token.pos === "NOUN" && next?.pos === "NOUN" && isTouching(token, next);
176
+ const compoundHead = token.pos === "NOUN" && next?.pos === "NOUN" && isTouching(token, next) && !skips.phraseSuffixes.has(next.surface);
166
177
  return [{ key, spelling: token.lemma, sentence, offset: token.span.start, compoundHead }];
167
178
  }),
168
179
  ];
@@ -260,7 +271,7 @@ const latinWords = (sentence: Sentence, isOpen: IsOpen, skip: ReadonlySet<string
260
271
  const plain = word.toLowerCase().replaceAll("-", "");
261
272
  const end = match.index + word.length;
262
273
  if (plain.length < MIN_LATIN_KEY || !LOWER.test(word) || isCapitalsNotSpelling(word, acronyms) || skip.has(word.toLowerCase())) return [];
263
- if (isPartOfAddress(sentence.text, match.index, end) || !isOpen(match.index, end)) return [];
274
+ if (isPartOfAddress(sentence.text, match.index, end) || !isOpen(match.index, end) || isInCapitalsPassage(sentence.text, match.index, end)) return [];
264
275
  return [{ key: `latin|${plain}`, spelling: latinSpelling(word), shown: word, sentence, offset: sentence.span.start + match.index }];
265
276
  });
266
277
  };
@@ -305,6 +316,7 @@ export const orthographicVariant: Detector = (doc, options): Finding[] => {
305
316
  skip: new Set([...patternsOf(doc, DISTINCT, options.genre), ...patternsOf(doc, FUKUSHI, options.genre)]),
306
317
  idioms: new Set(patternsOf(doc, IDIOM, options.genre)),
307
318
  wholeWords: new Map((doc.lexicons[WHOLE_WORD] ?? []).map((entry) => [entry.pattern, entry.group ?? entry.pattern])),
319
+ phraseSuffixes: new Set(patternsOf(doc, PHRASE_SUFFIX, options.genre)),
308
320
  };
309
321
  const names = doc.names ?? [];
310
322
  const placed: Place[] = [
@@ -314,7 +326,11 @@ export const orthographicVariant: Detector = (doc, options): Finding[] => {
314
326
  const reading = byKanji(placed.flatMap(({ sentence, isOpen }) => readingWords(sentence, isOpen, skips)));
315
327
  const katakana = placed.flatMap(({ sentence, isOpen }) => katakanaWords(sentence, isOpen));
316
328
  const runs = placed.flatMap(({ sentence, isOpen }) => katakanaRunWords(sentence, isOpen));
317
- const latin = placed.flatMap(({ sentence, isOpen, readsLatin }) => (readsLatin ? latinWords(sentence, isOpen, skips.skip) : []));
329
+ const dictionary = doc.dictionary?.();
330
+ const latin = withoutCoinedNames(
331
+ placed.flatMap(({ sentence, isOpen, readsLatin }) => (readsLatin ? latinWords(sentence, isOpen, skips.skip) : [])),
332
+ (word) => dictionary?.has(word) ?? true,
333
+ );
318
334
  const odd = [reading, katakana, latin].flatMap((words) => oddSpellings(words, options.limit));
319
335
  const oddRuns = oddSpellings(runs, options.limit).filter(({ word }) => !odd.some((other) => coversOffset(word, other.word.offset)));
320
336
  const all = [...reading, ...katakana, ...runs, ...latin];
@@ -1,18 +1,26 @@
1
- import type { Detector, Finding, ProseDocument, Sentence, Span } from "../plugin.ts";
1
+ import type { Detector, Finding, LexiconEntry, ProseDocument, Sentence, Span } from "../plugin.ts";
2
+ import { conjugatedStartsOutside } from "./conjugated-entry.ts";
2
3
  import { calendarRuns, calendarUnitsOf, type CalendarUnits } from "../calendar-number.ts";
3
4
  import { escapeRegExp, latinBoundaries, occurrencesOutside, type Boundary, type SpacingKind } from "../orthography.ts";
4
- import { minorityReport } from "../spacing-minority.ts";
5
+ import { minorityReport, withoutSideOnTie } from "../spacing-minority.ts";
5
6
  import { isWithinAny, quotedSpans } from "../quoted-span.ts";
6
7
  import { digitRunAround, endsWithDivisionLabel, isNumberName, sequenceLabelStarts, type NameContext } from "../number-name.ts";
7
8
  import { isSpacedLocationPart, type FloorWords } from "../location-part.ts";
8
- import { isNameSeparator, type OrganizationWords } from "../name-separator.ts";
9
+ import { isFieldSeparator, isNameSeparator, type OrganizationWords } from "../name-separator.ts";
9
10
  import { addressSpans, clockTimeSpans, identifierSpans, isInsideSpan } from "../spacing-code.ts";
10
11
 
12
+ /** 書いた形の出現に、動詞の活用した形(行う → 行います)を足したもの。同じ位置は一度だけ。 */
13
+ const avoidedStarts = (sentence: Sentence, entry: LexiconEntry, use: string): number[] => {
14
+ const written = occurrencesOutside(sentence.text, entry.pattern, use);
15
+ const conjugated = conjugatedStartsOutside(sentence, entry, use).filter((at) => !written.includes(at));
16
+ return [...written, ...conjugated].toSorted((left, right) => left - right);
17
+ };
18
+
11
19
  /** チームが chaff.yaml の prefer に書いた「使わない書き方」。書いていなければ何も言わない。 */
12
20
  export const preferredTerm: Detector = (doc, options): Finding[] => {
13
- const pairs = (options.lexicon ?? []).flatMap((entry) => (entry.instead_of === undefined ? [] : [{ avoid: entry.pattern, use: entry.instead_of }]));
21
+ const pairs = (options.lexicon ?? []).flatMap((entry) => (entry.instead_of === undefined ? [] : [{ entry, avoid: entry.pattern, use: entry.instead_of }]));
14
22
  const hits = doc.sentences.flatMap((sentence) =>
15
- pairs.flatMap((pair) => occurrencesOutside(sentence.text, pair.avoid, pair.use).map((at) => ({ sentence, at, pair }))),
23
+ pairs.flatMap((pair) => avoidedStarts(sentence, pair.entry, pair.use).map((at) => ({ sentence, at, pair }))),
16
24
  );
17
25
  if (hits.length === 0 || hits.length < options.limit) return [];
18
26
  return hits.map((hit) => ({
@@ -91,7 +99,7 @@ type SentenceCodes = {
91
99
  * 日付・時刻は前の境目(「は 9月」「午後3時」「令和 3 年」)も数えない。日付はまとめて一つの書き方で、数量の空け方の票にはしない。コロンで書いた時刻(13:30)も同じ。
92
100
  * メールアドレス・URL の前後の境目も数えない(spacing-code.ts)。「予約番号 MN-48215 を」の番号の前後も、番号を文から区切る空白なので数えない。
93
101
  * 「本社 5階」のように名前の後ろに空白で区切った階・部屋の番号の前の空白も、所在の組の区切りなので数えない(location-part.ts)。
94
- * 「経営企画部 IR担当」のように名前だけを並べた行で、名前と名前を分ける空白も数えない(name-separator.ts)。
102
+ * 「経営企画部 IR担当」のように名前だけを並べた行で、名前と名前を分ける空白も、「所属:経済学科 1年」のように項目の値の組を分ける空白も数えない(name-separator.ts)。
95
103
  */
96
104
  const isCounted = (sentence: Sentence, boundary: Boundary, context: NumberContext, codes: SentenceCodes): boolean => {
97
105
  if (followsItemNumber(sentence.text, boundary, context.itemNumbers) || besideSpan(codes.identifiers, boundary)) return false;
@@ -103,6 +111,7 @@ const isCounted = (sentence: Sentence, boundary: Boundary, context: NumberContex
103
111
  if (run === undefined) return true;
104
112
  if (codes.calendar.has(run.start)) return false;
105
113
  if (boundary.kind === "before-digit" && isSpacedLocationPart(sentence.text, run, sentence.tokens, sentence.span.start, context.floors)) return false;
114
+ if (isFieldSeparator(sentence.text, boundary, sentence.tokens, sentence.span.start)) return false;
106
115
  return !isNumberName(sentence.text, run, sentence.tokens, sentence.span.start, context);
107
116
  };
108
117
 
@@ -135,9 +144,9 @@ const findingAt = (entry: Located, values: Finding["values"], variant?: string):
135
144
  values: { ...values, offset: entry.sentence.span.start + entry.offset },
136
145
  });
137
146
 
138
- /** 一つの種類の境目の指摘。少ないほうを 1 箇所ずつか、書き方が二通りあれば 1 件で(spacing-minority.ts)。 */
147
+ /** 一つの種類の境目の指摘。少ないほうを 1 箇所ずつか、書き方が二通りあれば 1 件で(spacing-minority.ts)。同数ならどちらの側にも立たない。 */
139
148
  const findingsOf = (kind: SpacingKind, ofKind: readonly Located[], limit: number): Finding[] => {
140
- const report = minorityReport(ofKind, limit);
149
+ const report = withoutSideOnTie(minorityReport(ofKind, limit), ofKind);
141
150
  if (report === undefined) return [];
142
151
  if (report.mode === "mixed") {
143
152
  const { first, odd, spaced, touching } = report;
@@ -0,0 +1,48 @@
1
+ import { escapeRegExp } from "../orthography.ts";
2
+
3
+ /**
4
+ * 行頭の、文字で振った見出しの番号(議事録の Z. の次の AA.、AB. … BZ.)。表計算の列名と同じく A〜Z の次は AA と進む。
5
+ * 略語ではない。行頭で . か ) が続き、その前か後の番号も同じ文書の行頭にあるときだけ番号と読む。1 か所だけの
6
+ * 行頭の大文字(IT. の説明、FAQ) の行)は略語のまま数える。そう読めた番号を区切りの名前の後ろで指す所(See Attachment AA)も
7
+ * 番号。区切りの名前は言語パッケージの語彙表から読む。
8
+ */
9
+
10
+ type Span = { readonly start: number; readonly end: number };
11
+
12
+ const LABEL = /^[ \t]*(?<label>[A-Z]{1,3})[.)](?=[ \t]|$)/gmu;
13
+ const ALPHABET = 26;
14
+ const CODE_BEFORE_A = 64;
15
+
16
+ /** A=1、Z=26、AA=27、AZ=52、BA=53。 */
17
+ const positionOf = (label: string): number => [...label].reduce((total, letter) => total * ALPHABET + (letter.charCodeAt(0) - CODE_BEFORE_A), 0);
18
+
19
+ type Label = { readonly text: string; readonly position: number; readonly span: Span };
20
+
21
+ const labelsOf = (source: string): Label[] =>
22
+ [...source.matchAll(LABEL)].map((match) => {
23
+ const text = match.groups?.["label"] ?? "";
24
+ const start = match.index + match[0].indexOf(text);
25
+ return { text, position: positionOf(text), span: { start, end: start + text.length } };
26
+ });
27
+
28
+ const lineLabels = (source: string): Label[] => {
29
+ const labels = labelsOf(source);
30
+ const positions = new Set(labels.map((label) => label.position));
31
+ return labels.filter(({ position }) => positions.has(position - 1) || positions.has(position + 1));
32
+ };
33
+
34
+ const referenceSpans = (source: string, labels: readonly Label[], divisions: readonly string[]): Span[] => {
35
+ const texts = [...new Set(labels.map((label) => label.text))];
36
+ if (texts.length === 0 || divisions.length === 0) return [];
37
+ const pattern = new RegExp(String.raw`(?<![A-Za-z0-9_])(?:${divisions.map(escapeRegExp).join("|")})\s+(?<label>${texts.join("|")})(?![A-Za-z0-9_&])`, "gu");
38
+ return [...source.matchAll(pattern)].map((match) => {
39
+ const end = match.index + match[0].length;
40
+ return { start: end - (match.groups?.["label"] ?? "").length, end };
41
+ });
42
+ };
43
+
44
+ /** 文書の中の、隣の番号と並んだ文字の番号と、それを区切りの名前の後ろで指す所の範囲。位置は文書の頭からの文字数。 */
45
+ export const outlineLabelSpans = (source: string, divisions: readonly string[]): Span[] => {
46
+ const labels = lineLabels(source);
47
+ return [...labels.map((label) => label.span), ...referenceSpans(source, labels, divisions)];
48
+ };
@@ -0,0 +1,26 @@
1
+ import { escapeRegExp } from "../orthography.ts";
2
+ import type { LengthUnit } from "../plugin.ts";
3
+
4
+ /**
5
+ * Page markers a converted print edition leaves inside a sentence ("( printed page 52044)", "[[Page 52044]]", 「-12-」).
6
+ * They are the page break, not the writer's words. The shapes come from the lexicon: "#" stands for the page number and a
7
+ * space for any run of spaces, none included. A marker touching a digit is part of a number (an address, 1-2-3).
8
+ */
9
+ const NUMBER = "#";
10
+
11
+ const TEMPLATE_PARTS: Readonly<Record<string, string>> = { [NUMBER]: String.raw`\p{Nd}+`, " ": String.raw`\s*` };
12
+
13
+ const templatePattern = (template: string): string => [...template].map((char) => TEMPLATE_PARTS[char] ?? escapeRegExp(char)).join("");
14
+
15
+ /** One pattern for every page marker the lexicon names, or undefined when it names none. */
16
+ export const pageMarkerPattern = (templates: readonly string[]): RegExp | undefined =>
17
+ templates.length === 0 ? undefined : new RegExp(String.raw`(?<!\p{Nd})(?:${templates.map(templatePattern).join("|")})(?!\p{Nd})`, "gu");
18
+
19
+ const sizeOf = (marker: string, unit: LengthUnit): number =>
20
+ unit === "word" ? marker.split(/\s+/u).filter((word) => word.length > 0).length : marker.replace(/\s+/gu, "").length;
21
+
22
+ /** How much of a sentence its page markers take up, in the document's unit: their words, or their characters without spaces. */
23
+ export const pageMarkerSize = (text: string, pattern: RegExp | undefined, unit: LengthUnit): number => {
24
+ if (pattern === undefined) return 0;
25
+ return [...text.matchAll(pattern)].map((match) => match[0]).reduce((size, marker) => size + sizeOf(marker, unit), 0);
26
+ };