chaffjs 0.35.0 → 0.37.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 (823) hide show
  1. package/README.ja.md +12 -0
  2. package/README.md +15 -0
  3. package/dist/announced-count.d.ts +2 -0
  4. package/dist/announced-count.d.ts.map +1 -1
  5. package/dist/announced-count.js +29 -7
  6. package/dist/announced-count.js.map +1 -1
  7. package/dist/chronology-rows.d.ts +9 -0
  8. package/dist/chronology-rows.d.ts.map +1 -0
  9. package/dist/chronology-rows.js +79 -0
  10. package/dist/chronology-rows.js.map +1 -0
  11. package/dist/company-name-run.d.ts +8 -0
  12. package/dist/company-name-run.d.ts.map +1 -0
  13. package/dist/company-name-run.js +30 -0
  14. package/dist/company-name-run.js.map +1 -0
  15. package/dist/compound-head.d.ts +7 -0
  16. package/dist/compound-head.d.ts.map +1 -0
  17. package/dist/compound-head.js +19 -0
  18. package/dist/compound-head.js.map +1 -0
  19. package/dist/date-format.d.ts +8 -3
  20. package/dist/date-format.d.ts.map +1 -1
  21. package/dist/date-format.js +36 -3
  22. package/dist/date-format.js.map +1 -1
  23. package/dist/derived/count-per-period.d.ts +23 -0
  24. package/dist/derived/count-per-period.d.ts.map +1 -0
  25. package/dist/derived/count-per-period.js +14 -0
  26. package/dist/derived/count-per-period.js.map +1 -0
  27. package/dist/detectors/acronym-context.d.ts +4 -0
  28. package/dist/detectors/acronym-context.d.ts.map +1 -1
  29. package/dist/detectors/acronym-context.js +29 -1
  30. package/dist/detectors/acronym-context.js.map +1 -1
  31. package/dist/detectors/acronym-expansion.d.ts +5 -1
  32. package/dist/detectors/acronym-expansion.d.ts.map +1 -1
  33. package/dist/detectors/acronym-expansion.js +42 -3
  34. package/dist/detectors/acronym-expansion.js.map +1 -1
  35. package/dist/detectors/acronym-known.d.ts +19 -0
  36. package/dist/detectors/acronym-known.d.ts.map +1 -0
  37. package/dist/detectors/acronym-known.js +32 -0
  38. package/dist/detectors/acronym-known.js.map +1 -0
  39. package/dist/detectors/acronym-link.d.ts +19 -0
  40. package/dist/detectors/acronym-link.d.ts.map +1 -0
  41. package/dist/detectors/acronym-link.js +65 -0
  42. package/dist/detectors/acronym-link.js.map +1 -0
  43. package/dist/detectors/acronym-mention.d.ts +5 -0
  44. package/dist/detectors/acronym-mention.d.ts.map +1 -0
  45. package/dist/detectors/acronym-mention.js +34 -0
  46. package/dist/detectors/acronym-mention.js.map +1 -0
  47. package/dist/detectors/acronym-name.d.ts +8 -1
  48. package/dist/detectors/acronym-name.d.ts.map +1 -1
  49. package/dist/detectors/acronym-name.js +25 -6
  50. package/dist/detectors/acronym-name.js.map +1 -1
  51. package/dist/detectors/addressee-edge.d.ts +13 -0
  52. package/dist/detectors/addressee-edge.d.ts.map +1 -0
  53. package/dist/detectors/addressee-edge.js +13 -0
  54. package/dist/detectors/addressee-edge.js.map +1 -0
  55. package/dist/detectors/addressee-title-edge.d.ts +21 -0
  56. package/dist/detectors/addressee-title-edge.d.ts.map +1 -0
  57. package/dist/detectors/addressee-title-edge.js +22 -0
  58. package/dist/detectors/addressee-title-edge.js.map +1 -0
  59. package/dist/detectors/announced-count.d.ts.map +1 -1
  60. package/dist/detectors/announced-count.js +1 -0
  61. package/dist/detectors/announced-count.js.map +1 -1
  62. package/dist/detectors/bare-comparative.d.ts +4 -0
  63. package/dist/detectors/bare-comparative.d.ts.map +1 -1
  64. package/dist/detectors/bare-comparative.js +28 -3
  65. package/dist/detectors/bare-comparative.js.map +1 -1
  66. package/dist/detectors/blank-structure.d.ts +7 -1
  67. package/dist/detectors/blank-structure.d.ts.map +1 -1
  68. package/dist/detectors/blank-structure.js +13 -8
  69. package/dist/detectors/blank-structure.js.map +1 -1
  70. package/dist/detectors/bracket-specified.d.ts +6 -0
  71. package/dist/detectors/bracket-specified.d.ts.map +1 -0
  72. package/dist/detectors/bracket-specified.js +23 -0
  73. package/dist/detectors/bracket-specified.js.map +1 -0
  74. package/dist/detectors/broken-link.d.ts +6 -0
  75. package/dist/detectors/broken-link.d.ts.map +1 -1
  76. package/dist/detectors/broken-link.js +23 -2
  77. package/dist/detectors/broken-link.js.map +1 -1
  78. package/dist/detectors/capitalised-term.d.ts +4 -0
  79. package/dist/detectors/capitalised-term.d.ts.map +1 -1
  80. package/dist/detectors/capitalised-term.js +18 -1
  81. package/dist/detectors/capitalised-term.js.map +1 -1
  82. package/dist/detectors/caps-caption.d.ts +17 -6
  83. package/dist/detectors/caps-caption.d.ts.map +1 -1
  84. package/dist/detectors/caps-caption.js +65 -0
  85. package/dist/detectors/caps-caption.js.map +1 -1
  86. package/dist/detectors/caps-phrase.d.ts +6 -0
  87. package/dist/detectors/caps-phrase.d.ts.map +1 -0
  88. package/dist/detectors/caps-phrase.js +16 -0
  89. package/dist/detectors/caps-phrase.js.map +1 -0
  90. package/dist/detectors/char-shape.d.ts +1 -0
  91. package/dist/detectors/char-shape.d.ts.map +1 -1
  92. package/dist/detectors/char-shape.js +56 -20
  93. package/dist/detectors/char-shape.js.map +1 -1
  94. package/dist/detectors/citation-sentence.d.ts +8 -0
  95. package/dist/detectors/citation-sentence.d.ts.map +1 -0
  96. package/dist/detectors/citation-sentence.js +40 -0
  97. package/dist/detectors/citation-sentence.js.map +1 -0
  98. package/dist/detectors/cited-title.d.ts +3 -2
  99. package/dist/detectors/cited-title.d.ts.map +1 -1
  100. package/dist/detectors/cited-title.js +14 -3
  101. package/dist/detectors/cited-title.js.map +1 -1
  102. package/dist/detectors/contraction-mention.d.ts +3 -0
  103. package/dist/detectors/contraction-mention.d.ts.map +1 -0
  104. package/dist/detectors/contraction-mention.js +22 -0
  105. package/dist/detectors/contraction-mention.js.map +1 -0
  106. package/dist/detectors/counter-edge.d.ts +2 -1
  107. package/dist/detectors/counter-edge.d.ts.map +1 -1
  108. package/dist/detectors/counter-edge.js +17 -2
  109. package/dist/detectors/counter-edge.js.map +1 -1
  110. package/dist/detectors/dash-break.d.ts +7 -0
  111. package/dist/detectors/dash-break.d.ts.map +1 -0
  112. package/dist/detectors/dash-break.js +30 -0
  113. package/dist/detectors/dash-break.js.map +1 -0
  114. package/dist/detectors/date-any-year.d.ts +7 -3
  115. package/dist/detectors/date-any-year.d.ts.map +1 -1
  116. package/dist/detectors/date-any-year.js +30 -8
  117. package/dist/detectors/date-any-year.js.map +1 -1
  118. package/dist/detectors/date-format.d.ts.map +1 -1
  119. package/dist/detectors/date-format.js +2 -1
  120. package/dist/detectors/date-format.js.map +1 -1
  121. package/dist/detectors/date-year.d.ts +9 -3
  122. package/dist/detectors/date-year.d.ts.map +1 -1
  123. package/dist/detectors/date-year.js +45 -9
  124. package/dist/detectors/date-year.js.map +1 -1
  125. package/dist/detectors/deadline-unit.d.ts +20 -0
  126. package/dist/detectors/deadline-unit.d.ts.map +1 -0
  127. package/dist/detectors/deadline-unit.js +19 -0
  128. package/dist/detectors/deadline-unit.js.map +1 -0
  129. package/dist/detectors/defined-term-form.d.ts.map +1 -1
  130. package/dist/detectors/defined-term-form.js +33 -7
  131. package/dist/detectors/defined-term-form.js.map +1 -1
  132. package/dist/detectors/definition-use.d.ts.map +1 -1
  133. package/dist/detectors/definition-use.js +14 -6
  134. package/dist/detectors/definition-use.js.map +1 -1
  135. package/dist/detectors/derived-numbers.d.ts.map +1 -1
  136. package/dist/detectors/derived-numbers.js +17 -4
  137. package/dist/detectors/derived-numbers.js.map +1 -1
  138. package/dist/detectors/document-shape.d.ts +5 -0
  139. package/dist/detectors/document-shape.d.ts.map +1 -1
  140. package/dist/detectors/document-shape.js +15 -1
  141. package/dist/detectors/document-shape.js.map +1 -1
  142. package/dist/detectors/doubled-across-aside.d.ts +9 -0
  143. package/dist/detectors/doubled-across-aside.d.ts.map +1 -0
  144. package/dist/detectors/doubled-across-aside.js +27 -0
  145. package/dist/detectors/doubled-across-aside.js.map +1 -0
  146. package/dist/detectors/doubled-punctuation.d.ts +3 -3
  147. package/dist/detectors/doubled-punctuation.d.ts.map +1 -1
  148. package/dist/detectors/doubled-punctuation.js +23 -4
  149. package/dist/detectors/doubled-punctuation.js.map +1 -1
  150. package/dist/detectors/doubled-word.d.ts.map +1 -1
  151. package/dist/detectors/doubled-word.js +2 -1
  152. package/dist/detectors/doubled-word.js.map +1 -1
  153. package/dist/detectors/duplicate-heading.d.ts +1 -0
  154. package/dist/detectors/duplicate-heading.d.ts.map +1 -1
  155. package/dist/detectors/duplicate-heading.js +25 -3
  156. package/dist/detectors/duplicate-heading.js.map +1 -1
  157. package/dist/detectors/ellipsis.d.ts.map +1 -1
  158. package/dist/detectors/ellipsis.js +13 -1
  159. package/dist/detectors/ellipsis.js.map +1 -1
  160. package/dist/detectors/email-letter.d.ts +40 -3
  161. package/dist/detectors/email-letter.d.ts.map +1 -1
  162. package/dist/detectors/email-letter.js +110 -17
  163. package/dist/detectors/email-letter.js.map +1 -1
  164. package/dist/detectors/field-label.d.ts +7 -0
  165. package/dist/detectors/field-label.d.ts.map +1 -0
  166. package/dist/detectors/field-label.js +23 -0
  167. package/dist/detectors/field-label.js.map +1 -0
  168. package/dist/detectors/footnote-mismatch.d.ts +6 -1
  169. package/dist/detectors/footnote-mismatch.d.ts.map +1 -1
  170. package/dist/detectors/footnote-mismatch.js +28 -7
  171. package/dist/detectors/footnote-mismatch.js.map +1 -1
  172. package/dist/detectors/fullwidth-alnum.d.ts.map +1 -1
  173. package/dist/detectors/fullwidth-alnum.js +7 -1
  174. package/dist/detectors/fullwidth-alnum.js.map +1 -1
  175. package/dist/detectors/graded-step.d.ts +20 -0
  176. package/dist/detectors/graded-step.d.ts.map +1 -0
  177. package/dist/detectors/graded-step.js +33 -0
  178. package/dist/detectors/graded-step.js.map +1 -0
  179. package/dist/detectors/gram-openers.d.ts +9 -0
  180. package/dist/detectors/gram-openers.d.ts.map +1 -0
  181. package/dist/detectors/gram-openers.js +40 -0
  182. package/dist/detectors/gram-openers.js.map +1 -0
  183. package/dist/detectors/gram-place.d.ts +3 -1
  184. package/dist/detectors/gram-place.d.ts.map +1 -1
  185. package/dist/detectors/gram-place.js +8 -0
  186. package/dist/detectors/gram-place.js.map +1 -1
  187. package/dist/detectors/gram-predicate.d.ts.map +1 -1
  188. package/dist/detectors/gram-predicate.js +37 -3
  189. package/dist/detectors/gram-predicate.js.map +1 -1
  190. package/dist/detectors/heading-echo.d.ts.map +1 -1
  191. package/dist/detectors/heading-echo.js +28 -2
  192. package/dist/detectors/heading-echo.js.map +1 -1
  193. package/dist/detectors/heading-record-rhythm.d.ts +9 -0
  194. package/dist/detectors/heading-record-rhythm.d.ts.map +1 -0
  195. package/dist/detectors/heading-record-rhythm.js +57 -0
  196. package/dist/detectors/heading-record-rhythm.js.map +1 -0
  197. package/dist/detectors/ime-residue.d.ts +1 -1
  198. package/dist/detectors/ime-residue.d.ts.map +1 -1
  199. package/dist/detectors/ime-residue.js +4 -3
  200. package/dist/detectors/ime-residue.js.map +1 -1
  201. package/dist/detectors/kanji-compound-slip.d.ts +3 -0
  202. package/dist/detectors/kanji-compound-slip.d.ts.map +1 -0
  203. package/dist/detectors/kanji-compound-slip.js +50 -0
  204. package/dist/detectors/kanji-compound-slip.js.map +1 -0
  205. package/dist/detectors/kutoten-consistency.d.ts +10 -2
  206. package/dist/detectors/kutoten-consistency.d.ts.map +1 -1
  207. package/dist/detectors/kutoten-consistency.js +83 -12
  208. package/dist/detectors/kutoten-consistency.js.map +1 -1
  209. package/dist/detectors/lexicon.d.ts.map +1 -1
  210. package/dist/detectors/lexicon.js +13 -4
  211. package/dist/detectors/lexicon.js.map +1 -1
  212. package/dist/detectors/link-shape.d.ts.map +1 -1
  213. package/dist/detectors/link-shape.js +9 -3
  214. package/dist/detectors/link-shape.js.map +1 -1
  215. package/dist/detectors/list-item-ending.d.ts +18 -0
  216. package/dist/detectors/list-item-ending.d.ts.map +1 -0
  217. package/dist/detectors/list-item-ending.js +35 -0
  218. package/dist/detectors/list-item-ending.js.map +1 -0
  219. package/dist/detectors/list-parallel.d.ts +18 -5
  220. package/dist/detectors/list-parallel.d.ts.map +1 -1
  221. package/dist/detectors/list-parallel.js +116 -36
  222. package/dist/detectors/list-parallel.js.map +1 -1
  223. package/dist/detectors/list-sentence.d.ts +4 -0
  224. package/dist/detectors/list-sentence.d.ts.map +1 -1
  225. package/dist/detectors/list-sentence.js +1 -1
  226. package/dist/detectors/list-sentence.js.map +1 -1
  227. package/dist/detectors/mark-shape.d.ts +13 -4
  228. package/dist/detectors/mark-shape.d.ts.map +1 -1
  229. package/dist/detectors/mark-shape.js +73 -10
  230. package/dist/detectors/mark-shape.js.map +1 -1
  231. package/dist/detectors/mentioned-phrase.d.ts +9 -0
  232. package/dist/detectors/mentioned-phrase.d.ts.map +1 -0
  233. package/dist/detectors/mentioned-phrase.js +25 -0
  234. package/dist/detectors/mentioned-phrase.js.map +1 -0
  235. package/dist/detectors/middle-dot.d.ts +2 -2
  236. package/dist/detectors/middle-dot.d.ts.map +1 -1
  237. package/dist/detectors/middle-dot.js +4 -2
  238. package/dist/detectors/middle-dot.js.map +1 -1
  239. package/dist/detectors/modal-conflict.d.ts.map +1 -1
  240. package/dist/detectors/modal-conflict.js +5 -2
  241. package/dist/detectors/modal-conflict.js.map +1 -1
  242. package/dist/detectors/name-variant.d.ts.map +1 -1
  243. package/dist/detectors/name-variant.js +6 -0
  244. package/dist/detectors/name-variant.js.map +1 -1
  245. package/dist/detectors/notice-paragraph.d.ts +9 -0
  246. package/dist/detectors/notice-paragraph.d.ts.map +1 -0
  247. package/dist/detectors/notice-paragraph.js +21 -0
  248. package/dist/detectors/notice-paragraph.js.map +1 -0
  249. package/dist/detectors/number-style.d.ts.map +1 -1
  250. package/dist/detectors/number-style.js +15 -2
  251. package/dist/detectors/number-style.js.map +1 -1
  252. package/dist/detectors/number-unit.d.ts.map +1 -1
  253. package/dist/detectors/number-unit.js +24 -1
  254. package/dist/detectors/number-unit.js.map +1 -1
  255. package/dist/detectors/numeral-opener.d.ts +6 -0
  256. package/dist/detectors/numeral-opener.d.ts.map +1 -1
  257. package/dist/detectors/numeral-opener.js +24 -1
  258. package/dist/detectors/numeral-opener.js.map +1 -1
  259. package/dist/detectors/obligation-without-deadline.d.ts +5 -1
  260. package/dist/detectors/obligation-without-deadline.d.ts.map +1 -1
  261. package/dist/detectors/obligation-without-deadline.js +44 -23
  262. package/dist/detectors/obligation-without-deadline.js.map +1 -1
  263. package/dist/detectors/open-end-class.d.ts +16 -0
  264. package/dist/detectors/open-end-class.d.ts.map +1 -0
  265. package/dist/detectors/open-end-class.js +65 -0
  266. package/dist/detectors/open-end-class.js.map +1 -0
  267. package/dist/detectors/open-end-condition.d.ts +7 -0
  268. package/dist/detectors/open-end-condition.d.ts.map +1 -0
  269. package/dist/detectors/open-end-condition.js +35 -0
  270. package/dist/detectors/open-end-condition.js.map +1 -0
  271. package/dist/detectors/open-end-names.d.ts +9 -3
  272. package/dist/detectors/open-end-names.d.ts.map +1 -1
  273. package/dist/detectors/open-end-names.js +5 -2
  274. package/dist/detectors/open-end-names.js.map +1 -1
  275. package/dist/detectors/open-end-question.d.ts +15 -0
  276. package/dist/detectors/open-end-question.d.ts.map +1 -0
  277. package/dist/detectors/open-end-question.js +37 -0
  278. package/dist/detectors/open-end-question.js.map +1 -0
  279. package/dist/detectors/open-end-scope.d.ts +16 -0
  280. package/dist/detectors/open-end-scope.d.ts.map +1 -0
  281. package/dist/detectors/open-end-scope.js +47 -0
  282. package/dist/detectors/open-end-scope.js.map +1 -0
  283. package/dist/detectors/opening-date.d.ts +10 -0
  284. package/dist/detectors/opening-date.d.ts.map +1 -0
  285. package/dist/detectors/opening-date.js +33 -0
  286. package/dist/detectors/opening-date.js.map +1 -0
  287. package/dist/detectors/ordinary-phrase.d.ts +20 -0
  288. package/dist/detectors/ordinary-phrase.d.ts.map +1 -0
  289. package/dist/detectors/ordinary-phrase.js +54 -0
  290. package/dist/detectors/ordinary-phrase.js.map +1 -0
  291. package/dist/detectors/organisation-run.d.ts +5 -7
  292. package/dist/detectors/organisation-run.d.ts.map +1 -1
  293. package/dist/detectors/organisation-run.js +10 -0
  294. package/dist/detectors/organisation-run.js.map +1 -1
  295. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  296. package/dist/detectors/orthographic-variant.js +85 -20
  297. package/dist/detectors/orthographic-variant.js.map +1 -1
  298. package/dist/detectors/orthography.d.ts.map +1 -1
  299. package/dist/detectors/orthography.js +9 -2
  300. package/dist/detectors/orthography.js.map +1 -1
  301. package/dist/detectors/oxford-comma.d.ts.map +1 -1
  302. package/dist/detectors/oxford-comma.js +70 -3
  303. package/dist/detectors/oxford-comma.js.map +1 -1
  304. package/dist/detectors/person-consistency.d.ts +2 -1
  305. package/dist/detectors/person-consistency.d.ts.map +1 -1
  306. package/dist/detectors/person-consistency.js +5 -3
  307. package/dist/detectors/person-consistency.js.map +1 -1
  308. package/dist/detectors/phrase-match.d.ts +2 -0
  309. package/dist/detectors/phrase-match.d.ts.map +1 -1
  310. package/dist/detectors/phrase-match.js +11 -4
  311. package/dist/detectors/phrase-match.js.map +1 -1
  312. package/dist/detectors/placeholder-text.d.ts.map +1 -1
  313. package/dist/detectors/placeholder-text.js +18 -3
  314. package/dist/detectors/placeholder-text.js.map +1 -1
  315. package/dist/detectors/placeholder.d.ts +3 -1
  316. package/dist/detectors/placeholder.d.ts.map +1 -1
  317. package/dist/detectors/placeholder.js +8 -3
  318. package/dist/detectors/placeholder.js.map +1 -1
  319. package/dist/detectors/postcode-end.d.ts +3 -0
  320. package/dist/detectors/postcode-end.d.ts.map +1 -0
  321. package/dist/detectors/postcode-end.js +15 -0
  322. package/dist/detectors/postcode-end.js.map +1 -0
  323. package/dist/detectors/prose-total-words.d.ts +5 -0
  324. package/dist/detectors/prose-total-words.d.ts.map +1 -0
  325. package/dist/detectors/prose-total-words.js +14 -0
  326. package/dist/detectors/prose-total-words.js.map +1 -0
  327. package/dist/detectors/range-notation.d.ts +2 -2
  328. package/dist/detectors/range-notation.d.ts.map +1 -1
  329. package/dist/detectors/range-notation.js +18 -7
  330. package/dist/detectors/range-notation.js.map +1 -1
  331. package/dist/detectors/registry/kanji-compound-slip.d.ts +3 -0
  332. package/dist/detectors/registry/kanji-compound-slip.d.ts.map +1 -0
  333. package/dist/detectors/registry/kanji-compound-slip.js +3 -0
  334. package/dist/detectors/registry/kanji-compound-slip.js.map +1 -0
  335. package/dist/detectors/registry/phrase-in-use.d.ts +3 -0
  336. package/dist/detectors/registry/phrase-in-use.d.ts.map +1 -0
  337. package/dist/detectors/registry/phrase-in-use.js +3 -0
  338. package/dist/detectors/registry/phrase-in-use.js.map +1 -0
  339. package/dist/detectors/requirement-smell.d.ts.map +1 -1
  340. package/dist/detectors/requirement-smell.js +35 -7
  341. package/dist/detectors/requirement-smell.js.map +1 -1
  342. package/dist/detectors/scaled-figure-unit.d.ts +28 -0
  343. package/dist/detectors/scaled-figure-unit.d.ts.map +1 -0
  344. package/dist/detectors/scaled-figure-unit.js +78 -0
  345. package/dist/detectors/scaled-figure-unit.js.map +1 -0
  346. package/dist/detectors/sentence-counts.d.ts +12 -2
  347. package/dist/detectors/sentence-counts.d.ts.map +1 -1
  348. package/dist/detectors/sentence-counts.js +52 -11
  349. package/dist/detectors/sentence-counts.js.map +1 -1
  350. package/dist/detectors/sentence-ending.d.ts +2 -0
  351. package/dist/detectors/sentence-ending.d.ts.map +1 -1
  352. package/dist/detectors/sentence-ending.js +10 -3
  353. package/dist/detectors/sentence-ending.js.map +1 -1
  354. package/dist/detectors/sentence-length.d.ts.map +1 -1
  355. package/dist/detectors/sentence-length.js +13 -4
  356. package/dist/detectors/sentence-length.js.map +1 -1
  357. package/dist/detectors/sentence-load.d.ts +4 -1
  358. package/dist/detectors/sentence-load.d.ts.map +1 -1
  359. package/dist/detectors/sentence-load.js +9 -2
  360. package/dist/detectors/sentence-load.js.map +1 -1
  361. package/dist/detectors/signals.d.ts.map +1 -1
  362. package/dist/detectors/signals.js +44 -52
  363. package/dist/detectors/signals.js.map +1 -1
  364. package/dist/detectors/structure-tree.d.ts.map +1 -1
  365. package/dist/detectors/structure-tree.js +14 -13
  366. package/dist/detectors/structure-tree.js.map +1 -1
  367. package/dist/detectors/structure.d.ts.map +1 -1
  368. package/dist/detectors/structure.js +2 -1
  369. package/dist/detectors/structure.js.map +1 -1
  370. package/dist/detectors/subject-name-line.d.ts +8 -0
  371. package/dist/detectors/subject-name-line.d.ts.map +1 -0
  372. package/dist/detectors/subject-name-line.js +53 -0
  373. package/dist/detectors/subject-name-line.js.map +1 -0
  374. package/dist/detectors/superlative-name.d.ts +5 -0
  375. package/dist/detectors/superlative-name.d.ts.map +1 -1
  376. package/dist/detectors/superlative-name.js +9 -0
  377. package/dist/detectors/superlative-name.js.map +1 -1
  378. package/dist/detectors/table-header.d.ts.map +1 -1
  379. package/dist/detectors/table-header.js +13 -1
  380. package/dist/detectors/table-header.js.map +1 -1
  381. package/dist/detectors/technical-docs.d.ts.map +1 -1
  382. package/dist/detectors/technical-docs.js +4 -1
  383. package/dist/detectors/technical-docs.js.map +1 -1
  384. package/dist/detectors/term-mention-sentence.d.ts +4 -0
  385. package/dist/detectors/term-mention-sentence.d.ts.map +1 -0
  386. package/dist/detectors/term-mention-sentence.js +28 -0
  387. package/dist/detectors/term-mention-sentence.js.map +1 -0
  388. package/dist/detectors/titled-run.d.ts +2 -1
  389. package/dist/detectors/titled-run.d.ts.map +1 -1
  390. package/dist/detectors/titled-run.js +9 -4
  391. package/dist/detectors/titled-run.js.map +1 -1
  392. package/dist/detectors/token-shape.d.ts.map +1 -1
  393. package/dist/detectors/token-shape.js +15 -5
  394. package/dist/detectors/token-shape.js.map +1 -1
  395. package/dist/detectors/undefined-term.d.ts.map +1 -1
  396. package/dist/detectors/undefined-term.js +5 -0
  397. package/dist/detectors/undefined-term.js.map +1 -1
  398. package/dist/detectors/unknown-word.d.ts +4 -1
  399. package/dist/detectors/unknown-word.d.ts.map +1 -1
  400. package/dist/detectors/unknown-word.js +1 -1
  401. package/dist/detectors/unknown-word.js.map +1 -1
  402. package/dist/detectors/vague-density.d.ts +5 -2
  403. package/dist/detectors/vague-density.d.ts.map +1 -1
  404. package/dist/detectors/vague-density.js +17 -4
  405. package/dist/detectors/vague-density.js.map +1 -1
  406. package/dist/document-paragraphs.d.ts +4 -0
  407. package/dist/document-paragraphs.d.ts.map +1 -0
  408. package/dist/document-paragraphs.js +24 -0
  409. package/dist/document-paragraphs.js.map +1 -0
  410. package/dist/document.d.ts.map +1 -1
  411. package/dist/document.js +2 -19
  412. package/dist/document.js.map +1 -1
  413. package/dist/figure-references.d.ts +3 -0
  414. package/dist/figure-references.d.ts.map +1 -1
  415. package/dist/figure-references.js +6 -2
  416. package/dist/figure-references.js.map +1 -1
  417. package/dist/format-template.d.ts +3 -0
  418. package/dist/format-template.d.ts.map +1 -0
  419. package/dist/format-template.js +13 -0
  420. package/dist/format-template.js.map +1 -0
  421. package/dist/formula-brackets.d.ts +7 -0
  422. package/dist/formula-brackets.d.ts.map +1 -0
  423. package/dist/formula-brackets.js +29 -0
  424. package/dist/formula-brackets.js.map +1 -0
  425. package/dist/html/html-markdown.d.ts.map +1 -1
  426. package/dist/html/html-markdown.js +2 -1
  427. package/dist/html/html-markdown.js.map +1 -1
  428. package/dist/html/html-site-chrome.d.ts +5 -0
  429. package/dist/html/html-site-chrome.d.ts.map +1 -0
  430. package/dist/html/html-site-chrome.js +56 -0
  431. package/dist/html/html-site-chrome.js.map +1 -0
  432. package/dist/joined-view.d.ts.map +1 -1
  433. package/dist/joined-view.js +1 -0
  434. package/dist/joined-view.js.map +1 -1
  435. package/dist/kanji-compound-slip.d.ts +32 -0
  436. package/dist/kanji-compound-slip.d.ts.map +1 -0
  437. package/dist/kanji-compound-slip.js +63 -0
  438. package/dist/kanji-compound-slip.js.map +1 -0
  439. package/dist/latin-company-form.d.ts +6 -0
  440. package/dist/latin-company-form.d.ts.map +1 -0
  441. package/dist/latin-company-form.js +32 -0
  442. package/dist/latin-company-form.js.map +1 -0
  443. package/dist/latin-word-boundary.d.ts +20 -0
  444. package/dist/latin-word-boundary.d.ts.map +1 -0
  445. package/dist/latin-word-boundary.js +57 -0
  446. package/dist/latin-word-boundary.js.map +1 -0
  447. package/dist/leading-label.d.ts +4 -0
  448. package/dist/leading-label.d.ts.map +1 -0
  449. package/dist/leading-label.js +14 -0
  450. package/dist/leading-label.js.map +1 -0
  451. package/dist/lexicon-genres.d.ts +2 -0
  452. package/dist/lexicon-genres.d.ts.map +1 -1
  453. package/dist/lexicon-genres.js +1 -1
  454. package/dist/lexicon-genres.js.map +1 -1
  455. package/dist/link-shape.d.ts +6 -0
  456. package/dist/link-shape.d.ts.map +1 -1
  457. package/dist/link-shape.js +27 -0
  458. package/dist/link-shape.js.map +1 -1
  459. package/dist/link-title.d.ts +4 -0
  460. package/dist/link-title.d.ts.map +1 -0
  461. package/dist/link-title.js +33 -0
  462. package/dist/link-title.js.map +1 -0
  463. package/dist/list-item-paragraphs.d.ts +15 -0
  464. package/dist/list-item-paragraphs.d.ts.map +1 -0
  465. package/dist/list-item-paragraphs.js +19 -0
  466. package/dist/list-item-paragraphs.js.map +1 -0
  467. package/dist/literal-quote.d.ts +12 -0
  468. package/dist/literal-quote.d.ts.map +1 -0
  469. package/dist/literal-quote.js +43 -0
  470. package/dist/literal-quote.js.map +1 -0
  471. package/dist/nado-closed-list.d.ts.map +1 -1
  472. package/dist/nado-closed-list.js +39 -5
  473. package/dist/nado-closed-list.js.map +1 -1
  474. package/dist/name-misspelt-usual.d.ts +5 -0
  475. package/dist/name-misspelt-usual.d.ts.map +1 -0
  476. package/dist/name-misspelt-usual.js +19 -0
  477. package/dist/name-misspelt-usual.js.map +1 -0
  478. package/dist/name-separator.d.ts.map +1 -1
  479. package/dist/name-separator.js +25 -2
  480. package/dist/name-separator.js.map +1 -1
  481. package/dist/nominal-stem.d.ts +14 -1
  482. package/dist/nominal-stem.d.ts.map +1 -1
  483. package/dist/nominal-stem.js +42 -4
  484. package/dist/nominal-stem.js.map +1 -1
  485. package/dist/notice-header.d.ts +19 -0
  486. package/dist/notice-header.d.ts.map +1 -0
  487. package/dist/notice-header.js +31 -0
  488. package/dist/notice-header.js.map +1 -0
  489. package/dist/person-forms.d.ts +8 -0
  490. package/dist/person-forms.d.ts.map +1 -1
  491. package/dist/person-forms.js +12 -0
  492. package/dist/person-forms.js.map +1 -1
  493. package/dist/plugin.d.ts +5 -0
  494. package/dist/plugin.d.ts.map +1 -1
  495. package/dist/preamble-paragraphs.d.ts +3 -2
  496. package/dist/preamble-paragraphs.d.ts.map +1 -1
  497. package/dist/preamble-paragraphs.js +8 -2
  498. package/dist/preamble-paragraphs.js.map +1 -1
  499. package/dist/sentence-load.d.ts +2 -1
  500. package/dist/sentence-load.d.ts.map +1 -1
  501. package/dist/sentence-load.js +11 -3
  502. package/dist/sentence-load.js.map +1 -1
  503. package/dist/spacing-code.d.ts +1 -0
  504. package/dist/spacing-code.d.ts.map +1 -1
  505. package/dist/spacing-code.js +4 -1
  506. package/dist/spacing-code.js.map +1 -1
  507. package/dist/split-noun.d.ts +10 -0
  508. package/dist/split-noun.d.ts.map +1 -0
  509. package/dist/split-noun.js +50 -0
  510. package/dist/split-noun.js.map +1 -0
  511. package/dist/structure/attached-parts.d.ts +12 -0
  512. package/dist/structure/attached-parts.d.ts.map +1 -0
  513. package/dist/structure/attached-parts.js +44 -0
  514. package/dist/structure/attached-parts.js.map +1 -0
  515. package/dist/structure/build.d.ts.map +1 -1
  516. package/dist/structure/build.js +7 -4
  517. package/dist/structure/build.js.map +1 -1
  518. package/dist/structure/contents-lines.d.ts +7 -0
  519. package/dist/structure/contents-lines.d.ts.map +1 -0
  520. package/dist/structure/contents-lines.js +51 -0
  521. package/dist/structure/contents-lines.js.map +1 -0
  522. package/dist/structure/defining-names.d.ts +37 -0
  523. package/dist/structure/defining-names.d.ts.map +1 -0
  524. package/dist/structure/defining-names.js +122 -0
  525. package/dist/structure/defining-names.js.map +1 -0
  526. package/dist/structure/definition-use.d.ts +8 -4
  527. package/dist/structure/definition-use.d.ts.map +1 -1
  528. package/dist/structure/definition-use.js +123 -38
  529. package/dist/structure/definition-use.js.map +1 -1
  530. package/dist/structure/gerund-phrase.d.ts +8 -0
  531. package/dist/structure/gerund-phrase.d.ts.map +1 -0
  532. package/dist/structure/gerund-phrase.js +30 -0
  533. package/dist/structure/gerund-phrase.js.map +1 -0
  534. package/dist/structure/issues.d.ts +4 -1
  535. package/dist/structure/issues.d.ts.map +1 -1
  536. package/dist/structure/issues.js +5 -2
  537. package/dist/structure/issues.js.map +1 -1
  538. package/dist/structure/list-lead-in.d.ts +19 -0
  539. package/dist/structure/list-lead-in.d.ts.map +1 -0
  540. package/dist/structure/list-lead-in.js +85 -0
  541. package/dist/structure/list-lead-in.js.map +1 -0
  542. package/dist/structure/modal-conflict.d.ts +7 -2
  543. package/dist/structure/modal-conflict.d.ts.map +1 -1
  544. package/dist/structure/modal-conflict.js +36 -7
  545. package/dist/structure/modal-conflict.js.map +1 -1
  546. package/dist/structure/negated-act.d.ts +17 -0
  547. package/dist/structure/negated-act.d.ts.map +1 -0
  548. package/dist/structure/negated-act.js +32 -0
  549. package/dist/structure/negated-act.js.map +1 -0
  550. package/dist/structure/numbering.d.ts +3 -1
  551. package/dist/structure/numbering.d.ts.map +1 -1
  552. package/dist/structure/numbering.js +20 -8
  553. package/dist/structure/numbering.js.map +1 -1
  554. package/dist/structure/prose-total.d.ts +4 -0
  555. package/dist/structure/prose-total.d.ts.map +1 -1
  556. package/dist/structure/prose-total.js +16 -6
  557. package/dist/structure/prose-total.js.map +1 -1
  558. package/dist/structure/repeated-number.d.ts +24 -0
  559. package/dist/structure/repeated-number.d.ts.map +1 -0
  560. package/dist/structure/repeated-number.js +89 -0
  561. package/dist/structure/repeated-number.js.map +1 -0
  562. package/dist/structure/rounded-amount.d.ts +8 -0
  563. package/dist/structure/rounded-amount.d.ts.map +1 -0
  564. package/dist/structure/rounded-amount.js +48 -0
  565. package/dist/structure/rounded-amount.js.map +1 -0
  566. package/dist/structure/side-step.d.ts +8 -0
  567. package/dist/structure/side-step.d.ts.map +1 -0
  568. package/dist/structure/side-step.js +21 -0
  569. package/dist/structure/side-step.js.map +1 -0
  570. package/dist/structure/spanned-label-blank.d.ts +8 -0
  571. package/dist/structure/spanned-label-blank.d.ts.map +1 -0
  572. package/dist/structure/spanned-label-blank.js +37 -0
  573. package/dist/structure/spanned-label-blank.js.map +1 -0
  574. package/dist/structure/universal.d.ts +10 -4
  575. package/dist/structure/universal.d.ts.map +1 -1
  576. package/dist/structure/universal.js +26 -7
  577. package/dist/structure/universal.js.map +1 -1
  578. package/dist/structure/unspaced-heading.d.ts +10 -0
  579. package/dist/structure/unspaced-heading.d.ts.map +1 -0
  580. package/dist/structure/unspaced-heading.js +24 -0
  581. package/dist/structure/unspaced-heading.js.map +1 -0
  582. package/dist/structure/written-list-path.d.ts +10 -0
  583. package/dist/structure/written-list-path.d.ts.map +1 -0
  584. package/dist/structure/written-list-path.js +37 -0
  585. package/dist/structure/written-list-path.js.map +1 -0
  586. package/dist/structure/written-resolve.d.ts +1 -1
  587. package/dist/structure/written-resolve.d.ts.map +1 -1
  588. package/dist/structure/written-resolve.js +15 -9
  589. package/dist/structure/written-resolve.js.map +1 -1
  590. package/dist/title-line.d.ts +23 -0
  591. package/dist/title-line.d.ts.map +1 -0
  592. package/dist/title-line.js +28 -0
  593. package/dist/title-line.js.map +1 -0
  594. package/dist/topic-clause.d.ts +7 -0
  595. package/dist/topic-clause.d.ts.map +1 -0
  596. package/dist/topic-clause.js +87 -0
  597. package/dist/topic-clause.js.map +1 -0
  598. package/dist/uncounted-particles.d.ts +18 -0
  599. package/dist/uncounted-particles.d.ts.map +1 -0
  600. package/dist/uncounted-particles.js +47 -0
  601. package/dist/uncounted-particles.js.map +1 -0
  602. package/package.json +3 -3
  603. package/rules/adversative-ga-repeat.yaml +1 -0
  604. package/rules/all-caps-shouting.yaml +2 -2
  605. package/rules/announced-count-mismatch.yaml +2 -2
  606. package/rules/bare-url-mix.yaml +2 -2
  607. package/rules/bracket-nesting.yaml +2 -2
  608. package/rules/bracket-width-consistency.yaml +2 -2
  609. package/rules/broken-link.yaml +2 -2
  610. package/rules/cliche.yaml +4 -3
  611. package/rules/code-fence-language-mix.yaml +2 -2
  612. package/rules/comparative-without-baseline.yaml +2 -2
  613. package/rules/concrete-evidence-density.yaml +1 -0
  614. package/rules/contraction-consistency.yaml +2 -2
  615. package/rules/dangling-figure-reference.yaml +2 -2
  616. package/rules/date-without-year.yaml +10 -2
  617. package/rules/defined-term-form.yaml +2 -2
  618. package/rules/doubled-punctuation.yaml +4 -4
  619. package/rules/doubled-word.yaml +2 -2
  620. package/rules/duplicate-definition.yaml +2 -2
  621. package/rules/duplicate-heading.yaml +2 -2
  622. package/rules/duration-mismatch.yaml +2 -2
  623. package/rules/email-greeting-closing.yaml +2 -2
  624. package/rules/email-subject-length.yaml +2 -2
  625. package/rules/empty-table-cell.yaml +2 -2
  626. package/rules/footnote-mismatch.yaml +2 -2
  627. package/rules/fullwidth-alnum-consistency.yaml +2 -2
  628. package/rules/heading-echo.yaml +2 -2
  629. package/rules/ime-residue.yaml +2 -2
  630. package/rules/kanji-compound-slip.yaml +67 -0
  631. package/rules/kutoten-consistency.yaml +4 -4
  632. package/rules/latin-spacing.yaml +2 -2
  633. package/rules/list-item-form-mix.yaml +2 -2
  634. package/rules/max-kanji-continuous.yaml +6 -4
  635. package/rules/max-sentence-length.yaml +2 -2
  636. package/rules/modal-conflict.yaml +1 -0
  637. package/rules/nado-closed-list.yaml +2 -2
  638. package/rules/ngram-repetition.yaml +2 -2
  639. package/rules/no-doubled-joshi.yaml +2 -2
  640. package/rules/no-mixed-desumasu.yaml +3 -3
  641. package/rules/no-nakaguro-parallel.yaml +2 -0
  642. package/rules/number-without-unit.yaml +9 -4
  643. package/rules/numbering-gap.yaml +7 -2
  644. package/rules/numeral-sentence-start.yaml +2 -2
  645. package/rules/obligation-without-deadline.yaml +2 -2
  646. package/rules/orthographic-variant.yaml +2 -2
  647. package/rules/oxford-comma-consistency.yaml +3 -3
  648. package/rules/preamble-length.yaml +3 -2
  649. package/rules/range-notation-consistency.yaml +2 -2
  650. package/rules/requirement-smell.yaml +3 -3
  651. package/rules/table-header-variant.yaml +2 -2
  652. package/rules/teki-overuse.yaml +3 -2
  653. package/rules/title-length.yaml +2 -2
  654. package/rules/topic-predicate-distance.yaml +2 -2
  655. package/rules/total-mismatch.yaml +2 -2
  656. package/rules/translationese-density.yaml +2 -2
  657. package/rules/undefined-acronym.yaml +5 -2
  658. package/rules/undefined-term.yaml +2 -2
  659. package/rules/unfilled-placeholder.yaml +4 -4
  660. package/rules/unqualified-superlative.yaml +1 -1
  661. package/rules/unused-definition.yaml +2 -2
  662. package/rules/use-before-definition.yaml +2 -2
  663. package/rules/vague-word-density.yaml +2 -2
  664. package/skills/chaff/SKILL.md +7 -1
  665. package/src/announced-count.ts +35 -8
  666. package/src/chronology-rows.ts +86 -0
  667. package/src/company-name-run.ts +37 -0
  668. package/src/compound-head.ts +25 -0
  669. package/src/date-format.ts +43 -4
  670. package/src/derived/count-per-period.ts +28 -0
  671. package/src/detectors/acronym-context.ts +30 -1
  672. package/src/detectors/acronym-expansion.ts +54 -6
  673. package/src/detectors/acronym-known.ts +40 -0
  674. package/src/detectors/acronym-link.ts +75 -0
  675. package/src/detectors/acronym-mention.ts +44 -0
  676. package/src/detectors/acronym-name.ts +29 -6
  677. package/src/detectors/addressee-edge.ts +16 -0
  678. package/src/detectors/addressee-title-edge.ts +39 -0
  679. package/src/detectors/announced-count.ts +1 -0
  680. package/src/detectors/bare-comparative.ts +44 -3
  681. package/src/detectors/blank-structure.ts +21 -10
  682. package/src/detectors/bracket-specified.ts +25 -0
  683. package/src/detectors/broken-link.ts +26 -2
  684. package/src/detectors/capitalised-term.ts +26 -2
  685. package/src/detectors/caps-caption.ts +76 -0
  686. package/src/detectors/caps-phrase.ts +17 -0
  687. package/src/detectors/char-shape.ts +73 -14
  688. package/src/detectors/citation-sentence.ts +44 -0
  689. package/src/detectors/cited-title.ts +15 -3
  690. package/src/detectors/contraction-mention.ts +24 -0
  691. package/src/detectors/counter-edge.ts +17 -2
  692. package/src/detectors/dash-break.ts +45 -0
  693. package/src/detectors/date-any-year.ts +34 -9
  694. package/src/detectors/date-format.ts +2 -1
  695. package/src/detectors/date-year.ts +64 -16
  696. package/src/detectors/deadline-unit.ts +40 -0
  697. package/src/detectors/defined-term-form.ts +32 -12
  698. package/src/detectors/definition-use.ts +17 -9
  699. package/src/detectors/derived-numbers.ts +19 -4
  700. package/src/detectors/document-shape.ts +20 -1
  701. package/src/detectors/doubled-across-aside.ts +36 -0
  702. package/src/detectors/doubled-punctuation.ts +28 -7
  703. package/src/detectors/doubled-word.ts +2 -1
  704. package/src/detectors/duplicate-heading.ts +26 -3
  705. package/src/detectors/ellipsis.ts +16 -1
  706. package/src/detectors/email-letter.ts +142 -23
  707. package/src/detectors/field-label.ts +25 -0
  708. package/src/detectors/footnote-mismatch.ts +39 -7
  709. package/src/detectors/fullwidth-alnum.ts +9 -1
  710. package/src/detectors/graded-step.ts +52 -0
  711. package/src/detectors/gram-openers.ts +50 -0
  712. package/src/detectors/gram-place.ts +10 -1
  713. package/src/detectors/gram-predicate.ts +43 -3
  714. package/src/detectors/heading-echo.ts +31 -3
  715. package/src/detectors/heading-record-rhythm.ts +57 -0
  716. package/src/detectors/ime-residue.ts +4 -3
  717. package/src/detectors/kanji-compound-slip.ts +61 -0
  718. package/src/detectors/kutoten-consistency.ts +102 -14
  719. package/src/detectors/lexicon.ts +18 -5
  720. package/src/detectors/link-shape.ts +10 -3
  721. package/src/detectors/list-item-ending.ts +51 -0
  722. package/src/detectors/list-parallel.ts +158 -33
  723. package/src/detectors/list-sentence.ts +5 -1
  724. package/src/detectors/mark-shape.ts +89 -10
  725. package/src/detectors/mentioned-phrase.ts +38 -0
  726. package/src/detectors/middle-dot.ts +7 -2
  727. package/src/detectors/modal-conflict.ts +5 -2
  728. package/src/detectors/name-variant.ts +6 -0
  729. package/src/detectors/notice-paragraph.ts +33 -0
  730. package/src/detectors/number-style.ts +14 -2
  731. package/src/detectors/number-unit.ts +28 -1
  732. package/src/detectors/numeral-opener.ts +27 -1
  733. package/src/detectors/obligation-without-deadline.ts +29 -4
  734. package/src/detectors/open-end-class.ts +78 -0
  735. package/src/detectors/open-end-condition.ts +40 -0
  736. package/src/detectors/open-end-names.ts +9 -3
  737. package/src/detectors/open-end-question.ts +50 -0
  738. package/src/detectors/open-end-scope.ts +62 -0
  739. package/src/detectors/opening-date.ts +47 -0
  740. package/src/detectors/ordinary-phrase.ts +62 -0
  741. package/src/detectors/organisation-run.ts +18 -2
  742. package/src/detectors/orthographic-variant.ts +124 -25
  743. package/src/detectors/orthography.ts +15 -2
  744. package/src/detectors/oxford-comma.ts +74 -3
  745. package/src/detectors/person-consistency.ts +5 -3
  746. package/src/detectors/phrase-match.ts +16 -5
  747. package/src/detectors/placeholder-text.ts +18 -3
  748. package/src/detectors/placeholder.ts +10 -3
  749. package/src/detectors/postcode-end.ts +16 -0
  750. package/src/detectors/prose-total-words.ts +18 -0
  751. package/src/detectors/range-notation.ts +26 -6
  752. package/src/detectors/registry/kanji-compound-slip.ts +4 -0
  753. package/src/detectors/registry/phrase-in-use.ts +4 -0
  754. package/src/detectors/requirement-smell.ts +45 -8
  755. package/src/detectors/scaled-figure-unit.ts +103 -0
  756. package/src/detectors/sentence-counts.ts +64 -12
  757. package/src/detectors/sentence-ending.ts +12 -3
  758. package/src/detectors/sentence-length.ts +17 -4
  759. package/src/detectors/sentence-load.ts +9 -2
  760. package/src/detectors/signals.ts +50 -53
  761. package/src/detectors/structure-tree.ts +14 -14
  762. package/src/detectors/structure.ts +2 -1
  763. package/src/detectors/subject-name-line.ts +66 -0
  764. package/src/detectors/superlative-name.ts +10 -0
  765. package/src/detectors/table-header.ts +15 -1
  766. package/src/detectors/technical-docs.ts +5 -1
  767. package/src/detectors/term-mention-sentence.ts +31 -0
  768. package/src/detectors/titled-run.ts +9 -4
  769. package/src/detectors/token-shape.ts +16 -5
  770. package/src/detectors/undefined-term.ts +8 -0
  771. package/src/detectors/unknown-word.ts +1 -1
  772. package/src/detectors/vague-density.ts +20 -4
  773. package/src/document-paragraphs.ts +27 -0
  774. package/src/document.ts +3 -23
  775. package/src/figure-references.ts +7 -2
  776. package/src/format-template.ts +15 -0
  777. package/src/formula-brackets.ts +36 -0
  778. package/src/html/html-markdown.ts +2 -1
  779. package/src/html/html-site-chrome.ts +104 -0
  780. package/src/joined-view.ts +1 -0
  781. package/src/kanji-compound-slip.ts +98 -0
  782. package/src/latin-company-form.ts +38 -0
  783. package/src/latin-word-boundary.ts +64 -0
  784. package/src/leading-label.ts +15 -0
  785. package/src/lexicon-genres.ts +1 -1
  786. package/src/link-shape.ts +31 -0
  787. package/src/link-title.ts +38 -0
  788. package/src/list-item-paragraphs.ts +22 -0
  789. package/src/literal-quote.ts +55 -0
  790. package/src/nado-closed-list.ts +48 -5
  791. package/src/name-misspelt-usual.ts +25 -0
  792. package/src/name-separator.ts +27 -2
  793. package/src/nominal-stem.ts +62 -5
  794. package/src/notice-header.ts +57 -0
  795. package/src/person-forms.ts +15 -0
  796. package/src/plugin.ts +5 -0
  797. package/src/preamble-paragraphs.ts +13 -3
  798. package/src/sentence-load.ts +14 -3
  799. package/src/spacing-code.ts +5 -1
  800. package/src/split-noun.ts +63 -0
  801. package/src/structure/attached-parts.ts +47 -0
  802. package/src/structure/build.ts +7 -4
  803. package/src/structure/contents-lines.ts +63 -0
  804. package/src/structure/defining-names.ts +155 -0
  805. package/src/structure/definition-use.ts +149 -32
  806. package/src/structure/gerund-phrase.ts +31 -0
  807. package/src/structure/issues.ts +7 -3
  808. package/src/structure/list-lead-in.ts +94 -0
  809. package/src/structure/modal-conflict.ts +42 -7
  810. package/src/structure/negated-act.ts +49 -0
  811. package/src/structure/numbering.ts +24 -9
  812. package/src/structure/prose-total.ts +20 -6
  813. package/src/structure/repeated-number.ts +110 -0
  814. package/src/structure/rounded-amount.ts +55 -0
  815. package/src/structure/side-step.ts +21 -0
  816. package/src/structure/spanned-label-blank.ts +39 -0
  817. package/src/structure/universal.ts +33 -9
  818. package/src/structure/unspaced-heading.ts +27 -0
  819. package/src/structure/written-list-path.ts +46 -0
  820. package/src/structure/written-resolve.ts +16 -9
  821. package/src/title-line.ts +53 -0
  822. package/src/topic-clause.ts +109 -0
  823. package/src/uncounted-particles.ts +72 -0
@@ -12,8 +12,20 @@ export type WrittenRange = { readonly offset: number; readonly written: string;
12
12
  const FULLWIDTH_OFFSET = 0xfee0;
13
13
  const NUMBER = "[0-90-9]+(?:[..][0-90-9]+)?";
14
14
 
15
- /** 範囲のすぐ後ろ(空白一つまで)の単位や語。番号にも使う記号(ハイフン)は、これが続くときだけ範囲と読む。 */
16
- const UNIT_AFTER = /^\s?[\p{L}%%]/u;
15
+ /** 範囲のすぐ後ろ(同じ行の空白一つまで)の単位や語。番号にも使う記号(ハイフン)は、これが続くときだけ範囲と読む。 */
16
+ const UNIT_AFTER = /^[^\S\n]?[\p{L}%%]/u;
17
+
18
+ /**
19
+ * 漢字の語に詰めて書いた番号の後ろに仮名が続けば、文書の番号(直資4-5ほか、課資3-1の)。範囲なら後ろは単位(約3-5日)で、
20
+ * 仮名で始まる単位(約3-5か月、3-5つ)は語彙表 range-kana-unit が言う。
21
+ */
22
+ const CODE_BEFORE = /\p{Script=Han}$/u;
23
+ const KANA_AFTER = /^[^\S\n]?(\p{Script=Hiragana}.*)/u;
24
+
25
+ const isDocumentNumber = (lineBefore: string, after: string, kanaUnits: readonly string[]): boolean => {
26
+ const kana = KANA_AFTER.exec(after)?.[1];
27
+ return CODE_BEFORE.test(lineBefore) && kana !== undefined && !kanaUnits.some((unit) => kana.startsWith(unit));
28
+ };
17
29
 
18
30
  /** 行の頭(見出しや箇条書きの印の後ろ)の「1-2」は節の番号、閉じ括弧のすぐ後ろの「(703) 292-7827」は電話番号。 */
19
31
  const LABEL_BEFORE = /(?:^\s*[#>*+|-][\s#>*+|-]*|\)\s?)$/u;
@@ -30,9 +42,15 @@ const halfWidth = (text: string): string => text.replace(/[0-9.]/gu, (char
30
42
  /**
31
43
  * 文字列の中の数の範囲。前後にさらに数が続く並び(日付 2026-10-02、電話番号、時刻 10:00、版 1.2-3)は範囲ではない。
32
44
  * 終わりが始まりより小さいもの(郵便番号 100-0001、試合の 3-2)も範囲ではない。ambiguous の記号は、後ろに単位や語が続き、
33
- * 前が番号の札(図 2-1、Section 1-2、NSF 13-542)でないときだけ。
45
+ * 前が番号の札(図 2-1、Section 1-2、NSF 13-542)でも文書の番号(直資4-5ほか)でもないときだけ。
34
46
  */
35
- export const rangesIn = (text: string, marks: readonly string[], ambiguous: readonly string[] = [], labels: readonly string[] = []): WrittenRange[] => {
47
+ export const rangesIn = (
48
+ text: string,
49
+ marks: readonly string[],
50
+ ambiguous: readonly string[] = [],
51
+ labels: readonly string[] = [],
52
+ kanaUnits: readonly string[] = [],
53
+ ): WrittenRange[] => {
36
54
  if (marks.length === 0) return [];
37
55
  const joiner = marks
38
56
  .toSorted((left, right) => right.length - left.length)
@@ -46,9 +64,10 @@ export const rangesIn = (text: string, marks: readonly string[], ambiguous: read
46
64
  const from = Number(halfWidth(match.groups?.["from"] ?? ""));
47
65
  const to = Number(halfWidth(match.groups?.["to"] ?? ""));
48
66
  const mark = match.groups?.["mark"] ?? "";
49
- const unitFollows = UNIT_AFTER.test(text.slice(match.index + match[0].length));
67
+ const after = text.slice(match.index + match[0].length);
50
68
  const lineBefore = text.slice(text.lastIndexOf("\n", match.index - 1) + 1, match.index);
51
- return to > from && !LABEL_BEFORE.test(lineBefore) && (!ambiguous.includes(mark) || (unitFollows && !isNumberLabel(lineBefore, labels)))
69
+ const readsAsRange = UNIT_AFTER.test(after) && !isNumberLabel(lineBefore, labels) && !isDocumentNumber(lineBefore, after, kanaUnits);
70
+ return to > from && !LABEL_BEFORE.test(lineBefore) && (!ambiguous.includes(mark) || readsAsRange)
52
71
  ? [{ offset: match.index, written: match[0], form: mark }]
53
72
  : [];
54
73
  });
@@ -62,6 +81,7 @@ export const rangeNotation: Detector = (doc, options): Finding[] => {
62
81
  entries.map((entry) => entry.pattern),
63
82
  entries.filter((entry) => entry.group === "ambiguous").map((entry) => entry.pattern),
64
83
  ["figure-label", "numbered-division", "numbered-label"].flatMap((id) => (doc.lexicons[id] ?? []).map((entry) => entry.pattern)),
84
+ (doc.lexicons["range-kana-unit"] ?? []).map((entry) => entry.pattern),
65
85
  );
66
86
  const minority = formMinority(ranges, options.limit);
67
87
  if (minority === undefined) return [];
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { kanjiCompoundSlip } from "../kanji-compound-slip.ts";
3
+
4
+ export const detector: Detector = kanjiCompoundSlip;
@@ -0,0 +1,4 @@
1
+ import type { Detector } from "../../plugin.ts";
2
+ import { phraseInUse } from "../phrase-match.ts";
3
+
4
+ export const detector: Detector = phraseInUse;
@@ -1,6 +1,11 @@
1
1
  import type { Detector, Finding, Lexicon, LexiconEntry, ProseDocument, Sentence } from "../plugin.ts";
2
+ import { entriesForGenre } from "../lexicon-genres.ts";
2
3
  import { entryCloses, entryIn, entryRanges } from "./lexicon-match.ts";
4
+ import { classWordsOf, isClassCue, namesClassAfter } from "./open-end-class.ts";
5
+ import { glossesCondition } from "./open-end-condition.ts";
3
6
  import { openEndAt, openEndNames, type OpenEndNames } from "./open-end-names.ts";
7
+ import { asksAfter, questionWordsOf } from "./open-end-question.ts";
8
+ import { isScopeCue, openOnPurpose, scopeWordsOf } from "./open-end-scope.ts";
4
9
  import { statesConcrete } from "./vague-deadline.ts";
5
10
 
6
11
  // Requirements smells (Femmer et al. 2017; Berry et al. 2003; ISO/IEC/IEEE 29148): a loophole, an open-ended list and
@@ -9,6 +14,10 @@ import { statesConcrete } from "./vague-deadline.ts";
9
14
 
10
15
  const OPEN_END = "requirement-open-end";
11
16
  const LOOPHOLE = "requirement-loophole";
17
+ /** The words of a question that an open list gives example answers to. */
18
+ const OPEN_QUESTION = "requirement-open-question";
19
+ /** The words of a condition whose bracketed examples an open list may give. */
20
+ const OPEN_CONDITION = "requirement-open-condition";
12
21
  const TIME = "time";
13
22
  const CONCRETE_DEADLINE = "concrete-deadline";
14
23
 
@@ -56,30 +65,58 @@ const boundedInTime = (doc: ProseDocument, sentence: Sentence, entry: LexiconEnt
56
65
  (doc.lexicons[CONCRETE_DEADLINE] ?? []).map((limit) => limit.pattern),
57
66
  );
58
67
 
59
- /** Where the word stands as a smell. An open-end word inside a name the document gives (業務執行取締役等) is none; without tokens it cannot be told apart. */
68
+ /**
69
+ * A lexicon's words that hold in the document's genre ("but not limited to" is a term of art in a contract); the open-end
70
+ * lexicon also holds the cues of a class named after the list and of what holds it, which are no smell.
71
+ */
72
+ const smellWords = (doc: ProseDocument, lexicon: string, genre: string | undefined): LexiconEntry[] =>
73
+ entriesForGenre(doc.lexicons[lexicon] ?? [], genre).filter((entry) => !isClassCue(entry) && !isScopeCue(entry));
74
+
75
+ /**
76
+ * Where the word stands as a smell. An open-end word inside a name the document gives (業務執行取締役等), giving examples
77
+ * of a class named right after it (印刷等、二次的に利用), or ending a list a condition, a permission or a prohibition holds
78
+ * (転載等をしてはならない), is none; without tokens none of these can be told apart.
79
+ */
60
80
  const smellAt = (doc: ProseDocument, sentence: Sentence, entry: LexiconEntry, lexicon: string, names: () => OpenEndNames): number | undefined => {
61
81
  if (!entryIn(sentence, entry) || boundedInTime(doc, sentence, entry, lexicon)) return undefined;
62
82
  const tokenized = sentence.tokens !== undefined && (entry.tokens?.length ?? 0) > 0;
63
- return lexicon === OPEN_END && tokenized ? openEndAt(doc, sentence, entry, names()) : offsetOf(sentence, entry);
83
+ if (lexicon !== OPEN_END || !tokenized) return offsetOf(sentence, entry);
84
+ const classWords = classWordsOf(doc.lexicons[OPEN_END] ?? []);
85
+ const scopeWords = scopeWordsOf(doc.lexicons[OPEN_END] ?? []);
86
+ return openEndAt(doc, sentence, entry, names(), (tokens, range) => namesClassAfter(tokens, range, classWords) || openOnPurpose(tokens, range, scopeWords));
64
87
  };
65
88
 
89
+ /** An open list right before a question the reader answers (…措置など、どのような措置を求めるのか): its items are example answers. */
90
+ const answersQuestion = (doc: ProseDocument, sentence: Sentence, entry: LexiconEntry, lexicon: string, offset: number): boolean =>
91
+ lexicon === OPEN_END && asksAfter(sentence, offset + entry.pattern.length, questionWordsOf(doc.lexicons[OPEN_QUESTION] ?? []));
92
+
93
+ /** An open list in brackets right after a condition word (場合(単一テーブルへの SELECT 等)): examples of when, not of what. */
94
+ const glossesConditionAt = (doc: ProseDocument, sentence: Sentence, lexicon: string, offset: number): boolean =>
95
+ lexicon === OPEN_END &&
96
+ glossesCondition(
97
+ sentence,
98
+ offset,
99
+ (doc.lexicons[OPEN_CONDITION] ?? []).map((entry) => entry.pattern),
100
+ );
101
+
66
102
  /** The first word of each smell in one requirement sentence: one finding per smell, not per word. */
67
- const smellsIn = (doc: ProseDocument, sentence: Sentence, names: () => OpenEndNames): Finding[] =>
103
+ const smellsIn = (doc: ProseDocument, sentence: Sentence, genre: string | undefined, names: () => OpenEndNames): Finding[] =>
68
104
  SMELLS.flatMap(({ lexicon, variant }) =>
69
- (doc.lexicons[lexicon] ?? [])
105
+ smellWords(doc, lexicon, genre)
70
106
  .flatMap((entry) => {
71
107
  const offset = smellAt(doc, sentence, entry, lexicon, names);
72
- return offset === undefined ? [] : [findingOf(sentence, entry, variant, offset)];
108
+ const examples = offset !== undefined && (answersQuestion(doc, sentence, entry, lexicon, offset) || glossesConditionAt(doc, sentence, lexicon, offset));
109
+ return offset === undefined || examples ? [] : [findingOf(sentence, entry, variant, offset)];
73
110
  })
74
111
  .slice(0, 1),
75
112
  );
76
113
 
77
- export const requirementSmell: Detector = (doc): Finding[] => {
114
+ export const requirementSmell: Detector = (doc, options): Finding[] => {
78
115
  const markers = doc.lexicons[MARKERS] ?? [];
79
116
  const notMarkers = doc.lexicons[NOT_MARKERS] ?? [];
80
117
  const statements = (doc.lexicons[STATEMENTS] ?? []).map((entry) => entry.pattern);
81
118
  // Read once, and only when a requirement has an open-end word to tell apart from a name.
82
119
  const cache: { names?: OpenEndNames } = {};
83
- const names = (): OpenEndNames => (cache.names ??= openEndNames(doc, doc.lexicons[OPEN_END] ?? [], statements));
84
- return doc.sentences.filter((sentence) => isRequirement(sentence, markers, notMarkers)).flatMap((sentence) => smellsIn(doc, sentence, names));
120
+ const names = (): OpenEndNames => (cache.names ??= openEndNames(doc, smellWords(doc, OPEN_END, options.genre), statements));
121
+ return doc.sentences.filter((sentence) => isRequirement(sentence, markers, notMarkers)).flatMap((sentence) => smellsIn(doc, sentence, options.genre, names));
85
122
  };
@@ -0,0 +1,103 @@
1
+ // number-without-unit, in prose: a number written with a word of scale and no unit (83,494百万, 83 million) where the
2
+ // document writes that word of scale with one unit many times and without one nowhere else (83,494百万円, $83 million).
3
+ // Pure; the words of scale, the currency marks and the joiners come from the language's lexicons.
4
+ import { escapeRegExp } from "../orthography.ts";
5
+ import type { CurrencyForm } from "./currency-notation.ts";
6
+ import { AMOUNT } from "./currency-notation.ts";
7
+
8
+ /** A number with a word of scale: from its currency mark (if any) to the end of its unit, and the unit ("" when bare). */
9
+ export type ScaledFigure = { readonly offset: number; readonly end: number; readonly written: string; readonly scale: string; readonly unit: string };
10
+
11
+ export type ScaleWords = { readonly scales: readonly string[]; readonly forms: readonly CurrencyForm[]; readonly joiners: readonly string[] };
12
+
13
+ export type ScaleGap = { readonly figure: ScaledFigure; readonly unit: string };
14
+
15
+ /** How many numbers must carry the unit before the one without it reads as a slip rather than a way of writing. */
16
+ export const MIN_WITH_UNIT = 5;
17
+
18
+ const LATIN = /[A-Za-z]/u;
19
+ const longestFirst = (words: readonly string[]): string[] => words.toSorted((left, right) => right.length - left.length);
20
+
21
+ const figurePattern = (scales: readonly string[]): RegExp => {
22
+ const scale = longestFirst(scales)
23
+ .map((word) => `${escapeRegExp(word)}${LATIN.test(word) ? "(?![A-Za-z])" : ""}`)
24
+ .join("|");
25
+ return new RegExp(`(?<![\\w.,,.0-9])${AMOUNT}\\s?(?:${scale})`, "gu");
26
+ };
27
+
28
+ const formMatches = (text: string, pattern: string, side: "before" | "after"): boolean => {
29
+ if (side === "before") return text.endsWith(pattern) && !(LATIN.test(pattern.charAt(0)) && LATIN.test(text.charAt(text.length - pattern.length - 1)));
30
+ return text.startsWith(pattern) && !(LATIN.test(pattern.at(-1) ?? "") && LATIN.test(text.charAt(pattern.length)));
31
+ };
32
+
33
+ /** The currency mark written before a number ($, US$, ¥), with the one space it may have. */
34
+ const markBefore = (text: string, offset: number, forms: readonly CurrencyForm[]): string => {
35
+ const before = text.slice(Math.max(0, offset - 8), offset);
36
+ const spaced = before.endsWith(" ") ? before.slice(0, -1) : before;
37
+ const form = longestFirst(forms.filter((entry) => entry.position === "before").map((entry) => entry.pattern)).find((pattern) =>
38
+ formMatches(spaced, pattern, "before"),
39
+ );
40
+ if (form === undefined) return "";
41
+ return spaced === before ? form : `${form} `;
42
+ };
43
+
44
+ /** What follows a word of scale as its unit: a currency word (円, dollars), else the next word ("people", 人, ドル); "" when none. */
45
+ const unitAfter = (rest: string, forms: readonly CurrencyForm[]): string => {
46
+ const spaced = rest.startsWith(" ") ? rest.slice(1) : rest;
47
+ const form = longestFirst(forms.filter((entry) => entry.position === "after").map((entry) => entry.pattern)).find((pattern) =>
48
+ formMatches(spaced, pattern, "after"),
49
+ );
50
+ const word = form ?? /^(?:[A-Za-z]+|[\p{Script=Katakana}ー]+|\p{Script=Han})/u.exec(spaced)?.[0];
51
+ if (word === undefined) return "";
52
+ return spaced === rest ? word : ` ${word}`;
53
+ };
54
+
55
+ const figureAt = (text: string, match: RegExpExecArray, words: ScaleWords): ScaledFigure | undefined => {
56
+ const end = match.index + match[0].length;
57
+ const rest = text.slice(end);
58
+ if (/^\s?[0-90-9]/u.test(rest)) return undefined;
59
+ const mark = markBefore(text, match.index, words.forms);
60
+ const after = mark === "" ? unitAfter(rest, words.forms) : "";
61
+ const scale = longestFirst(words.scales).find((word) => match[0].endsWith(word)) ?? "";
62
+ return { offset: match.index - mark.length, end: end + after.length, written: match[0], scale, unit: (mark || after).trim() };
63
+ };
64
+
65
+ /** Every number with a word of scale in a text, in order; one that runs on into another number (1億2,000万円) is left out. */
66
+ export const scaledFiguresIn = (text: string, words: ScaleWords): ScaledFigure[] =>
67
+ words.scales.length === 0 ? [] : [...text.matchAll(figurePattern(words.scales))].flatMap((match) => figureAt(text, match, words) ?? []);
68
+
69
+ /** A bare number joined to its neighbour by a range or list word, so that one unit serves both (100百万〜200百万円). */
70
+ const sharesUnit = (text: string, left: ScaledFigure | undefined, right: ScaledFigure | undefined, joiners: readonly string[]): boolean => {
71
+ if (left === undefined || right === undefined) return false;
72
+ const gap = text.slice(left.end, right.offset).trim();
73
+ return gap === "" || joiners.includes(gap) || joiners.includes(gap.toLowerCase());
74
+ };
75
+
76
+ const gapOfScale = (text: string, figures: readonly ScaledFigure[], joiners: readonly string[]): ScaleGap[] => {
77
+ const bare = figures.filter(
78
+ (figure, index) => figure.unit === "" && !sharesUnit(text, figure, figures[index + 1], joiners) && !sharesUnit(text, figures[index - 1], figure, joiners),
79
+ );
80
+ const withUnit = figures.filter((figure) => figure.unit !== "");
81
+ const units = new Set(withUnit.map((figure) => figure.unit));
82
+ const [unit] = units;
83
+ const [figure] = bare;
84
+ if (figure === undefined || unit === undefined || bare.length !== 1 || units.size !== 1 || withUnit.length < MIN_WITH_UNIT) return [];
85
+ return [{ figure, unit }];
86
+ };
87
+
88
+ /**
89
+ * The one bare number of a word of scale whose other numbers all carry one unit, at least MIN_WITH_UNIT times. Two bare
90
+ * numbers, or two units (百万円 and 百万株), and the document is read as writing the word that way on purpose.
91
+ */
92
+ export const scaleGaps = (text: string, figures: readonly ScaledFigure[], joiners: readonly string[]): ScaleGap[] => {
93
+ const scales = [...new Set(figures.map((figure) => figure.scale))];
94
+ return scales
95
+ .flatMap((scale) =>
96
+ gapOfScale(
97
+ text,
98
+ figures.filter((figure) => figure.scale === scale),
99
+ joiners,
100
+ ),
101
+ )
102
+ .toSorted((left, right) => left.figure.offset - right.figure.offset);
103
+ };
@@ -1,4 +1,5 @@
1
- import type { Detector, DetectorOptions, Finding, Lexicon, ProseDocument, Sentence, Token } from "../plugin.ts";
1
+ import type { Detector, DetectorOptions, Finding, Lexicon, ProseDocument, Sentence, Span, Token } from "../plugin.ts";
2
+ import { escapeRegExp } from "../orthography.ts";
2
3
  import { isWithinAny, quotedIn } from "../quoted-span.ts";
3
4
  import { entryOpens } from "./lexicon-match.ts";
4
5
 
@@ -6,10 +7,25 @@ type TokenTest = (token: Token, at: number, tokens: readonly Token[]) => boolean
6
7
 
7
8
  const wordsOf = (lexicon: Lexicon | undefined): ReadonlySet<string> => new Set((lexicon ?? []).map((entry) => entry.pattern));
8
9
 
9
- /** The tokens of a sentence that pass the test, outside anything quoted in 「」『』: a quotation is not the writer's to rephrase. */
10
- const countedTokens = (sentence: Sentence, test: TokenTest): Token[] => {
11
- const quoted = quotedIn(sentence);
12
- return (sentence.tokens ?? []).filter((token, at, tokens) => test(token, at, tokens) && !isWithinAny(quoted, token.span));
10
+ /** The terms whose counted word belongs to the term itself (電磁的方法), not to the writer's style. */
11
+ export const FIXED_TERM_LEXICON = "teki-fixed-term";
12
+
13
+ /** Where the sentence holds one of the terms, in the document's coordinates. */
14
+ const termSpans = (sentence: Sentence, terms: Lexicon): Span[] =>
15
+ terms.flatMap((entry) =>
16
+ [...sentence.text.matchAll(new RegExp(escapeRegExp(entry.pattern), "gu"))].map((match) => ({
17
+ start: sentence.span.start + match.index,
18
+ end: sentence.span.start + match.index + entry.pattern.length,
19
+ })),
20
+ );
21
+
22
+ /**
23
+ * The tokens of a sentence that pass the test, outside anything quoted in 「」『』 and outside the fixed terms: neither a
24
+ * quotation nor a term the law defines (電磁的方法) is the writer's to rephrase.
25
+ */
26
+ const countedTokens = (sentence: Sentence, test: TokenTest, fixedTerms: Lexicon): Token[] => {
27
+ const kept = [...quotedIn(sentence), ...termSpans(sentence, fixedTerms)];
28
+ return (sentence.tokens ?? []).filter((token, at, tokens) => test(token, at, tokens) && !isWithinAny(kept, token.span));
13
29
  };
14
30
 
15
31
  const findingOf = (sentence: Sentence, counted: readonly Token[], limit: number): Finding => ({
@@ -21,16 +37,16 @@ const findingOf = (sentence: Sentence, counted: readonly Token[], limit: number)
21
37
  values: { word: counted[0]?.surface ?? "", count: counted.length, limit, offset: sentence.span.start },
22
38
  });
23
39
 
24
- const sentencesOver = (doc: ProseDocument, limit: number, test: TokenTest): Finding[] =>
40
+ const sentencesOver = (doc: ProseDocument, limit: number, test: TokenTest, fixedTerms: Lexicon = []): Finding[] =>
25
41
  doc.sentences.flatMap((sentence) => {
26
- const counted = countedTokens(sentence, test);
42
+ const counted = countedTokens(sentence, test, fixedTerms);
27
43
  return counted.length > limit ? [findingOf(sentence, counted, limit)] : [];
28
44
  });
29
45
 
30
46
  /** A sentence holding more than limit tokens written as one of the lexicon's words (the suffix 的). */
31
47
  export const sentenceWordCount: Detector = (doc, options): Finding[] => {
32
48
  const words = wordsOf(options.lexicon);
33
- return sentencesOver(doc, options.limit, (token) => words.has(token.surface));
49
+ return sentencesOver(doc, options.limit, (token) => words.has(token.surface), doc.lexicons[FIXED_TERM_LEXICON] ?? []);
34
50
  };
35
51
 
36
52
  const NOMINAL: ReadonlySet<string> = new Set(["NOUN", "PROPN", "NUM"]);
@@ -53,9 +69,39 @@ const itemEndBefore = (at: number, tokens: readonly Token[]): number => {
53
69
  /** The index of the token the next item starts with, past spaces. */
54
70
  const itemStartAfter = (at: number, tokens: readonly Token[]): number => tokens.findIndex((token, index) => index > at && !isSpace(token));
55
71
 
56
- /** A comma between two nouns separates listed items (名前、会社名、連絡先), not clauses. A bracketed note after an item is part of it. */
72
+ /** A prefix bound to the noun after it (第I, 各部署) starts a noun. */
73
+ const isBoundPrefix = (token: Token | undefined): boolean => token?.features?.["Bound"] === "Yes" && token.pos === "ADJ";
74
+
75
+ const startsNoun = (at: number, tokens: readonly Token[]): boolean => {
76
+ const start = itemStartAfter(at, tokens);
77
+ return isNominal(tokens[start]) || (isBoundPrefix(tokens[start]) && isNominal(tokens[start + 1]));
78
+ };
79
+
80
+ const QUOTE_CLOSERS: ReadonlySet<string> = new Set(["」", "』"]);
81
+ const QUOTE_OPENERS: ReadonlySet<string> = new Set(["「", "『"]);
82
+
83
+ /** Whether the token at `closer` closes a quotation of a noun phrase (「技術の確立」), not of a clause (「成功した」). */
84
+ const closesNounQuotation = (closer: number, tokens: readonly Token[]): boolean =>
85
+ QUOTE_CLOSERS.has(tokens[closer]?.surface ?? "") && isNominal(tokens[closer - 1]);
86
+
87
+ /**
88
+ * A comma from one quoted noun phrase straight to the next (「計画」、「予算」) lists quoted items. A noun before a quotation
89
+ * (対応するもの、「A」に関しては) may end a clause, and so may a quoted clause, so only noun quotation to noun quotation counts.
90
+ */
91
+ const betweenQuotations = (at: number, tokens: readonly Token[]): boolean => {
92
+ const before = tokens.findLastIndex((token, index) => index < at && !isSpace(token));
93
+ const start = itemStartAfter(at, tokens);
94
+ if (!QUOTE_OPENERS.has(tokens[start]?.surface ?? "")) return false;
95
+ const after = tokens.findIndex((token, index) => index > start && QUOTE_CLOSERS.has(token.surface));
96
+ return closesNounQuotation(before, tokens) && closesNounQuotation(after, tokens);
97
+ };
98
+
99
+ /**
100
+ * A comma between two nouns separates listed items (名前、会社名、連絡先), not clauses. A bracketed note after an item is part of
101
+ * it, a noun after its prefix (第I、第II) is a noun, and so is a quotation listed next to another.
102
+ */
57
103
  export const separatesItems = (at: number, tokens: readonly Token[]): boolean =>
58
- isNominal(tokens[itemEndBefore(at, tokens)]) && isNominal(tokens[itemStartAfter(at, tokens)]);
104
+ betweenQuotations(at, tokens) || (isNominal(tokens[itemEndBefore(at, tokens)]) && startsNoun(at, tokens));
59
105
 
60
106
  /** A sentence cut by more than limit of the lexicon's commas (読点). Commas between listed nouns are not counted. */
61
107
  export const sentenceCommaCount: Detector = (doc, options): Finding[] => {
@@ -65,10 +111,16 @@ export const sentenceCommaCount: Detector = (doc, options): Finding[] => {
65
111
 
66
112
  const CONJUNCTIVE = "SCONJ";
67
113
 
68
- /** A sentence joining more than limit clauses with the lexicon's conjunctive particle (逆接の「が」), not the same word as a case particle. */
114
+ /** The phrases ending in a prefatory が (繰り返しになりますが、〜の件でありますが): no contrast with what follows. */
115
+ export const PREFATORY_LEXICON = "adversative-ga-prefatory";
116
+
117
+ /**
118
+ * A sentence joining more than limit clauses with the lexicon's conjunctive particle (逆接の「が」), not the same word as a
119
+ * case particle, and not inside a prefatory phrase.
120
+ */
69
121
  export const sentenceConjunctiveCount: Detector = (doc, options): Finding[] => {
70
122
  const words = wordsOf(options.lexicon);
71
- return sentencesOver(doc, options.limit, (token) => token.pos === CONJUNCTIVE && words.has(token.surface));
123
+ return sentencesOver(doc, options.limit, (token) => token.pos === CONJUNCTIVE && words.has(token.surface), doc.lexicons[PREFATORY_LEXICON] ?? []);
72
124
  };
73
125
 
74
126
  type Opened = { readonly sentence: Sentence; readonly opener: string | undefined };
@@ -1,7 +1,9 @@
1
1
  import { endingTokens, isClosed } from "../sentence-shape.ts";
2
2
  import { enumeratedRuns, enumeratorStarts, numberedStarts } from "./enumerated-runs.ts";
3
- import { continuesInto, groupOf, registerOf, slipsOf, type Register } from "./register.ts";
3
+ import { continuesInto, groupOf, majorityOf, registerOf, slipsOf, type Register } from "./register.ts";
4
4
  import { isRunInLabel } from "./run-in-label.ts";
5
+ import { noticeSentences } from "./notice-paragraph.ts";
6
+ import { chronologyRows } from "../chronology-rows.ts";
5
7
  import type { Detector, Finding, LexiconEntry, ProseDocument, Sentence, Span } from "../plugin.ts";
6
8
 
7
9
  /**
@@ -10,6 +12,8 @@ import type { Detector, Finding, LexiconEntry, ProseDocument, Sentence, Span } f
10
12
  * どちらが正しいかは決めない。決めると、方針の違う書き手にそのまま無視される。
11
13
  * 見るのは文書の中での一貫性だけで、少数派のほうを指摘する。spec §12.3 の方針を日本語にも。
12
14
  * 終止符で終わらないもの(見出しの下の `MaaSサービス` のような名前だけの行)と、項目や段落の頭の太字の札(**速く書ける。**)は文として数えない。
15
+ * 年表の行(1921年信号装置の製作を開始する。)も、文書の文体と揃えない書き方なので数えない。
16
+ * 断り書きの段落(…ご了承ください。)も、本文とは別の声で書く決まり文句なので数えない(notice-paragraph.ts)。
13
17
  */
14
18
  type Entry = { readonly sentence: Sentence; readonly register: Register; readonly group: number | undefined };
15
19
 
@@ -35,11 +39,16 @@ const runsOf = (doc: ProseDocument, registers: readonly Register[]): Span[] => {
35
39
  export const judgedSentences = (doc: ProseDocument, polite: readonly LexiconEntry[]): Entry[] => {
36
40
  const neutral = doc.lexicons["neutral-ending"] ?? [];
37
41
  const lists = doc.lists.map((list) => list.span);
38
- const found = doc.sentences.flatMap((sentence, index): { sentence: Sentence; register: Register }[] => {
39
- if (!isClosed(sentence) || continuesInto(sentence, doc.sentences[index + 1]) || isRunInLabel(doc.source, sentence.span)) return [];
42
+ const rows = chronologyRows(doc);
43
+ const all = doc.sentences.flatMap((sentence, index): { sentence: Sentence; register: Register }[] => {
44
+ if (!isClosed(sentence) || rows.has(sentence) || continuesInto(sentence, doc.sentences[index + 1]) || isRunInLabel(doc.source, sentence.span)) return [];
40
45
  const register = registerOfSentence(sentence, polite, neutral);
41
46
  return register === undefined ? [] : [{ sentence, register }];
42
47
  });
48
+ const registers = new Map(all.map((entry) => [entry.sentence, entry.register]));
49
+ const majority = majorityOf(all.map((entry) => ({ register: entry.register, group: undefined })));
50
+ const notices = noticeSentences(doc.paragraphs, doc.lexicons["notice-phrase"] ?? [], (sentence) => registers.get(sentence), majority);
51
+ const found = all.filter((entry) => !notices.has(entry.sentence));
43
52
  const runs = runsOf(
44
53
  doc,
45
54
  found.map((entry) => entry.register),
@@ -1,26 +1,39 @@
1
1
  import { lengthOf, proseText } from "../measure.ts";
2
2
  import type { Detector, DetectorOptions, Finding, LengthUnit, Sentence } from "../plugin.ts";
3
+ import { citationLead } from "./citation-sentence.ts";
3
4
  import { pageMarkerPattern, pageMarkerSize } from "./page-marker.ts";
4
5
 
5
6
  type Measure = { readonly size: number; readonly limit: number; readonly variant?: string };
6
7
 
8
+ /** The page markers' pattern and the citation signals ("see"), read once per document. */
9
+ type SentenceWords = { readonly markers: RegExp | undefined; readonly citationSignals: readonly string[] };
10
+
11
+ const sizeOf = (text: string, unit: LengthUnit): number =>
12
+ unit === "word" ? text.split(/\s+/u).filter((word) => word.length > 0).length : text.replace(/\s+/gu, "").length;
13
+
7
14
  /**
8
15
  * 文書と違う言語の文(和文の中の英文)は、その言語の単位と上限で測る。rule がその言語の段を持たなければ文書のもので。
9
16
  * 印刷版のページの印(( printed page 52044))は文の言葉ではないので数えない。
17
+ * 脚注の文献の記載(著者 (2025), "題," …)も書き手の文ではないので、その前に書き手が置いた言葉(For example, see …)だけを測る。
10
18
  */
11
- const measureOf = (sentence: Sentence, unit: LengthUnit, options: DetectorOptions, markers: RegExp | undefined): Measure => {
19
+ const measureOf = (sentence: Sentence, unit: LengthUnit, options: DetectorOptions, words: SentenceWords): Measure => {
20
+ const lead = citationLead(proseText(sentence), words.citationSignals);
21
+ if (lead !== undefined) return { size: sizeOf(lead, unit), limit: options.limit };
12
22
  const embedded = sentence.embeddedLanguage;
13
23
  const limit = embedded === undefined ? undefined : options.embeddedLimits?.[embedded.id];
14
24
  if (embedded === undefined || limit === undefined) {
15
- return { size: lengthOf(sentence, unit) - pageMarkerSize(proseText(sentence), markers, unit), limit: options.limit };
25
+ return { size: lengthOf(sentence, unit) - pageMarkerSize(proseText(sentence), words.markers, unit), limit: options.limit };
16
26
  }
17
27
  return { size: lengthOf(sentence, embedded.lengthUnit), limit, variant: `embedded-${embedded.id}` };
18
28
  };
19
29
 
20
30
  export const sentenceLength: Detector = (doc, options): Finding[] => {
21
- const markers = pageMarkerPattern((options.lexicon ?? []).map((entry) => entry.pattern));
31
+ const words: SentenceWords = {
32
+ markers: pageMarkerPattern((options.lexicon ?? []).map((entry) => entry.pattern)),
33
+ citationSignals: (doc.lexicons["citation-signal"] ?? []).map((entry) => entry.pattern),
34
+ };
22
35
  return doc.sentences
23
- .map((sentence) => ({ sentence, measure: measureOf(sentence, doc.lengthUnit, options, markers) }))
36
+ .map((sentence) => ({ sentence, measure: measureOf(sentence, doc.lengthUnit, options, words) }))
24
37
  .filter(({ measure }) => measure.size > measure.limit)
25
38
  .map(({ sentence, measure }) => ({
26
39
  rule: "max-sentence-length",
@@ -1,6 +1,7 @@
1
1
  import type { Detector, Finding, Sentence, Token } from "../plugin.ts";
2
2
  import { proseText } from "../measure.ts";
3
3
  import { quotedSpans } from "../quoted-span.ts";
4
+ import { literalCues, withoutLiteralQuotes } from "../literal-quote.ts";
4
5
  import { bracketDepth, clauseCount, topicDistance } from "../sentence-load.ts";
5
6
 
6
7
  const findingOf = (sentence: Sentence, count: number, limit: number): Finding => ({
@@ -35,8 +36,14 @@ const ownTokens = (sentence: Sentence): Token[] => {
35
36
  return (sentence.tokens ?? []).filter((token) => !inQuote(token));
36
37
  };
37
38
 
38
- /** Brackets inside brackets: 「(注(a)参照)」. The depth is read from the text, so it works in every language. */
39
- export const bracketNesting: Detector = overLimit((sentence) => bracketDepth(sentence.text));
39
+ /**
40
+ * Brackets inside brackets: 「(注(a)参照)」. The depth is read from the text, so it works in every language. A quotation of a
41
+ * string to type as it stands (件名に「応募(総務課)」と記載) counts as one bracket: its own brackets cannot be taken out.
42
+ */
43
+ export const bracketNesting: Detector = (doc, options) => {
44
+ const cues = literalCues(doc.lexicons["literal-quote-cue"] ?? []);
45
+ return overLimit((sentence) => bracketDepth(withoutLiteralQuotes(sentence.text, cues)))(doc, options);
46
+ };
40
47
 
41
48
  /** Clauses chained in one sentence (調べて、まとめ、報告したが、返事がないので、…). Needs the language's tokens. */
42
49
  export const clauseChain: Detector = overLimit((sentence) => (sentence.tokens === undefined ? undefined : clauseCount(ownTokens(sentence))));