chaffjs 0.34.0 → 0.36.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 (976) 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/capitals-passage.d.ts +3 -0
  8. package/dist/capitals-passage.d.ts.map +1 -0
  9. package/dist/capitals-passage.js +26 -0
  10. package/dist/capitals-passage.js.map +1 -0
  11. package/dist/chronology-rows.d.ts +9 -0
  12. package/dist/chronology-rows.d.ts.map +1 -0
  13. package/dist/chronology-rows.js +79 -0
  14. package/dist/chronology-rows.js.map +1 -0
  15. package/dist/coined-hyphen-name.d.ts +13 -0
  16. package/dist/coined-hyphen-name.d.ts.map +1 -0
  17. package/dist/coined-hyphen-name.js +21 -0
  18. package/dist/coined-hyphen-name.js.map +1 -0
  19. package/dist/company-name-run.d.ts +8 -0
  20. package/dist/company-name-run.d.ts.map +1 -0
  21. package/dist/company-name-run.js +30 -0
  22. package/dist/company-name-run.js.map +1 -0
  23. package/dist/company-names.d.ts +6 -1
  24. package/dist/company-names.d.ts.map +1 -1
  25. package/dist/company-names.js +22 -3
  26. package/dist/company-names.js.map +1 -1
  27. package/dist/compound-head.d.ts +7 -0
  28. package/dist/compound-head.d.ts.map +1 -0
  29. package/dist/compound-head.js +19 -0
  30. package/dist/compound-head.js.map +1 -0
  31. package/dist/date-format.d.ts +8 -3
  32. package/dist/date-format.d.ts.map +1 -1
  33. package/dist/date-format.js +36 -3
  34. package/dist/date-format.js.map +1 -1
  35. package/dist/derived/count-per-period.d.ts +23 -0
  36. package/dist/derived/count-per-period.d.ts.map +1 -0
  37. package/dist/derived/count-per-period.js +14 -0
  38. package/dist/derived/count-per-period.js.map +1 -0
  39. package/dist/detectors/acronym-context.d.ts +5 -1
  40. package/dist/detectors/acronym-context.d.ts.map +1 -1
  41. package/dist/detectors/acronym-context.js +32 -4
  42. package/dist/detectors/acronym-context.js.map +1 -1
  43. package/dist/detectors/acronym-definition.d.ts +13 -0
  44. package/dist/detectors/acronym-definition.d.ts.map +1 -0
  45. package/dist/detectors/acronym-definition.js +90 -0
  46. package/dist/detectors/acronym-definition.js.map +1 -0
  47. package/dist/detectors/acronym-expansion.d.ts +5 -1
  48. package/dist/detectors/acronym-expansion.d.ts.map +1 -1
  49. package/dist/detectors/acronym-expansion.js +35 -3
  50. package/dist/detectors/acronym-expansion.js.map +1 -1
  51. package/dist/detectors/acronym-known.d.ts +19 -0
  52. package/dist/detectors/acronym-known.d.ts.map +1 -0
  53. package/dist/detectors/acronym-known.js +32 -0
  54. package/dist/detectors/acronym-known.js.map +1 -0
  55. package/dist/detectors/acronym-link.d.ts +14 -0
  56. package/dist/detectors/acronym-link.d.ts.map +1 -0
  57. package/dist/detectors/acronym-link.js +32 -0
  58. package/dist/detectors/acronym-link.js.map +1 -0
  59. package/dist/detectors/acronym-lone.d.ts +13 -0
  60. package/dist/detectors/acronym-lone.d.ts.map +1 -0
  61. package/dist/detectors/acronym-lone.js +22 -0
  62. package/dist/detectors/acronym-lone.js.map +1 -0
  63. package/dist/detectors/acronym-name.d.ts +62 -0
  64. package/dist/detectors/acronym-name.d.ts.map +1 -0
  65. package/dist/detectors/acronym-name.js +94 -0
  66. package/dist/detectors/acronym-name.js.map +1 -0
  67. package/dist/detectors/addressee-edge.d.ts +13 -0
  68. package/dist/detectors/addressee-edge.d.ts.map +1 -0
  69. package/dist/detectors/addressee-edge.js +13 -0
  70. package/dist/detectors/addressee-edge.js.map +1 -0
  71. package/dist/detectors/announced-count.d.ts.map +1 -1
  72. package/dist/detectors/announced-count.js +1 -0
  73. package/dist/detectors/announced-count.js.map +1 -1
  74. package/dist/detectors/bare-comparative.d.ts +4 -0
  75. package/dist/detectors/bare-comparative.d.ts.map +1 -1
  76. package/dist/detectors/bare-comparative.js +28 -3
  77. package/dist/detectors/bare-comparative.js.map +1 -1
  78. package/dist/detectors/blank-structure.d.ts +7 -1
  79. package/dist/detectors/blank-structure.d.ts.map +1 -1
  80. package/dist/detectors/blank-structure.js +13 -8
  81. package/dist/detectors/blank-structure.js.map +1 -1
  82. package/dist/detectors/bracket-specified.d.ts +6 -0
  83. package/dist/detectors/bracket-specified.d.ts.map +1 -0
  84. package/dist/detectors/bracket-specified.js +23 -0
  85. package/dist/detectors/bracket-specified.js.map +1 -0
  86. package/dist/detectors/broken-link.d.ts +6 -0
  87. package/dist/detectors/broken-link.d.ts.map +1 -1
  88. package/dist/detectors/broken-link.js +23 -2
  89. package/dist/detectors/broken-link.js.map +1 -1
  90. package/dist/detectors/capitalised-term.d.ts +14 -2
  91. package/dist/detectors/capitalised-term.d.ts.map +1 -1
  92. package/dist/detectors/capitalised-term.js +115 -4
  93. package/dist/detectors/capitalised-term.js.map +1 -1
  94. package/dist/detectors/caps-caption.d.ts +12 -0
  95. package/dist/detectors/caps-caption.d.ts.map +1 -0
  96. package/dist/detectors/caps-caption.js +89 -0
  97. package/dist/detectors/caps-caption.js.map +1 -0
  98. package/dist/detectors/caps-phrase.d.ts +6 -0
  99. package/dist/detectors/caps-phrase.d.ts.map +1 -0
  100. package/dist/detectors/caps-phrase.js +16 -0
  101. package/dist/detectors/caps-phrase.js.map +1 -0
  102. package/dist/detectors/char-shape.d.ts +1 -0
  103. package/dist/detectors/char-shape.d.ts.map +1 -1
  104. package/dist/detectors/char-shape.js +72 -30
  105. package/dist/detectors/char-shape.js.map +1 -1
  106. package/dist/detectors/cited-title.d.ts +3 -2
  107. package/dist/detectors/cited-title.d.ts.map +1 -1
  108. package/dist/detectors/cited-title.js +14 -3
  109. package/dist/detectors/cited-title.js.map +1 -1
  110. package/dist/detectors/clause-shape.d.ts +1 -1
  111. package/dist/detectors/clause-shape.d.ts.map +1 -1
  112. package/dist/detectors/clause-shape.js +9 -4
  113. package/dist/detectors/clause-shape.js.map +1 -1
  114. package/dist/detectors/concrete-evidence.d.ts +13 -1
  115. package/dist/detectors/concrete-evidence.d.ts.map +1 -1
  116. package/dist/detectors/concrete-evidence.js +59 -0
  117. package/dist/detectors/concrete-evidence.js.map +1 -1
  118. package/dist/detectors/contraction-minority.d.ts +11 -0
  119. package/dist/detectors/contraction-minority.d.ts.map +1 -0
  120. package/dist/detectors/contraction-minority.js +10 -0
  121. package/dist/detectors/contraction-minority.js.map +1 -0
  122. package/dist/detectors/counter-edge.d.ts +7 -1
  123. package/dist/detectors/counter-edge.d.ts.map +1 -1
  124. package/dist/detectors/counter-edge.js +40 -2
  125. package/dist/detectors/counter-edge.js.map +1 -1
  126. package/dist/detectors/date-any-year.d.ts +12 -5
  127. package/dist/detectors/date-any-year.d.ts.map +1 -1
  128. package/dist/detectors/date-any-year.js +69 -12
  129. package/dist/detectors/date-any-year.js.map +1 -1
  130. package/dist/detectors/date-format.d.ts.map +1 -1
  131. package/dist/detectors/date-format.js +2 -1
  132. package/dist/detectors/date-format.js.map +1 -1
  133. package/dist/detectors/date-heading-year.d.ts +18 -0
  134. package/dist/detectors/date-heading-year.d.ts.map +1 -0
  135. package/dist/detectors/date-heading-year.js +38 -0
  136. package/dist/detectors/date-heading-year.js.map +1 -0
  137. package/dist/detectors/date-year.d.ts +19 -3
  138. package/dist/detectors/date-year.d.ts.map +1 -1
  139. package/dist/detectors/date-year.js +69 -8
  140. package/dist/detectors/date-year.js.map +1 -1
  141. package/dist/detectors/deadline-unit.d.ts +20 -0
  142. package/dist/detectors/deadline-unit.d.ts.map +1 -0
  143. package/dist/detectors/deadline-unit.js +19 -0
  144. package/dist/detectors/deadline-unit.js.map +1 -0
  145. package/dist/detectors/defined-term-form.d.ts.map +1 -1
  146. package/dist/detectors/defined-term-form.js +59 -12
  147. package/dist/detectors/defined-term-form.js.map +1 -1
  148. package/dist/detectors/definition-use.d.ts.map +1 -1
  149. package/dist/detectors/definition-use.js +6 -3
  150. package/dist/detectors/definition-use.js.map +1 -1
  151. package/dist/detectors/derived-numbers.d.ts.map +1 -1
  152. package/dist/detectors/derived-numbers.js +17 -4
  153. package/dist/detectors/derived-numbers.js.map +1 -1
  154. package/dist/detectors/doubled-across-aside.d.ts +9 -0
  155. package/dist/detectors/doubled-across-aside.d.ts.map +1 -0
  156. package/dist/detectors/doubled-across-aside.js +27 -0
  157. package/dist/detectors/doubled-across-aside.js.map +1 -0
  158. package/dist/detectors/doubled-punctuation.d.ts +3 -3
  159. package/dist/detectors/doubled-punctuation.d.ts.map +1 -1
  160. package/dist/detectors/doubled-punctuation.js +23 -4
  161. package/dist/detectors/doubled-punctuation.js.map +1 -1
  162. package/dist/detectors/doubled-word.d.ts.map +1 -1
  163. package/dist/detectors/doubled-word.js +2 -1
  164. package/dist/detectors/doubled-word.js.map +1 -1
  165. package/dist/detectors/due-date.d.ts.map +1 -1
  166. package/dist/detectors/due-date.js +6 -0
  167. package/dist/detectors/due-date.js.map +1 -1
  168. package/dist/detectors/ellipsis.d.ts.map +1 -1
  169. package/dist/detectors/ellipsis.js +13 -1
  170. package/dist/detectors/ellipsis.js.map +1 -1
  171. package/dist/detectors/email-letter.d.ts +31 -1
  172. package/dist/detectors/email-letter.d.ts.map +1 -1
  173. package/dist/detectors/email-letter.js +76 -14
  174. package/dist/detectors/email-letter.js.map +1 -1
  175. package/dist/detectors/en-shape.d.ts.map +1 -1
  176. package/dist/detectors/en-shape.js +5 -1
  177. package/dist/detectors/en-shape.js.map +1 -1
  178. package/dist/detectors/fact-consistency.d.ts.map +1 -1
  179. package/dist/detectors/fact-consistency.js +3 -2
  180. package/dist/detectors/fact-consistency.js.map +1 -1
  181. package/dist/detectors/field-label.d.ts +7 -0
  182. package/dist/detectors/field-label.d.ts.map +1 -0
  183. package/dist/detectors/field-label.js +23 -0
  184. package/dist/detectors/field-label.js.map +1 -0
  185. package/dist/detectors/footnote-mismatch.d.ts +6 -1
  186. package/dist/detectors/footnote-mismatch.d.ts.map +1 -1
  187. package/dist/detectors/footnote-mismatch.js +28 -7
  188. package/dist/detectors/footnote-mismatch.js.map +1 -1
  189. package/dist/detectors/graded-step.d.ts +20 -0
  190. package/dist/detectors/graded-step.d.ts.map +1 -0
  191. package/dist/detectors/graded-step.js +33 -0
  192. package/dist/detectors/graded-step.js.map +1 -0
  193. package/dist/detectors/gram-openers.d.ts +8 -0
  194. package/dist/detectors/gram-openers.d.ts.map +1 -0
  195. package/dist/detectors/gram-openers.js +16 -0
  196. package/dist/detectors/gram-openers.js.map +1 -0
  197. package/dist/detectors/gram-passages.d.ts +11 -0
  198. package/dist/detectors/gram-passages.d.ts.map +1 -0
  199. package/dist/detectors/gram-passages.js +26 -0
  200. package/dist/detectors/gram-passages.js.map +1 -0
  201. package/dist/detectors/gram-place.d.ts +3 -1
  202. package/dist/detectors/gram-place.d.ts.map +1 -1
  203. package/dist/detectors/gram-place.js +8 -0
  204. package/dist/detectors/gram-place.js.map +1 -1
  205. package/dist/detectors/gram-predicate.d.ts.map +1 -1
  206. package/dist/detectors/gram-predicate.js +37 -3
  207. package/dist/detectors/gram-predicate.js.map +1 -1
  208. package/dist/detectors/heading-echo.d.ts.map +1 -1
  209. package/dist/detectors/heading-echo.js +28 -2
  210. package/dist/detectors/heading-echo.js.map +1 -1
  211. package/dist/detectors/heading-end-mark.d.ts +8 -3
  212. package/dist/detectors/heading-end-mark.d.ts.map +1 -1
  213. package/dist/detectors/heading-end-mark.js +18 -8
  214. package/dist/detectors/heading-end-mark.js.map +1 -1
  215. package/dist/detectors/heading-names.d.ts +7 -0
  216. package/dist/detectors/heading-names.d.ts.map +1 -0
  217. package/dist/detectors/heading-names.js +24 -0
  218. package/dist/detectors/heading-names.js.map +1 -0
  219. package/dist/detectors/heading-numbering.d.ts.map +1 -1
  220. package/dist/detectors/heading-numbering.js +7 -2
  221. package/dist/detectors/heading-numbering.js.map +1 -1
  222. package/dist/detectors/ime-residue.d.ts +1 -1
  223. package/dist/detectors/ime-residue.d.ts.map +1 -1
  224. package/dist/detectors/ime-residue.js +4 -3
  225. package/dist/detectors/ime-residue.js.map +1 -1
  226. package/dist/detectors/inch-mark.d.ts +10 -0
  227. package/dist/detectors/inch-mark.d.ts.map +1 -0
  228. package/dist/detectors/inch-mark.js +48 -0
  229. package/dist/detectors/inch-mark.js.map +1 -0
  230. package/dist/detectors/kanji-compound-slip.d.ts +3 -0
  231. package/dist/detectors/kanji-compound-slip.d.ts.map +1 -0
  232. package/dist/detectors/kanji-compound-slip.js +50 -0
  233. package/dist/detectors/kanji-compound-slip.js.map +1 -0
  234. package/dist/detectors/kutoten-consistency.d.ts +10 -2
  235. package/dist/detectors/kutoten-consistency.d.ts.map +1 -1
  236. package/dist/detectors/kutoten-consistency.js +76 -12
  237. package/dist/detectors/kutoten-consistency.js.map +1 -1
  238. package/dist/detectors/lexicon.d.ts +0 -1
  239. package/dist/detectors/lexicon.d.ts.map +1 -1
  240. package/dist/detectors/lexicon.js +37 -25
  241. package/dist/detectors/lexicon.js.map +1 -1
  242. package/dist/detectors/link-shape.d.ts.map +1 -1
  243. package/dist/detectors/link-shape.js +9 -3
  244. package/dist/detectors/link-shape.js.map +1 -1
  245. package/dist/detectors/list-item-ending.d.ts +18 -0
  246. package/dist/detectors/list-item-ending.d.ts.map +1 -0
  247. package/dist/detectors/list-item-ending.js +35 -0
  248. package/dist/detectors/list-item-ending.js.map +1 -0
  249. package/dist/detectors/list-parallel.d.ts +18 -5
  250. package/dist/detectors/list-parallel.d.ts.map +1 -1
  251. package/dist/detectors/list-parallel.js +116 -36
  252. package/dist/detectors/list-parallel.js.map +1 -1
  253. package/dist/detectors/list-sentence.d.ts +4 -0
  254. package/dist/detectors/list-sentence.d.ts.map +1 -1
  255. package/dist/detectors/list-sentence.js +1 -1
  256. package/dist/detectors/list-sentence.js.map +1 -1
  257. package/dist/detectors/mark-shape.d.ts +15 -5
  258. package/dist/detectors/mark-shape.d.ts.map +1 -1
  259. package/dist/detectors/mark-shape.js +64 -10
  260. package/dist/detectors/mark-shape.js.map +1 -1
  261. package/dist/detectors/mentioned-phrase.d.ts +9 -0
  262. package/dist/detectors/mentioned-phrase.d.ts.map +1 -0
  263. package/dist/detectors/mentioned-phrase.js +25 -0
  264. package/dist/detectors/mentioned-phrase.js.map +1 -0
  265. package/dist/detectors/middle-dot.d.ts +2 -2
  266. package/dist/detectors/middle-dot.d.ts.map +1 -1
  267. package/dist/detectors/middle-dot.js +4 -2
  268. package/dist/detectors/middle-dot.js.map +1 -1
  269. package/dist/detectors/modal-conflict.d.ts.map +1 -1
  270. package/dist/detectors/modal-conflict.js +5 -2
  271. package/dist/detectors/modal-conflict.js.map +1 -1
  272. package/dist/detectors/name-variant-apart.d.ts +27 -0
  273. package/dist/detectors/name-variant-apart.d.ts.map +1 -0
  274. package/dist/detectors/name-variant-apart.js +51 -0
  275. package/dist/detectors/name-variant-apart.js.map +1 -0
  276. package/dist/detectors/name-variant.d.ts.map +1 -1
  277. package/dist/detectors/name-variant.js +18 -11
  278. package/dist/detectors/name-variant.js.map +1 -1
  279. package/dist/detectors/notice-paragraph.d.ts +9 -0
  280. package/dist/detectors/notice-paragraph.d.ts.map +1 -0
  281. package/dist/detectors/notice-paragraph.js +21 -0
  282. package/dist/detectors/notice-paragraph.js.map +1 -0
  283. package/dist/detectors/number-style.d.ts.map +1 -1
  284. package/dist/detectors/number-style.js +15 -2
  285. package/dist/detectors/number-style.js.map +1 -1
  286. package/dist/detectors/number-unit.d.ts.map +1 -1
  287. package/dist/detectors/number-unit.js +24 -1
  288. package/dist/detectors/number-unit.js.map +1 -1
  289. package/dist/detectors/numeral-opener.d.ts +6 -0
  290. package/dist/detectors/numeral-opener.d.ts.map +1 -1
  291. package/dist/detectors/numeral-opener.js +24 -1
  292. package/dist/detectors/numeral-opener.js.map +1 -1
  293. package/dist/detectors/numeral-word.d.ts +15 -0
  294. package/dist/detectors/numeral-word.d.ts.map +1 -0
  295. package/dist/detectors/numeral-word.js +26 -0
  296. package/dist/detectors/numeral-word.js.map +1 -0
  297. package/dist/detectors/obligation-without-deadline.d.ts +5 -1
  298. package/dist/detectors/obligation-without-deadline.d.ts.map +1 -1
  299. package/dist/detectors/obligation-without-deadline.js +44 -23
  300. package/dist/detectors/obligation-without-deadline.js.map +1 -1
  301. package/dist/detectors/open-end-class.d.ts +16 -0
  302. package/dist/detectors/open-end-class.d.ts.map +1 -0
  303. package/dist/detectors/open-end-class.js +65 -0
  304. package/dist/detectors/open-end-class.js.map +1 -0
  305. package/dist/detectors/open-end-condition.d.ts +7 -0
  306. package/dist/detectors/open-end-condition.d.ts.map +1 -0
  307. package/dist/detectors/open-end-condition.js +35 -0
  308. package/dist/detectors/open-end-condition.js.map +1 -0
  309. package/dist/detectors/open-end-names.d.ts +9 -3
  310. package/dist/detectors/open-end-names.d.ts.map +1 -1
  311. package/dist/detectors/open-end-names.js +5 -2
  312. package/dist/detectors/open-end-names.js.map +1 -1
  313. package/dist/detectors/open-end-question.d.ts +15 -0
  314. package/dist/detectors/open-end-question.d.ts.map +1 -0
  315. package/dist/detectors/open-end-question.js +37 -0
  316. package/dist/detectors/open-end-question.js.map +1 -0
  317. package/dist/detectors/open-end-scope.d.ts +16 -0
  318. package/dist/detectors/open-end-scope.d.ts.map +1 -0
  319. package/dist/detectors/open-end-scope.js +47 -0
  320. package/dist/detectors/open-end-scope.js.map +1 -0
  321. package/dist/detectors/opening-date.d.ts +10 -0
  322. package/dist/detectors/opening-date.d.ts.map +1 -0
  323. package/dist/detectors/opening-date.js +33 -0
  324. package/dist/detectors/opening-date.js.map +1 -0
  325. package/dist/detectors/ordinary-phrase.d.ts +20 -0
  326. package/dist/detectors/ordinary-phrase.d.ts.map +1 -0
  327. package/dist/detectors/ordinary-phrase.js +54 -0
  328. package/dist/detectors/ordinary-phrase.js.map +1 -0
  329. package/dist/detectors/organisation-run.d.ts +18 -0
  330. package/dist/detectors/organisation-run.d.ts.map +1 -0
  331. package/dist/detectors/organisation-run.js +80 -0
  332. package/dist/detectors/organisation-run.js.map +1 -0
  333. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  334. package/dist/detectors/orthographic-variant.js +65 -21
  335. package/dist/detectors/orthographic-variant.js.map +1 -1
  336. package/dist/detectors/orthography.d.ts.map +1 -1
  337. package/dist/detectors/orthography.js +6 -1
  338. package/dist/detectors/orthography.js.map +1 -1
  339. package/dist/detectors/outline-label.d.ts +14 -0
  340. package/dist/detectors/outline-label.d.ts.map +1 -0
  341. package/dist/detectors/outline-label.js +32 -0
  342. package/dist/detectors/outline-label.js.map +1 -0
  343. package/dist/detectors/oxford-comma.d.ts.map +1 -1
  344. package/dist/detectors/oxford-comma.js +38 -1
  345. package/dist/detectors/oxford-comma.js.map +1 -1
  346. package/dist/detectors/page-marker.d.ts +6 -0
  347. package/dist/detectors/page-marker.d.ts.map +1 -0
  348. package/dist/detectors/page-marker.js +19 -0
  349. package/dist/detectors/page-marker.js.map +1 -0
  350. package/dist/detectors/parallel-definition.d.ts +16 -0
  351. package/dist/detectors/parallel-definition.d.ts.map +1 -0
  352. package/dist/detectors/parallel-definition.js +51 -0
  353. package/dist/detectors/parallel-definition.js.map +1 -0
  354. package/dist/detectors/person-consistency.d.ts +2 -1
  355. package/dist/detectors/person-consistency.d.ts.map +1 -1
  356. package/dist/detectors/person-consistency.js +5 -3
  357. package/dist/detectors/person-consistency.js.map +1 -1
  358. package/dist/detectors/phrase-match.d.ts +2 -0
  359. package/dist/detectors/phrase-match.d.ts.map +1 -1
  360. package/dist/detectors/phrase-match.js +11 -4
  361. package/dist/detectors/phrase-match.js.map +1 -1
  362. package/dist/detectors/placeholder-text.d.ts.map +1 -1
  363. package/dist/detectors/placeholder-text.js +18 -3
  364. package/dist/detectors/placeholder-text.js.map +1 -1
  365. package/dist/detectors/placeholder.d.ts +3 -1
  366. package/dist/detectors/placeholder.d.ts.map +1 -1
  367. package/dist/detectors/placeholder.js +8 -3
  368. package/dist/detectors/placeholder.js.map +1 -1
  369. package/dist/detectors/postcode-end.d.ts +3 -0
  370. package/dist/detectors/postcode-end.d.ts.map +1 -0
  371. package/dist/detectors/postcode-end.js +15 -0
  372. package/dist/detectors/postcode-end.js.map +1 -0
  373. package/dist/detectors/prose-total-words.d.ts +5 -0
  374. package/dist/detectors/prose-total-words.d.ts.map +1 -0
  375. package/dist/detectors/prose-total-words.js +14 -0
  376. package/dist/detectors/prose-total-words.js.map +1 -0
  377. package/dist/detectors/reference-text.d.ts.map +1 -1
  378. package/dist/detectors/reference-text.js +1 -0
  379. package/dist/detectors/reference-text.js.map +1 -1
  380. package/dist/detectors/registry/kanji-compound-slip.d.ts +3 -0
  381. package/dist/detectors/registry/kanji-compound-slip.d.ts.map +1 -0
  382. package/dist/detectors/registry/kanji-compound-slip.js +3 -0
  383. package/dist/detectors/registry/kanji-compound-slip.js.map +1 -0
  384. package/dist/detectors/registry/phrase-in-use.d.ts +3 -0
  385. package/dist/detectors/registry/phrase-in-use.d.ts.map +1 -0
  386. package/dist/detectors/registry/phrase-in-use.js +3 -0
  387. package/dist/detectors/registry/phrase-in-use.js.map +1 -0
  388. package/dist/detectors/registry/unfilled-placeholder.d.ts.map +1 -1
  389. package/dist/detectors/registry/unfilled-placeholder.js +2 -2
  390. package/dist/detectors/registry/unfilled-placeholder.js.map +1 -1
  391. package/dist/detectors/registry/vague-density.js +1 -1
  392. package/dist/detectors/registry/vague-density.js.map +1 -1
  393. package/dist/detectors/request-owner.d.ts +6 -2
  394. package/dist/detectors/request-owner.d.ts.map +1 -1
  395. package/dist/detectors/request-owner.js +57 -7
  396. package/dist/detectors/request-owner.js.map +1 -1
  397. package/dist/detectors/requirement-smell.d.ts.map +1 -1
  398. package/dist/detectors/requirement-smell.js +39 -7
  399. package/dist/detectors/requirement-smell.js.map +1 -1
  400. package/dist/detectors/scaled-figure-unit.d.ts +28 -0
  401. package/dist/detectors/scaled-figure-unit.d.ts.map +1 -0
  402. package/dist/detectors/scaled-figure-unit.js +78 -0
  403. package/dist/detectors/scaled-figure-unit.js.map +1 -0
  404. package/dist/detectors/sentence-counts.d.ts +2 -0
  405. package/dist/detectors/sentence-counts.d.ts.map +1 -1
  406. package/dist/detectors/sentence-counts.js +18 -7
  407. package/dist/detectors/sentence-counts.js.map +1 -1
  408. package/dist/detectors/sentence-ending.d.ts +2 -0
  409. package/dist/detectors/sentence-ending.d.ts.map +1 -1
  410. package/dist/detectors/sentence-ending.js +10 -3
  411. package/dist/detectors/sentence-ending.js.map +1 -1
  412. package/dist/detectors/sentence-length.d.ts.map +1 -1
  413. package/dist/detectors/sentence-length.js +24 -16
  414. package/dist/detectors/sentence-length.js.map +1 -1
  415. package/dist/detectors/sentence-load.d.ts +4 -1
  416. package/dist/detectors/sentence-load.d.ts.map +1 -1
  417. package/dist/detectors/sentence-load.js +9 -2
  418. package/dist/detectors/sentence-load.js.map +1 -1
  419. package/dist/detectors/sentence-rhythm.d.ts.map +1 -1
  420. package/dist/detectors/sentence-rhythm.js +6 -3
  421. package/dist/detectors/sentence-rhythm.js.map +1 -1
  422. package/dist/detectors/series-label.d.ts +2 -1
  423. package/dist/detectors/series-label.d.ts.map +1 -1
  424. package/dist/detectors/series-label.js +10 -4
  425. package/dist/detectors/series-label.js.map +1 -1
  426. package/dist/detectors/signals.d.ts +4 -0
  427. package/dist/detectors/signals.d.ts.map +1 -1
  428. package/dist/detectors/signals.js +91 -52
  429. package/dist/detectors/signals.js.map +1 -1
  430. package/dist/detectors/structure-tree.d.ts.map +1 -1
  431. package/dist/detectors/structure-tree.js +21 -19
  432. package/dist/detectors/structure-tree.js.map +1 -1
  433. package/dist/detectors/structure.d.ts.map +1 -1
  434. package/dist/detectors/structure.js +2 -1
  435. package/dist/detectors/structure.js.map +1 -1
  436. package/dist/detectors/subject-name-line.d.ts +8 -0
  437. package/dist/detectors/subject-name-line.d.ts.map +1 -0
  438. package/dist/detectors/subject-name-line.js +53 -0
  439. package/dist/detectors/subject-name-line.js.map +1 -0
  440. package/dist/detectors/table-header.d.ts.map +1 -1
  441. package/dist/detectors/table-header.js +13 -1
  442. package/dist/detectors/table-header.js.map +1 -1
  443. package/dist/detectors/technical-docs.d.ts.map +1 -1
  444. package/dist/detectors/technical-docs.js +4 -1
  445. package/dist/detectors/technical-docs.js.map +1 -1
  446. package/dist/detectors/template-sections.d.ts +14 -0
  447. package/dist/detectors/template-sections.d.ts.map +1 -0
  448. package/dist/detectors/template-sections.js +25 -0
  449. package/dist/detectors/template-sections.js.map +1 -0
  450. package/dist/detectors/term-mention-sentence.d.ts +4 -0
  451. package/dist/detectors/term-mention-sentence.d.ts.map +1 -0
  452. package/dist/detectors/term-mention-sentence.js +28 -0
  453. package/dist/detectors/term-mention-sentence.js.map +1 -0
  454. package/dist/detectors/titled-run.d.ts +23 -0
  455. package/dist/detectors/titled-run.d.ts.map +1 -0
  456. package/dist/detectors/titled-run.js +39 -0
  457. package/dist/detectors/titled-run.js.map +1 -0
  458. package/dist/detectors/token-shape.d.ts.map +1 -1
  459. package/dist/detectors/token-shape.js +13 -5
  460. package/dist/detectors/token-shape.js.map +1 -1
  461. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
  462. package/dist/detectors/unbalanced-bracket.js +4 -0
  463. package/dist/detectors/unbalanced-bracket.js.map +1 -1
  464. package/dist/detectors/undefined-term.d.ts.map +1 -1
  465. package/dist/detectors/undefined-term.js +8 -0
  466. package/dist/detectors/undefined-term.js.map +1 -1
  467. package/dist/detectors/unfilled-placeholder.d.ts +4 -0
  468. package/dist/detectors/unfilled-placeholder.d.ts.map +1 -0
  469. package/dist/detectors/unfilled-placeholder.js +9 -0
  470. package/dist/detectors/unfilled-placeholder.js.map +1 -0
  471. package/dist/detectors/vague-density.d.ts +8 -0
  472. package/dist/detectors/vague-density.d.ts.map +1 -0
  473. package/dist/detectors/vague-density.js +65 -0
  474. package/dist/detectors/vague-density.js.map +1 -0
  475. package/dist/document-paragraphs.d.ts +4 -0
  476. package/dist/document-paragraphs.d.ts.map +1 -0
  477. package/dist/document-paragraphs.js +24 -0
  478. package/dist/document-paragraphs.js.map +1 -0
  479. package/dist/document.d.ts.map +1 -1
  480. package/dist/document.js +2 -19
  481. package/dist/document.js.map +1 -1
  482. package/dist/facts/fact-scope.d.ts +10 -1
  483. package/dist/facts/fact-scope.d.ts.map +1 -1
  484. package/dist/facts/fact-scope.js +34 -3
  485. package/dist/facts/fact-scope.js.map +1 -1
  486. package/dist/facts/table-facts.d.ts +12 -2
  487. package/dist/facts/table-facts.d.ts.map +1 -1
  488. package/dist/facts/table-facts.js +22 -4
  489. package/dist/facts/table-facts.js.map +1 -1
  490. package/dist/figure-references.d.ts +3 -0
  491. package/dist/figure-references.d.ts.map +1 -1
  492. package/dist/figure-references.js +6 -2
  493. package/dist/figure-references.js.map +1 -1
  494. package/dist/format-template.d.ts +3 -0
  495. package/dist/format-template.d.ts.map +1 -0
  496. package/dist/format-template.js +13 -0
  497. package/dist/format-template.js.map +1 -0
  498. package/dist/formula-brackets.d.ts +7 -0
  499. package/dist/formula-brackets.d.ts.map +1 -0
  500. package/dist/formula-brackets.js +29 -0
  501. package/dist/formula-brackets.js.map +1 -0
  502. package/dist/grade-api.d.ts +9 -2
  503. package/dist/grade-api.d.ts.map +1 -1
  504. package/dist/grade-api.js +31 -15
  505. package/dist/grade-api.js.map +1 -1
  506. package/dist/heading-numbering.d.ts +5 -2
  507. package/dist/heading-numbering.d.ts.map +1 -1
  508. package/dist/heading-numbering.js +27 -6
  509. package/dist/heading-numbering.js.map +1 -1
  510. package/dist/html/html-markdown.d.ts.map +1 -1
  511. package/dist/html/html-markdown.js +2 -1
  512. package/dist/html/html-markdown.js.map +1 -1
  513. package/dist/html/html-site-chrome.d.ts +5 -0
  514. package/dist/html/html-site-chrome.d.ts.map +1 -0
  515. package/dist/html/html-site-chrome.js +33 -0
  516. package/dist/html/html-site-chrome.js.map +1 -0
  517. package/dist/joined-view.d.ts.map +1 -1
  518. package/dist/joined-view.js +1 -0
  519. package/dist/joined-view.js.map +1 -1
  520. package/dist/kanji-compound-slip.d.ts +32 -0
  521. package/dist/kanji-compound-slip.d.ts.map +1 -0
  522. package/dist/kanji-compound-slip.js +63 -0
  523. package/dist/kanji-compound-slip.js.map +1 -0
  524. package/dist/latin-company-form.d.ts +6 -0
  525. package/dist/latin-company-form.d.ts.map +1 -0
  526. package/dist/latin-company-form.js +32 -0
  527. package/dist/latin-company-form.js.map +1 -0
  528. package/dist/latin-word-boundary.d.ts +15 -0
  529. package/dist/latin-word-boundary.d.ts.map +1 -0
  530. package/dist/latin-word-boundary.js +40 -0
  531. package/dist/latin-word-boundary.js.map +1 -0
  532. package/dist/lexicon-genres.d.ts +2 -0
  533. package/dist/lexicon-genres.d.ts.map +1 -1
  534. package/dist/lexicon-genres.js +1 -1
  535. package/dist/lexicon-genres.js.map +1 -1
  536. package/dist/link-shape.d.ts +5 -0
  537. package/dist/link-shape.d.ts.map +1 -1
  538. package/dist/link-shape.js +18 -0
  539. package/dist/link-shape.js.map +1 -1
  540. package/dist/link-title.d.ts +4 -0
  541. package/dist/link-title.d.ts.map +1 -0
  542. package/dist/link-title.js +33 -0
  543. package/dist/link-title.js.map +1 -0
  544. package/dist/list-item-paragraphs.d.ts +15 -0
  545. package/dist/list-item-paragraphs.d.ts.map +1 -0
  546. package/dist/list-item-paragraphs.js +19 -0
  547. package/dist/list-item-paragraphs.js.map +1 -0
  548. package/dist/literal-quote.d.ts +12 -0
  549. package/dist/literal-quote.d.ts.map +1 -0
  550. package/dist/literal-quote.js +43 -0
  551. package/dist/literal-quote.js.map +1 -0
  552. package/dist/nado-closed-list.d.ts.map +1 -1
  553. package/dist/nado-closed-list.js +39 -5
  554. package/dist/nado-closed-list.js.map +1 -1
  555. package/dist/name-end-letter.d.ts +5 -0
  556. package/dist/name-end-letter.d.ts.map +1 -1
  557. package/dist/name-end-letter.js +8 -0
  558. package/dist/name-end-letter.js.map +1 -1
  559. package/dist/name-given-before.d.ts +15 -0
  560. package/dist/name-given-before.d.ts.map +1 -0
  561. package/dist/name-given-before.js +30 -0
  562. package/dist/name-given-before.js.map +1 -0
  563. package/dist/name-separator.d.ts +2 -2
  564. package/dist/name-separator.d.ts.map +1 -1
  565. package/dist/name-separator.js +79 -5
  566. package/dist/name-separator.js.map +1 -1
  567. package/dist/name-variants.d.ts +3 -1
  568. package/dist/name-variants.d.ts.map +1 -1
  569. package/dist/name-variants.js +8 -7
  570. package/dist/name-variants.js.map +1 -1
  571. package/dist/name-word-order.d.ts +9 -5
  572. package/dist/name-word-order.d.ts.map +1 -1
  573. package/dist/name-word-order.js +47 -15
  574. package/dist/name-word-order.js.map +1 -1
  575. package/dist/nominal-stem.d.ts +26 -0
  576. package/dist/nominal-stem.d.ts.map +1 -0
  577. package/dist/nominal-stem.js +70 -0
  578. package/dist/nominal-stem.js.map +1 -0
  579. package/dist/person-forms.d.ts +8 -0
  580. package/dist/person-forms.d.ts.map +1 -1
  581. package/dist/person-forms.js +12 -0
  582. package/dist/person-forms.js.map +1 -1
  583. package/dist/plugin.d.ts +5 -0
  584. package/dist/plugin.d.ts.map +1 -1
  585. package/dist/preamble-paragraphs.d.ts +3 -2
  586. package/dist/preamble-paragraphs.d.ts.map +1 -1
  587. package/dist/preamble-paragraphs.js +8 -2
  588. package/dist/preamble-paragraphs.js.map +1 -1
  589. package/dist/sentence-load.d.ts +2 -1
  590. package/dist/sentence-load.d.ts.map +1 -1
  591. package/dist/sentence-load.js +6 -2
  592. package/dist/sentence-load.js.map +1 -1
  593. package/dist/spacing-code.d.ts +1 -0
  594. package/dist/spacing-code.d.ts.map +1 -1
  595. package/dist/spacing-code.js +4 -1
  596. package/dist/spacing-code.js.map +1 -1
  597. package/dist/split-noun.d.ts +10 -0
  598. package/dist/split-noun.d.ts.map +1 -0
  599. package/dist/split-noun.js +50 -0
  600. package/dist/split-noun.js.map +1 -0
  601. package/dist/structure/attached-parts.d.ts +11 -0
  602. package/dist/structure/attached-parts.d.ts.map +1 -0
  603. package/dist/structure/attached-parts.js +31 -0
  604. package/dist/structure/attached-parts.js.map +1 -0
  605. package/dist/structure/build.d.ts.map +1 -1
  606. package/dist/structure/build.js +7 -4
  607. package/dist/structure/build.js.map +1 -1
  608. package/dist/structure/cited-document-section.d.ts +7 -0
  609. package/dist/structure/cited-document-section.d.ts.map +1 -0
  610. package/dist/structure/cited-document-section.js +33 -0
  611. package/dist/structure/cited-document-section.js.map +1 -0
  612. package/dist/structure/contents-lines.d.ts +7 -0
  613. package/dist/structure/contents-lines.d.ts.map +1 -0
  614. package/dist/structure/contents-lines.js +51 -0
  615. package/dist/structure/contents-lines.js.map +1 -0
  616. package/dist/structure/defining-names.d.ts +37 -0
  617. package/dist/structure/defining-names.d.ts.map +1 -0
  618. package/dist/structure/defining-names.js +122 -0
  619. package/dist/structure/defining-names.js.map +1 -0
  620. package/dist/structure/definition-use.d.ts +3 -2
  621. package/dist/structure/definition-use.d.ts.map +1 -1
  622. package/dist/structure/definition-use.js +99 -31
  623. package/dist/structure/definition-use.js.map +1 -1
  624. package/dist/structure/html-text-blocks.d.ts +8 -0
  625. package/dist/structure/html-text-blocks.d.ts.map +1 -0
  626. package/dist/structure/html-text-blocks.js +47 -0
  627. package/dist/structure/html-text-blocks.js.map +1 -0
  628. package/dist/structure/issues.d.ts +5 -2
  629. package/dist/structure/issues.d.ts.map +1 -1
  630. package/dist/structure/issues.js +24 -6
  631. package/dist/structure/issues.js.map +1 -1
  632. package/dist/structure/labelled-date-order.d.ts +4 -1
  633. package/dist/structure/labelled-date-order.d.ts.map +1 -1
  634. package/dist/structure/labelled-date-order.js +2 -2
  635. package/dist/structure/labelled-date-order.js.map +1 -1
  636. package/dist/structure/labelled-order.d.ts +3 -0
  637. package/dist/structure/labelled-order.d.ts.map +1 -1
  638. package/dist/structure/labelled-order.js +8 -3
  639. package/dist/structure/labelled-order.js.map +1 -1
  640. package/dist/structure/list-lead-in.d.ts +19 -0
  641. package/dist/structure/list-lead-in.d.ts.map +1 -0
  642. package/dist/structure/list-lead-in.js +85 -0
  643. package/dist/structure/list-lead-in.js.map +1 -0
  644. package/dist/structure/list-numbering.d.ts +20 -4
  645. package/dist/structure/list-numbering.d.ts.map +1 -1
  646. package/dist/structure/list-numbering.js +65 -9
  647. package/dist/structure/list-numbering.js.map +1 -1
  648. package/dist/structure/listed-paragraph.d.ts +16 -0
  649. package/dist/structure/listed-paragraph.d.ts.map +1 -0
  650. package/dist/structure/listed-paragraph.js +37 -0
  651. package/dist/structure/listed-paragraph.js.map +1 -0
  652. package/dist/structure/modal-conflict.d.ts +7 -2
  653. package/dist/structure/modal-conflict.d.ts.map +1 -1
  654. package/dist/structure/modal-conflict.js +36 -7
  655. package/dist/structure/modal-conflict.js.map +1 -1
  656. package/dist/structure/negated-act.d.ts +17 -0
  657. package/dist/structure/negated-act.d.ts.map +1 -0
  658. package/dist/structure/negated-act.js +32 -0
  659. package/dist/structure/negated-act.js.map +1 -0
  660. package/dist/structure/numbering.d.ts +5 -2
  661. package/dist/structure/numbering.d.ts.map +1 -1
  662. package/dist/structure/numbering.js +49 -12
  663. package/dist/structure/numbering.js.map +1 -1
  664. package/dist/structure/prose-total.d.ts +4 -0
  665. package/dist/structure/prose-total.d.ts.map +1 -1
  666. package/dist/structure/prose-total.js +16 -6
  667. package/dist/structure/prose-total.js.map +1 -1
  668. package/dist/structure/reference-text.d.ts +9 -1
  669. package/dist/structure/reference-text.d.ts.map +1 -1
  670. package/dist/structure/reference-text.js +21 -3
  671. package/dist/structure/reference-text.js.map +1 -1
  672. package/dist/structure/repeated-number.d.ts +24 -0
  673. package/dist/structure/repeated-number.d.ts.map +1 -0
  674. package/dist/structure/repeated-number.js +89 -0
  675. package/dist/structure/repeated-number.js.map +1 -0
  676. package/dist/structure/rounded-amount.d.ts +8 -0
  677. package/dist/structure/rounded-amount.d.ts.map +1 -0
  678. package/dist/structure/rounded-amount.js +48 -0
  679. package/dist/structure/rounded-amount.js.map +1 -0
  680. package/dist/structure/section-names.d.ts +12 -0
  681. package/dist/structure/section-names.d.ts.map +1 -0
  682. package/dist/structure/section-names.js +26 -0
  683. package/dist/structure/section-names.js.map +1 -0
  684. package/dist/structure/side-step.d.ts +8 -0
  685. package/dist/structure/side-step.d.ts.map +1 -0
  686. package/dist/structure/side-step.js +21 -0
  687. package/dist/structure/side-step.js.map +1 -0
  688. package/dist/structure/spanned-label-blank.d.ts +8 -0
  689. package/dist/structure/spanned-label-blank.d.ts.map +1 -0
  690. package/dist/structure/spanned-label-blank.js +37 -0
  691. package/dist/structure/spanned-label-blank.js.map +1 -0
  692. package/dist/structure/universal.d.ts +3 -1
  693. package/dist/structure/universal.d.ts.map +1 -1
  694. package/dist/structure/universal.js +9 -2
  695. package/dist/structure/universal.js.map +1 -1
  696. package/dist/structure/unspaced-heading.d.ts +10 -0
  697. package/dist/structure/unspaced-heading.d.ts.map +1 -0
  698. package/dist/structure/unspaced-heading.js +24 -0
  699. package/dist/structure/unspaced-heading.js.map +1 -0
  700. package/dist/structure/versioned-label.d.ts +16 -0
  701. package/dist/structure/versioned-label.d.ts.map +1 -0
  702. package/dist/structure/versioned-label.js +48 -0
  703. package/dist/structure/versioned-label.js.map +1 -0
  704. package/dist/structure/written-headings.d.ts +31 -0
  705. package/dist/structure/written-headings.d.ts.map +1 -0
  706. package/dist/structure/written-headings.js +119 -0
  707. package/dist/structure/written-headings.js.map +1 -0
  708. package/dist/structure/written-list-path.d.ts +10 -0
  709. package/dist/structure/written-list-path.d.ts.map +1 -0
  710. package/dist/structure/written-list-path.js +37 -0
  711. package/dist/structure/written-list-path.js.map +1 -0
  712. package/dist/structure/written-resolve.d.ts +12 -0
  713. package/dist/structure/written-resolve.d.ts.map +1 -0
  714. package/dist/structure/written-resolve.js +55 -0
  715. package/dist/structure/written-resolve.js.map +1 -0
  716. package/dist/title-line.d.ts +21 -0
  717. package/dist/title-line.d.ts.map +1 -0
  718. package/dist/title-line.js +27 -0
  719. package/dist/title-line.js.map +1 -0
  720. package/package.json +3 -3
  721. package/rules/all-caps-shouting.yaml +2 -2
  722. package/rules/announced-count-mismatch.yaml +2 -2
  723. package/rules/bare-url-mix.yaml +2 -2
  724. package/rules/bracket-nesting.yaml +2 -2
  725. package/rules/bracket-width-consistency.yaml +2 -2
  726. package/rules/broken-link.yaml +2 -2
  727. package/rules/cliche.yaml +4 -3
  728. package/rules/code-fence-language-mix.yaml +2 -2
  729. package/rules/comparative-without-baseline.yaml +2 -2
  730. package/rules/concrete-evidence-density.yaml +2 -2
  731. package/rules/contraction-consistency.yaml +13 -13
  732. package/rules/dangling-figure-reference.yaml +2 -2
  733. package/rules/dangling-reference.yaml +2 -2
  734. package/rules/date-without-year.yaml +10 -2
  735. package/rules/defined-name-repeated.yaml +2 -2
  736. package/rules/defined-term-form.yaml +2 -2
  737. package/rules/doubled-punctuation.yaml +4 -4
  738. package/rules/doubled-word.yaml +2 -2
  739. package/rules/duplicate-definition.yaml +2 -2
  740. package/rules/duration-mismatch.yaml +2 -2
  741. package/rules/email-greeting-closing.yaml +2 -2
  742. package/rules/email-subject-length.yaml +2 -2
  743. package/rules/empty-table-cell.yaml +2 -2
  744. package/rules/fact-conflict.yaml +2 -2
  745. package/rules/footnote-mismatch.yaml +2 -2
  746. package/rules/heading-echo.yaml +2 -2
  747. package/rules/heading-end-punctuation-mix.yaml +2 -2
  748. package/rules/heading-numbering-mix.yaml +2 -2
  749. package/rules/ime-residue.yaml +2 -2
  750. package/rules/kanji-compound-slip.yaml +67 -0
  751. package/rules/kutoten-consistency.yaml +4 -4
  752. package/rules/latin-spacing.yaml +4 -4
  753. package/rules/list-item-form-mix.yaml +2 -2
  754. package/rules/max-kanji-continuous.yaml +7 -3
  755. package/rules/max-sentence-length.yaml +3 -2
  756. package/rules/modal-conflict.yaml +1 -0
  757. package/rules/nado-closed-list.yaml +2 -2
  758. package/rules/name-variant.yaml +2 -2
  759. package/rules/ngram-repetition.yaml +2 -2
  760. package/rules/no-doubled-joshi.yaml +2 -2
  761. package/rules/no-mixed-desumasu.yaml +3 -3
  762. package/rules/no-nakaguro-parallel.yaml +2 -0
  763. package/rules/number-without-unit.yaml +9 -4
  764. package/rules/numbering-gap.yaml +7 -2
  765. package/rules/numeral-sentence-start.yaml +2 -2
  766. package/rules/obligation-without-deadline.yaml +2 -2
  767. package/rules/orthographic-variant.yaml +2 -2
  768. package/rules/oxford-comma-consistency.yaml +3 -3
  769. package/rules/preamble-length.yaml +2 -2
  770. package/rules/reference-title-mismatch.yaml +2 -2
  771. package/rules/repeated-sentence-ending.yaml +3 -2
  772. package/rules/request-without-deadline.yaml +2 -2
  773. package/rules/requirement-smell.yaml +3 -3
  774. package/rules/sentence-rhythm.yaml +2 -2
  775. package/rules/table-header-variant.yaml +2 -2
  776. package/rules/teki-overuse.yaml +3 -2
  777. package/rules/title-case-consistency.yaml +2 -2
  778. package/rules/total-mismatch.yaml +2 -2
  779. package/rules/translationese-density.yaml +2 -2
  780. package/rules/unbalanced-bracket.yaml +2 -2
  781. package/rules/undefined-acronym.yaml +15 -4
  782. package/rules/undefined-term.yaml +2 -2
  783. package/rules/unfilled-placeholder.yaml +4 -4
  784. package/rules/use-before-definition.yaml +2 -2
  785. package/rules/vague-word-density.yaml +2 -2
  786. package/skills/chaff/SKILL.md +7 -1
  787. package/src/announced-count.ts +35 -8
  788. package/src/capitals-passage.ts +31 -0
  789. package/src/chronology-rows.ts +86 -0
  790. package/src/coined-hyphen-name.ts +27 -0
  791. package/src/company-name-run.ts +37 -0
  792. package/src/company-names.ts +24 -3
  793. package/src/compound-head.ts +25 -0
  794. package/src/date-format.ts +43 -4
  795. package/src/derived/count-per-period.ts +28 -0
  796. package/src/detectors/acronym-context.ts +34 -6
  797. package/src/detectors/acronym-definition.ts +123 -0
  798. package/src/detectors/acronym-expansion.ts +47 -6
  799. package/src/detectors/acronym-known.ts +40 -0
  800. package/src/detectors/acronym-link.ts +37 -0
  801. package/src/detectors/acronym-lone.ts +26 -0
  802. package/src/detectors/acronym-name.ts +140 -0
  803. package/src/detectors/addressee-edge.ts +16 -0
  804. package/src/detectors/announced-count.ts +1 -0
  805. package/src/detectors/bare-comparative.ts +44 -3
  806. package/src/detectors/blank-structure.ts +21 -10
  807. package/src/detectors/bracket-specified.ts +25 -0
  808. package/src/detectors/broken-link.ts +26 -2
  809. package/src/detectors/capitalised-term.ts +154 -4
  810. package/src/detectors/caps-caption.ts +103 -0
  811. package/src/detectors/caps-phrase.ts +17 -0
  812. package/src/detectors/char-shape.ts +99 -26
  813. package/src/detectors/cited-title.ts +15 -3
  814. package/src/detectors/clause-shape.ts +14 -4
  815. package/src/detectors/concrete-evidence.ts +77 -1
  816. package/src/detectors/contraction-minority.ts +11 -0
  817. package/src/detectors/counter-edge.ts +40 -2
  818. package/src/detectors/date-any-year.ts +79 -12
  819. package/src/detectors/date-format.ts +2 -1
  820. package/src/detectors/date-heading-year.ts +55 -0
  821. package/src/detectors/date-year.ts +107 -14
  822. package/src/detectors/deadline-unit.ts +40 -0
  823. package/src/detectors/defined-term-form.ts +58 -17
  824. package/src/detectors/definition-use.ts +7 -3
  825. package/src/detectors/derived-numbers.ts +19 -4
  826. package/src/detectors/doubled-across-aside.ts +36 -0
  827. package/src/detectors/doubled-punctuation.ts +28 -7
  828. package/src/detectors/doubled-word.ts +2 -1
  829. package/src/detectors/due-date.ts +10 -1
  830. package/src/detectors/ellipsis.ts +16 -1
  831. package/src/detectors/email-letter.ts +97 -21
  832. package/src/detectors/en-shape.ts +5 -1
  833. package/src/detectors/fact-consistency.ts +3 -2
  834. package/src/detectors/field-label.ts +25 -0
  835. package/src/detectors/footnote-mismatch.ts +39 -7
  836. package/src/detectors/graded-step.ts +52 -0
  837. package/src/detectors/gram-openers.ts +21 -0
  838. package/src/detectors/gram-passages.ts +36 -0
  839. package/src/detectors/gram-place.ts +10 -1
  840. package/src/detectors/gram-predicate.ts +43 -3
  841. package/src/detectors/heading-echo.ts +31 -3
  842. package/src/detectors/heading-end-mark.ts +23 -10
  843. package/src/detectors/heading-names.ts +31 -0
  844. package/src/detectors/heading-numbering.ts +7 -2
  845. package/src/detectors/ime-residue.ts +4 -3
  846. package/src/detectors/inch-mark.ts +49 -0
  847. package/src/detectors/kanji-compound-slip.ts +61 -0
  848. package/src/detectors/kutoten-consistency.ts +93 -14
  849. package/src/detectors/lexicon.ts +44 -24
  850. package/src/detectors/link-shape.ts +10 -3
  851. package/src/detectors/list-item-ending.ts +51 -0
  852. package/src/detectors/list-parallel.ts +158 -33
  853. package/src/detectors/list-sentence.ts +5 -1
  854. package/src/detectors/mark-shape.ts +70 -10
  855. package/src/detectors/mentioned-phrase.ts +38 -0
  856. package/src/detectors/middle-dot.ts +7 -2
  857. package/src/detectors/modal-conflict.ts +5 -2
  858. package/src/detectors/name-variant-apart.ts +63 -0
  859. package/src/detectors/name-variant.ts +30 -12
  860. package/src/detectors/notice-paragraph.ts +33 -0
  861. package/src/detectors/number-style.ts +14 -2
  862. package/src/detectors/number-unit.ts +28 -1
  863. package/src/detectors/numeral-opener.ts +27 -1
  864. package/src/detectors/numeral-word.ts +33 -0
  865. package/src/detectors/obligation-without-deadline.ts +29 -4
  866. package/src/detectors/open-end-class.ts +78 -0
  867. package/src/detectors/open-end-condition.ts +40 -0
  868. package/src/detectors/open-end-names.ts +9 -3
  869. package/src/detectors/open-end-question.ts +50 -0
  870. package/src/detectors/open-end-scope.ts +62 -0
  871. package/src/detectors/opening-date.ts +47 -0
  872. package/src/detectors/ordinary-phrase.ts +62 -0
  873. package/src/detectors/organisation-run.ts +97 -0
  874. package/src/detectors/orthographic-variant.ts +103 -27
  875. package/src/detectors/orthography.ts +10 -1
  876. package/src/detectors/outline-label.ts +48 -0
  877. package/src/detectors/oxford-comma.ts +40 -1
  878. package/src/detectors/page-marker.ts +26 -0
  879. package/src/detectors/parallel-definition.ts +64 -0
  880. package/src/detectors/person-consistency.ts +5 -3
  881. package/src/detectors/phrase-match.ts +16 -5
  882. package/src/detectors/placeholder-text.ts +18 -3
  883. package/src/detectors/placeholder.ts +10 -3
  884. package/src/detectors/postcode-end.ts +16 -0
  885. package/src/detectors/prose-total-words.ts +18 -0
  886. package/src/detectors/reference-text.ts +1 -0
  887. package/src/detectors/registry/kanji-compound-slip.ts +4 -0
  888. package/src/detectors/registry/phrase-in-use.ts +4 -0
  889. package/src/detectors/registry/unfilled-placeholder.ts +2 -2
  890. package/src/detectors/registry/vague-density.ts +1 -1
  891. package/src/detectors/request-owner.ts +71 -8
  892. package/src/detectors/requirement-smell.ts +53 -7
  893. package/src/detectors/scaled-figure-unit.ts +103 -0
  894. package/src/detectors/sentence-counts.ts +24 -8
  895. package/src/detectors/sentence-ending.ts +12 -3
  896. package/src/detectors/sentence-length.ts +14 -6
  897. package/src/detectors/sentence-load.ts +9 -2
  898. package/src/detectors/sentence-rhythm.ts +8 -4
  899. package/src/detectors/series-label.ts +13 -4
  900. package/src/detectors/signals.ts +105 -55
  901. package/src/detectors/structure-tree.ts +22 -20
  902. package/src/detectors/structure.ts +2 -1
  903. package/src/detectors/subject-name-line.ts +66 -0
  904. package/src/detectors/table-header.ts +15 -1
  905. package/src/detectors/technical-docs.ts +5 -1
  906. package/src/detectors/template-sections.ts +37 -0
  907. package/src/detectors/term-mention-sentence.ts +31 -0
  908. package/src/detectors/titled-run.ts +48 -0
  909. package/src/detectors/token-shape.ts +14 -5
  910. package/src/detectors/unbalanced-bracket.ts +3 -0
  911. package/src/detectors/undefined-term.ts +8 -0
  912. package/src/detectors/unfilled-placeholder.ts +10 -0
  913. package/src/detectors/vague-density.ts +84 -0
  914. package/src/document-paragraphs.ts +27 -0
  915. package/src/document.ts +3 -23
  916. package/src/facts/fact-scope.ts +53 -4
  917. package/src/facts/table-facts.ts +43 -6
  918. package/src/figure-references.ts +7 -2
  919. package/src/format-template.ts +15 -0
  920. package/src/formula-brackets.ts +36 -0
  921. package/src/grade-api.ts +38 -16
  922. package/src/heading-numbering.ts +35 -8
  923. package/src/html/html-markdown.ts +2 -1
  924. package/src/html/html-site-chrome.ts +47 -0
  925. package/src/joined-view.ts +1 -0
  926. package/src/kanji-compound-slip.ts +98 -0
  927. package/src/latin-company-form.ts +38 -0
  928. package/src/latin-word-boundary.ts +46 -0
  929. package/src/lexicon-genres.ts +1 -1
  930. package/src/link-shape.ts +19 -0
  931. package/src/link-title.ts +38 -0
  932. package/src/list-item-paragraphs.ts +22 -0
  933. package/src/literal-quote.ts +55 -0
  934. package/src/nado-closed-list.ts +48 -5
  935. package/src/name-end-letter.ts +9 -0
  936. package/src/name-given-before.ts +40 -0
  937. package/src/name-separator.ts +91 -5
  938. package/src/name-variants.ts +21 -11
  939. package/src/name-word-order.ts +62 -17
  940. package/src/nominal-stem.ts +93 -0
  941. package/src/person-forms.ts +15 -0
  942. package/src/plugin.ts +5 -0
  943. package/src/preamble-paragraphs.ts +13 -3
  944. package/src/sentence-load.ts +7 -2
  945. package/src/spacing-code.ts +5 -1
  946. package/src/split-noun.ts +63 -0
  947. package/src/structure/attached-parts.ts +32 -0
  948. package/src/structure/build.ts +7 -4
  949. package/src/structure/cited-document-section.ts +42 -0
  950. package/src/structure/contents-lines.ts +63 -0
  951. package/src/structure/defining-names.ts +155 -0
  952. package/src/structure/definition-use.ts +116 -25
  953. package/src/structure/html-text-blocks.ts +45 -0
  954. package/src/structure/issues.ts +26 -7
  955. package/src/structure/labelled-date-order.ts +5 -2
  956. package/src/structure/labelled-order.ts +12 -3
  957. package/src/structure/list-lead-in.ts +94 -0
  958. package/src/structure/list-numbering.ts +100 -11
  959. package/src/structure/listed-paragraph.ts +45 -0
  960. package/src/structure/modal-conflict.ts +42 -7
  961. package/src/structure/negated-act.ts +49 -0
  962. package/src/structure/numbering.ts +70 -26
  963. package/src/structure/prose-total.ts +20 -6
  964. package/src/structure/reference-text.ts +25 -3
  965. package/src/structure/repeated-number.ts +110 -0
  966. package/src/structure/rounded-amount.ts +55 -0
  967. package/src/structure/section-names.ts +32 -0
  968. package/src/structure/side-step.ts +21 -0
  969. package/src/structure/spanned-label-blank.ts +39 -0
  970. package/src/structure/universal.ts +11 -2
  971. package/src/structure/unspaced-heading.ts +27 -0
  972. package/src/structure/versioned-label.ts +52 -0
  973. package/src/structure/written-headings.ts +137 -0
  974. package/src/structure/written-list-path.ts +46 -0
  975. package/src/structure/written-resolve.ts +64 -0
  976. package/src/title-line.ts +52 -0
@@ -0,0 +1,66 @@
1
+ // A line under a heading that gives the name of what the heading is about, not a sentence restating it: the label of a
2
+ // link or an attachment the heading introduces (### 実施要綱について → 実施要綱), or a list named after the heading
3
+ // (## 皆さんの声 → 「皆さんの声」一覧). A converted page keeps such labels as plain lines. Pure.
4
+ import { isContent } from "./content-morphemes.ts";
5
+ import type { Token } from "../plugin.ts";
6
+
7
+ /** A title is made of these: names, the words that build a name (annual, の, of, and), no predicate. */
8
+ const TITLE_POS: ReadonlySet<string> = new Set(["NOUN", "PROPN", "NUM", "PUNCT", "SYM", "X", "ADJ", "ADP", "DET", "CCONJ"]);
9
+ /** A line that ends like a sentence says something, whatever its words. */
10
+ const SENTENCE_END = /[。..!?!?]$/u;
11
+
12
+ const isTitle = (tokens: readonly Token[]): boolean => tokens.some(isContent) && tokens.every((token) => TITLE_POS.has(token.pos));
13
+
14
+ const baseForm = (token: Token): string => (token.lemma ?? token.surface).toLowerCase();
15
+
16
+ /** Brackets a line quotes a title in. */
17
+ const QUOTES: readonly (readonly [string, string])[] = [
18
+ ["「", "」"],
19
+ ["『", "』"],
20
+ ["“", "”"],
21
+ ['"', '"'],
22
+ ];
23
+
24
+ type Span = { readonly start: number; readonly end: number };
25
+
26
+ /** Where the line quotes the whole heading as a title, in the tokens' coordinates. */
27
+ const quotedHeading = (heading: string, line: string, lineStart: number): Span | undefined => {
28
+ const quoted = QUOTES.map(([open, close]) => `${open}${heading}${close}`).find((form) => line.includes(form));
29
+ if (quoted === undefined) return undefined;
30
+ const start = lineStart + line.indexOf(quoted);
31
+ return { start, end: start + quoted.length };
32
+ };
33
+
34
+ /** 「見出し」一覧: the heading quoted as a title, and only a name after it that says what the line is (一覧, page). */
35
+ const namesListAfterHeading = (outside: readonly Token[]): boolean => isTitle(outside);
36
+
37
+ /**
38
+ * 実施要綱 under ### 実施要綱について: the line is a title, and what the heading has beyond it only frames the name (について,
39
+ * About, 紹介). A line that copies the heading whole (### 研究科 → 研究科) is a repeat, and one that drops a word of the
40
+ * heading's own (### 精算方法の概要 → 精算方法) does not name the heading's subject.
41
+ */
42
+ const namesHeadingTopic = (heading: readonly Token[], line: readonly Token[], announcing: ReadonlySet<string>): boolean => {
43
+ if (!isTitle(line)) return false;
44
+ const named = new Set(line.map(baseForm));
45
+ const beyond = heading.filter((token) => token.pos !== "PUNCT" && !named.has(baseForm(token)));
46
+ return beyond.length > 0 && beyond.every((token) => !isContent(token) || announcing.has(baseForm(token)));
47
+ };
48
+
49
+ /**
50
+ * The first line under a heading names what the heading is about. `heading` is the heading's text without its number
51
+ * label, `headingTokens` its tokens; `lineTokens` are the line's, in the coordinates `lineStart` gives. `announcing`
52
+ * holds the words that only frame a subject (the heading-announcer lexicon's ungrouped entries).
53
+ */
54
+ export const namesHeadingSubject = (
55
+ heading: string,
56
+ headingTokens: readonly Token[],
57
+ line: string,
58
+ lineStart: number,
59
+ lineTokens: readonly Token[],
60
+ announcing: ReadonlySet<string>,
61
+ ): boolean => {
62
+ if (line.trim().includes("\n") || SENTENCE_END.test(line.trim()) || heading.trim() === "") return false;
63
+ const quoted = quotedHeading(heading.trim(), line, lineStart);
64
+ if (quoted !== undefined) return namesListAfterHeading(lineTokens.filter((token) => token.span.start < quoted.start || token.span.start >= quoted.end));
65
+ return namesHeadingTopic(headingTokens, lineTokens, announcing);
66
+ };
@@ -53,7 +53,21 @@ const rawCells = (line: Line): { readonly raw: string; readonly from: number }[]
53
53
  return inner.at(-1)?.raw.trim() === "" ? inner.slice(0, -1) : inner;
54
54
  };
55
55
 
56
- const labelCell = (line: Line, { raw, from }: { readonly raw: string; readonly from: number }): HeaderCell[] => {
56
+ /**
57
+ * An inline HTML tag in a cell (`<div style="…">`, `</div>`, `<br/>`): the reader sees none of it. A tag name ends at a space,
58
+ * a slash or `>`, so an autolink (`<https://…>`) is not one; an attribute in double quotes may hold a `>`.
59
+ */
60
+ const HTML_TAG = /<\/?[A-Za-z][\w-]*(?:\s(?:"[^"]*"|[^<>"])*)?\/?>/gu;
61
+
62
+ /**
63
+ * The cell with its HTML tags blanked out, same length, so the words keep their offsets and the spaces around them trim.
64
+ * A cell with a code span is left whole: a tag written in code is text the reader sees.
65
+ */
66
+ const withoutTags = (raw: string): string => (raw.includes("`") ? raw : raw.replace(HTML_TAG, (tag) => " ".repeat(tag.length)));
67
+
68
+ const labelCell = (line: Line, cell: { readonly raw: string; readonly from: number }): HeaderCell[] => {
69
+ const { from } = cell;
70
+ const raw = withoutTags(cell.raw);
57
71
  const trimmed = raw.trim();
58
72
  const unwrapped = unwrap(trimmed);
59
73
  const written = unwrapped.replace(INNER_MARKS, "").trim();
@@ -6,6 +6,7 @@ import { codeFences, codeSpans, type CodeFence } from "./code-fences.ts";
6
6
  import { opensAsNounPhrase } from "./nominal-step.ts";
7
7
  import { quoteAt } from "./structure-tree.ts";
8
8
  import { escapeRegExp } from "../orthography.ts";
9
+ import { isFormatTemplate } from "../format-template.ts";
9
10
  import type { Detector, Finding, ProseDocument, Span, Token } from "../plugin.ts";
10
11
 
11
12
  const patternsOf = (doc: ProseDocument, id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
@@ -25,6 +26,9 @@ const finding = (doc: ProseDocument, rule: string, offset: number, values: Reado
25
26
  values: { ...values, offset },
26
27
  });
27
28
 
29
+ /** A fence that should name a language: an untagged format template (<MAJOR>.<MINOR>) is in none, so it is left out. */
30
+ const wantsLanguage = (fence: CodeFence): boolean => fence.language !== "" || !isFormatTemplate(fence.lines);
31
+
28
32
  /** Fences without a language, when they are the fewer kind: a document that mostly leaves the language out is not reported. */
29
33
  export const untaggedFewer = (fences: readonly CodeFence[], limit: number): readonly CodeFence[] => {
30
34
  const untagged = fences.filter((fence) => fence.language === "");
@@ -33,7 +37,7 @@ export const untaggedFewer = (fences: readonly CodeFence[], limit: number): read
33
37
  };
34
38
 
35
39
  export const codeFenceLanguage: Detector = (doc, options): Finding[] => {
36
- const fences = codeFences(doc.source);
40
+ const fences = codeFences(doc.source).filter(wantsLanguage);
37
41
  const tagged = fences.filter((fence) => fence.language !== "").length;
38
42
  return untaggedFewer(fences, options.limit).map((fence) =>
39
43
  finding(doc, "code-fence-language-mix", fence.start, { tagged, untagged: fences.length - tagged }),
@@ -0,0 +1,37 @@
1
+ import type { Lexicon, MarkupHeading } from "../plugin.ts";
2
+ import { escapeRegExp } from "../orthography.ts";
3
+
4
+ type Span = { readonly start: number; readonly end: number };
5
+
6
+ /** Lexicon group of placeholder-word: a word that, in a heading, says what follows is a template (Template, 雛形). */
7
+ export const TEMPLATE = "template";
8
+
9
+ const LATIN = /\p{Script=Latin}/u;
10
+
11
+ /** Does the character beside a match end the word? A Latin edge needs a non-letter next to it; a CJK word stands anywhere. */
12
+ const boundsWord = (edge: string, beside: string | undefined): boolean => !LATIN.test(edge) || beside === undefined || !/[\p{L}\p{N}]/u.test(beside);
13
+
14
+ const holdsWordAt = (text: string, pattern: string, index: number): boolean =>
15
+ boundsWord(pattern[0] ?? "", text[index - 1]) && boundsWord(pattern.at(-1) ?? "", text[index + pattern.length]);
16
+
17
+ /** The heading names a template: one of the words appears in it as a whole word, in any case. */
18
+ export const namesTemplate = (heading: string, words: Lexicon): boolean => {
19
+ const text = heading.toLowerCase();
20
+ return words.some((word) => {
21
+ const pattern = word.pattern.toLowerCase();
22
+ return [...text.matchAll(new RegExp(escapeRegExp(pattern), "gu"))].some((match) => holdsWordAt(text, pattern, match.index));
23
+ });
24
+ };
25
+
26
+ /** A heading's section runs from the heading to the next one at its depth or above; text before a template title stays checked. */
27
+ const sectionOf = (headings: readonly MarkupHeading[], index: number, documentEnd: number): Span => {
28
+ const heading = headings[index];
29
+ const next = headings.slice(index + 1).find((later) => later.depth <= (heading?.depth ?? 0));
30
+ return { start: heading?.start ?? 0, end: next?.start ?? documentEnd };
31
+ };
32
+
33
+ /** The parts of a document under a heading that names a template: their blanks are the point, not a slip. */
34
+ export const templateSections = (headings: readonly MarkupHeading[], documentEnd: number, words: Lexicon): Span[] =>
35
+ words.length === 0 ? [] : headings.flatMap((heading, index) => (namesTemplate(heading.text, words) ? [sectionOf(headings, index, documentEnd)] : []));
36
+
37
+ export const isInside = (spans: readonly Span[], offset: number): boolean => spans.some((span) => span.start <= offset && offset < span.end);
@@ -0,0 +1,31 @@
1
+ import { escapeRegExp } from "../orthography.ts";
2
+ import type { Sentence } from "../plugin.ts";
3
+
4
+ // An entry of a definitions list opens with the term it defines, in quotes ("Capital Contributions" The capital
5
+ // contribution to the Venture …). The words after the quoted name are the definition's own body, not uses of the term.
6
+ // Pure.
7
+
8
+ /** The ending a quoted name may carry past the term: a plural or a possessive (Contributions, Contribution's). */
9
+ const ENDING = String.raw`(?:e?s|['’]s)?`;
10
+ /** The label of a list item before the entry (a., (b), 1., iv)). */
11
+ const ITEM_LABEL = String.raw`(?:\(?[\p{L}\p{N}]{1,4}[.)]\s+)?`;
12
+ /** The quotes a term is named in, each with its own closing mark. */
13
+ const QUOTE_PAIRS = [
14
+ ['"', '"'],
15
+ ["“", "”"],
16
+ ["「", "」"],
17
+ ["『", "』"],
18
+ ] as const;
19
+
20
+ const entryHead = (term: string): RegExp => {
21
+ const quoted = QUOTE_PAIRS.map(([open, close]) => `${open}${escapeRegExp(term)}${ENDING}${close}`).join("|");
22
+ return new RegExp(`^\\s*${ITEM_LABEL}(?:${quoted})`, "u");
23
+ };
24
+
25
+ /** Whether the sentence holding offset is a definitions entry that opens with the term in quotes, and offset is after that name. */
26
+ export const inEntryOfTerm = (sentences: readonly Sentence[], term: string, offset: number): boolean => {
27
+ const sentence = sentences.find((candidate) => candidate.span.start <= offset && offset < candidate.span.end);
28
+ if (sentence === undefined) return false;
29
+ const head = entryHead(term).exec(sentence.text);
30
+ return head !== null && offset - sentence.span.start >= head[0].length;
31
+ };
@@ -0,0 +1,48 @@
1
+ import type { Token } from "../plugin.ts";
2
+ import { quotedSpans } from "../quoted-span.ts";
3
+
4
+ /** 題の付いたものの名前を閉じる語(語彙表 title-ending: 〜要綱、〜試験、〜事業、〜法)。 */
5
+ export type TitleWords = { readonly endings: readonly string[] };
6
+
7
+ /** 題を囲む括弧。鉤括弧と、見出しや分類の名前を囲む隅付き括弧。 */
8
+ const TITLE_MARKS = { "「": "」", "『": "』", "【": "】" };
9
+ /**
10
+ * 名前のすぐ後ろ(同じ行の空白を挟んでもよい)に付く、その名前の補い(就職氷河期世代、<創業型>)、略称(以下「奨励金」という。)、
11
+ * 日付や番号、ファイルの種類と大きさ([PDFファイル/333KB])の括弧。角括弧は同じ行で閉じ、Markdown のリンク([文字](…))でないもの。
12
+ * 半角の < は HTML の札と見分けられないので読まない。
13
+ */
14
+ const QUALIFIER = /^[ \t\u3000]*(?:[((<〈[]|\[[^\]\n]*\](?![([]))/u;
15
+ /** 閉じる語の前に要る字数。1 字なら、題ではなく普通の語(新法、本事業)。 */
16
+ const MIN_BODY_LENGTH = 2;
17
+ const BLANK = /^\s*$/u;
18
+
19
+ const surfaceOf = (tokens: readonly Token[]): string => tokens.map((token) => token.surface).join("");
20
+
21
+ /**
22
+ * 連なりの語(run: 隙間なく並ぶ語)が、題の名前を閉じる語で終わるか。閉じる語は語の切れ目で始まる
23
+ * (地方自治法の「法」は語、解決方法の「法」は方法の一部)。閉じる語の前に 2 字以上の語が要る。
24
+ */
25
+ export const endsInTitle = (run: readonly Token[], words: TitleWords): boolean =>
26
+ run.some((_, at) => {
27
+ const tail = surfaceOf(run.slice(at));
28
+ return words.endings.includes(tail) && [...surfaceOf(run.slice(0, at))].length >= MIN_BODY_LENGTH;
29
+ });
30
+
31
+ /**
32
+ * 文(text)の start から end までの連なりが、題の名前の置き方をしているか。
33
+ * 括弧の中身の終わりで閉じる(「令和8年度高度統計人材育成強化拠点形成事業」)、すぐ後ろに補いの括弧が付く
34
+ * (国家公務員中途採用者選考試験(就職氷河期世代)、持続化補助金<創業型>、登録申込書 [PDFファイル/333KB])、
35
+ * または文がその連なりだけ(要綱の題を並べた行)。
36
+ */
37
+ export const isTitlePosition = (text: string, start: number, end: number): boolean => {
38
+ const closesBracket = quotedSpans(text, TITLE_MARKS).some((span) => span.end === end && span.start <= start);
39
+ const qualified = QUALIFIER.test(text.slice(end));
40
+ const alone = BLANK.test(text.slice(0, start)) && BLANK.test(text.slice(end));
41
+ return closesBracket || qualified || alone;
42
+ };
43
+
44
+ /**
45
+ * 文書の中で題として置かれた名前(titled: 題の置き方をした連なりと、見出しの中の漢字の連なり)に、
46
+ * この連なりの字(text)が名前の終わりとして含まれるか。同じ名前は、文の中で使っても名前(認定職業訓練実施奨励金の支給額)。
47
+ */
48
+ export const isTitledName = (text: string, titled: readonly string[]): boolean => titled.some((name) => name.endsWith(text));
@@ -1,10 +1,12 @@
1
1
  import { hasParticle, isClosed, lastContent } from "../sentence-shape.ts";
2
2
  import { isWithinAny, quotedIn } from "../quoted-span.ts";
3
+ import { chronologyRows } from "../chronology-rows.ts";
4
+ import { externalLinkTitleSpans } from "../link-title.ts";
3
5
  import type { Detector, Finding, Span, Token } from "../plugin.ts";
4
6
 
5
7
  /**
6
8
  * 文末が名詞で終わる(体言止め)。箇条書きでは普通だが、本文では文が途中で切れて読める。
7
- * 実文書で測ったら、指摘の 9 割が箇条書きの項目だった。箇条書きは除く。
9
+ * 実文書で測ったら、指摘の 9 割が箇条書きの項目だった。箇条書きは除く。年表の行(1950年4月 設立。)も名詞で止める書き方なので除く。
8
10
  */
9
11
  const NOMINAL = new Set(["NOUN", "PROPN"]);
10
12
 
@@ -14,8 +16,9 @@ const isDependent = (token: Token): boolean => token.features?.["NounType"] ===
14
16
  const inside = (span: Span, spans: readonly Span[]): boolean => spans.some((other) => span.start >= other.start && span.start < other.end);
15
17
 
16
18
  export const nounEnding: Detector = (doc, options): Finding[] => {
19
+ const rows = chronologyRows(doc);
17
20
  const ended = doc.sentences.filter((sentence) => {
18
- if (inside(sentence.span, doc.listSpans) || !isClosed(sentence) || !hasParticle(sentence)) return false;
21
+ if (inside(sentence.span, doc.listSpans) || rows.has(sentence) || !isClosed(sentence) || !hasParticle(sentence)) return false;
19
22
  const last = lastContent(sentence);
20
23
  return last !== undefined && NOMINAL.has(last.pos) && !isDependent(last);
21
24
  });
@@ -62,19 +65,25 @@ const BREAK: Run = { surface: "", tokens: [] };
62
65
  *
63
66
  * 鉤括弧で引いたもの(括弧ごと)は、名詞と同じく連なりの中身として飛ばす。引いた題名(「食品中のウイルスの制御のための…ガイドライン」)や
64
67
  * 発言は書き手が言い換えられないので、中の助詞は数えない。題名も名前なので、外の連なり(弊社の「新製品」の販売の計画)は続けて数える。
68
+ * 外のページの題名を引いたリンクの文字(- [サービスの料金の計算の方法](https://…))も、引いた題名と同じに読む。
65
69
  */
66
- const runsOf = (tokens: readonly Token[], nesting: readonly string[], quoted: readonly Span[]): Run[] =>
70
+ const runsOf = (tokens: readonly Token[], nesting: readonly string[], breaks: readonly string[], quoted: readonly Span[]): Run[] =>
67
71
  tokens.reduce<Run[]>((acc, token) => {
68
72
  if (isWithinAny(quoted, token.span)) return acc;
69
73
  if (nesting.includes(token.surface)) return extend(acc, token);
70
- if (token.pos === "PUNCT" || PARTICLE.has(token.pos)) acc.push(BREAK);
74
+ if (token.pos === "PUNCT" || PARTICLE.has(token.pos) || breaks.includes(token.surface)) acc.push(BREAK);
71
75
  return acc;
72
76
  }, []);
73
77
 
78
+ /** 句と句の間の記号(制限=タグの制限、A→B)。半角の = や : は名詞として読まれ、句読点のようには切れない。 */
79
+ const RUN_BREAK_LEXICON = "particle-run-break";
80
+
74
81
  export const doubledParticle: Detector = (doc, options): Finding[] => {
75
82
  const nesting = (options.lexicon ?? []).map((entry) => entry.pattern);
83
+ const titles = externalLinkTitleSpans(doc.source, doc.links);
84
+ const breaks = (doc.lexicons[RUN_BREAK_LEXICON] ?? []).map((entry) => entry.pattern);
76
85
  return doc.sentences.flatMap((sentence) =>
77
- runsOf(sentence.tokens ?? [], nesting, quotedIn(sentence))
86
+ runsOf(sentence.tokens ?? [], nesting, breaks, [...quotedIn(sentence), ...titles])
78
87
  .filter((run) => run.tokens.length > options.limit)
79
88
  .map((run) => ({
80
89
  rule: "no-doubled-joshi",
@@ -5,6 +5,7 @@ import { quoteAround } from "./quote-around.ts";
5
5
  import { mergeSpans } from "../span-merge.ts";
6
6
  import { firstEndingAfter } from "../soft-break.ts";
7
7
  import { isLabelClose, isLabelInAside } from "./bracket-label.ts";
8
+ import { isInchMark } from "./inch-mark.ts";
8
9
 
9
10
  /**
10
11
  * 括弧の組。どの言語でも同じ字の決まりなので、語彙表ではなくここに置く。family は形(丸・角)で、全角と半角は同じ形の別の幅。
@@ -93,6 +94,8 @@ export const bracketProblems = (text: string): BracketProblem[] => {
93
94
  const scan: Scan = { open: [], problems: [] };
94
95
  const heads = paragraphHeads(text);
95
96
  [...text.matchAll(MARKS)].forEach((match) => {
97
+ const quoteOpen = scan.open.some((entry) => entry.bracket.family === "quote");
98
+ if (isInchMark(text, match.index, quoteOpen)) return;
96
99
  const opening = BY_OPEN.get(match[0]);
97
100
  const closing = BY_CLOSE.get(match[0]);
98
101
  if (opening !== undefined) openWith(scan, opening, match.index, heads.has(match.index));
@@ -91,6 +91,8 @@ const findingOf = (doc: ProseDocument, use: UndefinedTerm): Finding => ({
91
91
  });
92
92
 
93
93
  const NAME_LISTS = ["proper-name-word", "place-region", "calendar-name", "month-name", "company-form", "party-role"] as const;
94
+ /** The lists whose words end a name right after a comma (Post Holdings, Inc.; Canton, Ohio). */
95
+ const FORM_ENDS = ["company-form", "place-region"] as const;
94
96
 
95
97
  /** Capitalised terms, for a language whose package lists the words that join one name (name-joiner); Japanese has none. */
96
98
  const capitalisedUses = (doc: ProseDocument, sentences: readonly (readonly Token[])[], defined: readonly Defined[]): UndefinedTerm[] => {
@@ -99,6 +101,12 @@ const capitalisedUses = (doc: ProseDocument, sentences: readonly (readonly Token
99
101
  names: NAME_LISTS.flatMap((id) => patternsOf(doc, id)),
100
102
  divisions: patternsOf(doc, "numbered-division"),
101
103
  joiners: patternsOf(doc, "name-joiner"),
104
+ nameEnds: patternsOf(doc, "proper-name-word"),
105
+ formEnds: FORM_ENDS.flatMap((id) => patternsOf(doc, id)),
106
+ definitionMarkers: patternsOf(doc, "definition-marker"),
107
+ definedElsewhere: patternsOf(doc, "defined-elsewhere"),
108
+ capacityMarkers: patternsOf(doc, "capacity-marker"),
109
+ articles: patternsOf(doc, "article"),
102
110
  };
103
111
  const marked = [...(doc.markup?.headings ?? []), ...doc.links, ...setApartSpans(doc.source)];
104
112
  return capitalisedTerms({ source: doc.source, readable: readableText(doc.source), sentences, defined, named: namedWords(doc.source), marked, words });
@@ -0,0 +1,10 @@
1
+ import type { Detector } from "../plugin.ts";
2
+ import { unfilledPlaceholder } from "./ai-phrasing.ts";
3
+ import { TEMPLATE, isInside, templateSections } from "./template-sections.ts";
4
+
5
+ /** A blank under a heading that names a template (Template, 雛形) is what the template is for, so it is not reported. */
6
+ export const unfilledPlaceholderOutsideTemplates: Detector = (doc, options) => {
7
+ const words = (options.lexicon ?? []).filter((word) => word.group === TEMPLATE);
8
+ const templates = templateSections(doc.markup?.headings ?? [], doc.source.length, words);
9
+ return unfilledPlaceholder(doc, options).filter((finding) => !isInside(templates, Number(finding.values["offset"])));
10
+ };
@@ -0,0 +1,84 @@
1
+ // Vague words dense for the document's length (vague-word-density). Each sentence counts the vague words it holds once:
2
+ // a word inside a longer one ("timely" in "in a timely manner") is that longer word, and a word inside a term of art of the
3
+ // document's genre ("reasonably" in a contract, "adequately compensate" as the test for an injunction) is not vague
4
+ // there. The rule speaks once per sentence, about the document's density. Pure: the words come from the language's
5
+ // lexicons vague-word and vague-word-term-of-art, the genre from the options.
6
+ import { entriesForGenre } from "../lexicon-genres.ts";
7
+ import { escapeRegExp } from "../orthography.ts";
8
+ import type { Detector, Finding, Lexicon, LexiconEntry, Sentence } from "../plugin.ts";
9
+ import { comparableText, comparableWords, entryRanges } from "./lexicon-match.ts";
10
+ import { rateOver } from "./lexicon.ts";
11
+ import { specifiedByBracket } from "./bracket-specified.ts";
12
+
13
+ const TERMS_OF_ART = "vague-word-term-of-art";
14
+ /** The words that start an aside giving a name (以下「HR」という, hereinafter): such an aside pins nothing down. */
15
+ const NAME_MARKERS = "definition-marker";
16
+
17
+ type Place = { readonly start: number; readonly end: number };
18
+
19
+ type Match = { readonly pattern: string; readonly place: Place };
20
+
21
+ /** Token spans are places in the document and text places are in the sentence, so one sentence uses one kind for every entry. */
22
+ const readsTokens = (sentence: Sentence, entries: Lexicon): boolean =>
23
+ sentence.tokens !== undefined && entries.every((entry) => (entry.tokens?.length ?? 0) > 0);
24
+
25
+ /** Where an entry stands in the sentence, as character spans: its tokens, or the comparable text. */
26
+ const placesOf = (sentence: Sentence, entry: LexiconEntry, byTokens: boolean): Place[] => {
27
+ const tokens = sentence.tokens;
28
+ if (byTokens && tokens !== undefined)
29
+ return entryRanges(sentence, entry).map((range) => ({ start: tokens[range.start]?.span.start ?? 0, end: tokens[range.end - 1]?.span.end ?? 0 }));
30
+ const word = comparableWords(entry.pattern);
31
+ if (word === "") return [];
32
+ return [...comparableText(sentence).matchAll(new RegExp(escapeRegExp(word), "gu"))].map((found) => ({ start: found.index, end: found.index + word.length }));
33
+ };
34
+
35
+ const matchesOf = (sentence: Sentence, lexicon: Lexicon, byTokens: boolean): Match[] =>
36
+ lexicon.flatMap((entry) => placesOf(sentence, entry, byTokens).map((place) => ({ pattern: entry.pattern, place })));
37
+
38
+ const covers = (outer: Place, inner: Place): boolean => outer.start <= inner.start && inner.end <= outer.end;
39
+
40
+ const isLonger = (outer: Match, inner: Match): boolean => outer.place.end - outer.place.start > inner.place.end - inner.place.start;
41
+
42
+ /** Whether a bracket right after the match pins the word down; token places are in the document, text places in the comparable text. */
43
+ const pinnedDown = (sentence: Sentence, match: Match, byTokens: boolean, nameMarkers: readonly string[]): boolean =>
44
+ byTokens
45
+ ? specifiedByBracket(sentence.text, match.place.end - sentence.span.start, nameMarkers)
46
+ : specifiedByBracket(comparableText(sentence), match.place.end, nameMarkers);
47
+
48
+ /**
49
+ * The vague words of one sentence, in the order written, each once: none inside a longer vague word or a term of art,
50
+ * and none pinned down by the bracket right after it (一定の事項(…)). nameMarkers: the words that start a name in an aside.
51
+ */
52
+ export const vagueWordsIn = (sentence: Sentence, vague: Lexicon, termsOfArt: Lexicon, nameMarkers: readonly string[] = []): string[] => {
53
+ const byTokens = readsTokens(sentence, [...vague, ...termsOfArt]);
54
+ const matches = matchesOf(sentence, vague, byTokens);
55
+ const terms = matchesOf(sentence, termsOfArt, byTokens);
56
+ const kept = matches.filter(
57
+ (match) =>
58
+ !matches.some((other) => isLonger(other, match) && covers(other.place, match.place)) &&
59
+ !terms.some((term) => covers(term.place, match.place)) &&
60
+ !pinnedDown(sentence, match, byTokens, nameMarkers),
61
+ );
62
+ return [...new Set(kept.toSorted((left, right) => left.place.start - right.place.start).map((match) => match.pattern))];
63
+ };
64
+
65
+ type SentenceHits = { readonly sentence: Sentence; readonly words: readonly string[] };
66
+
67
+ export const vagueDensity: Detector = (doc, options): Finding[] => {
68
+ const termsOfArt = entriesForGenre(doc.lexicons[TERMS_OF_ART] ?? [], options.genre);
69
+ const nameMarkers = (doc.lexicons[NAME_MARKERS] ?? []).map((entry) => entry.pattern);
70
+ const hits: SentenceHits[] = doc.sentences
71
+ .map((sentence) => ({ sentence, words: vagueWordsIn(sentence, options.lexicon ?? [], termsOfArt, nameMarkers) }))
72
+ .filter((hit) => hit.words.length > 0);
73
+ const count = hits.reduce((sum, hit) => sum + hit.words.length, 0);
74
+ const density = rateOver(doc, count, options.limit);
75
+ if (density === undefined) return [];
76
+ return hits.map(({ sentence, words }) => ({
77
+ rule: "vague-word-density",
78
+ severity: "warning",
79
+ line: 0,
80
+ column: 0,
81
+ quote: sentence.text.trim(),
82
+ values: { matched: words[0] ?? "", count, density, limit: options.limit, offset: sentence.span.start },
83
+ }));
84
+ };
@@ -0,0 +1,27 @@
1
+ import { documentLineParagraphs } from "./line-paragraphs.ts";
2
+ import { listItemParagraphs } from "./list-item-paragraphs.ts";
3
+ import type { Paragraph, Sentence, Span } from "./plugin.ts";
4
+
5
+ /** sentences(並び順)の中で、start が offset 以上の最初の添字。1 行 1 段落の何万行でも、段落ごとに全部をなめない。 */
6
+ const firstStartingAt = (sentences: readonly Sentence[], offset: number): number => {
7
+ const search = (low: number, high: number): number => {
8
+ if (low >= high) return low;
9
+ const middle = (low + high) >> 1;
10
+ return (sentences[middle]?.span.start ?? Number.POSITIVE_INFINITY) >= offset ? search(low, middle) : search(middle + 1, high);
11
+ };
12
+ return search(0, sentences.length);
13
+ };
14
+
15
+ const sentencesWithin = (sentences: readonly Sentence[], span: Span): Sentence[] =>
16
+ sentences.slice(firstStartingAt(sentences, span.start), firstStartingAt(sentences, span.end));
17
+
18
+ /** 文書の段落と、その中の文。spans は Markdown の段落、listSpans は箇条書きの項目と同じに読む範囲。 */
19
+ export const paragraphsOf = (prose: string, spans: readonly Span[], sentences: readonly Sentence[], listSpans: readonly Span[]): Paragraph[] => {
20
+ // 箇条書きの中の段落は「段落」として数えない。項目 1 つを 1 段落と読むと、
21
+ // 段落あたりの文数も長さのばらつきも、箇条書きの多い文書で壊れる。
22
+ const outsideLists = spans.filter((span) => !listSpans.some((list) => span.start >= list.start && span.start < list.end));
23
+ const withSentences = outsideLists.map((span) => ({ span, sentences: sentencesWithin(sentences, span).map((sentence) => sentence.span) }));
24
+ // 1 行 1 段落の書き方かは、行頭の印の項目で割る前の段落で決める。割った後の段落は、その手がかりにならない。
25
+ const items = documentLineParagraphs(prose, withSentences).flatMap((span) => listItemParagraphs(span, sentencesWithin(sentences, span)));
26
+ return items.map((span) => ({ span, sentences: sentencesWithin(sentences, span) }));
27
+ };
package/src/document.ts CHANGED
@@ -4,7 +4,7 @@ import { hasTitle } from "./heading-title.ts";
4
4
  import { maskSpans } from "./mask.ts";
5
5
  import { spansWithin, unmaskedSoftBreaks } from "./soft-break.ts";
6
6
  import { segmentJoined } from "./joined-view.ts";
7
- import { documentLineParagraphs } from "./line-paragraphs.ts";
7
+ import { paragraphsOf } from "./document-paragraphs.ts";
8
8
  import { closingRun, standaloneLines, subheadingPieces, type StandsAlone } from "./subheading-line.ts";
9
9
  import { isLinkLine } from "./link-line.ts";
10
10
  import { speakerLabels } from "./speaker-labels.ts";
@@ -26,7 +26,7 @@ import { markdownFigures } from "./text-figures.ts";
26
26
  import { documentMarkup } from "./markup.ts";
27
27
  import { BARE_URL } from "./bare-url.ts";
28
28
  import { lazyCells, tableCellsOf } from "./table-cells.ts";
29
- import type { BulletList, LanguageAdapter, Markup, Paragraph, ProseDocument, Sentence, Span, StructureNode, DocumentProfile } from "./plugin.ts";
29
+ import type { BulletList, LanguageAdapter, Markup, ProseDocument, Sentence, Span, StructureNode, DocumentProfile } from "./plugin.ts";
30
30
 
31
31
  /**
32
32
  * 本文として数えないもの。
@@ -234,30 +234,10 @@ const sentencesOf = (prose: string, paragraphs: readonly Span[], adapter: Langua
234
234
  ...(sentence.tokens === undefined ? {} : { tokens: sentence.tokens.map((token) => ({ ...token, span: shift(token.span, paragraph.start) })) }),
235
235
  ...(sentence.wrapBreaks === undefined ? {} : { wrapBreaks: sentence.wrapBreaks.map((span) => shift(span, paragraph.start)) }),
236
236
  ...(sentence.embeddedLanguage === undefined ? {} : { embeddedLanguage: sentence.embeddedLanguage }),
237
+ ...(sentence.listItem === undefined ? {} : { listItem: sentence.listItem }),
237
238
  })),
238
239
  );
239
240
 
240
- /** sentences(並び順)の中で、start が offset 以上の最初の添字。1 行 1 段落の何万行でも、段落ごとに全部をなめない。 */
241
- const firstStartingAt = (sentences: readonly Sentence[], offset: number): number => {
242
- const search = (low: number, high: number): number => {
243
- if (low >= high) return low;
244
- const middle = (low + high) >> 1;
245
- return (sentences[middle]?.span.start ?? Number.POSITIVE_INFINITY) >= offset ? search(low, middle) : search(middle + 1, high);
246
- };
247
- return search(0, sentences.length);
248
- };
249
-
250
- const sentencesWithin = (sentences: readonly Sentence[], span: Span): Sentence[] =>
251
- sentences.slice(firstStartingAt(sentences, span.start), firstStartingAt(sentences, span.end));
252
-
253
- const paragraphsOf = (prose: string, spans: readonly Span[], sentences: readonly Sentence[], listSpans: readonly Span[]): Paragraph[] => {
254
- // 箇条書きの中の段落は「段落」として数えない。項目 1 つを 1 段落と読むと、
255
- // 段落あたりの文数も長さのばらつきも、箇条書きの多い文書で壊れる。
256
- const outsideLists = spans.filter((span) => !listSpans.some((list) => span.start >= list.start && span.start < list.end));
257
- const withSentences = outsideLists.map((span) => ({ span, sentences: sentencesWithin(sentences, span).map((sentence) => sentence.span) }));
258
- return documentLineParagraphs(prose, withSentences).map((span) => ({ span, sentences: sentencesWithin(sentences, span) }));
259
- };
260
-
261
241
  /** 箇条書きは list ノードの直下の項目を数える。入れ子の項目は内側の list のものとして数える。目次のような案内だけの箇条書きは数えない。 */
262
242
  const listsOf = (root: Node, source: string, anchors: InPageAnchors): BulletList[] => {
263
243
  const found: BulletList[] = [];
@@ -118,20 +118,69 @@ const headCount = (heads: ReadonlyMap<string, readonly number[]>, from: number,
118
118
 
119
119
  type Lines = { readonly lines: readonly Line[]; readonly breakers: readonly number[]; readonly heads: ReadonlyMap<string, readonly number[]> };
120
120
 
121
- const scopeOf = (fact: Fact, innermost: StructureNode | undefined, at: Lines): { scope: string; record: boolean } => {
121
+ /** 表の、見出しを繰り返した何番目の並びの升か(table-facts の columnGroup)。並びごとに別の範囲。 */
122
+ type PlacedFact = Fact & { readonly columnGroup?: number };
123
+
124
+ const scopeOf = (fact: PlacedFact, innermost: StructureNode | undefined, at: Lines): { scope: string; record: boolean } => {
122
125
  const index = lineIndexAt(at.lines, fact.value.start);
123
126
  const from = innermost === undefined ? 0 : lineIndexAt(at.lines, innermost.span.start);
124
127
  const to = innermost === undefined ? at.lines.length : lineIndexAt(at.lines, innermost.span.end - 1) + 1;
125
- const scope = [innermost?.address ?? "doc", (at.breakers[index] ?? 0) - (at.breakers[from] ?? 0), parentItem(at.lines, index)].join("#");
128
+ const place = [innermost?.address ?? "doc", (at.breakers[index] ?? 0) - (at.breakers[from] ?? 0), parentItem(at.lines, index)];
129
+ const scope = [...place, ...(fact.columnGroup === undefined ? [] : [`g${fact.columnGroup}`])].join("#");
126
130
  return { scope, record: headCount(at.heads, from, to, fact.key) >= RECORD_REPEATS };
127
131
  };
128
132
 
133
+ const MAX_PARAGRAPH_HEAD = 40;
134
+ /** 文の終わりか続きの印。これで終わる行は小見出しではない。 */
135
+ const SENTENCE_END = /[.!?。.!?::;;,、,]$/u;
136
+ const NOT_PLAIN_LINE = /^[ \t]*(?:[#>|]|```|~~~)/u;
137
+ /** setext の見出しの下線。上の行は見出しで、節として木が分ける。 */
138
+ const SETEXT_UNDERLINE = /^[ \t]*(?:=+|-+)[ \t]*$/u;
139
+
140
+ /**
141
+ * 段落の頭の、短い名前だけの行(「Example」「Element 1 (standard rated portion)」「例」)。文の終わりの印も値も無く、項目や表の行でもない。
142
+ * 例や場合ごとに名前を付けた段落の頭で、続く値はその例の値。
143
+ */
144
+ const isNameOnly = (line: string): boolean => {
145
+ const text = line.trim();
146
+ if (text === "" || text.length > MAX_PARAGRAPH_HEAD) return false;
147
+ return /\p{L}/u.test(text) && !SENTENCE_END.test(text) && !LIST_ITEM.test(line) && !NOT_PLAIN_LINE.test(line);
148
+ };
149
+
150
+ const isParagraphHead = (lines: readonly Line[], index: number, valueLines: ReadonlySet<number>): boolean => {
151
+ const startsParagraph = (lines[index - 1]?.text.trim() ?? "") === "";
152
+ const isSetextHeading = SETEXT_UNDERLINE.test(lines[index + 1]?.text ?? "");
153
+ return startsParagraph && !isSetextHeading && !valueLines.has(index) && isNameOnly(lines[index]?.text ?? "");
154
+ };
155
+
156
+ /** 小見出しの代わりの行の数に、段落の頭の名前だけの行も数える。 */
157
+ const withParagraphHeads = (lines: readonly Line[], facts: readonly Fact[]): number[] => {
158
+ const valueLines = new Set(facts.map((fact) => lineIndexAt(lines, fact.value.start)));
159
+ return lines.reduce<number[]>(
160
+ (counts, line, index) => {
161
+ counts.push((counts[index] ?? 0) + (isBreaker(line) || isParagraphHead(lines, index, valueLines) ? 1 : 0));
162
+ return counts;
163
+ },
164
+ [0],
165
+ );
166
+ };
167
+
168
+ /** paragraphHeads: 段落の頭の名前だけの行(Example、例)でも範囲を分ける。 */
169
+ export type ScopeReading = { readonly paragraphHeads?: boolean };
170
+
129
171
  /** 事実ごとに、比べてよい範囲と、文書のどの部分かを付ける。 */
130
- export const scopedFacts = (facts: readonly Fact[], tree: StructureNode, source: string, summaryWords: readonly string[]): ScopedFact[] => {
172
+ export const scopedFacts = (
173
+ facts: readonly PlacedFact[],
174
+ tree: StructureNode,
175
+ source: string,
176
+ summaryWords: readonly string[],
177
+ reading: ScopeReading = {},
178
+ ): ScopedFact[] => {
131
179
  if (facts.length === 0) return [];
132
180
  const nodes = inDocumentOrder(tree).filter((node) => CONTAINERS.has(node.kind));
133
181
  const lines = linesOf(source);
134
- const at: Lines = { lines, breakers: breakerCounts(lines), heads: headLines(lines) };
182
+ const breakers = reading.paragraphHeads === true ? withParagraphHeads(lines, facts) : breakerCounts(lines);
183
+ const at: Lines = { lines, breakers, heads: headLines(lines) };
135
184
  return facts
136
185
  .toSorted((left, right) => left.value.start - right.value.start)
137
186
  .map((fact) => {