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,9 +1,11 @@
1
- import type { Detector, DocumentProfile, Finding, Sentence, Span, Token } from "../plugin.ts";
1
+ import type { Detector, DocumentProfile, Finding, ProseDocument, Sentence, Span, Token } from "../plugin.ts";
2
2
  import { compacted } from "./gram-place.ts";
3
- import { leadingCounter } from "./counter-edge.ts";
3
+ import { leadingCounter, trailingPrefix } from "./counter-edge.ts";
4
4
  import { maskAddresses } from "../address-chain.ts";
5
5
  import { isAddressRun } from "./place-run.ts";
6
6
  import { isOneName } from "./name-run.ts";
7
+ import { isOrganisationRun, type OrganisationWords } from "./organisation-run.ts";
8
+ import { endsInTitle, isTitlePosition, isTitledName, type TitleWords } from "./titled-run.ts";
7
9
  import { proseText } from "../measure.ts";
8
10
  import { parallelDotCount } from "./middle-dot.ts";
9
11
  import { maskSpans } from "../mask.ts";
@@ -16,11 +18,17 @@ import { nameSpans } from "../team-names.ts";
16
18
  */
17
19
  const KANJI_RUN = /[一-鿿]+/gu;
18
20
 
19
- /** 漢字の連なりと、その文書全体の座標での範囲。quoted は鉤括弧の中身がまるごとこの連なりであること。 */
20
- type KanjiRun = { readonly text: string; readonly span: Span | undefined; readonly quoted: boolean };
21
+ /**
22
+ * 漢字の連なりと、その文書全体の座標での範囲。quoted は括弧の中身がまるごとこの連なりであること。
23
+ * placed は、題の名前の置き方(括弧を閉じる、補いの括弧が続く、文がこれだけ)をしていること。
24
+ */
25
+ type KanjiRun = { readonly text: string; readonly span: Span | undefined; readonly quoted: boolean; readonly placed: boolean };
21
26
 
22
27
  const SPACE = /\s/gu;
23
28
 
29
+ /** 名前を囲む括弧。鉤括弧と、見出しや分類の名前を囲む隅付き括弧(【浪速区役所公募型比較見積】)。 */
30
+ const NAME_MARKS = { "「": "」", "『": "』", "【": "】" };
31
+
24
32
  /**
25
33
  * 同じ連なりが文に二度出ても、それぞれの位置で読む。proseText は空白を詰めたり除いたりするだけなので、
26
34
  * 空白でない k 文字目は元の文でも空白でない k 文字目。番地の覆いは長さを保つので、proseText の位置がそのまま使える。
@@ -29,9 +37,9 @@ const SPACE = /\s/gu;
29
37
  const maskedProse = (prose: string, profile: DocumentProfile | undefined, names: readonly string[]): string =>
30
38
  maskSpans(maskAddresses(prose, profile), nameSpans(prose, names));
31
39
 
32
- /** 鉤括弧の中身が、ちょうどこの範囲(文の先頭からの位置)か。括弧でくくった漢字だけの語は、書き手が 1 つの名前として示したもの。 */
40
+ /** 鉤括弧と隅付き括弧の中身が、ちょうどこの範囲(文の先頭からの位置)か。括弧でくくった漢字だけの語は、書き手が 1 つの名前として示したもの。 */
33
41
  const fillsQuote = (sentence: Sentence, start: number, end: number): boolean =>
34
- quotedSpans(sentence.text).some((span) => span.start === start && span.end === end);
42
+ quotedSpans(sentence.text, NAME_MARKS).some((span) => span.start === start && span.end === end);
35
43
 
36
44
  const runsOf = (sentence: Sentence, profile: DocumentProfile | undefined, names: readonly string[]): KanjiRun[] => {
37
45
  const prose = proseText(sentence);
@@ -39,42 +47,86 @@ const runsOf = (sentence: Sentence, profile: DocumentProfile | undefined, names:
39
47
  return [...maskedProse(prose, profile, names).matchAll(KANJI_RUN)].map((match) => {
40
48
  const before = prose.slice(0, match.index).replace(SPACE, "").length;
41
49
  const [start, last] = [printed[before], printed[before + match[0].length - 1]];
42
- if (start === undefined || last === undefined) return { text: match[0], span: undefined, quoted: false };
43
- return { text: match[0], span: { start: sentence.span.start + start, end: sentence.span.start + last + 1 }, quoted: fillsQuote(sentence, start, last + 1) };
50
+ if (start === undefined || last === undefined) return { text: match[0], span: undefined, quoted: false, placed: false };
51
+ const span = { start: sentence.span.start + start, end: sentence.span.start + last + 1 };
52
+ return { text: match[0], span, quoted: fillsQuote(sentence, start, last + 1), placed: isTitlePosition(sentence.text, start, last + 1) };
44
53
  });
45
54
  };
46
55
 
47
- /** 漢字の連なりが住所(東京都港区新橋二丁目)か 1 つの名前(日本銀行)か。形態素解析の地名・人名・組織名と数で決める。 */
48
- const isPlaceName = (tokens: readonly Token[], span: Span, topUnits: ReadonlySet<string>): boolean => {
49
- const covering = tokens.flatMap((token, index) => (token.span.start < span.end && span.start < token.span.end ? [index] : []));
50
- return isAddressRun(tokens, covering, topUnits) || isOneName(tokens, covering);
56
+ /** 連なりを数えないと決める語彙: 住所の先頭にしか来ない単位(都道府県)と、組織の名前の形と単位と、題の名前を閉じる語。 */
57
+ type NameWords = { readonly topUnits: ReadonlySet<string>; readonly organisation: OrganisationWords; readonly title: TitleWords };
58
+
59
+ /** 1 つの文書で連なりを読むのに要るもの。titled は、文書の中で題として置かれた名前(titledNames)。 */
60
+ type RunContext = {
61
+ readonly profile: DocumentProfile | undefined;
62
+ readonly names: readonly string[];
63
+ readonly words: NameWords;
64
+ readonly titled: readonly string[];
51
65
  };
52
66
 
67
+ const coveringOf = (tokens: readonly Token[], span: Span): number[] =>
68
+ tokens.flatMap((token, index) => (token.span.start < span.end && span.start < token.span.end ? [index] : []));
69
+
53
70
  /**
54
- * 数えない連なりは空。頭の、数に付いた助数詞(2日日本弁護士連合会の「日」)は数えない。
55
- * 住所か名前かは、助数詞を外した残りで決める(1日日本銀行の「日本銀行」)。品詞が無ければ判定しない。
71
+ * 漢字の連なりが住所(東京都港区新橋二丁目)か 1 つの名前(日本銀行)か 1 つの組織の名前(国立研究開発法人産業技術総合研究所)か。
72
+ * 形態素解析の地名・人名・組織名と数、組織の語彙で決める。
56
73
  */
57
- const measuredRun = (tokens: readonly Token[] | undefined, run: KanjiRun, topUnits: ReadonlySet<string>): string => {
74
+ const isPlaceName = (tokens: readonly Token[], span: Span, words: NameWords): boolean => {
75
+ const covering = coveringOf(tokens, span);
76
+ return isAddressRun(tokens, covering, words.topUnits) || isOneName(tokens, covering) || isOrganisationRun(tokens, covering, words.organisation);
77
+ };
78
+
79
+ /** 題の名前(大阪市鶴見区役所公募型比較見積実施要綱)か。題を閉じる語で終わり、ここか文書のほかの所で題として置かれている。 */
80
+ const isTitle = (tokens: readonly Token[], span: Span, text: string, placed: boolean, context: RunContext): boolean =>
81
+ endsInTitle(
82
+ coveringOf(tokens, span).flatMap((index) => tokens.slice(index, index + 1)),
83
+ context.words.title,
84
+ ) &&
85
+ (placed || isTitledName(text, context.titled));
86
+
87
+ /**
88
+ * 数えない連なりは空。頭の、数に付いた助数詞(2日日本弁護士連合会の「日」)と、尻の、数に付く接頭の語(施行令第172条の「第」)は数えない。
89
+ * 住所か名前かは、それを外した残りで決める(1日日本銀行の「日本銀行」)。品詞が無ければ判定しない。
90
+ */
91
+ const measuredRun = (tokens: readonly Token[] | undefined, run: KanjiRun, context: RunContext): string => {
58
92
  if (run.quoted) return "";
59
93
  if (tokens === undefined || run.span === undefined) return run.text;
60
94
  const counter = leadingCounter(tokens, run.span.start, run.text);
61
- const rest = counter === undefined ? run.span : { start: counter.span.end, end: run.span.end };
62
- return isPlaceName(tokens, rest, topUnits) ? "" : run.text.slice(counter?.surface.length ?? 0);
95
+ const prefix = trailingPrefix(tokens, run.span.end, run.text);
96
+ const rest = { start: counter?.span.end ?? run.span.start, end: prefix?.span.start ?? run.span.end };
97
+ const text = run.text.slice(counter?.surface.length ?? 0, run.text.length - (prefix?.surface.length ?? 0));
98
+ return isPlaceName(tokens, rest, context.words) || isTitle(tokens, rest, text, run.placed, context) ? "" : text;
63
99
  };
64
100
 
65
- const longestKanji = (sentence: Sentence, profile: DocumentProfile | undefined, topUnits: ReadonlySet<string>, names: readonly string[]): string =>
66
- runsOf(sentence, profile, names)
67
- .map((run) => measuredRun(sentence.tokens, run, topUnits))
101
+ const longestKanji = (sentence: Sentence, context: RunContext): string =>
102
+ runsOf(sentence, context.profile, context.names)
103
+ .map((run) => measuredRun(sentence.tokens, run, context))
68
104
  .reduce((longest, run) => (run.length > longest.length ? run : longest), "");
69
105
 
106
+ /**
107
+ * 文書の中で題として置かれた漢字の連なり: 題の置き方をした文の中の連なりと、見出しの中の連なり。
108
+ * 同じ名前を文の中で使えば(認定職業訓練実施奨励金の支給額)、それも題の名前と読む。
109
+ */
110
+ const titledNames = (doc: ProseDocument, profile: DocumentProfile | undefined, names: readonly string[]): string[] => [
111
+ ...doc.sentences.flatMap((sentence) => runsOf(sentence, profile, names).flatMap((run) => (run.placed ? [run.text] : []))),
112
+ ...(doc.markup?.headings ?? []).flatMap((heading) => [...heading.text.matchAll(KANJI_RUN)].map((match) => match[0])),
113
+ ];
114
+
70
115
  /**
71
116
  * 漢字が続くと、どこで語が切れるのか読み手が探すことになる。
72
117
  * 「情報処理推進機構認定試験」は 12 字。ひらがなを 1 つ挟むだけで読める。
73
118
  */
74
119
  export const kanjiRun: Detector = (doc, options): Finding[] => {
75
- const topUnits = new Set((doc.lexicons["prefecture-unit"] ?? []).map((entry) => entry.pattern));
120
+ const patterns = (id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
121
+ const words: NameWords = {
122
+ topUnits: new Set(patterns("prefecture-unit")),
123
+ organisation: { forms: patterns("organisation-form"), units: patterns("organisation-unit") },
124
+ title: { endings: patterns("title-ending") },
125
+ };
126
+ const names = doc.names ?? [];
127
+ const context: RunContext = { profile: doc.profile, names, words, titled: titledNames(doc, doc.profile, names) };
76
128
  return doc.sentences
77
- .map((sentence) => ({ sentence, run: longestKanji(sentence, doc.profile, topUnits, doc.names ?? []) }))
129
+ .map((sentence) => ({ sentence, run: longestKanji(sentence, context) }))
78
130
  .filter(({ run }) => run.length > options.limit)
79
131
  .map(({ sentence, run }) => ({
80
132
  rule: "max-kanji-continuous",
@@ -1,5 +1,6 @@
1
1
  import type { Detector, DetectorOptions, Finding, Lexicon, ProseDocument, Sentence, Token } from "../plugin.ts";
2
2
  import { isWithinAny, quotedIn } from "../quoted-span.ts";
3
+ import { definitionWordsOf, isParallelDefinition } from "./parallel-definition.ts";
3
4
 
4
5
  // The shape of a clause read from its words: how it ends, a paired word left alone, an adverb that needs a
5
6
  // negation, a particle used where another one belongs. Every word comes from a lexicon; this file knows parts of speech.
@@ -74,13 +75,22 @@ const runFinding = (run: readonly Ended[], limit: number): Finding => {
74
75
  };
75
76
  };
76
77
 
77
- /** More than limit sentences in a row within one paragraph that end with the same words. */
78
- export const endingRun: Detector = (doc, options): Finding[] =>
79
- doc.paragraphs.flatMap((paragraph) =>
78
+ /** More than limit sentences in a row within one paragraph that end with the same words, unless they define different terms in one frame. */
79
+ export const endingRun: Detector = (doc, options): Finding[] => {
80
+ const words = definitionWordsOf(options.lexicon);
81
+ return doc.paragraphs.flatMap((paragraph) =>
80
82
  endingRuns(paragraph.sentences)
81
- .filter((run) => run.length > options.limit)
83
+ .filter(
84
+ (run) =>
85
+ run.length > options.limit &&
86
+ !isParallelDefinition(
87
+ run.map(({ sentence }) => sentence),
88
+ words,
89
+ ),
90
+ )
82
91
  .map((run) => runFinding(run, options.limit)),
83
92
  );
93
+ };
84
94
 
85
95
  // --- unpaired-parallel: a word that lists by pairs (〜たり) used once, followed by another clause -----------------
86
96
 
@@ -20,6 +20,7 @@ const wordsOf = (doc: ProseDocument): BalanceWords => ({
20
20
  outflow: patternsOf(doc, LEXICON, "outflow"),
21
21
  closing: patternsOf(doc, LEXICON, "closing"),
22
22
  },
23
+ asOf: patternsOf(doc, LEXICON, "as-of"),
23
24
  magnitudes: patternsOf(doc, "amount-multiplier"),
24
25
  percentUnits: patternsOf(doc, "percent-unit"),
25
26
  });
@@ -3,6 +3,7 @@
3
3
  import { parse } from "../markdown-read.ts";
4
4
  import { spanOf } from "../markdown-node.ts";
5
5
  import { eachPreOrder } from "../tree-walk.ts";
6
+ import { maskSpans } from "../mask.ts";
6
7
 
7
8
  export type CodeFence = {
8
9
  /** Where the opening fence line starts. */
@@ -79,6 +80,15 @@ export const codeFences = (source: string): readonly CodeFence[] => {
79
80
  return fences;
80
81
  };
81
82
 
83
+ /**
84
+ * The source with every fenced code block blanked, offsets and line breaks kept. A list or a sentence in a code block is an
85
+ * example, not the document's own: a rule that reads values from the source line by line reads this instead.
86
+ */
87
+ export const withoutCodeBlocks = (source: string): string => {
88
+ const fences = codeFences(source);
89
+ return fences.length === 0 ? source : maskSpans(source, fences);
90
+ };
91
+
82
92
  /** Inline code spans in a stretch of text: a run of backticks closed by a run of the same length. */
83
93
  export const codeSpans = (text: string, offset = 0): CodeSpan[] => {
84
94
  const spans: CodeSpan[] = [];
@@ -1,5 +1,6 @@
1
- import type { Span, StructureKind, StructureNode, Token } from "../plugin.ts";
1
+ import type { Sentence, Span, StructureKind, StructureNode, Token } from "../plugin.ts";
2
2
  import { preOrder } from "../tree-walk.ts";
3
+ import { isStatement } from "./technical-docs.ts";
3
4
 
4
5
  /**
5
6
  * 形態素解析が数と読んだ語(UD の NumType=Card)。漢数字の「二割」「十五分」も、算用数字と同じ具体的な数。
@@ -30,3 +31,78 @@ const EVIDENCE: ReadonlySet<StructureKind> = new Set(["reference", "quantity", "
30
31
 
31
32
  export const evidenceSpans = (root: StructureNode | undefined): Span[] =>
32
33
  root === undefined ? [] : preOrder(root).flatMap((node) => (EVIDENCE.has(node.kind) ? [node.span] : []));
34
+
35
+ /** 読み手にすることを伝える言い方。英語は文の書き出し(Never use, Please submit)、日本語は文末(〜ください、〜しましょう)。 */
36
+ export type AdviceWords = { readonly openers: readonly string[]; readonly endings: readonly string[] };
37
+
38
+ const CLOSERS = new Set(Array.from("\"'”’」』))】〕〉》]]"));
39
+ const TERMINALS = new Set(Array.from("。..!!"));
40
+ const QUESTION_MARKS = new Set(["?", "?"]);
41
+ const SKIPPED = new Set(["PUNCT", "SYM", "X", "SPACE"]);
42
+
43
+ /** 文末から、閉じ括弧・引用符(と、渡されれば句点)を外した残り。 */
44
+ const withoutTail = (text: string, tail: ReadonlySet<string>): string => {
45
+ const chars = Array.from(text.trimEnd());
46
+ const last = chars.findLastIndex((char) => !tail.has(char) && char.trim() !== "");
47
+ return chars.slice(0, last + 1).join("");
48
+ };
49
+
50
+ const isQuestion = (text: string): boolean => QUESTION_MARKS.has(Array.from(withoutTail(text, CLOSERS)).at(-1) ?? "");
51
+
52
+ const opensWith = (text: string, openers: readonly string[]): boolean => {
53
+ const lower = text.trimStart().toLowerCase();
54
+ return openers.some((opener) => lower.startsWith(`${opener} `));
55
+ };
56
+
57
+ const endsWith = (text: string, endings: readonly string[]): boolean => {
58
+ const body = withoutTail(text, new Set([...CLOSERS, ...TERMINALS]));
59
+ return endings.some((ending) => body.endsWith(ending));
60
+ };
61
+
62
+ /** 項目の番号(a, 12, iv)。 */
63
+ const ENUMERATOR = /^(?:\p{L}|\p{Nd}{1,3}|[ivx]{1,4})$/iu;
64
+ const BRACKETED = /^[((](.+)[))]$/u;
65
+ const MARKED = /^(.+)[.)).]$/u;
66
+
67
+ /** 項目の番号だけが文として切り出されたもの(a. や (1))。述べることも問うことも無い。 */
68
+ export const isLabelOnly = (sentence: Pick<Sentence, "text">): boolean => {
69
+ const text = sentence.text.trim();
70
+ const core = BRACKETED.exec(text)?.[1] ?? MARKED.exec(text)?.[1];
71
+ return core !== undefined && ENUMERATOR.test(core);
72
+ };
73
+
74
+ /** 動詞の目的語の書き出し(Use a generator, Review our benefits)。名詞と読まれた語の後ろにこれが来れば、その語は動詞。 */
75
+ const OBJECT_OPENER = new Set(["DET", "PRON"]);
76
+
77
+ /**
78
+ * 原形の動詞(Keep, Take)。解析器が名詞と読んだ、動詞にもなる語も、目的語が続けば同じ(Use a generator)。
79
+ * 後ろが名詞や前置詞なら名詞句の頭(evidence of complexity, trust development plans)。
80
+ */
81
+ const isBaseVerb = (token: Token, next: Token | undefined): boolean =>
82
+ (token.pos === "VERB" && token.lemma?.toLowerCase() === token.surface.toLowerCase() && token.features?.["VerbForm"] === undefined) ||
83
+ (token.pos === "NOUN" && token.features?.["AlsoVerb"] === "Yes" && token.features["Number"] !== "Plur" && OBJECT_OPENER.has(next?.pos ?? ""));
84
+
85
+ /** 頭の語が一語として立っている。空白を置かずに続けば、語の一部(Cloud.gov の Cloud)。 */
86
+ const standsAlone = (tokens: readonly Token[], head: Token): boolean => {
87
+ const after = tokens[tokens.indexOf(head) + 1];
88
+ return after === undefined || after.span.start > head.span.end || after === tokens.at(-1) || after.surface === ",";
89
+ };
90
+
91
+ /**
92
+ * 動詞で始まる英語の文(Keep freezers closed)は指示。すぐ後ろがコロンなら見出し語(Release: none)で、主語のある文は述べる文。
93
+ * 日本語は動詞が文末に来るので、品詞では読まない。
94
+ */
95
+ const opensWithVerb = (tokens: readonly Token[], language: string): boolean => {
96
+ const [head, next] = tokens.filter((token) => !SKIPPED.has(token.pos) || token.surface === ":");
97
+ return language === "en" && head !== undefined && isBaseVerb(head, next) && standsAlone(tokens, head) && next?.surface !== ":" && !isStatement(tokens);
98
+ };
99
+
100
+ /**
101
+ * 読み手が裏づけを求められることを述べた文。問い(情報提供の依頼に並ぶ質問)と指示(安全の手引き)は主張ではなく、
102
+ * 数字が欠けているとは言えない。
103
+ */
104
+ export const isClaim = (sentence: Pick<Sentence, "text" | "tokens">, language: string, words: AdviceWords): boolean =>
105
+ !isQuestion(sentence.text) &&
106
+ !opensWith(sentence.text, words.openers) &&
107
+ !endsWith(sentence.text, words.endings) &&
108
+ !opensWithVerb(sentence.tokens ?? [], language);
@@ -0,0 +1,60 @@
1
+ import type { Detector, Finding, Lexicon, Sentence, Token } from "../plugin.ts";
2
+ import { isWithinAny, quotedIn } from "../quoted-span.ts";
3
+
4
+ // A noun for a point in time written where the clause states a condition (認定を受けた時は → 認定を受けたときは). One word
5
+ // list gives the noun and its kana form, another the particles that make the clause a condition; this file knows parts of
6
+ // speech. Pure: the sentence and the word lists come in.
7
+
8
+ export type ConditionWords = { readonly nouns: ReadonlyMap<string, string>; readonly followers: ReadonlySet<string> };
9
+
10
+ export type ConditionSpelling = { readonly written: string; readonly preferred: string; readonly offset: number };
11
+
12
+ /** A predicate ends the clause before the noun (受けた時, 過ぎる時, 支払わない時, 必要な時); の, その and ある (事故の時, その時) do not. */
13
+ const PREDICATE_POS: ReadonlySet<string> = new Set(["VERB", "AUX", "ADJ"]);
14
+
15
+ const FOLLOWER_LIST = "condition-follower";
16
+
17
+ /** The nouns with their rewrite (時 → とき), and the particles that follow them in a condition (は, には, も). */
18
+ export const conditionWordsOf = (nouns: Lexicon | undefined, followers: Lexicon | undefined): ConditionWords => ({
19
+ nouns: new Map((nouns ?? []).flatMap((entry): [string, string][] => (entry.rewrite === undefined ? [] : [[entry.pattern, entry.rewrite]]))),
20
+ followers: new Set((followers ?? []).map((entry) => entry.pattern)),
21
+ });
22
+
23
+ /** The follower right after index: one particle (は, も) or two the tagger splits (に + は). */
24
+ const isFollowedByCondition = (tokens: readonly Token[], index: number, followers: ReadonlySet<string>): boolean => {
25
+ const next = tokens[index + 1]?.surface ?? "";
26
+ const pair = `${next}${tokens[index + 2]?.surface ?? ""}`;
27
+ return followers.has(next) || followers.has(pair);
28
+ };
29
+
30
+ const isConditionNoun = (tokens: readonly Token[], index: number, words: ConditionWords): boolean => {
31
+ const token = tokens[index];
32
+ if (token === undefined || !words.nouns.has(token.surface)) return false;
33
+ const previous = tokens[index - 1];
34
+ return previous !== undefined && PREDICATE_POS.has(previous.pos) && isFollowedByCondition(tokens, index, words.followers);
35
+ };
36
+
37
+ /** Each noun in the sentence, outside 「」『』, that ends a predicate and is followed by は, には or も. */
38
+ export const conditionSpellingsIn = (sentence: Sentence, words: ConditionWords): ConditionSpelling[] => {
39
+ const tokens = sentence.tokens ?? [];
40
+ const quoted = quotedIn(sentence);
41
+ return tokens.flatMap((token, index) =>
42
+ isConditionNoun(tokens, index, words) && !isWithinAny(quoted, token.span)
43
+ ? [{ written: token.surface, preferred: words.nouns.get(token.surface) ?? "", offset: token.span.start }]
44
+ : [],
45
+ );
46
+ };
47
+
48
+ export const conditionToki: Detector = (doc, options): Finding[] => {
49
+ const words = conditionWordsOf(options.lexicon, doc.lexicons[FOLLOWER_LIST]);
50
+ return doc.sentences.flatMap((sentence) =>
51
+ conditionSpellingsIn(sentence, words).map((spelling) => ({
52
+ rule: "",
53
+ severity: "info",
54
+ line: 0,
55
+ column: 0,
56
+ quote: sentence.text.trim(),
57
+ values: { matched: spelling.written, preferred: spelling.preferred, offset: spelling.offset },
58
+ })),
59
+ );
60
+ };
@@ -0,0 +1,53 @@
1
+ import type { LexiconEntry, Sentence, Span, Token } from "../plugin.ts";
2
+ import { escapeRegExp } from "../orthography.ts";
3
+ import { entryRanges } from "./lexicon-match.ts";
4
+
5
+ /**
6
+ * チームが辞書形の動詞で書いた語か(巻き取る・握っておく・utilize)。最後の語が動詞の原形のときだけ。
7
+ * 名詞(巻き取り・onboarding)や活用した形(握った)は書いた形のまま照らす。動詞の名詞形まで当てると、チームが並べていない語を指摘する。
8
+ */
9
+ export const isDictionaryVerb = (entry: LexiconEntry): boolean => {
10
+ const last = entry.tokens?.at(-1);
11
+ return last?.pos === "VERB" && last.lemma?.toLowerCase() === last.surface.toLowerCase();
12
+ };
13
+
14
+ /** 直前に動詞が詰めて書いてある(受け|取ります)。そこは別の複合動詞の後ろ半分で、並べた動詞ではない。 */
15
+ const tailOfCompound = (tokens: readonly Token[], start: number): boolean => {
16
+ const before = tokens[start - 1];
17
+ return before?.pos === "VERB" && before.span.end === tokens[start]?.span.start;
18
+ };
19
+
20
+ /**
21
+ * 辞書形の動詞で書いた語が、活用した形で文のどこに出たか(文の中の字の範囲)。複合動詞は語に割れる(巻き/取り)ので、語の並びで照らす。
22
+ * 品詞が無い文書、動詞でない語には何も返さない。字で探す側がそのまま当たる。
23
+ */
24
+ export const conjugatedSpans = (sentence: Sentence, entry: LexiconEntry): Span[] => {
25
+ const tokens = sentence.tokens;
26
+ if (tokens === undefined || !isDictionaryVerb(entry)) return [];
27
+ return entryRanges(sentence, entry).flatMap((range) => {
28
+ const first = tokens[range.start];
29
+ const last = tokens[range.end - 1];
30
+ if (first === undefined || last === undefined || tailOfCompound(tokens, range.start)) return [];
31
+ return [{ start: first.span.start - sentence.span.start, end: last.span.end - sentence.span.start }];
32
+ });
33
+ };
34
+
35
+ const occurrencesOf = (text: string, word: string): Span[] =>
36
+ word === ""
37
+ ? []
38
+ : [...text.matchAll(new RegExp(escapeRegExp(word), "giu"))].map((match) => ({
39
+ start: match.index,
40
+ end: match.index + match[0].length,
41
+ }));
42
+
43
+ /**
44
+ * prefer の「使わない書き方」が動詞のとき、活用した形の始まり(文の中の字の位置)。「使う書き方」の中に出たものは除く。
45
+ * 大文字小文字だけ違う組(Javascript・JavaScript)は語で照らすと区別が消えるので、字で探す側に任せる。
46
+ */
47
+ export const conjugatedStartsOutside = (sentence: Sentence, entry: LexiconEntry, use: string): number[] => {
48
+ if (entry.pattern.toLowerCase() === use.toLowerCase()) return [];
49
+ const covered = occurrencesOf(sentence.text, use);
50
+ return conjugatedSpans(sentence, entry)
51
+ .filter((span) => !covered.some((cover) => cover.start <= span.start && span.end <= cover.end))
52
+ .map((span) => span.start);
53
+ };
@@ -7,7 +7,8 @@ import type { Token } from "../plugin.ts";
7
7
  const CONTENT_POS = new Set(["NOUN", "PROPN", "NUM", "VERB", "ADJ", "ADV"]);
8
8
 
9
9
  /** 接頭詞・接尾・非自立の語(Bound)と、動詞にするだけの「する」(VerbType=Light)は、付いた語が中身を持つ。 */
10
- const isContent = (token: Token): boolean => CONTENT_POS.has(token.pos) && token.features?.["Bound"] !== "Yes" && token.features?.["VerbType"] !== "Light";
10
+ export const isContent = (token: Token): boolean =>
11
+ CONTENT_POS.has(token.pos) && token.features?.["Bound"] !== "Yes" && token.features?.["VerbType"] !== "Light";
11
12
 
12
13
  /** 原形で照らす(変えました → 変える)。原形の無い語は書いた形で。 */
13
14
  const baseForm = (token: Token): string => (token.lemma ?? token.surface).toLowerCase();
@@ -0,0 +1,11 @@
1
+ /** 1 つの対(「don't」と「do not」)が、文書の中でそれぞれ何回出てくるか。 */
2
+ export type PairUses = { readonly short: number; readonly long: number };
3
+
4
+ /**
5
+ * その対で少ないほうの書きかた。"short" なら短縮形、"long" なら長い形、少数派が無ければ undefined。
6
+ * 片方しか出てこない対は揃っている。両方が同じ回数なら、どちらを指しても当て推量になる。
7
+ */
8
+ export const pairMinority = (uses: PairUses): "short" | "long" | undefined => {
9
+ if (uses.short === 0 || uses.long === 0 || uses.short === uses.long) return undefined;
10
+ return uses.short < uses.long ? "short" : "long";
11
+ };
@@ -27,3 +27,26 @@ export const leadingCounter = (tokens: readonly Token[], start: number, run: str
27
27
  if (counter === undefined || !isCounter(counter) || !isNumber(wordBefore(tokens, at))) return undefined;
28
28
  return run.startsWith(counter.surface) ? counter : undefined;
29
29
  };
30
+
31
+ const isPrefix = (token: Token | undefined): boolean => token?.pos === "ADJ" && token.features?.["Bound"] === "Yes";
32
+
33
+ /** at の語のすぐ後ろの語。空白一つ(改行を含む)を挟んでもよい(「第\n172条」)。 */
34
+ const wordAfter = (tokens: readonly Token[], at: number): Token | undefined => {
35
+ const [token, next] = [tokens[at], tokens[at + 1]];
36
+ if (token === undefined || next === undefined || !touches(token, next)) return undefined;
37
+ if (!BLANK.test(next.surface)) return next;
38
+ const beyond = tokens[at + 2];
39
+ return beyond !== undefined && touches(next, beyond) ? beyond : undefined;
40
+ };
41
+
42
+ /**
43
+ * 漢字の連なり run(文書全体の座標で end に終わる)の尻が、すぐ後ろの数に付く接頭の語(地方自治法施行令第172条の「第」)なら、その語。
44
+ * 接頭の語は後ろの数の一部で、前の複合語の一部ではない。そうでなければ undefined。
45
+ */
46
+ export const trailingPrefix = (tokens: readonly Token[], end: number, run: string): Token | undefined => {
47
+ // 折り返しをまたぐ語は span が surface より長いので、end で終わる語ではなく end の直前の字を覆う語を探す。
48
+ const at = tokens.findIndex((token) => token.span.start < end && end <= token.span.end);
49
+ const prefix = tokens[at];
50
+ if (prefix === undefined || !isPrefix(prefix) || !isNumber(wordAfter(tokens, at))) return undefined;
51
+ return run.endsWith(prefix.surface) ? prefix : undefined;
52
+ };
@@ -9,6 +9,7 @@ import { scopedFacts, type ScopedFact } from "../facts/fact-scope.ts";
9
9
  import { factsOutOfStep, writtenValue, type FactOutOfStep } from "../facts/cross-facts.ts";
10
10
  import { factWordsOf } from "./fact-consistency.ts";
11
11
  import { quoteAt } from "./structure-tree.ts";
12
+ import { perUnitsOf } from "./per-unit-words.ts";
12
13
 
13
14
  // cross-doc-fact-conflict reads facts as fact-conflict does (fact-consistency.ts), with two more kinds of value that a docs
14
15
  // site repeats from page to page: an email address and a version of three parts or more (2.4.1, v3).
@@ -32,7 +33,7 @@ const COLON_BEFORE = /[::][\s*_]*$/u;
32
33
  const isEntry = (source: string, fact: Fact): boolean => COLON_BEFORE.test(source.slice(source.lastIndexOf("\n", fact.value.start - 1) + 1, fact.value.start));
33
34
 
34
35
  const factsOf = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
35
- const values = factValues(tree, doc.source, namedValues(doc));
36
+ const values = perUnitsOf(doc, factValues(tree, doc.source, namedValues(doc)));
36
37
  const entries = labelledFacts(doc.source, values, factWordsOf(doc)).filter((fact) => isEntry(doc.source, fact));
37
38
  return scopedFacts([...entries, ...tableFacts(doc.source, values)], tree, doc.source, summaryHeadings(doc));
38
39
  };
@@ -3,6 +3,8 @@ import { occurrencesOutside } from "../orthography.ts";
3
3
  import { tokenRuns } from "../custom/token-pattern.ts";
4
4
  import { joinedView, type JoinedView } from "../joined-view.ts";
5
5
  import { boundedMatches } from "../custom/bounded-match.ts";
6
+ import { entriesForGenre } from "../lexicon-genres.ts";
7
+ import { NO_REWRITE } from "../custom/no-rewrite.ts";
6
8
 
7
9
  // The detectors behind a team's custom_rules. Each reports every place it finds, at the rule's level; the spec comes from
8
10
  // the rule (DetectorOptions.custom). Positions are the document's, like every other finding.
@@ -18,6 +20,9 @@ const findingOf = (hit: Hit): Finding => ({
18
20
  values: { matched: hit.matched, preferred: hit.preferred, offset: hit.sentence.span.start + hit.offset },
19
21
  });
20
22
 
23
+ /** A words finding: with no spelling to use (a word-list entry without rewrite), its rule's message for that. */
24
+ const wordsFindingOf = (hit: Hit): Finding => ({ ...findingOf(hit), ...(hit.preferred === "" ? { variant: NO_REWRITE } : {}) });
25
+
21
26
  /**
22
27
  * The sentence with the line breaks that fall inside a word taken out (「関\nする」 reads 「関する」), so words and patterns
23
28
  * are found as the reader reads them. Positions found in it go back to the sentence's own.
@@ -48,7 +53,9 @@ const pairsOf = (
48
53
  spec: { readonly words: readonly { readonly avoid: string; readonly use: string }[] },
49
54
  options: DetectorOptions,
50
55
  ): readonly { avoid: string; use: string }[] =>
51
- spec.words.length > 0 ? spec.words : (options.lexicon ?? []).map((entry) => ({ avoid: entry.pattern, use: entry.rewrite ?? "" }));
56
+ spec.words.length > 0
57
+ ? spec.words
58
+ : entriesForGenre(options.lexicon ?? [], options.genre).map((entry) => ({ avoid: entry.pattern, use: entry.rewrite ?? "" }));
52
59
 
53
60
  /** words: each spelling to avoid, outside the spelling to use (「ユーザ」 inside 「ユーザー」 is not reported). */
54
61
  export const customWords: Detector = (doc, options): Finding[] => {
@@ -58,7 +65,7 @@ export const customWords: Detector = (doc, options): Finding[] => {
58
65
  return doc.sentences.flatMap((sentence) => {
59
66
  const view = readAsWritten(sentence);
60
67
  return pairs.flatMap((pair) =>
61
- occurrencesOutside(view.text, pair.avoid, pair.use).map((start) => findingOf(hitAt(sentence, view, start, start + pair.avoid.length, pair.use))),
68
+ occurrencesOutside(view.text, pair.avoid, pair.use).map((start) => wordsFindingOf(hitAt(sentence, view, start, start + pair.avoid.length, pair.use))),
62
69
  );
63
70
  });
64
71
  };
@@ -9,10 +9,14 @@ export const YEAR_SPAN_JOINER_LEXICON = "year-span-joiner";
9
9
 
10
10
  /**
11
11
  * Where a marker reaches. `sentence`: earlier in the date's sentence, not closed off by a bracket (例えば…4月1日), or the
12
- * line a list of dates hangs from ("for example:"). `adjacent`: just before the date ("each December 31"). `label`: before
13
- * the bracket the date is in (年末年始閉庁日(12月29日~1月3日)).
12
+ * line a list of dates hangs from ("for example:"). `example`: as `sentence`, and on to the end of the list item it is in.
13
+ * `adjacent`: just before the date ("each December 31"). `near`: ending a few characters before it (決算日は、12月31日).
14
+ * `label`: before the bracket the date is in (年末年始閉庁日(12月29日~1月3日)). `continues`: opening a list item just
15
+ * after an example's item, it carries the example on ("- For example, … June 22." then "- If instead … June 25").
14
16
  */
15
- export type MarkerReach = "sentence" | "adjacent" | "label";
17
+ export type MarkerReach = "sentence" | "example" | "adjacent" | "near" | "label" | "continues";
18
+
19
+ export const MARKER_REACHES: readonly MarkerReach[] = ["sentence", "example", "adjacent", "near", "label", "continues"];
16
20
 
17
21
  export type AnyYearMarker = { readonly word: string; readonly reach: MarkerReach };
18
22
 
@@ -25,6 +29,9 @@ const SPAN_GAP_REACH = 12;
25
29
  /** How many lines above a list item its introducing line is looked for: a longer list is read as no example. */
26
30
  const LIST_REACH = 64;
27
31
 
32
+ /** How many characters a `near` marker may end before the date: 「は、」 of 「決算日は、」, " is " of "fiscal year end is". */
33
+ const NEAR_REACH = 4;
34
+
28
35
  /** The end of a sentence: 。, a line break, or a full stop before a capital or a digit ("Mar 3. The", "so. 10 November"). */
29
36
  const SENTENCE_END = /[。!?\n]|[.!?]["'”’)\]]*\s+(?=[A-Z0-9])/u;
30
37
  const OPENERS = "((「『[【〔";
@@ -109,17 +116,56 @@ const introOf = (source: string, before: string, offset: number): string | undef
109
116
  /** The line ends with the marker, before or after its colon: 「例:」 and "for example:" alike. */
110
117
  const introEndsWith = (intro: string, word: string): boolean => isAdjacent(intro, word) || isAdjacent(intro.replace(COLON_END, ""), word);
111
118
 
119
+ const wordsOf = (markers: readonly AnyYearMarker[], reach: MarkerReach): string[] =>
120
+ markers.flatMap((marker) => (marker.reach === reach && marker.word !== "" ? [latinLower(marker.word)] : []));
121
+
122
+ /** A list item's text after its bullet: "If instead …" of " - If instead …". */
123
+ const itemText = (line: string): string => line.replace(LIST_ITEM, "");
124
+
125
+ const indentOf = (line: string): number => line.length - line.trimStart().length;
126
+
127
+ /** The line just above the one at `offset`, when it is a list item at the same depth (no blank line between). */
128
+ const itemAbove = (source: string, offset: number): string | undefined => {
129
+ const start = lineStart(source, offset);
130
+ if (start === 0) return undefined;
131
+ const above = source.slice(lineStart(source, start - 1), start - 1);
132
+ return LIST_ITEM.test(above) && indentOf(above) === indentOf(source.slice(start, offset)) ? above : undefined;
133
+ };
134
+
135
+ const opensWith = (text: string, word: string): boolean => text.startsWith(word) && !runsOn(text, word);
136
+
137
+ const opensWithAny = (line: string, words: readonly string[]): boolean => words.some((word) => opensWith(latinLower(itemText(line)), word));
138
+
139
+ /** `item` holds an example, or carries one on from the item above it; `steps` bounds how far up the chain is followed. */
140
+ const exampleItem = (source: string, item: string, itemEnd: number, markers: readonly AnyYearMarker[], steps: number): boolean => {
141
+ if (wordsOf(markers, "example").some((word) => lastWordAt(latinLower(item), word) !== -1)) return true;
142
+ if (steps === 0 || !opensWithAny(item, wordsOf(markers, "continues"))) return false;
143
+ const above = itemAbove(source, itemEnd);
144
+ return above !== undefined && exampleItem(source, above, lineStart(source, itemEnd) - 1, markers, steps - 1);
145
+ };
146
+
147
+ /** The date's list item opens with a word that carries on the example in the list item just above it. */
148
+ const continuesExample = (date: DateSpan, before: string, source: string, markers: readonly AnyYearMarker[]): boolean => {
149
+ if (!LIST_ITEM.test(before) || !opensWithAny(before, wordsOf(markers, "continues"))) return false;
150
+ const above = itemAbove(source, date.offset);
151
+ return above !== undefined && exampleItem(source, above, lineStart(source, date.offset) - 1, markers, LIST_REACH);
152
+ };
153
+
154
+ const coversDate = (before: string, dateStart: string, intro: string | undefined, word: string, reach: MarkerReach): boolean => {
155
+ if (reach === "adjacent") return isAdjacent(latinLower(before), word);
156
+ if (reach === "near") return lastWordAt(latinLower(before.slice(-(word.length + NEAR_REACH))), word) !== -1;
157
+ if (reach === "label") return latinLower(labelOf(before) ?? "").includes(word);
158
+ if (reach === "continues") return false;
159
+ const inItem = reach === "example" && LIST_ITEM.test(before) && lastWordAt(latinLower(before), word) !== -1;
160
+ return inItem || inSentence(before, dateStart, word) || (intro !== undefined && introEndsWith(latinLower(intro), word));
161
+ };
162
+
112
163
  /** The date is a recurring day or a worked example: a marker stands where its reach covers the date. */
113
164
  export const anyYearDate = (date: DateSpan, source: string, markers: readonly AnyYearMarker[]): boolean => {
114
165
  const before = source.slice(lineStart(source, date.offset), date.offset);
115
166
  const intro = introOf(source, before, date.offset);
116
- return markers.some(({ word: written, reach }) => {
117
- const word = latinLower(written);
118
- if (word === "") return false;
119
- if (reach === "adjacent") return isAdjacent(latinLower(before), word);
120
- if (reach === "label") return latinLower(labelOf(before) ?? "").includes(word);
121
- return inSentence(before, source.charAt(date.offset), word) || (intro !== undefined && introEndsWith(latinLower(intro), word));
122
- });
167
+ const covered = markers.some(({ word, reach }) => word !== "" && coversDate(before, source.charAt(date.offset), intro, latinLower(word), reach));
168
+ return covered || continuesExample(date, before, source, markers);
123
169
  };
124
170
 
125
171
  /** The date opens a period whose other end, just after it, follows a joiner (「4月1日から翌年3月31日」). */