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
@@ -1,6 +1,7 @@
1
1
  // A date written without its year where the reader cannot tell which year it is: the document's dated dates span more
2
2
  // than one year, or its dates cross the turn of a year. Pure; reads the date nodes of the structure tree.
3
- import type { Detector, Finding, LexiconEntry, ProseDocument, StructureNode } from "../plugin.ts";
3
+ import type { Detector, DetectorOptions, Finding, LexiconEntry, ProseDocument, StructureNode } from "../plugin.ts";
4
+ import { isIn } from "../lexicon-genres.ts";
4
5
  import { inDocumentOrder } from "../structure/issues.ts";
5
6
  import { quoteAt } from "./structure-tree.ts";
6
7
  import {
@@ -13,17 +14,29 @@ import {
13
14
  type MarkerReach,
14
15
  } from "./date-any-year.ts";
15
16
  import { datesUnderYearHeadings, yearLabelOf, type HeadingYearWords } from "./date-heading-year.ts";
17
+ import { openingDateOf } from "./opening-date.ts";
18
+ import { withNearestYear } from "../structure/weekday.ts";
16
19
 
17
- /** The words that make a yearless date any year's (毎年, 例えば, "each") and that join a period's two ends (から, "to"). */
18
- export type AnyYearWords = { readonly markers: readonly AnyYearMarker[]; readonly joiners: readonly string[] };
20
+ /**
21
+ * The words that make a yearless date any year's (毎年, 例えば, "each"), that join a period's two ends (から, "to"), and
22
+ * that join the names of one list (及び, "and"), for a marker named in one list with the date.
23
+ */
24
+ export type AnyYearWords = { readonly markers: readonly AnyYearMarker[]; readonly joiners: readonly string[]; readonly listJoiners?: readonly string[] };
19
25
 
20
26
  const NO_ANY_YEAR_WORDS: AnyYearWords = { markers: [], joiners: [] };
21
27
 
22
28
  /**
23
29
  * A date as the tree reads it: "2026-10-14" with its year, "10-14" without. `yearHeaded`: the heading of its section
24
- * names a year ("FY27-Q2 (May 1)", 「2026年度の予定」), which the date takes.
30
+ * names a year ("FY27-Q2 (May 1)", 「2026年度の予定」), which the date takes. `nearStamp`: the document's own date (minutes
31
+ * dated "January 17, 2024") lies within a few months of it in one year only, which the date takes.
25
32
  */
26
- export type DatePoint = { readonly offset: number; readonly end: number; readonly value: string; readonly yearHeaded?: boolean };
33
+ export type DatePoint = {
34
+ readonly offset: number;
35
+ readonly end: number;
36
+ readonly value: string;
37
+ readonly yearHeaded?: boolean;
38
+ readonly nearStamp?: boolean;
39
+ };
27
40
 
28
41
  /** The first and the last year of the document's dated dates. */
29
42
  export type YearSpan = { readonly from: number; readonly to: number };
@@ -118,7 +131,8 @@ const hasYearWord = (point: DatePoint, source: string, yearWords: readonly YearW
118
131
  */
119
132
  const yearGiven = (point: DatePoint, anchors: readonly DatePoint[], source: string, yearWords: readonly YearWord[]): boolean => {
120
133
  const start = lineStart(source, point.offset);
121
- return point.yearHeaded === true || hasYearWord(point, source, yearWords) || anchors.some((other) => other.offset >= start && other.offset < point.offset);
134
+ const placed = point.yearHeaded === true || point.nearStamp === true;
135
+ return placed || hasYearWord(point, source, yearWords) || anchors.some((other) => other.offset >= start && other.offset < point.offset);
122
136
  };
123
137
 
124
138
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -153,10 +167,14 @@ export const yearGaps = (
153
167
  const previousOf = new Map(points.map((point, index) => [point, points[index - 1]]));
154
168
  const yearlySpan = (start: DatePoint | undefined, end: DatePoint | undefined): boolean =>
155
169
  start !== undefined && end !== undefined && wholeYear(start.value, end.value) && opensSpan(start, end, source, anyYear.joiners);
170
+ const markedAnyYear = (point: DatePoint | undefined): boolean => point !== undefined && anyYearDate(point, source, anyYear.markers, anyYear.listJoiners);
156
171
  const yearOfAny = (point: DatePoint): boolean => {
157
172
  const next = nextOf.get(point);
158
- if (anyYearDate(point, source, anyYear.markers)) return true;
159
- if (yearlySpan(point, next) || yearlySpan(previousOf.get(point), point)) return true;
173
+ const previous = previousOf.get(point);
174
+ if (markedAnyYear(point)) return true;
175
+ if (yearlySpan(point, next) || yearlySpan(previous, point)) return true;
176
+ // The end of a period whose start is any year's is too: 「祝休日及び12月29日から1月3日まで」.
177
+ if (previous !== undefined && opensSpan(previous, point, source, anyYear.joiners) && markedAnyYear(previous)) return true;
160
178
  return next !== undefined && opensSpan(point, next, source, anyYear.joiners) && hasYearWord(next, source, yearWords);
161
179
  };
162
180
  // A recurring day or an example's date has no year to write, and is not the document's way of writing dates either.
@@ -172,15 +190,41 @@ export const yearGaps = (
172
190
 
173
191
  const NO_HEADING_YEAR_WORDS: HeadingYearWords = { eras: [], labels: [] };
174
192
 
175
- export const datePoints = (tree: StructureNode, headingWords: HeadingYearWords = NO_HEADING_YEAR_WORDS): DatePoint[] => {
193
+ /** A yearless date that the document's own date ("2024-01-17") places in one year: within a few months of it. */
194
+ const nearStampOf = (value: string, stamp: string | undefined): boolean => stamp !== undefined && withNearestYear(value, stamp) !== undefined;
195
+
196
+ export const datePoints = (tree: StructureNode, headingWords: HeadingYearWords = NO_HEADING_YEAR_WORDS, stamp?: string): DatePoint[] => {
176
197
  const yearHeaded = new Set(datesUnderYearHeadings(tree, headingWords));
177
- return inDocumentOrder(tree).flatMap((node) =>
178
- node.kind === "date"
179
- ? [{ offset: node.span.start, end: node.span.end, value: String(node.attrs["value"]), yearHeaded: yearHeaded.has(node.span.start) }]
180
- : [],
181
- );
198
+ return inDocumentOrder(tree).flatMap((node) => {
199
+ if (node.kind !== "date") return [];
200
+ const value = String(node.attrs["value"]);
201
+ return [{ offset: node.span.start, end: node.span.end, value, yearHeaded: yearHeaded.has(node.span.start), nearStamp: nearStampOf(value, stamp) }];
202
+ });
182
203
  };
183
204
 
205
+ /**
206
+ * The document's own date: a date alone, or labelled, on a line of its title block. A date-only paragraph further down
207
+ * (an agenda's "April 4, 2023") is a date the text talks about, not the document's.
208
+ */
209
+ const stampOf = (doc: ProseDocument, tree: StructureNode): string | undefined => {
210
+ const dates = inDocumentOrder(tree).flatMap((node) => (node.kind === "date" ? [{ ...node.span, value: String(node.attrs["value"]) }] : []));
211
+ const labels = (doc.lexicons["date-stamp-label"] ?? []).map((entry: LexiconEntry) => entry.pattern);
212
+ return openingDateOf(doc.source, dates, labels);
213
+ };
214
+
215
+ /**
216
+ * The genres whose date at the top is the occasion the text is about (minutes, a letter), from the rule's dated_genres.
217
+ * A web page's date at the top says when it was posted, and its days and months may be any year's.
218
+ */
219
+ const datedByOccasion = (options: DetectorOptions): boolean => {
220
+ const genres = options.settings?.["dated_genres"];
221
+ const genre = options.genre;
222
+ return genre !== undefined && Array.isArray(genres) && genres.some((target: string) => isIn(genre, target));
223
+ };
224
+
225
+ const pointsOf = (doc: ProseDocument, tree: StructureNode, options: DetectorOptions): DatePoint[] =>
226
+ datePoints(tree, headingYearWordsOf(doc), datedByOccasion(options) ? stampOf(doc, tree) : undefined);
227
+
184
228
  const yearWordsOf = (doc: ProseDocument): YearWord[] =>
185
229
  (doc.lexicons[YEAR_REFERENCE_LEXICON] ?? []).map((entry: LexiconEntry) => ({ word: entry.pattern, position: entry.position }));
186
230
 
@@ -192,17 +236,21 @@ const headingYearWordsOf = (doc: ProseDocument): HeadingYearWords => ({
192
236
  ),
193
237
  });
194
238
 
239
+ /** The words that join the names of one list (及び, "and"): a `listed` marker stands before the date with these between. */
240
+ const LIST_JOINER_LEXICON = "enumeration-joiner";
241
+
195
242
  const reachOf = (group: string | undefined): MarkerReach => MARKER_REACHES.find((reach) => reach === group) ?? "sentence";
196
243
 
197
244
  const anyYearWordsOf = (doc: ProseDocument): AnyYearWords => ({
198
245
  markers: (doc.lexicons[ANY_YEAR_MARKER_LEXICON] ?? []).map((entry: LexiconEntry) => ({ word: entry.pattern, reach: reachOf(entry.group) })),
199
246
  joiners: (doc.lexicons[YEAR_SPAN_JOINER_LEXICON] ?? []).map((entry: LexiconEntry) => entry.pattern),
247
+ listJoiners: (doc.lexicons[LIST_JOINER_LEXICON] ?? []).map((entry: LexiconEntry) => entry.pattern),
200
248
  });
201
249
 
202
- export const dateWithoutYear: Detector = (doc: ProseDocument): Finding[] =>
250
+ export const dateWithoutYear: Detector = (doc: ProseDocument, options: DetectorOptions): Finding[] =>
203
251
  doc.structure === undefined
204
252
  ? []
205
- : yearGaps(datePoints(doc.structure, headingYearWordsOf(doc)), doc.source, yearWordsOf(doc), anyYearWordsOf(doc)).map((gap) => ({
253
+ : yearGaps(pointsOf(doc, doc.structure, options), doc.source, yearWordsOf(doc), anyYearWordsOf(doc)).map((gap) => ({
206
254
  rule: "date-without-year",
207
255
  severity: "warning",
208
256
  line: 0,
@@ -0,0 +1,40 @@
1
+ import type { Span } from "../plugin.ts";
2
+
3
+ // The unit a duty is written in: its article, else its list, else its paragraph. A duty in a unit that names the dated
4
+ // deadline of its own act is timed by it: 「乙は代金を支払う。」 beside 「支払期日までに支払うことができないときは…」. A date
5
+ // for another act (a delivery date beside a duty to pay) times nothing. Pure.
6
+
7
+ /** The spans a document is cut into, from the widest kind that counts as one unit to the narrowest. */
8
+ export type Units = { readonly articles: readonly Span[]; readonly lists: readonly Span[]; readonly paragraphs: readonly Span[] };
9
+
10
+ /** A dated deadline's name (支払期日, due date) and the act it times (支払, pay). */
11
+ export type NamedDeadline = { readonly name: string; readonly act: string };
12
+
13
+ const within = (span: Span, offset: number): boolean => offset >= span.start && offset < span.end;
14
+
15
+ /** The innermost span holding the offset: an article nested in another is a unit of its own. */
16
+ const innermost = (spans: readonly Span[], offset: number): Span | undefined =>
17
+ spans
18
+ .filter((span) => within(span, offset))
19
+ .reduce<Span | undefined>((inner, span) => (inner === undefined || span.start > inner.start ? span : inner), undefined);
20
+
21
+ /** The unit that holds the offset: its article, else its list, else its paragraph; undefined when none does. */
22
+ export const unitAt = (units: Units, offset: number): Span | undefined =>
23
+ [units.articles, units.lists, units.paragraphs].map((spans) => innermost(spans, offset)).find((span) => span !== undefined);
24
+
25
+ /**
26
+ * The acts whose dated deadline the unit holding the offset names. holds: whether a text holds a name (as a phrase, so
27
+ * that a Latin name is read as whole words).
28
+ */
29
+ export const actsTimedAt = (
30
+ source: string,
31
+ units: Units,
32
+ offset: number,
33
+ deadlines: readonly NamedDeadline[],
34
+ holds: (text: string, name: string) => boolean,
35
+ ): string[] => {
36
+ const unit = unitAt(units, offset);
37
+ if (unit === undefined) return [];
38
+ const text = source.slice(unit.start, unit.end);
39
+ return [...new Set(deadlines.filter((deadline) => holds(text, deadline.name)).map((deadline) => deadline.act))];
40
+ };
@@ -1,12 +1,14 @@
1
1
  // A defined term used later in another form, and a long name used again after its short name was defined. Pure. The
2
2
  // definitions come from the document's structure tree (以下「甲」という, ("Seller")); which words may stand in a long
3
3
  // name is read from the tokens' parts of speech.
4
+ import { inEntryOfTerm } from "./term-mention-sentence.ts";
4
5
  import { definedTerms, usesOf, type BodyText, type DefinedTerm } from "../structure/definition-use.ts";
5
6
  import { escapeRegExp } from "../orthography.ts";
6
7
  import { prefixGroupsOf, prefixVariants, variantUses } from "../structure/term-prefix.ts";
7
8
  import { quoteAt } from "./structure-tree.ts";
8
9
  import { isPartOfAddress } from "./address-word.ts";
9
10
  import { exactOffsets, extendedAfter, extendedBefore } from "./term-extension.ts";
11
+ import { headsKindPhrase, insideLongerTerm, isNamedAsTerm, isNarrowedUse } from "./ordinary-phrase.ts";
10
12
  import { CLOSES_SENTENCE, isNameField, isSignatureLine, opensClosingBlock, SLACK } from "./name-field.ts";
11
13
  import type { Detector, Finding, ProseDocument, Sentence, Span, Token } from "../plugin.ts";
12
14
 
@@ -146,18 +148,36 @@ const prefixFindings = (doc: ProseDocument, texts: readonly BodyText[], term: De
146
148
  ),
147
149
  );
148
150
 
149
- /** The term set in quotes again, unless the document's profile says a quoted term is the term mentioned (「株主」とあるのは). */
150
- const quotedFindings = (doc: ProseDocument, term: DefinedTerm, uses: readonly number[], definingEnd: number): Finding[] =>
151
- doc.profile?.quoteMentionsTerm === true
152
- ? []
153
- : quotedUses(doc.source, term.term, uses, definingEnd).map((offset) =>
154
- finding(doc, "defined-term-form", offset, "quoted", { term: term.term, line: term.line }),
155
- );
151
+ const patternsOf = (doc: ProseDocument, lexicon: string): string[] => (doc.lexicons[lexicon] ?? []).map((entry) => entry.pattern);
152
+
153
+ /**
154
+ * The term set in quotes again, unless the document's profile says a quoted term is the term mentioned (「株主」とあるのは),
155
+ * or the words before the quote name it as a term (the definition of "Material Adverse Effect").
156
+ */
157
+ const quotedFindings = (doc: ProseDocument, term: DefinedTerm, uses: readonly number[], definingEnd: number): Finding[] => {
158
+ if (doc.profile?.quoteMentionsTerm === true) return [];
159
+ const cues = patternsOf(doc, "term-mention-cue");
160
+ return quotedUses(doc.source, term.term, uses, definingEnd)
161
+ .filter((offset) => !isNamedAsTerm(doc.source, offset - 1, cues))
162
+ .map((offset) => finding(doc, "defined-term-form", offset, "quoted", { term: term.term, line: term.line }));
163
+ };
164
+
165
+ /**
166
+ * A lower-case use that is the ordinary word in a phrase of its own: inside another defined term (certificate of merger),
167
+ * narrowed by the word before it (the common parent), or heading a kind of thing (certificates of deposit).
168
+ */
169
+ const isOrdinaryPhraseAt = (doc: ProseDocument, offset: number, term: string, defined: readonly string[]): boolean => {
170
+ if (insideLongerTerm(doc.source, offset, term, defined)) return true;
171
+ const { tokens, at } = tokensAt(doc, offset);
172
+ if (at === -1) return false;
173
+ const last = tokens.findLastIndex((token) => token.span.start < offset + term.length);
174
+ return isNarrowedUse(tokens, at, patternsOf(doc, "defined-term-pointer")) || headsKindPhrase(tokens, last);
175
+ };
156
176
 
157
177
  /** The term written longer with a word of its definition (文書管理責任者, the Application), after the sentence that defines it. */
158
178
  const extendedFindings = (doc: ProseDocument, texts: readonly BodyText[], term: DefinedTerm, spans: readonly Span[], defined: readonly string[]): Finding[] => {
159
179
  const definition = definingSentence(doc, term.span)?.text ?? "";
160
- const pointers = (doc.lexicons["defined-term-pointer"] ?? []).map((entry) => entry.pattern);
180
+ const pointers = patternsOf(doc, "defined-term-pointer");
161
181
  // Every sentence that defines the term (a second definition too) holds the long words it is defined from.
162
182
  const defining = spans.map((span) => definingSentence(doc, span)?.span ?? span);
163
183
  const definingEnd = definingSentenceEnd(doc, term.span);
@@ -182,11 +202,11 @@ export const definedTermForm: Detector = (doc, options): Finding[] => {
182
202
  const uses = usesOf(term.term, texts, spans, "loose");
183
203
  const definingEnd = definingSentenceEnd(doc, term.span);
184
204
  const quoted = quotedFindings(doc, term, uses, definingEnd);
185
- const caseUses = withLoweredWords(doc, term.term, texts, spans, uses);
205
+ const caseUses = withLoweredWords(doc, term.term, texts, spans, uses).filter((offset) => !inEntryOfTerm(doc.sentences, term.term, offset));
186
206
  const nounUses = caseUses.filter((offset) => !isVerbAt(doc, offset));
187
- const lower = lowerCaseUses(doc.source, term.term, nounUses, definingEnd, options.limit).map((offset) =>
188
- finding(doc, "defined-term-form", offset, "case", { term: term.term, line: term.line }),
189
- );
207
+ const lower = lowerCaseUses(doc.source, term.term, nounUses, definingEnd, options.limit)
208
+ .filter((offset) => !isOrdinaryPhraseAt(doc, offset, term.term, defined))
209
+ .map((offset) => finding(doc, "defined-term-form", offset, "case", { term: term.term, line: term.line }));
190
210
  return [...quoted, ...lower, ...prefixFindings(doc, texts, term, definingEnd, defined), ...extendedFindings(doc, texts, term, spans, defined)];
191
211
  });
192
212
  };
@@ -1,6 +1,7 @@
1
1
  import type { Detector, Finding, ProseDocument } from "../plugin.ts";
2
2
  import { definedTerms, unusedDefinitions, usesBeforeDefinition, type BodyText, type IsTitle, type Mentioned } from "../structure/definition-use.ts";
3
3
  import { titleLineNumbers } from "../structure/title-lines.ts";
4
+ import { contentsLineNumbers } from "../structure/contents-lines.ts";
4
5
  import { expansionConflicts, expansionsIn } from "../acronym-expansions.ts";
5
6
  import { linesOf, lineNumberAt } from "../structure/lines.ts";
6
7
  import { isQuotedAlone } from "../quoted-span.ts";
@@ -26,18 +27,25 @@ const findingAt = (doc: ProseDocument, offset: number, values: Readonly<Record<s
26
27
  const headingsOf = (doc: ProseDocument): BodyText[] =>
27
28
  (doc.markup?.headings ?? []).map((heading) => ({ start: heading.start, text: doc.source.slice(heading.start, heading.end) }));
28
29
 
30
+ const patternsOf = (doc: ProseDocument, lexicon: string): string[] => (doc.lexicons[lexicon] ?? []).map((entry) => entry.pattern);
31
+
32
+ /** 動名詞の後ろに来て、それが目的語を取る動詞だと分かる語(冠詞と所有の語)。 */
33
+ const DETERMINER_LISTS = ["article", "dependent-possessive"] as const;
34
+
29
35
  /** 定義したのに、定義の外(文と見出し)で一度も使っていない語。 */
30
- export const unusedDefinition: Detector = (doc): Finding[] =>
31
- doc.structure === undefined
32
- ? []
33
- : unusedDefinitions(definedTerms(doc.structure), [...bodyOf(doc), ...headingsOf(doc)], mentionedIn(doc)).map((defined) =>
34
- findingAt(doc, defined.span.start, { term: defined.term }),
35
- );
36
+ export const unusedDefinition: Detector = (doc): Finding[] => {
37
+ if (doc.structure === undefined) return [];
38
+ const determiners = new Set(DETERMINER_LISTS.flatMap((list) => patternsOf(doc, list)));
39
+ return unusedDefinitions(definedTerms(doc.structure), [...bodyOf(doc), ...headingsOf(doc)], mentionedIn(doc), determiners).map((defined) =>
40
+ findingAt(doc, defined.span.start, { term: defined.term }),
41
+ );
42
+ };
36
43
 
37
- /** 題・見出し(Markdown の見出し、章・節の行、条の前の見出しの行)の上の位置か。 */
44
+ /** 題・見出し(Markdown の見出し、章・節の行、条の前の見出しの行)と、目次・索引の行の上の位置か。 */
38
45
  const titleIn = (doc: ProseDocument): IsTitle => {
39
46
  const lines = linesOf(doc.source);
40
- const numbers = titleLineNumbers(doc.structure, lines, doc.markup?.headings ?? []);
47
+ const headings = doc.markup?.headings ?? [];
48
+ const numbers = new Set([...titleLineNumbers(doc.structure, lines, headings), ...contentsLineNumbers(lines, headings, patternsOf(doc, "toc-heading"))]);
41
49
  return (offset) => numbers.has(lineNumberAt(lines, offset) ?? 0);
42
50
  };
43
51
 
@@ -45,7 +53,7 @@ const titleIn = (doc: ProseDocument): IsTitle => {
45
53
  export const useBeforeDefinition: Detector = (doc): Finding[] =>
46
54
  doc.structure === undefined
47
55
  ? []
48
- : usesBeforeDefinition(definedTerms(doc.structure), bodyOf(doc), mentionedIn(doc), titleIn(doc)).map((use) =>
56
+ : usesBeforeDefinition(definedTerms(doc.structure), bodyOf(doc), mentionedIn(doc), titleIn(doc), patternsOf(doc, "self-prefix")).map((use) =>
49
57
  findingAt(doc, use.offset, { term: use.term.term, defined: use.term.line }),
50
58
  );
51
59
 
@@ -4,6 +4,8 @@ import { documentDateOf } from "./document-date.ts";
4
4
  import { overlapsAny, spanIndex } from "../compare/spans.ts";
5
5
  import { yearOf, type DurationUnit } from "../derived/date-arithmetic.ts";
6
6
  import { durationMismatches, type DatedValue, type Duration } from "../derived/durations.ts";
7
+ import { isCountPerPeriod, type PeriodWord, type PerPeriodWords } from "../derived/count-per-period.ts";
8
+ import { occurrences } from "../structure/stated-multiple.ts";
7
9
  import { elapsedMismatches, type Elapsed, type OriginWord, type Year } from "../derived/elapsed.ts";
8
10
  import { numberWordCounts } from "../derived/number-word-counts.ts";
9
11
  import { hyphenatedCounts, withoutArticle } from "../derived/hyphenated-counts.ts";
@@ -91,12 +93,25 @@ const isApproximate = (doc: ProseDocument, span: Attributed): boolean =>
91
93
  positioned(doc, "approximate-marker", "before").some((word) => textBefore(doc, span).endsWith(word)) ||
92
94
  positioned(doc, "approximate-marker", "after").some((word) => textAfter(doc, span).startsWith(word));
93
95
 
94
- /** 木の数量(3 months)と、名詞の前に書いた期間(a 3-month trial)。 */
95
- const durationsOf = (doc: ProseDocument, quantities: readonly Quantity[], text: string): Duration[] =>
96
- [...quantities, ...hyphenatedCounts(text, patternsOf(doc, ...DURATION_LEXICONS.map(([id]) => id)))].flatMap((quantity) => {
96
+ const isDurationUnit = (group: string | undefined): group is DurationUnit => DURATION_LEXICONS.some(([, unit]) => unit === group);
97
+
98
+ const perPeriodWordsOf = (doc: ProseDocument): PerPeriodWords => ({
99
+ periods: (doc.lexicons["duration-per-period"] ?? []).flatMap((entry): PeriodWord[] =>
100
+ isDurationUnit(entry.group) ? [{ word: entry.pattern.toLowerCase(), position: entry.position === "after" ? "after" : "before", unit: entry.group }] : [],
101
+ ),
102
+ schedules: spanIndex(occurrences(doc.source, patternsOf(doc, "weekly-days-off"))),
103
+ });
104
+
105
+ /** 木の数量(3 months)と、名詞の前に書いた期間(a 3-month trial)。期間あたりの数(週3日)は期間ではない。 */
106
+ const durationsOf = (doc: ProseDocument, quantities: readonly Quantity[], text: string): Duration[] => {
107
+ const perPeriod = perPeriodWordsOf(doc);
108
+ return [...quantities, ...hyphenatedCounts(text, patternsOf(doc, ...DURATION_LEXICONS.map(([id]) => id)))].flatMap((quantity) => {
97
109
  const unit = DURATION_LEXICONS.find(([id]) => patternsOf(doc, id).some((pattern) => pattern.normalize("NFKC") === quantity.unit))?.[1];
98
- return unit === undefined || isApproximate(doc, quantity) ? [] : [{ ...quantity, unit }];
110
+ if (unit === undefined || isApproximate(doc, quantity)) return [];
111
+ const duration = { ...quantity, unit };
112
+ return isCountPerPeriod(duration, textBefore(doc, quantity), textAfter(doc, quantity), perPeriod) ? [] : [duration];
99
113
  });
114
+ };
100
115
 
101
116
  const sentencesOf = (doc: ProseDocument): Span[] => doc.sentences.map((sentence) => sentence.span);
102
117
 
@@ -99,6 +99,24 @@ const QUESTION_END = /[??]["'”’))」』]*$/u;
99
99
 
100
100
  export const isQuestionHeading = (heading: string): boolean => QUESTION_END.test(heading.trim());
101
101
 
102
+ /** A series label in brackets at a heading's end, a number and a colon opening it ("(490: Employee travel)"): the manual's reference. */
103
+ const SERIES_LABEL_END = /[((]\p{N}+[::][^()()]*[))]$/u;
104
+ const QUOTED = /「[^「」]*」/gu;
105
+ const QUOTED_NAME = "「」";
106
+
107
+ /**
108
+ * The words the heading's writer chose: without a series label at its end, and with another document's title, quoted
109
+ * right before what is done to it (「…の取扱いについて」等の一部改正, the cited-title-action word list), as one name.
110
+ */
111
+ export const ownWordsOf = (heading: string, citedTitleActions: readonly string[]): string =>
112
+ heading
113
+ .trimEnd()
114
+ .replace(SERIES_LABEL_END, "")
115
+ .trimEnd()
116
+ .replaceAll(QUOTED, (quote, offset: number) =>
117
+ citedTitleActions.some((action) => action !== "" && heading.startsWith(action, offset + quote.length)) ? QUOTED_NAME : quote,
118
+ );
119
+
102
120
  /** The heading's words without a number label at its head (Chapter 2, 1.), from the section the heading opens. */
103
121
  const unlabeledOf = (doc: ProseDocument, heading: MarkupHeading): string =>
104
122
  doc.sections.find((section) => section.span.start === heading.end)?.unlabeledHeading ?? heading.text;
@@ -107,10 +125,11 @@ const unlabeledOf = (doc: ProseDocument, heading: MarkupHeading): string =>
107
125
  export const titleLength: Detector = (doc, options): Finding[] => {
108
126
  const headings = writtenHeadings(doc);
109
127
  const title = headings.find((heading) => heading.depth === 1);
128
+ const citedTitleActions = (doc.lexicons["cited-title-action"] ?? []).map((entry) => entry.pattern);
110
129
  return headings
111
130
  .map((heading) => ({ heading, words: unlabeledOf(doc, heading) }))
112
131
  .filter(({ words }) => !isParagraphHeading(words) && !isQuestionHeading(words))
113
- .map(({ heading, words }) => ({ heading, count: headingLength(words, doc.lengthUnit) }))
132
+ .map(({ heading, words }) => ({ heading, count: headingLength(ownWordsOf(words, citedTitleActions), doc.lengthUnit) }))
114
133
  .filter(({ count }) => count > options.limit)
115
134
  .map(({ heading, count }) => ({
116
135
  ...findingAt(doc, heading, { heading: heading.text.trim(), count, limit: options.limit }, heading === title ? "title" : undefined),
@@ -0,0 +1,36 @@
1
+ import type { Token } from "../plugin.ts";
2
+
3
+ // 同じ助詞のあいだに括弧の注だけがある(「本利用規約は(以下、本規約)は」)。注を書き足したときに、前の助詞を消し忘れた跡。
4
+ // 「AはBは」の対比は、あいだに語があるので当たらない。
5
+
6
+ const MAX_ASIDE = 80;
7
+ /** 注の前後に置ける空白(行の中だけ)。 */
8
+ const MAX_SPACES = 2;
9
+ const SPACES = `[ \\t\\u3000]{0,${String(MAX_SPACES)}}`;
10
+ /** 助詞の後ろの、括弧ひとつの注(入れ子でない)とその前後の空白。 */
11
+ const ASIDE = new RegExp(`^${SPACES}[((][^(())\\n]{1,${String(MAX_ASIDE)}}[))]${SPACES}`, "u");
12
+ /** 括弧と注と前後の空白が収まる長さ。これより先は読まない。 */
13
+ const LOOK_AHEAD = MAX_ASIDE + 2 + MAX_SPACES * 2;
14
+
15
+ /** 「別表の(1)の欄」の「の」は、括弧の番号を挟んで名前を続ける書き方なので数えない。 */
16
+ const JOINS_NAMES = "の";
17
+
18
+ const isParticle = (token: Token): boolean => token.pos === "ADP" && token.surface !== JOINS_NAMES;
19
+
20
+ /** 二つの同じ助詞と、そのあいだの括弧の注。 */
21
+ export type AsidePair = { readonly first: Token; readonly second: Token };
22
+
23
+ /** first の後ろが括弧の注だけで、その直後に同じ助詞があれば、その助詞。source は文書全体で、token の span もその座標。 */
24
+ const particleAfterAside = (source: string, tokens: readonly Token[], first: Token): Token | undefined => {
25
+ const aside = ASIDE.exec(source.slice(first.span.end, first.span.end + LOOK_AHEAD))?.[0];
26
+ if (aside === undefined) return undefined;
27
+ const second = tokens.find((token) => token.span.start === first.span.end + aside.length);
28
+ return second !== undefined && isParticle(second) && second.surface === first.surface ? second : undefined;
29
+ };
30
+
31
+ /** 文の語のうち、括弧の注を挟んで同じ助詞が二度ある所。Pure. */
32
+ export const doubledAcrossAside = (source: string, tokens: readonly Token[]): AsidePair[] =>
33
+ tokens.flatMap((first) => {
34
+ const second = isParticle(first) ? particleAfterAside(source, tokens, first) : undefined;
35
+ return second === undefined ? [] : [{ first, second }];
36
+ });
@@ -1,4 +1,6 @@
1
- import type { Detector, Finding } from "../plugin.ts";
1
+ import type { Detector, Finding, Span } from "../plugin.ts";
2
+ import { latinCompanyFormRegExp, latinCompanyFormSpans } from "../latin-company-form.ts";
3
+ import { firstEndingAfter } from "../soft-break.ts";
2
4
  import { quoteAround } from "./quote-around.ts";
3
5
 
4
6
  /**
@@ -32,16 +34,35 @@ const withoutWordDot = (text: string, found: DoubledMarks): DoubledMarks =>
32
34
  ? { start: found.start, run: found.run.slice(0, -1) }
33
35
  : found;
34
36
 
35
- const isSlip = (text: string, { start, run }: DoubledMarks): boolean =>
36
- run.length >= 2 && !isDrawnOut(run) && !isDrawnOutThenClosed(run) && !AFTER_ABBREVIATION.test(run) && !isJoinedDots(text, start, run);
37
+ /**
38
+ * 並びのうち、英字の会社の形(CO.,LTD.、INC.)の中の印の数。形の点や「,」は名前の一部で、並びの印ではない。
39
+ * names は昇順で重ならない(正規表現の順の一致)。並びに掛かりうるのは、並びの終わる前に始まる高々 run.length 個の形。
40
+ */
41
+ const marksInNames = ({ start, run }: DoubledMarks, names: readonly Span[]): number => {
42
+ const first = firstEndingAfter(names, start);
43
+ const near = names.slice(first, first + run.length);
44
+ return [...run].filter((_, at) => near.some((name) => start + at >= name.start && start + at < name.end)).length;
45
+ };
46
+
47
+ const isSlip = (text: string, found: DoubledMarks, names: readonly Span[]): boolean => {
48
+ const { start, run } = found;
49
+ return (
50
+ run.length - marksInNames(found, names) >= 2 &&
51
+ !isDrawnOut(run) &&
52
+ !isDrawnOutThenClosed(run) &&
53
+ !AFTER_ABBREVIATION.test(run) &&
54
+ !isJoinedDots(text, start, run)
55
+ );
56
+ };
37
57
 
38
- /** text の中の、句読点が重なった並び(位置と並び)。 */
39
- export const doubledMarks = (text: string): DoubledMarks[] =>
40
- [...text.matchAll(PUNCTUATION_RUN)].map((match) => withoutWordDot(text, { start: match.index, run: match[0] })).filter((found) => isSlip(text, found));
58
+ /** text の中の、句読点が重なった並び(位置と並び)。names は数えない名前(英字の会社の形)の範囲。 */
59
+ export const doubledMarks = (text: string, names: readonly Span[] = []): DoubledMarks[] =>
60
+ [...text.matchAll(PUNCTUATION_RUN)].map((match) => withoutWordDot(text, { start: match.index, run: match[0] })).filter((found) => isSlip(text, found, names));
41
61
 
42
62
  export const doubledPunctuation: Detector = (doc): Finding[] => {
43
63
  const text = doc.prose ?? doc.source;
44
- return doubledMarks(text).map(({ start, run }) => ({
64
+ const forms = latinCompanyFormRegExp((doc.lexicons["company-form-latin"] ?? []).map((entry) => entry.pattern));
65
+ return doubledMarks(text, latinCompanyFormSpans(text, forms)).map(({ start, run }) => ({
45
66
  rule: "",
46
67
  severity: "warning",
47
68
  line: 0,
@@ -1,5 +1,6 @@
1
1
  import type { Detector, Finding, Lexicon, Sentence, Token } from "../plugin.ts";
2
2
  import { citedNamesOf, endsCitedName } from "./cited-name.ts";
3
+ import { doubledAcrossAside } from "./doubled-across-aside.ts";
3
4
 
4
5
  /**
5
6
  * 語を書き損じて二度書いた(the the / 資料をを)。消し忘れと、書き換えの途中で残った語(our the platform)の二つ。
@@ -159,7 +160,7 @@ export const doubledWord: Detector = (doc, options): Finding[] => {
159
160
  const kinds = new Set((doc.lexicons[DOCUMENT_KIND] ?? []).map((entry) => entry.pattern));
160
161
  const phrases = doc.lexicons[FIXED_PHRASE] ?? [];
161
162
  return doc.sentences.flatMap((sentence) =>
162
- doubledIn(doc.source, sentence.tokens ?? [], spaced, allowed, phrases)
163
+ [...doubledIn(doc.source, sentence.tokens ?? [], spaced, allowed, phrases), ...(spaced ? [] : doubledAcrossAside(doc.source, sentence.tokens ?? []))]
163
164
  .filter((doubled) => !endsCitedName(doubled.first, doubled.second, cited, kinds))
164
165
  .map((doubled) => findingOf(sentence, doubled, spaced)),
165
166
  );
@@ -1,5 +1,6 @@
1
1
  import type { Detector, Finding, MarkupHeading } from "../plugin.ts";
2
2
  import { lineNumberAt, linesOf } from "../structure/lines.ts";
3
+ import { recordLabelOf, recordRhythmMask } from "./heading-record-rhythm.ts";
3
4
  import { findingAt, writtenHeadings } from "./markup-finding.ts";
4
5
 
5
6
  /** 見出しの言葉を比べる形。全角と半角、大文字と小文字、空白の数は同じ見出しの違いにしない。 */
@@ -21,22 +22,44 @@ export type RepeatedHeading = { readonly heading: MarkupHeading; readonly first:
21
22
 
22
23
  type Seen = Map<number, Map<string, MarkupHeading>>;
23
24
 
25
+ /** 見出しごとに、同じ親の下の兄弟の型の並びで、決まった見出しの組をくり返す所にあるか(recordRhythmMask)。 */
26
+ const inRecordRhythm = (parents: readonly number[], keys: readonly string[]): boolean[] => {
27
+ const byParent = new Map<number, number[]>();
28
+ parents.forEach((parent, index) => {
29
+ const siblings = byParent.get(parent) ?? [];
30
+ siblings.push(index);
31
+ byParent.set(parent, siblings);
32
+ });
33
+ const inRhythm = keys.map(() => false);
34
+ byParent.forEach((indexes) => {
35
+ const mask = recordRhythmMask(indexes.map((index) => recordLabelOf(keys[index] ?? "")));
36
+ indexes.forEach((index, at) => {
37
+ inRhythm[index] = mask[at] === true;
38
+ });
39
+ });
40
+ return inRhythm;
41
+ };
42
+
24
43
  /**
25
44
  * 同じ親の下で、前の見出しと同じ言葉の見出し(markdownlint の MD024 siblings_only)。変更履歴の版ごとの「Added」「Fixed」のように、
26
45
  * 親が違えば同じ言葉でもよい。深さが違っても親が同じなら兄弟として比べる(飛んだ深さの見出しも同じ親の下にある)。
46
+ * 事例ごとに決まった見出しの組をくり返す所(recordRhythmMask)は、文書の作りとしての重複なので言わない。
27
47
  */
28
48
  export const repeatedSiblingHeadings = (headings: readonly MarkupHeading[]): RepeatedHeading[] => {
29
49
  const parents = parentIndexes(headings);
50
+ const keys = headings.map((heading) => headingKey(heading.text));
51
+ const inRhythm = inRecordRhythm(parents, keys);
30
52
  const seen: Seen = new Map();
31
- return headings.flatMap((heading, index) => {
32
- const key = headingKey(heading.text);
53
+ const repeats = headings.flatMap((heading, index) => {
54
+ const key = keys[index] ?? "";
33
55
  const parent = parents[index] ?? -1;
34
56
  const siblings = seen.get(parent) ?? new Map<string, MarkupHeading>();
35
57
  seen.set(parent, siblings);
36
58
  const first = siblings.get(key);
37
59
  if (first === undefined) siblings.set(key, heading);
38
- return first === undefined || key === "" ? [] : [{ heading, first }];
60
+ return first === undefined || key === "" || inRhythm[index] === true ? [] : [{ heading, first }];
39
61
  });
62
+ return repeats;
40
63
  };
41
64
 
42
65
  export const duplicateHeading: Detector = (doc): Finding[] => {
@@ -35,6 +35,19 @@ const wordAround = (text: string, start: number, end: number): string => {
35
35
  return text.slice(from, after === -1 ? text.length : end + after);
36
36
  };
37
37
 
38
+ /**
39
+ * A leader pads a label out to a column: the label opens a line or follows a sentence end, holds no space or punctuation,
40
+ * and two spaces or more follow the dots (化学品事業…… then two full-width spaces, then the description). One such place
41
+ * may be an ellipsis followed by spaces; MIN_LEADERS of them are a list of labels.
42
+ */
43
+ const LEADER_LABEL = /(?:^|[\n。.!?!?])[^\S\n]*[^\s\p{P}]{1,20}$/u;
44
+ const LEADER_PADDING = /^[^\S\n]{2}/u;
45
+ const LABEL_REACH = 24;
46
+ const MIN_LEADERS = 2;
47
+
48
+ const isLeaderShaped = (text: string, start: number, end: number): boolean =>
49
+ LEADER_PADDING.test(text.slice(end)) && LEADER_LABEL.test(text.slice(Math.max(0, start - LABEL_REACH), start));
50
+
38
51
  /** Dots that are not an ellipsis in running text: a range, a path or address, a table of contents leader. */
39
52
  const isNotProse = (text: string, start: number, end: number): boolean =>
40
53
  NOT_PROSE_BESIDE.test(text.charAt(start - 1)) ||
@@ -50,9 +63,11 @@ export const ellipsesIn = (text: string, forms: readonly string[]): WrittenEllip
50
63
  .map(escapeRegExp)
51
64
  .join("|");
52
65
  const pattern = new RegExp(`(?<!${ELLIPSIS_PART})(?:${alternatives})(?!${ELLIPSIS_PART})`, "gu");
53
- return [...text.matchAll(pattern)].flatMap((match) =>
66
+ const found = [...text.matchAll(pattern)].flatMap((match) =>
54
67
  isNotProse(text, match.index, match.index + match[0].length) ? [] : [{ offset: match.index, form: match[0] }],
55
68
  );
69
+ const leaders = found.filter((ellipsis) => isLeaderShaped(text, ellipsis.offset, ellipsis.offset + ellipsis.form.length));
70
+ return leaders.length < MIN_LEADERS ? found : found.filter((ellipsis) => !leaders.includes(ellipsis));
56
71
  };
57
72
 
58
73
  export const ellipsisConsistency: Detector = (doc, options): Finding[] => {