chaffjs 0.17.0 → 0.18.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 (840) hide show
  1. package/dist/announced-count.d.ts +26 -0
  2. package/dist/announced-count.d.ts.map +1 -0
  3. package/dist/announced-count.js +104 -0
  4. package/dist/announced-count.js.map +1 -0
  5. package/dist/bare-url.d.ts +14 -0
  6. package/dist/bare-url.d.ts.map +1 -0
  7. package/dist/bare-url.js +28 -0
  8. package/dist/bare-url.js.map +1 -0
  9. package/dist/baseline.d.ts +5 -0
  10. package/dist/baseline.d.ts.map +1 -1
  11. package/dist/baseline.js +16 -1
  12. package/dist/baseline.js.map +1 -1
  13. package/dist/body-section.d.ts +7 -0
  14. package/dist/body-section.d.ts.map +1 -0
  15. package/dist/body-section.js +6 -0
  16. package/dist/body-section.js.map +1 -0
  17. package/dist/calendar-number.d.ts +2 -0
  18. package/dist/calendar-number.d.ts.map +1 -1
  19. package/dist/calendar-number.js +9 -2
  20. package/dist/calendar-number.js.map +1 -1
  21. package/dist/cli-args.d.ts +4 -0
  22. package/dist/cli-args.d.ts.map +1 -1
  23. package/dist/cli-args.js +5 -0
  24. package/dist/cli-args.js.map +1 -1
  25. package/dist/cli-text.d.ts.map +1 -1
  26. package/dist/cli-text.js +8 -4
  27. package/dist/cli-text.js.map +1 -1
  28. package/dist/cli.js +33 -30
  29. package/dist/cli.js.map +1 -1
  30. package/dist/commands/compare.d.ts +8 -0
  31. package/dist/commands/compare.d.ts.map +1 -0
  32. package/dist/commands/compare.js +72 -0
  33. package/dist/commands/compare.js.map +1 -0
  34. package/dist/commands/eval.d.ts.map +1 -1
  35. package/dist/commands/eval.js +17 -9
  36. package/dist/commands/eval.js.map +1 -1
  37. package/dist/commands/feedback.d.ts +5 -2
  38. package/dist/commands/feedback.d.ts.map +1 -1
  39. package/dist/commands/feedback.js +11 -5
  40. package/dist/commands/feedback.js.map +1 -1
  41. package/dist/commands/test.d.ts.map +1 -1
  42. package/dist/commands/test.js +2 -4
  43. package/dist/commands/test.js.map +1 -1
  44. package/dist/commands/tree.d.ts +13 -0
  45. package/dist/commands/tree.d.ts.map +1 -1
  46. package/dist/commands/tree.js +35 -5
  47. package/dist/commands/tree.js.map +1 -1
  48. package/dist/compare/atom.d.ts +31 -0
  49. package/dist/compare/atom.d.ts.map +1 -0
  50. package/dist/compare/atom.js +4 -0
  51. package/dist/compare/atom.js.map +1 -0
  52. package/dist/compare/clock-time.d.ts +8 -0
  53. package/dist/compare/clock-time.d.ts.map +1 -0
  54. package/dist/compare/clock-time.js +65 -0
  55. package/dist/compare/clock-time.js.map +1 -0
  56. package/dist/compare/extract.d.ts +15 -0
  57. package/dist/compare/extract.d.ts.map +1 -0
  58. package/dist/compare/extract.js +58 -0
  59. package/dist/compare/extract.js.map +1 -0
  60. package/dist/compare/fact-text.d.ts +23 -0
  61. package/dist/compare/fact-text.d.ts.map +1 -0
  62. package/dist/compare/fact-text.js +47 -0
  63. package/dist/compare/fact-text.js.map +1 -0
  64. package/dist/compare/markup-atoms.d.ts +11 -0
  65. package/dist/compare/markup-atoms.d.ts.map +1 -0
  66. package/dist/compare/markup-atoms.js +23 -0
  67. package/dist/compare/markup-atoms.js.map +1 -0
  68. package/dist/compare/match.d.ts +19 -0
  69. package/dist/compare/match.d.ts.map +1 -0
  70. package/dist/compare/match.js +84 -0
  71. package/dist/compare/match.js.map +1 -0
  72. package/dist/compare/outcome.d.ts +33 -0
  73. package/dist/compare/outcome.d.ts.map +1 -0
  74. package/dist/compare/outcome.js +40 -0
  75. package/dist/compare/outcome.js.map +1 -0
  76. package/dist/compare/proper-nouns.d.ts +19 -0
  77. package/dist/compare/proper-nouns.d.ts.map +1 -0
  78. package/dist/compare/proper-nouns.js +44 -0
  79. package/dist/compare/proper-nouns.js.map +1 -0
  80. package/dist/compare/render.d.ts +9 -0
  81. package/dist/compare/render.d.ts.map +1 -0
  82. package/dist/compare/render.js +64 -0
  83. package/dist/compare/render.js.map +1 -0
  84. package/dist/compare/spans.d.ts +9 -0
  85. package/dist/compare/spans.d.ts.map +1 -0
  86. package/dist/compare/spans.js +11 -0
  87. package/dist/compare/spans.js.map +1 -0
  88. package/dist/compare/text-atoms.d.ts +24 -0
  89. package/dist/compare/text-atoms.d.ts.map +1 -0
  90. package/dist/compare/text-atoms.js +67 -0
  91. package/dist/compare/text-atoms.js.map +1 -0
  92. package/dist/compare/text.d.ts +24 -0
  93. package/dist/compare/text.d.ts.map +1 -0
  94. package/dist/compare/text.js +90 -0
  95. package/dist/compare/text.js.map +1 -0
  96. package/dist/compare/tree-atoms.d.ts +20 -0
  97. package/dist/compare/tree-atoms.d.ts.map +1 -0
  98. package/dist/compare/tree-atoms.js +58 -0
  99. package/dist/compare/tree-atoms.js.map +1 -0
  100. package/dist/compare/written-names.d.ts +8 -0
  101. package/dist/compare/written-names.d.ts.map +1 -0
  102. package/dist/compare/written-names.js +24 -0
  103. package/dist/compare/written-names.js.map +1 -0
  104. package/dist/config/load.d.ts +15 -0
  105. package/dist/config/load.d.ts.map +1 -1
  106. package/dist/config/load.js +5 -0
  107. package/dist/config/load.js.map +1 -1
  108. package/dist/config/option-problems.d.ts +16 -0
  109. package/dist/config/option-problems.d.ts.map +1 -0
  110. package/dist/config/option-problems.js +58 -0
  111. package/dist/config/option-problems.js.map +1 -0
  112. package/dist/config/read.d.ts +4 -0
  113. package/dist/config/read.d.ts.map +1 -0
  114. package/dist/config/read.js +8 -0
  115. package/dist/config/read.js.map +1 -0
  116. package/dist/config/rule-problems.d.ts +2 -4
  117. package/dist/config/rule-problems.d.ts.map +1 -1
  118. package/dist/config/rule-problems.js +7 -1
  119. package/dist/config/rule-problems.js.map +1 -1
  120. package/dist/config/style.d.ts +16 -0
  121. package/dist/config/style.d.ts.map +1 -0
  122. package/dist/config/style.js +36 -0
  123. package/dist/config/style.js.map +1 -0
  124. package/dist/config/warnings.d.ts +6 -0
  125. package/dist/config/warnings.d.ts.map +1 -0
  126. package/dist/config/warnings.js +10 -0
  127. package/dist/config/warnings.js.map +1 -0
  128. package/dist/config/write.d.ts.map +1 -1
  129. package/dist/config/write.js +17 -4
  130. package/dist/config/write.js.map +1 -1
  131. package/dist/custom/bounded-match.d.ts +15 -0
  132. package/dist/custom/bounded-match.d.ts.map +1 -0
  133. package/dist/custom/bounded-match.js +43 -0
  134. package/dist/custom/bounded-match.js.map +1 -0
  135. package/dist/custom/load.d.ts +8 -0
  136. package/dist/custom/load.d.ts.map +1 -0
  137. package/dist/custom/load.js +11 -0
  138. package/dist/custom/load.js.map +1 -0
  139. package/dist/custom/parse.d.ts +70 -0
  140. package/dist/custom/parse.d.ts.map +1 -0
  141. package/dist/custom/parse.js +215 -0
  142. package/dist/custom/parse.js.map +1 -0
  143. package/dist/custom/problems.d.ts +5 -0
  144. package/dist/custom/problems.d.ts.map +1 -0
  145. package/dist/custom/problems.js +78 -0
  146. package/dist/custom/problems.js.map +1 -0
  147. package/dist/custom/regex-safety.d.ts +11 -0
  148. package/dist/custom/regex-safety.d.ts.map +1 -0
  149. package/dist/custom/regex-safety.js +110 -0
  150. package/dist/custom/regex-safety.js.map +1 -0
  151. package/dist/custom/token-pattern.d.ts +8 -0
  152. package/dist/custom/token-pattern.d.ts.map +1 -0
  153. package/dist/custom/token-pattern.js +75 -0
  154. package/dist/custom/token-pattern.js.map +1 -0
  155. package/dist/detect.d.ts.map +1 -1
  156. package/dist/detect.js +24 -2
  157. package/dist/detect.js.map +1 -1
  158. package/dist/detectors/acronym-context.d.ts +2 -0
  159. package/dist/detectors/acronym-context.d.ts.map +1 -1
  160. package/dist/detectors/acronym-context.js +12 -4
  161. package/dist/detectors/acronym-context.js.map +1 -1
  162. package/dist/detectors/ai-phrasing.d.ts +20 -0
  163. package/dist/detectors/ai-phrasing.d.ts.map +1 -0
  164. package/dist/detectors/ai-phrasing.js +112 -0
  165. package/dist/detectors/ai-phrasing.js.map +1 -0
  166. package/dist/detectors/announced-count.d.ts +4 -0
  167. package/dist/detectors/announced-count.d.ts.map +1 -0
  168. package/dist/detectors/announced-count.js +20 -0
  169. package/dist/detectors/announced-count.js.map +1 -0
  170. package/dist/detectors/broken-link.d.ts +17 -0
  171. package/dist/detectors/broken-link.d.ts.map +1 -0
  172. package/dist/detectors/broken-link.js +66 -0
  173. package/dist/detectors/broken-link.js.map +1 -0
  174. package/dist/detectors/cited-name.d.ts.map +1 -1
  175. package/dist/detectors/cited-name.js +4 -4
  176. package/dist/detectors/cited-name.js.map +1 -1
  177. package/dist/detectors/cited-title.d.ts +11 -0
  178. package/dist/detectors/cited-title.d.ts.map +1 -0
  179. package/dist/detectors/cited-title.js +75 -0
  180. package/dist/detectors/cited-title.js.map +1 -0
  181. package/dist/detectors/concrete-evidence.d.ts +1 -1
  182. package/dist/detectors/concrete-evidence.d.ts.map +1 -1
  183. package/dist/detectors/concrete-evidence.js +2 -1
  184. package/dist/detectors/concrete-evidence.js.map +1 -1
  185. package/dist/detectors/contrast-frame.d.ts +17 -0
  186. package/dist/detectors/contrast-frame.d.ts.map +1 -0
  187. package/dist/detectors/contrast-frame.js +32 -0
  188. package/dist/detectors/contrast-frame.js.map +1 -0
  189. package/dist/detectors/custom.d.ts +8 -0
  190. package/dist/detectors/custom.d.ts.map +1 -0
  191. package/dist/detectors/custom.js +71 -0
  192. package/dist/detectors/custom.js.map +1 -0
  193. package/dist/detectors/dangling-figure.d.ts +4 -0
  194. package/dist/detectors/dangling-figure.d.ts.map +1 -0
  195. package/dist/detectors/dangling-figure.js +18 -0
  196. package/dist/detectors/dangling-figure.js.map +1 -0
  197. package/dist/detectors/doubled-punctuation.d.ts +9 -0
  198. package/dist/detectors/doubled-punctuation.d.ts.map +1 -0
  199. package/dist/detectors/doubled-punctuation.js +33 -0
  200. package/dist/detectors/doubled-punctuation.js.map +1 -0
  201. package/dist/detectors/doubled-word.d.ts +5 -0
  202. package/dist/detectors/doubled-word.d.ts.map +1 -1
  203. package/dist/detectors/doubled-word.js +24 -11
  204. package/dist/detectors/doubled-word.js.map +1 -1
  205. package/dist/detectors/enumerated-runs.d.ts +1 -1
  206. package/dist/detectors/enumerated-runs.d.ts.map +1 -1
  207. package/dist/detectors/enumerated-runs.js +15 -4
  208. package/dist/detectors/enumerated-runs.js.map +1 -1
  209. package/dist/detectors/gram-furniture.d.ts +6 -0
  210. package/dist/detectors/gram-furniture.d.ts.map +1 -0
  211. package/dist/detectors/gram-furniture.js +21 -0
  212. package/dist/detectors/gram-furniture.js.map +1 -0
  213. package/dist/detectors/gram-place.d.ts +2 -0
  214. package/dist/detectors/gram-place.d.ts.map +1 -1
  215. package/dist/detectors/gram-place.js +9 -7
  216. package/dist/detectors/gram-place.js.map +1 -1
  217. package/dist/detectors/gram-windows.d.ts +9 -0
  218. package/dist/detectors/gram-windows.d.ts.map +1 -0
  219. package/dist/detectors/gram-windows.js +27 -0
  220. package/dist/detectors/gram-windows.js.map +1 -0
  221. package/dist/detectors/heading-case.d.ts +2 -0
  222. package/dist/detectors/heading-case.d.ts.map +1 -1
  223. package/dist/detectors/heading-case.js +29 -2
  224. package/dist/detectors/heading-case.js.map +1 -1
  225. package/dist/detectors/heading-code-words.d.ts +6 -0
  226. package/dist/detectors/heading-code-words.d.ts.map +1 -0
  227. package/dist/detectors/heading-code-words.js +29 -0
  228. package/dist/detectors/heading-code-words.js.map +1 -0
  229. package/dist/detectors/heading-echo.d.ts.map +1 -1
  230. package/dist/detectors/heading-echo.js +7 -4
  231. package/dist/detectors/heading-echo.js.map +1 -1
  232. package/dist/detectors/heading-level-skip.d.ts +12 -0
  233. package/dist/detectors/heading-level-skip.d.ts.map +1 -0
  234. package/dist/detectors/heading-level-skip.js +11 -0
  235. package/dist/detectors/heading-level-skip.js.map +1 -0
  236. package/dist/detectors/image-alt-text.d.ts +3 -0
  237. package/dist/detectors/image-alt-text.d.ts.map +1 -0
  238. package/dist/detectors/image-alt-text.js +9 -0
  239. package/dist/detectors/image-alt-text.js.map +1 -0
  240. package/dist/detectors/index.d.ts.map +1 -1
  241. package/dist/detectors/index.js +34 -1
  242. package/dist/detectors/index.js.map +1 -1
  243. package/dist/detectors/kutoten-consistency.d.ts +24 -0
  244. package/dist/detectors/kutoten-consistency.d.ts.map +1 -0
  245. package/dist/detectors/kutoten-consistency.js +77 -0
  246. package/dist/detectors/kutoten-consistency.js.map +1 -0
  247. package/dist/detectors/lead-in.d.ts +1 -0
  248. package/dist/detectors/lead-in.d.ts.map +1 -1
  249. package/dist/detectors/lead-in.js +2 -1
  250. package/dist/detectors/lead-in.js.map +1 -1
  251. package/dist/detectors/lexicon-match.d.ts +4 -0
  252. package/dist/detectors/lexicon-match.d.ts.map +1 -1
  253. package/dist/detectors/lexicon-match.js +7 -2
  254. package/dist/detectors/lexicon-match.js.map +1 -1
  255. package/dist/detectors/list-item.d.ts +45 -0
  256. package/dist/detectors/list-item.d.ts.map +1 -0
  257. package/dist/detectors/list-item.js +88 -0
  258. package/dist/detectors/list-item.js.map +1 -0
  259. package/dist/detectors/list-items.d.ts +31 -0
  260. package/dist/detectors/list-items.d.ts.map +1 -0
  261. package/dist/detectors/list-items.js +113 -0
  262. package/dist/detectors/list-items.js.map +1 -0
  263. package/dist/detectors/list-lead-in.d.ts +7 -0
  264. package/dist/detectors/list-lead-in.d.ts.map +1 -0
  265. package/dist/detectors/list-lead-in.js +28 -0
  266. package/dist/detectors/list-lead-in.js.map +1 -0
  267. package/dist/detectors/list-sentence.d.ts +65 -0
  268. package/dist/detectors/list-sentence.d.ts.map +1 -0
  269. package/dist/detectors/list-sentence.js +105 -0
  270. package/dist/detectors/list-sentence.js.map +1 -0
  271. package/dist/detectors/list-view.d.ts +34 -0
  272. package/dist/detectors/list-view.d.ts.map +1 -0
  273. package/dist/detectors/list-view.js +137 -0
  274. package/dist/detectors/list-view.js.map +1 -0
  275. package/dist/detectors/long-vowel.d.ts +7 -0
  276. package/dist/detectors/long-vowel.d.ts.map +1 -0
  277. package/dist/detectors/long-vowel.js +57 -0
  278. package/dist/detectors/long-vowel.js.map +1 -0
  279. package/dist/detectors/markup-finding.d.ts +6 -0
  280. package/dist/detectors/markup-finding.d.ts.map +1 -0
  281. package/dist/detectors/markup-finding.js +19 -0
  282. package/dist/detectors/markup-finding.js.map +1 -0
  283. package/dist/detectors/name-numeral.d.ts +1 -1
  284. package/dist/detectors/name-numeral.d.ts.map +1 -1
  285. package/dist/detectors/name-numeral.js +2 -7
  286. package/dist/detectors/name-numeral.js.map +1 -1
  287. package/dist/detectors/orthography.d.ts.map +1 -1
  288. package/dist/detectors/orthography.js +14 -10
  289. package/dist/detectors/orthography.js.map +1 -1
  290. package/dist/detectors/oxford-comma.d.ts +7 -1
  291. package/dist/detectors/oxford-comma.d.ts.map +1 -1
  292. package/dist/detectors/oxford-comma.js +135 -229
  293. package/dist/detectors/oxford-comma.js.map +1 -1
  294. package/dist/detectors/place-run.d.ts.map +1 -1
  295. package/dist/detectors/place-run.js +10 -6
  296. package/dist/detectors/place-run.js.map +1 -1
  297. package/dist/detectors/placeholder-text.d.ts +9 -0
  298. package/dist/detectors/placeholder-text.d.ts.map +1 -0
  299. package/dist/detectors/placeholder-text.js +18 -0
  300. package/dist/detectors/placeholder-text.js.map +1 -0
  301. package/dist/detectors/quote-around.d.ts +3 -0
  302. package/dist/detectors/quote-around.d.ts.map +1 -0
  303. package/dist/detectors/quote-around.js +8 -0
  304. package/dist/detectors/quote-around.js.map +1 -0
  305. package/dist/detectors/register.d.ts +11 -3
  306. package/dist/detectors/register.d.ts.map +1 -1
  307. package/dist/detectors/register.js +28 -9
  308. package/dist/detectors/register.js.map +1 -1
  309. package/dist/detectors/roman-numeral.d.ts +2 -0
  310. package/dist/detectors/roman-numeral.d.ts.map +1 -1
  311. package/dist/detectors/roman-numeral.js +2 -0
  312. package/dist/detectors/roman-numeral.js.map +1 -1
  313. package/dist/detectors/sentence-ending.d.ts +17 -1
  314. package/dist/detectors/sentence-ending.d.ts.map +1 -1
  315. package/dist/detectors/sentence-ending.js +13 -7
  316. package/dist/detectors/sentence-ending.js.map +1 -1
  317. package/dist/detectors/sentence-length.d.ts.map +1 -1
  318. package/dist/detectors/sentence-length.js +13 -4
  319. package/dist/detectors/sentence-length.js.map +1 -1
  320. package/dist/detectors/signals.d.ts +8 -0
  321. package/dist/detectors/signals.d.ts.map +1 -1
  322. package/dist/detectors/signals.js +67 -46
  323. package/dist/detectors/signals.js.map +1 -1
  324. package/dist/detectors/structure-tree.d.ts +6 -0
  325. package/dist/detectors/structure-tree.d.ts.map +1 -1
  326. package/dist/detectors/structure-tree.js +37 -1
  327. package/dist/detectors/structure-tree.js.map +1 -1
  328. package/dist/detectors/structure.d.ts +1 -3
  329. package/dist/detectors/structure.d.ts.map +1 -1
  330. package/dist/detectors/structure.js +3 -4
  331. package/dist/detectors/structure.js.map +1 -1
  332. package/dist/detectors/superlative-name.d.ts.map +1 -1
  333. package/dist/detectors/superlative-name.js +8 -5
  334. package/dist/detectors/superlative-name.js.map +1 -1
  335. package/dist/detectors/superlative-scope.d.ts.map +1 -1
  336. package/dist/detectors/superlative-scope.js +9 -4
  337. package/dist/detectors/superlative-scope.js.map +1 -1
  338. package/dist/detectors/token-column.d.ts +46 -0
  339. package/dist/detectors/token-column.d.ts.map +1 -0
  340. package/dist/detectors/token-column.js +95 -0
  341. package/dist/detectors/token-column.js.map +1 -0
  342. package/dist/detectors/unbalanced-bracket.d.ts +22 -0
  343. package/dist/detectors/unbalanced-bracket.d.ts.map +1 -0
  344. package/dist/detectors/unbalanced-bracket.js +119 -0
  345. package/dist/detectors/unbalanced-bracket.js.map +1 -0
  346. package/dist/detectors/url-run-on.d.ts +9 -0
  347. package/dist/detectors/url-run-on.d.ts.map +1 -0
  348. package/dist/detectors/url-run-on.js +19 -0
  349. package/dist/detectors/url-run-on.js.map +1 -0
  350. package/dist/document-sections.d.ts +13 -0
  351. package/dist/document-sections.d.ts.map +1 -0
  352. package/dist/document-sections.js +32 -0
  353. package/dist/document-sections.js.map +1 -0
  354. package/dist/document.d.ts +11 -4
  355. package/dist/document.d.ts.map +1 -1
  356. package/dist/document.js +90 -98
  357. package/dist/document.js.map +1 -1
  358. package/dist/email-parts.d.ts +28 -0
  359. package/dist/email-parts.d.ts.map +1 -0
  360. package/dist/email-parts.js +230 -0
  361. package/dist/email-parts.js.map +1 -0
  362. package/dist/eval.d.ts +2 -1
  363. package/dist/eval.d.ts.map +1 -1
  364. package/dist/eval.js +16 -4
  365. package/dist/eval.js.map +1 -1
  366. package/dist/figure-references.d.ts +30 -0
  367. package/dist/figure-references.d.ts.map +1 -0
  368. package/dist/figure-references.js +76 -0
  369. package/dist/figure-references.js.map +1 -0
  370. package/dist/files.d.ts +2 -0
  371. package/dist/files.d.ts.map +1 -1
  372. package/dist/files.js +4 -0
  373. package/dist/files.js.map +1 -1
  374. package/dist/heading-label.d.ts +22 -0
  375. package/dist/heading-label.d.ts.map +1 -0
  376. package/dist/heading-label.js +50 -0
  377. package/dist/heading-label.js.map +1 -0
  378. package/dist/in-page-nav.d.ts +4 -1
  379. package/dist/in-page-nav.d.ts.map +1 -1
  380. package/dist/in-page-nav.js +53 -18
  381. package/dist/in-page-nav.js.map +1 -1
  382. package/dist/joined-view.d.ts.map +1 -1
  383. package/dist/joined-view.js +1 -0
  384. package/dist/joined-view.js.map +1 -1
  385. package/dist/levels.d.ts +5 -1
  386. package/dist/levels.d.ts.map +1 -1
  387. package/dist/levels.js +9 -0
  388. package/dist/levels.js.map +1 -1
  389. package/dist/line-paragraphs.d.ts +8 -0
  390. package/dist/line-paragraphs.d.ts.map +1 -1
  391. package/dist/line-paragraphs.js +33 -10
  392. package/dist/line-paragraphs.js.map +1 -1
  393. package/dist/long-vowel.d.ts +35 -0
  394. package/dist/long-vowel.d.ts.map +1 -0
  395. package/dist/long-vowel.js +71 -0
  396. package/dist/long-vowel.js.map +1 -0
  397. package/dist/markdown-node.d.ts +19 -0
  398. package/dist/markdown-node.d.ts.map +1 -0
  399. package/dist/markdown-node.js +6 -0
  400. package/dist/markdown-node.js.map +1 -0
  401. package/dist/markdown-read.d.ts +17 -0
  402. package/dist/markdown-read.d.ts.map +1 -0
  403. package/dist/markdown-read.js +37 -0
  404. package/dist/markdown-read.js.map +1 -0
  405. package/dist/markup.d.ts +22 -0
  406. package/dist/markup.d.ts.map +1 -0
  407. package/dist/markup.js +180 -0
  408. package/dist/markup.js.map +1 -0
  409. package/dist/mask.js +8 -5
  410. package/dist/mask.js.map +1 -1
  411. package/dist/number-name.d.ts +21 -5
  412. package/dist/number-name.d.ts.map +1 -1
  413. package/dist/number-name.js +119 -17
  414. package/dist/number-name.js.map +1 -1
  415. package/dist/orthography.d.ts +2 -0
  416. package/dist/orthography.d.ts.map +1 -1
  417. package/dist/orthography.js +9 -4
  418. package/dist/orthography.js.map +1 -1
  419. package/dist/page-furniture.d.ts +5 -2
  420. package/dist/page-furniture.d.ts.map +1 -1
  421. package/dist/page-furniture.js +8 -2
  422. package/dist/page-furniture.js.map +1 -1
  423. package/dist/plain-source.d.ts +1 -0
  424. package/dist/plain-source.d.ts.map +1 -1
  425. package/dist/plain-source.js +2 -1
  426. package/dist/plain-source.js.map +1 -1
  427. package/dist/plugin.d.ts +115 -0
  428. package/dist/plugin.d.ts.map +1 -1
  429. package/dist/profile/for-file.d.ts.map +1 -1
  430. package/dist/profile/for-file.js +3 -1
  431. package/dist/profile/for-file.js.map +1 -1
  432. package/dist/quoted-span.d.ts.map +1 -1
  433. package/dist/quoted-span.js +8 -3
  434. package/dist/quoted-span.js.map +1 -1
  435. package/dist/reasons.d.ts +3 -0
  436. package/dist/reasons.d.ts.map +1 -1
  437. package/dist/reasons.js +6 -0
  438. package/dist/reasons.js.map +1 -1
  439. package/dist/reference-lists.d.ts +3 -0
  440. package/dist/reference-lists.d.ts.map +1 -0
  441. package/dist/reference-lists.js +75 -0
  442. package/dist/reference-lists.js.map +1 -0
  443. package/dist/render/explain.d.ts +7 -1
  444. package/dist/render/explain.d.ts.map +1 -1
  445. package/dist/render/explain.js +36 -12
  446. package/dist/render/explain.js.map +1 -1
  447. package/dist/render/friendly.d.ts.map +1 -1
  448. package/dist/render/friendly.js +19 -9
  449. package/dist/render/friendly.js.map +1 -1
  450. package/dist/render/options.d.ts +7 -0
  451. package/dist/render/options.d.ts.map +1 -0
  452. package/dist/render/options.js +50 -0
  453. package/dist/render/options.js.map +1 -0
  454. package/dist/render/rules-json.d.ts +4 -1
  455. package/dist/render/rules-json.d.ts.map +1 -1
  456. package/dist/render/rules-json.js +102 -12
  457. package/dist/render/rules-json.js.map +1 -1
  458. package/dist/render/rules-table.d.ts +4 -0
  459. package/dist/render/rules-table.d.ts.map +1 -0
  460. package/dist/render/rules-table.js +70 -0
  461. package/dist/render/rules-table.js.map +1 -0
  462. package/dist/render/sarif.js +4 -4
  463. package/dist/render/sarif.js.map +1 -1
  464. package/dist/render/semantic.js +3 -3
  465. package/dist/render/semantic.js.map +1 -1
  466. package/dist/render/severity-name.d.ts +6 -0
  467. package/dist/render/severity-name.d.ts.map +1 -0
  468. package/dist/render/severity-name.js +7 -0
  469. package/dist/render/severity-name.js.map +1 -0
  470. package/dist/render/text.d.ts +7 -2
  471. package/dist/render/text.d.ts.map +1 -1
  472. package/dist/render/text.js +15 -4
  473. package/dist/render/text.js.map +1 -1
  474. package/dist/resolve-genre.d.ts +1 -1
  475. package/dist/resolve-genre.d.ts.map +1 -1
  476. package/dist/resolve-genre.js +4 -1
  477. package/dist/resolve-genre.js.map +1 -1
  478. package/dist/rule-genres.d.ts +24 -0
  479. package/dist/rule-genres.d.ts.map +1 -0
  480. package/dist/rule-genres.js +11 -0
  481. package/dist/rule-genres.js.map +1 -0
  482. package/dist/rule-guide.d.ts +54 -0
  483. package/dist/rule-guide.d.ts.map +1 -0
  484. package/dist/rule-guide.js +81 -0
  485. package/dist/rule-guide.js.map +1 -0
  486. package/dist/rule-load.d.ts.map +1 -1
  487. package/dist/rule-load.js +87 -33
  488. package/dist/rule-load.js.map +1 -1
  489. package/dist/rule-options.d.ts +50 -0
  490. package/dist/rule-options.d.ts.map +1 -0
  491. package/dist/rule-options.js +106 -0
  492. package/dist/rule-options.js.map +1 -0
  493. package/dist/run.d.ts +13 -0
  494. package/dist/run.d.ts.map +1 -1
  495. package/dist/run.js +54 -10
  496. package/dist/run.js.map +1 -1
  497. package/dist/sentence-shape.d.ts.map +1 -1
  498. package/dist/sentence-shape.js +4 -4
  499. package/dist/sentence-shape.js.map +1 -1
  500. package/dist/setting-problems.d.ts +2 -1
  501. package/dist/setting-problems.d.ts.map +1 -1
  502. package/dist/setting-problems.js +6 -1
  503. package/dist/setting-problems.js.map +1 -1
  504. package/dist/span-cut.d.ts +6 -0
  505. package/dist/span-cut.d.ts.map +1 -0
  506. package/dist/span-cut.js +22 -0
  507. package/dist/span-cut.js.map +1 -0
  508. package/dist/structure/aside-depth.d.ts +21 -0
  509. package/dist/structure/aside-depth.d.ts.map +1 -0
  510. package/dist/structure/aside-depth.js +65 -0
  511. package/dist/structure/aside-depth.js.map +1 -0
  512. package/dist/structure/build.d.ts +5 -1
  513. package/dist/structure/build.d.ts.map +1 -1
  514. package/dist/structure/build.js +29 -17
  515. package/dist/structure/build.js.map +1 -1
  516. package/dist/structure/closed-pairs.d.ts +8 -0
  517. package/dist/structure/closed-pairs.d.ts.map +1 -0
  518. package/dist/structure/closed-pairs.js +22 -0
  519. package/dist/structure/closed-pairs.js.map +1 -0
  520. package/dist/structure/date-range.d.ts +21 -0
  521. package/dist/structure/date-range.d.ts.map +1 -0
  522. package/dist/structure/date-range.js +45 -0
  523. package/dist/structure/date-range.js.map +1 -0
  524. package/dist/structure/known-mentions.d.ts +18 -0
  525. package/dist/structure/known-mentions.d.ts.map +1 -0
  526. package/dist/structure/known-mentions.js +78 -0
  527. package/dist/structure/known-mentions.js.map +1 -0
  528. package/dist/structure/numbering.d.ts +1 -0
  529. package/dist/structure/numbering.d.ts.map +1 -1
  530. package/dist/structure/numbering.js +11 -6
  531. package/dist/structure/numbering.js.map +1 -1
  532. package/dist/structure/of.d.ts +3 -1
  533. package/dist/structure/of.d.ts.map +1 -1
  534. package/dist/structure/of.js +5 -1
  535. package/dist/structure/of.js.map +1 -1
  536. package/dist/structure/percent-sum.d.ts +16 -0
  537. package/dist/structure/percent-sum.d.ts.map +1 -0
  538. package/dist/structure/percent-sum.js +104 -0
  539. package/dist/structure/percent-sum.js.map +1 -0
  540. package/dist/structure/quoted-number.d.ts +8 -0
  541. package/dist/structure/quoted-number.d.ts.map +1 -0
  542. package/dist/structure/quoted-number.js +34 -0
  543. package/dist/structure/quoted-number.js.map +1 -0
  544. package/dist/structure/relative-find.d.ts.map +1 -1
  545. package/dist/structure/relative-find.js +34 -46
  546. package/dist/structure/relative-find.js.map +1 -1
  547. package/dist/structure/relative-resolve.d.ts.map +1 -1
  548. package/dist/structure/relative-resolve.js +76 -30
  549. package/dist/structure/relative-resolve.js.map +1 -1
  550. package/dist/structure/runs.d.ts +2 -0
  551. package/dist/structure/runs.d.ts.map +1 -1
  552. package/dist/structure/runs.js +2 -2
  553. package/dist/structure/runs.js.map +1 -1
  554. package/dist/structure/sexp.d.ts +1 -1
  555. package/dist/structure/sexp.d.ts.map +1 -1
  556. package/dist/structure/sexp.js +18 -6
  557. package/dist/structure/sexp.js.map +1 -1
  558. package/dist/structure/total.d.ts +3 -0
  559. package/dist/structure/total.d.ts.map +1 -1
  560. package/dist/structure/total.js +2 -2
  561. package/dist/structure/total.js.map +1 -1
  562. package/dist/structure/universal.d.ts +14 -2
  563. package/dist/structure/universal.d.ts.map +1 -1
  564. package/dist/structure/universal.js +17 -2
  565. package/dist/structure/universal.js.map +1 -1
  566. package/dist/structure/wrapped-tail.d.ts +14 -7
  567. package/dist/structure/wrapped-tail.d.ts.map +1 -1
  568. package/dist/structure/wrapped-tail.js +33 -8
  569. package/dist/structure/wrapped-tail.js.map +1 -1
  570. package/dist/style-load.d.ts +4 -0
  571. package/dist/style-load.d.ts.map +1 -0
  572. package/dist/style-load.js +28 -0
  573. package/dist/style-load.js.map +1 -0
  574. package/dist/style-parse.d.ts +19 -0
  575. package/dist/style-parse.d.ts.map +1 -0
  576. package/dist/style-parse.js +60 -0
  577. package/dist/style-parse.js.map +1 -0
  578. package/dist/subheading-line.d.ts +6 -0
  579. package/dist/subheading-line.d.ts.map +1 -0
  580. package/dist/subheading-line.js +57 -0
  581. package/dist/subheading-line.js.map +1 -0
  582. package/dist/template-syntax.d.ts +17 -0
  583. package/dist/template-syntax.d.ts.map +1 -0
  584. package/dist/template-syntax.js +140 -0
  585. package/dist/template-syntax.js.map +1 -0
  586. package/dist/text-above.d.ts +19 -0
  587. package/dist/text-above.d.ts.map +1 -0
  588. package/dist/text-above.js +43 -0
  589. package/dist/text-above.js.map +1 -0
  590. package/dist/text-figures.d.ts +10 -0
  591. package/dist/text-figures.d.ts.map +1 -0
  592. package/dist/text-figures.js +131 -0
  593. package/dist/text-figures.js.map +1 -0
  594. package/dist/trailing-aside.d.ts +2 -0
  595. package/dist/trailing-aside.d.ts.map +1 -0
  596. package/dist/trailing-aside.js +53 -0
  597. package/dist/trailing-aside.js.map +1 -0
  598. package/dist/tree-walk.d.ts +18 -0
  599. package/dist/tree-walk.d.ts.map +1 -0
  600. package/dist/tree-walk.js +45 -0
  601. package/dist/tree-walk.js.map +1 -0
  602. package/genres.yaml +26 -0
  603. package/package.json +5 -3
  604. package/reference-headings.yaml +17 -0
  605. package/rules/adverb-overuse.yaml +19 -0
  606. package/rules/agentless-passive.yaml +19 -0
  607. package/rules/agreement-slip.yaml +14 -1
  608. package/rules/ai-generated-composite.yaml +102 -0
  609. package/rules/ai-tell.yaml +23 -0
  610. package/rules/announced-count-mismatch.yaml +57 -0
  611. package/rules/announcing-opener.yaml +51 -0
  612. package/rules/assistant-residue.yaml +52 -0
  613. package/rules/bold-density.yaml +31 -0
  614. package/rules/broken-link.yaml +65 -0
  615. package/rules/closing-cliche.yaml +33 -0
  616. package/rules/colon-lead-in.yaml +59 -0
  617. package/rules/concrete-evidence-density.yaml +41 -0
  618. package/rules/contraction-consistency.yaml +18 -0
  619. package/rules/contrast-framing.yaml +57 -0
  620. package/rules/cushion-phrase-density.yaml +25 -0
  621. package/rules/dangling-figure-reference.yaml +61 -0
  622. package/rules/dangling-reference.yaml +53 -1
  623. package/rules/date-order.yaml +33 -1
  624. package/rules/date-range-reversed.yaml +46 -0
  625. package/rules/date-weekday-mismatch.yaml +17 -1
  626. package/rules/double-keigo.yaml +16 -0
  627. package/rules/doubled-punctuation.yaml +45 -0
  628. package/rules/doubled-word.yaml +17 -1
  629. package/rules/duplicate-definition.yaml +59 -1
  630. package/rules/emoji-density.yaml +25 -0
  631. package/rules/empty-conclusion.yaml +28 -0
  632. package/rules/empty-intensifier.yaml +19 -0
  633. package/rules/excessive-hedging.yaml +19 -0
  634. package/rules/expletive-construction.yaml +19 -0
  635. package/rules/heading-echo.yaml +31 -0
  636. package/rules/heading-level-skip.yaml +78 -0
  637. package/rules/hiragana-fukushi.yaml +16 -0
  638. package/rules/image-alt-text.yaml +54 -0
  639. package/rules/internal-jargon.yaml +21 -0
  640. package/rules/katakana-long-vowel.yaml +98 -0
  641. package/rules/kutoten-consistency.yaml +53 -0
  642. package/rules/latin-spacing.yaml +23 -4
  643. package/rules/max-kanji-continuous.yaml +16 -0
  644. package/rules/max-paragraph-length.yaml +33 -0
  645. package/rules/max-sentence-length.yaml +32 -0
  646. package/rules/ngram-repetition.yaml +29 -2
  647. package/rules/no-doubled-joshi.yaml +16 -0
  648. package/rules/no-em-dash.yaml +25 -0
  649. package/rules/no-mixed-desumasu.yaml +27 -2
  650. package/rules/no-nakaguro-parallel.yaml +20 -0
  651. package/rules/numbering-gap.yaml +53 -1
  652. package/rules/oxford-comma-consistency.yaml +18 -0
  653. package/rules/padded-intro.yaml +19 -0
  654. package/rules/paragraph-length-variance.yaml +49 -0
  655. package/rules/percent-sum-mismatch.yaml +58 -0
  656. package/rules/preamble-length.yaml +56 -0
  657. package/rules/preferred-term.yaml +27 -0
  658. package/rules/proper-noun-density.yaml +26 -0
  659. package/rules/repeated-conjunction.yaml +47 -0
  660. package/rules/repeated-sentence-head.yaml +23 -0
  661. package/rules/required-sections.yaml +49 -0
  662. package/rules/risk-disclosure.yaml +22 -0
  663. package/rules/rule-of-three.yaml +97 -0
  664. package/rules/sasete-itadaku.yaml +18 -0
  665. package/rules/section-length-uniformity.yaml +89 -0
  666. package/rules/sentence-initial-conjunction-run.yaml +18 -0
  667. package/rules/sentence-rhythm.yaml +25 -0
  668. package/rules/stock-transition.yaml +55 -0
  669. package/rules/stray-space.yaml +18 -0
  670. package/rules/taigen-dome-in-prose.yaml +19 -0
  671. package/rules/title-case-consistency.yaml +42 -0
  672. package/rules/total-mismatch.yaml +37 -1
  673. package/rules/unbalanced-bracket.yaml +56 -0
  674. package/rules/undefined-acronym.yaml +22 -0
  675. package/rules/unfilled-placeholder.yaml +50 -0
  676. package/rules/unqualified-superlative.yaml +19 -0
  677. package/rules/unsourced-number.yaml +16 -0
  678. package/rules/url-run-on.yaml +45 -0
  679. package/skills/chaff/SKILL.md +70 -0
  680. package/src/announced-count.ts +148 -0
  681. package/src/bare-url.ts +35 -0
  682. package/src/baseline.ts +17 -1
  683. package/src/body-section.ts +7 -0
  684. package/src/calendar-number.ts +18 -4
  685. package/src/cli-args.ts +6 -0
  686. package/src/cli-text.ts +8 -4
  687. package/src/cli.ts +37 -37
  688. package/src/commands/compare.ts +80 -0
  689. package/src/commands/eval.ts +19 -8
  690. package/src/commands/feedback.ts +12 -6
  691. package/src/commands/test.ts +2 -4
  692. package/src/commands/tree.ts +41 -5
  693. package/src/compare/atom.ts +33 -0
  694. package/src/compare/clock-time.ts +86 -0
  695. package/src/compare/extract.ts +78 -0
  696. package/src/compare/fact-text.ts +68 -0
  697. package/src/compare/markup-atoms.ts +29 -0
  698. package/src/compare/match.ts +105 -0
  699. package/src/compare/outcome.ts +70 -0
  700. package/src/compare/proper-nouns.ts +65 -0
  701. package/src/compare/render.ts +102 -0
  702. package/src/compare/spans.ts +17 -0
  703. package/src/compare/text-atoms.ts +95 -0
  704. package/src/compare/text.ts +120 -0
  705. package/src/compare/tree-atoms.ts +80 -0
  706. package/src/compare/written-names.ts +26 -0
  707. package/src/config/load.ts +21 -0
  708. package/src/config/option-problems.ts +70 -0
  709. package/src/config/read.ts +8 -0
  710. package/src/config/rule-problems.ts +12 -2
  711. package/src/config/style.ts +42 -0
  712. package/src/config/warnings.ts +13 -0
  713. package/src/config/write.ts +18 -4
  714. package/src/custom/bounded-match.ts +58 -0
  715. package/src/custom/load.ts +15 -0
  716. package/src/custom/parse.ts +274 -0
  717. package/src/custom/problems.ts +89 -0
  718. package/src/custom/regex-safety.ts +118 -0
  719. package/src/custom/token-pattern.ts +84 -0
  720. package/src/detect.ts +28 -2
  721. package/src/detectors/acronym-context.ts +16 -4
  722. package/src/detectors/ai-phrasing.ts +137 -0
  723. package/src/detectors/announced-count.ts +25 -0
  724. package/src/detectors/broken-link.ts +90 -0
  725. package/src/detectors/cited-name.ts +6 -5
  726. package/src/detectors/cited-title.ts +96 -0
  727. package/src/detectors/concrete-evidence.ts +3 -2
  728. package/src/detectors/contrast-frame.ts +54 -0
  729. package/src/detectors/custom.ts +89 -0
  730. package/src/detectors/dangling-figure.ts +22 -0
  731. package/src/detectors/doubled-punctuation.ts +49 -0
  732. package/src/detectors/doubled-word.ts +19 -4
  733. package/src/detectors/enumerated-runs.ts +13 -4
  734. package/src/detectors/gram-furniture.ts +30 -0
  735. package/src/detectors/gram-place.ts +9 -5
  736. package/src/detectors/gram-windows.ts +31 -0
  737. package/src/detectors/heading-case.ts +30 -2
  738. package/src/detectors/heading-code-words.ts +35 -0
  739. package/src/detectors/heading-echo.ts +8 -4
  740. package/src/detectors/heading-level-skip.ts +19 -0
  741. package/src/detectors/image-alt-text.ts +11 -0
  742. package/src/detectors/index.ts +43 -1
  743. package/src/detectors/kutoten-consistency.ts +96 -0
  744. package/src/detectors/lead-in.ts +3 -1
  745. package/src/detectors/lexicon-match.ts +9 -2
  746. package/src/detectors/list-item.ts +122 -0
  747. package/src/detectors/list-items.ts +163 -0
  748. package/src/detectors/list-lead-in.ts +33 -0
  749. package/src/detectors/list-sentence.ts +157 -0
  750. package/src/detectors/list-view.ts +157 -0
  751. package/src/detectors/long-vowel.ts +66 -0
  752. package/src/detectors/markup-finding.ts +24 -0
  753. package/src/detectors/name-numeral.ts +4 -2
  754. package/src/detectors/orthography.ts +23 -17
  755. package/src/detectors/oxford-comma.ts +178 -283
  756. package/src/detectors/place-run.ts +7 -4
  757. package/src/detectors/placeholder-text.ts +27 -0
  758. package/src/detectors/quote-around.ts +9 -0
  759. package/src/detectors/register.ts +37 -10
  760. package/src/detectors/roman-numeral.ts +3 -0
  761. package/src/detectors/sentence-ending.ts +14 -7
  762. package/src/detectors/sentence-length.ts +16 -5
  763. package/src/detectors/signals.ts +80 -46
  764. package/src/detectors/structure-tree.ts +45 -1
  765. package/src/detectors/structure.ts +3 -4
  766. package/src/detectors/superlative-name.ts +7 -4
  767. package/src/detectors/superlative-scope.ts +8 -3
  768. package/src/detectors/token-column.ts +149 -0
  769. package/src/detectors/unbalanced-bracket.ts +153 -0
  770. package/src/detectors/url-run-on.ts +27 -0
  771. package/src/document-sections.ts +46 -0
  772. package/src/document.ts +106 -138
  773. package/src/email-parts.ts +269 -0
  774. package/src/eval.ts +14 -4
  775. package/src/figure-references.ts +112 -0
  776. package/src/files.ts +5 -0
  777. package/src/heading-label.ts +55 -0
  778. package/src/in-page-nav.ts +48 -19
  779. package/src/joined-view.ts +1 -0
  780. package/src/levels.ts +14 -1
  781. package/src/line-paragraphs.ts +52 -9
  782. package/src/long-vowel.ts +99 -0
  783. package/src/markdown-node.ts +19 -0
  784. package/src/markdown-read.ts +44 -0
  785. package/src/markup.ts +210 -0
  786. package/src/mask.ts +8 -8
  787. package/src/number-name.ts +151 -24
  788. package/src/orthography.ts +10 -3
  789. package/src/page-furniture.ts +11 -2
  790. package/src/plain-source.ts +2 -1
  791. package/src/plugin.ts +101 -1
  792. package/src/profile/for-file.ts +3 -1
  793. package/src/quoted-span.ts +9 -3
  794. package/src/reasons.ts +9 -0
  795. package/src/reference-lists.ts +91 -0
  796. package/src/render/explain.ts +47 -13
  797. package/src/render/friendly.ts +20 -9
  798. package/src/render/options.ts +58 -0
  799. package/src/render/rules-json.ts +130 -14
  800. package/src/render/rules-table.ts +91 -0
  801. package/src/render/sarif.ts +4 -4
  802. package/src/render/semantic.ts +3 -3
  803. package/src/render/severity-name.ts +10 -0
  804. package/src/render/text.ts +21 -7
  805. package/src/resolve-genre.ts +4 -1
  806. package/src/rule-genres.ts +25 -0
  807. package/src/rule-guide.ts +135 -0
  808. package/src/rule-load.ts +91 -34
  809. package/src/rule-options.ts +131 -0
  810. package/src/run.ts +74 -11
  811. package/src/sentence-shape.ts +4 -5
  812. package/src/setting-problems.ts +7 -1
  813. package/src/span-cut.ts +28 -0
  814. package/src/structure/aside-depth.ts +67 -0
  815. package/src/structure/build.ts +38 -19
  816. package/src/structure/closed-pairs.ts +20 -0
  817. package/src/structure/date-range.ts +69 -0
  818. package/src/structure/known-mentions.ts +96 -0
  819. package/src/structure/numbering.ts +9 -5
  820. package/src/structure/of.ts +11 -3
  821. package/src/structure/percent-sum.ts +135 -0
  822. package/src/structure/quoted-number.ts +36 -0
  823. package/src/structure/relative-find.ts +34 -47
  824. package/src/structure/relative-resolve.ts +77 -30
  825. package/src/structure/runs.ts +2 -2
  826. package/src/structure/sexp.ts +17 -5
  827. package/src/structure/total.ts +2 -2
  828. package/src/structure/universal.ts +24 -4
  829. package/src/structure/wrapped-tail.ts +38 -13
  830. package/src/style-load.ts +28 -0
  831. package/src/style-parse.ts +77 -0
  832. package/src/subheading-line.ts +68 -0
  833. package/src/template-syntax.ts +164 -0
  834. package/src/text-above.ts +49 -0
  835. package/src/text-figures.ts +147 -0
  836. package/src/trailing-aside.ts +50 -0
  837. package/src/tree-walk.ts +48 -0
  838. package/styles/bunkacho.yaml +25 -0
  839. package/styles/ieice.yaml +29 -0
  840. package/styles/jis-z8301-2011.yaml +25 -0
@@ -0,0 +1,122 @@
1
+ import type { Token } from "../plugin.ts";
2
+ import { APPOSITIVE_ANCHOR, NOMINAL, verbFormOf, type Columns, type ItemScope } from "./list-sentence.ts";
3
+ import { countIn, firstIn, lastIn, lowerBound, type TokenRange } from "./token-column.ts";
4
+
5
+ // 並びの項目への問い。項目は文の中の一続きの範囲で、and / or と同じ深さの読点を除いたもの。どの問いも範囲を読み直さず、
6
+ // 文を一度読んで作った列(list-sentence.ts)から答える。
7
+
8
+ type ColumnName = keyof Columns;
9
+
10
+ const count = (scope: ItemScope, name: ColumnName, item: TokenRange): number => countIn(scope.sentence.column[name], item, scope.level);
11
+
12
+ const tokenAt = (scope: ItemScope, index: number): Token | undefined => (index === -1 ? undefined : scope.sentence.tokens[index]);
13
+
14
+ export const firstAt = (scope: ItemScope, name: ColumnName, item: TokenRange): number => firstIn(scope.sentence.column[name], item, scope.level);
15
+
16
+ const first = (scope: ItemScope, name: ColumnName, item: TokenRange): Token | undefined => tokenAt(scope, firstAt(scope, name, item));
17
+
18
+ const last = (scope: ItemScope, name: ColumnName, item: TokenRange): Token | undefined =>
19
+ tokenAt(scope, lastIn(scope.sentence.column[name], item, scope.level));
20
+
21
+ export const hasContent = (scope: ItemScope, item: TokenRange): boolean => count(scope, "content", item) > 0;
22
+
23
+ export const contentCount = (scope: ItemScope, item: TokenRange): number => count(scope, "content", item);
24
+
25
+ export const firstContent = (scope: ItemScope, item: TokenRange): Token | undefined => first(scope, "content", item);
26
+
27
+ export const lastContent = (scope: ItemScope, item: TokenRange): Token | undefined => last(scope, "content", item);
28
+
29
+ const shapeOfHead = (head: Token | undefined): string | undefined => {
30
+ if (head === undefined) return undefined;
31
+ return NOMINAL.has(head.pos) ? "NOMINAL" : head.pos;
32
+ };
33
+
34
+ /** 冠詞や引用符を飛ばした、項目の頭の品詞。the parser と an exporter と samples を同じ形と見る。 */
35
+ export const shapeOf = (scope: ItemScope, item: TokenRange): string | undefined => shapeOfHead(firstContent(scope, item));
36
+
37
+ /** 副詞を飛ばした頭の形。explain and justify と ultimately ensure は同じ動詞の項目。 */
38
+ export const leadShape = (scope: ItemScope, item: TokenRange): string | undefined => shapeOfHead(first(scope, "contentNotAdverb", item));
39
+
40
+ export const openingOf = (scope: ItemScope, item: TokenRange): Token | undefined => first(scope, "open", item);
41
+
42
+ export const isParticiple = (token: Token): boolean => token.features?.["VerbForm"] === "Part";
43
+
44
+ export const openingKind = (scope: ItemScope, item: TokenRange): string | undefined => {
45
+ const opening = openingOf(scope, item);
46
+ return opening !== undefined && isParticiple(opening) ? "PARTICIPLE" : shapeOf(scope, item);
47
+ };
48
+
49
+ export const hasVerb = (scope: ItemScope, item: TokenRange): boolean => count(scope, "verbal", item) > 0;
50
+
51
+ export const hasListConjunction = (scope: ItemScope, item: TokenRange): boolean => count(scope, "conjunction", item) > 0;
52
+
53
+ export const hasAdposition = (scope: ItemScope, item: TokenRange): boolean => count(scope, "adposition", item) > 0;
54
+
55
+ export const hasDeterminer = (scope: ItemScope, item: TokenRange): boolean => count(scope, "determiner", item) > 0;
56
+
57
+ /** 主語と述語のある項目。the team fixed the bug / these are crucial。gets us more は述語だけ。頭は冠詞か名詞なので、動詞はその後ろ。 */
58
+ export const isClause = (scope: ItemScope, item: TokenRange): boolean => {
59
+ const opening = openingOf(scope, item);
60
+ if (opening === undefined || !(opening.pos === "DET" || NOMINAL.has(opening.pos))) return false;
61
+ return hasVerb(scope, item);
62
+ };
63
+
64
+ /** 頭の語のあとに前置詞の句を連れた項目(updates on the Google Doc)。 */
65
+ export const hasPrepositionalTail = (scope: ItemScope, item: TokenRange): boolean => {
66
+ const head = firstAt(scope, "content", item);
67
+ return hasAdposition(scope, { start: head === -1 ? item.start : head + 1, end: item.end });
68
+ };
69
+
70
+ /** 項目の頭の分詞とその形。副詞は飛ばす(originally written)。引用符の中の語(‘modelling’)は語の例なので分詞と読まない。 */
71
+ export const participleOpening = (scope: ItemScope, item: TokenRange): { readonly at: number; readonly form: string } | undefined => {
72
+ const at = firstAt(scope, "notPunctuationOrAdverb", item);
73
+ const opening = tokenAt(scope, at);
74
+ if (opening === undefined) return undefined;
75
+ const form = scope.sentence.words.participle.has(opening.surface.toLowerCase()) ? "Ger" : verbFormOf(opening);
76
+ return form === undefined ? undefined : { at, form };
77
+ };
78
+
79
+ export const hasParticiple = (scope: ItemScope, item: TokenRange, form: string): boolean => count(scope, form === "Ger" ? "gerund" : "participle", item) > 0;
80
+
81
+ /** 名詞にかかる語。解析器は分詞を過去形とも読む(registered or certified mail の certified)ので、動詞も数える。 */
82
+ const MODIFIER = new Set(["ADJ", "VERB"]);
83
+
84
+ export const isModifier = (token: Token | undefined): boolean => token?.pos === "ADJ" || (token !== undefined && isParticiple(token));
85
+
86
+ /** 修飾語と名詞だけの句(certified mail / artificial flavor)。冠詞や目的語を連れた動詞(adopt their resources)は違う。 */
87
+ export const isModifiedNoun = (scope: ItemScope, item: TokenRange): boolean => {
88
+ const headAt = firstAt(scope, "open", item);
89
+ const tail = { start: headAt === -1 ? item.end : headAt + 1, end: item.end };
90
+ const tailLength = count(scope, "open", tail);
91
+ const nounPhrase = tailLength > 0 && tailLength === count(scope, "nounPhraseTail", tail);
92
+ return MODIFIER.has(tokenAt(scope, headAt)?.pos ?? "") && nounPhrase && APPOSITIVE_ANCHOR.has(last(scope, "open", tail)?.pos ?? "");
93
+ };
94
+
95
+ export const isPluralNounPhrase = (scope: ItemScope, item: TokenRange): boolean =>
96
+ count(scope, "content", item) === count(scope, "nounPhraseTail", item) && lastContent(scope, item)?.features?.["Number"] === "Plur";
97
+
98
+ export const firstNoun = (scope: ItemScope, item: TokenRange): Token | undefined => first(scope, "noun", item);
99
+
100
+ export const lastNoun = (scope: ItemScope, item: TokenRange): Token | undefined => last(scope, "noun", item);
101
+
102
+ /** and / or の後ろの項目。次の読点か節の切れ目まで。 */
103
+ export const itemAfter = (scope: ItemScope, at: number): TokenRange => {
104
+ const rest = { start: at + 1, end: scope.sentence.tokens.length };
105
+ const end = firstIn(scope.sentence.column.itemEnd, rest);
106
+ return { start: rest.start, end: end === -1 ? rest.end : end };
107
+ };
108
+
109
+ /**
110
+ * 項目の中で、and / or と同じ深さにある最後の例の句(such as / e.g.)の直後の位置。無ければ -1。句は項目の中で終わるものだけ。
111
+ * 項目の終わりをまたぐ句は、項目の最後の数語から始まるものだけなので、後ろから見て数個で決まる。
112
+ */
113
+ export const exampleEnd = (scope: ItemScope, item: TokenRange): number => {
114
+ const starts = scope.sentence.exampleStarts.get(scope.level) ?? [];
115
+ const within = (from: number): number => {
116
+ const start = starts[from];
117
+ if (start === undefined || start < item.start) return -1;
118
+ const end = (scope.sentence.exampleEnds[start] ?? []).find((phraseLast) => phraseLast < item.end);
119
+ return end === undefined ? within(from - 1) : end + 1;
120
+ };
121
+ return within(lowerBound(starts, item.end) - 1);
122
+ };
@@ -0,0 +1,163 @@
1
+ import {
2
+ exampleEnd,
3
+ firstContent,
4
+ hasContent,
5
+ hasPrepositionalTail,
6
+ hasVerb,
7
+ isClause,
8
+ lastContent,
9
+ openingOf,
10
+ participleOpening,
11
+ shapeOf,
12
+ } from "./list-item.ts";
13
+ import { isListConjunction, scopeOf, VERBAL, type ItemScope, type ListSentence } from "./list-sentence.ts";
14
+ import { lowerBound, type TokenRange } from "./token-column.ts";
15
+
16
+ // and / or の前の項目を、節の頭から読点ごとに切った並び。and / or ごとに節の頭から切り直すと、and の多い文で語数の二乗になる。
17
+ // ここでは深さごとに一度だけ左から読み、読点で閉じた項目は固めて、並び全体への問い(どれも節か、最後に例の句がある項目はどれか)
18
+ // に答えるための表を足していく。and / or のたびに作るのは、まだ閉じていない最後の 1、2 項目だけ。
19
+
20
+ /** 項目ごとに一度だけ答えを覚えておく問い。 */
21
+ export type Flag = "closed" | "example" | "participle" | "verbalShape" | "hasVerb" | "isClause" | "prepositionalTail" | "notNounHead" | "notProperNounHead";
22
+
23
+ type FlagTest = (scope: ItemScope, item: TokenRange) => boolean;
24
+
25
+ export const FLAG_TESTS: Readonly<Record<Flag, FlagTest>> = {
26
+ closed: (scope, item) => isListConjunction(openingOf(scope, item)),
27
+ example: (scope, item) => exampleEnd(scope, item) !== -1,
28
+ participle: (scope, item) => participleOpening(scope, item) !== undefined,
29
+ verbalShape: (scope, item) => VERBAL.has(shapeOf(scope, item) ?? ""),
30
+ hasVerb,
31
+ isClause,
32
+ prepositionalTail: hasPrepositionalTail,
33
+ notNounHead: (scope, item) => firstContent(scope, item)?.pos !== "NOUN",
34
+ notProperNounHead: (scope, item) => firstContent(scope, item)?.pos !== "PROPN",
35
+ };
36
+
37
+ const FLAGS = Object.keys(FLAG_TESTS).filter((name): name is Flag => Object.hasOwn(FLAG_TESTS, name));
38
+
39
+ type PerFlag<T> = Record<Flag, T>;
40
+
41
+ const perFlag = <T>(make: () => T): PerFlag<T> => ({
42
+ closed: make(),
43
+ example: make(),
44
+ participle: make(),
45
+ verbalShape: make(),
46
+ hasVerb: make(),
47
+ isClause: make(),
48
+ prepositionalTail: make(),
49
+ notNounHead: make(),
50
+ notProperNounHead: make(),
51
+ });
52
+
53
+ /** 閉じた項目と、その問いの答え。trueAt は答えが真の項目の位置、lastFalse は最後に偽だった位置(WithContent は中身のある項目だけ)。 */
54
+ type Frozen = {
55
+ readonly items: TokenRange[];
56
+ readonly content: boolean[];
57
+ readonly contentAt: number[];
58
+ readonly shapes: (string | undefined)[];
59
+ /** 中身のある項目のうち、次の中身のある項目と頭の形が違う最後のもの。無ければ -1。 */
60
+ lastShapeChange: number;
61
+ readonly flags: PerFlag<boolean[]>;
62
+ readonly trueAt: PerFlag<number[]>;
63
+ readonly trueWithContentAt: PerFlag<number[]>;
64
+ readonly lastFalse: PerFlag<number>;
65
+ readonly lastFalseWithContent: PerFlag<number>;
66
+ };
67
+
68
+ const emptyFrozen = (): Frozen => ({
69
+ items: [],
70
+ content: [],
71
+ contentAt: [],
72
+ shapes: [],
73
+ lastShapeChange: -1,
74
+ flags: perFlag((): boolean[] => []),
75
+ trueAt: perFlag((): number[] => []),
76
+ trueWithContentAt: perFlag((): number[] => []),
77
+ lastFalse: perFlag(() => -1),
78
+ lastFalseWithContent: perFlag(() => -1),
79
+ });
80
+
81
+ const recordFlags = (frozen: Frozen, scope: ItemScope, item: TokenRange, content: boolean): void => {
82
+ const index = frozen.items.length - 1;
83
+ FLAGS.forEach((flag) => {
84
+ const holds = FLAG_TESTS[flag](scope, item);
85
+ frozen.flags[flag].push(holds);
86
+ if (holds) frozen.trueAt[flag].push(index);
87
+ else frozen.lastFalse[flag] = index;
88
+ if (holds && content) frozen.trueWithContentAt[flag].push(index);
89
+ if (!holds && content) frozen.lastFalseWithContent[flag] = index;
90
+ });
91
+ };
92
+
93
+ const freeze = (frozen: Frozen, scope: ItemScope, item: TokenRange): void => {
94
+ const content = hasContent(scope, item);
95
+ const shape = shapeOf(scope, item);
96
+ const previous = frozen.contentAt.at(-1);
97
+ frozen.items.push(item);
98
+ frozen.content.push(content);
99
+ frozen.shapes.push(shape);
100
+ if (content && previous !== undefined && frozen.shapes[previous] !== shape) frozen.lastShapeChange = previous;
101
+ if (content) frozen.contentAt.push(frozen.items.length - 1);
102
+ recordFlags(frozen, scope, item, content);
103
+ };
104
+
105
+ /** 形容詞のあとの読点は、名詞の前で形容詞を重ねているだけのことが多い(the long, winding bridge)。次の項目が名詞で終わるならつなげ直す。 */
106
+ const stacks = (scope: ItemScope, previous: TokenRange, item: TokenRange): boolean =>
107
+ lastContent(scope, previous)?.pos === "ADJ" && lastContent(scope, item)?.pos !== "ADJ";
108
+
109
+ /** 1 つの深さの並び。start は節の頭、rawStart は読点でまだ閉じていない項目の頭、pending は次の項目とつながりうる最後の項目。 */
110
+ type LevelItems = {
111
+ readonly start: number;
112
+ readonly scope: ItemScope;
113
+ readonly commas: readonly number[];
114
+ nextComma: number;
115
+ rawStart: number;
116
+ pending: TokenRange | undefined;
117
+ readonly frozen: Frozen;
118
+ };
119
+
120
+ /** 節の頭から and / or までの項目。閉じた項目の表と、まだ閉じていない最後の 1、2 項目。 */
121
+ export type ItemList = { readonly scope: ItemScope; readonly frozen: Frozen; readonly tail: readonly TokenRange[] };
122
+
123
+ const addItem = (items: LevelItems, item: TokenRange): void => {
124
+ if (item.end <= item.start) return;
125
+ if (items.pending !== undefined && stacks(items.scope, items.pending, item)) {
126
+ items.pending = { start: items.pending.start, end: item.end };
127
+ return;
128
+ }
129
+ if (items.pending !== undefined) freeze(items.frozen, items.scope, items.pending);
130
+ items.pending = item;
131
+ };
132
+
133
+ const tailOf = (scope: ItemScope, pending: TokenRange | undefined, live: TokenRange | undefined): TokenRange[] => {
134
+ if (live === undefined) return pending === undefined ? [] : [pending];
135
+ if (pending === undefined) return [live];
136
+ return stacks(scope, pending, live) ? [{ start: pending.start, end: live.end }] : [pending, live];
137
+ };
138
+
139
+ /** 深さごとの並びを、and / or の位置 at まで読み進める。at は呼ぶたびに大きくなる。返した並びは、次に読み進めるまでのもの。 */
140
+ export const listReader = (sentence: ListSentence): ((at: number) => ItemList) => {
141
+ const byLevel = new Map<number, LevelItems>();
142
+ const opened = (level: number, start: number): LevelItems => {
143
+ const known = byLevel.get(level);
144
+ if (known !== undefined && known.start === start) return known;
145
+ const commas = sentence.commas.get(level) ?? [];
146
+ const scope = scopeOf(sentence, level);
147
+ const fresh = { start, scope, commas, nextComma: lowerBound(commas, start), rawStart: start, pending: undefined, frozen: emptyFrozen() };
148
+ byLevel.set(level, fresh);
149
+ return fresh;
150
+ };
151
+ return (at) => {
152
+ const level = sentence.depths[at] ?? 0;
153
+ const items = opened(level, (sentence.column.clauseBreak.previous[at] ?? -1) + 1);
154
+ const reached = lowerBound(items.commas, at);
155
+ items.commas.slice(items.nextComma, reached).forEach((comma) => {
156
+ addItem(items, { start: items.rawStart, end: comma });
157
+ items.rawStart = comma + 1;
158
+ });
159
+ items.nextComma = reached;
160
+ const live = items.rawStart < at ? { start: items.rawStart, end: at } : undefined;
161
+ return { scope: items.scope, frozen: items.frozen, tail: tailOf(items.scope, items.pending, live) };
162
+ };
163
+ };
@@ -0,0 +1,33 @@
1
+ import type { BulletList, Sentence, Span } from "../plugin.ts";
2
+ import { endsWithColon } from "./lead-in.ts";
3
+
4
+ /** Between a lead-in and its list: only blank space. A thematic break (`***`) separates them; bold marks sit inside the sentence. */
5
+ const ONLY_BLANKS = /^\s*$/u;
6
+
7
+ /** How many sentences end at or before an offset. Sentences are in document order, so a binary search. */
8
+ const countEndingBy = (sentences: readonly Sentence[], offset: number): number => {
9
+ const search = (low: number, high: number): number => {
10
+ if (low >= high) return low;
11
+ const middle = Math.floor((low + high) / 2);
12
+ return (sentences[middle]?.span.end ?? Infinity) <= offset ? search(middle + 1, high) : search(low, middle);
13
+ };
14
+ return search(0, sentences.length);
15
+ };
16
+
17
+ /** The sentence that ends last before the list starts, if nothing but blanks lies between them. */
18
+ const sentenceRightBefore = (sentences: readonly Sentence[], list: BulletList, source: string): Sentence | undefined => {
19
+ const before = sentences[countEndingBy(sentences, list.span.start) - 1];
20
+ return before !== undefined && ONLY_BLANKS.test(source.slice(before.span.end, list.span.start)) ? before : undefined;
21
+ };
22
+
23
+ const insideAny = (spans: readonly Span[], offset: number): boolean => spans.some((span) => span.start <= offset && offset < span.end);
24
+
25
+ /**
26
+ * Prose sentences ending in a colon that hand the reader straight to a list (「以下の通りです:」, "Here's what you need:").
27
+ * An item of a list is not prose: 「例: `code`」 ends in a colon once its code is masked, and it leads nowhere.
28
+ */
29
+ export const colonLeadIns = (sentences: readonly Sentence[], lists: readonly BulletList[], listSpans: readonly Span[], source: string): Sentence[] =>
30
+ lists.flatMap((list) => {
31
+ const before = sentenceRightBefore(sentences, list, source);
32
+ return before !== undefined && endsWithColon(before.text) && !insideAny(listSpans, before.span.start) ? [before] : [];
33
+ });
@@ -0,0 +1,157 @@
1
+ import type { Lexicon, Token } from "../plugin.ts";
2
+ import { citedTitles } from "./cited-title.ts";
3
+ import { columnOf, type Column } from "./token-column.ts";
4
+
5
+ /**
6
+ * 並びを読むための語彙表。participle は解析器が分詞と読まないが読点のあとで分詞の句を始める語(meaning)、
7
+ * example は例を挙げる句(such as, e.g.)、pair は 2 つだけを結ぶ語とその接続詞(between and / either or)。
8
+ */
9
+ export type ListWords = { readonly participle: ReadonlySet<string>; readonly example: Lexicon; readonly pair: ReadonlySet<string> };
10
+
11
+ const LIST_CONJUNCTION: ReadonlySet<string> = new Set(["and", "or"]);
12
+
13
+ export const isListConjunction = (token: Token | undefined): boolean => LIST_CONJUNCTION.has(token?.surface.toLowerCase() ?? "");
14
+
15
+ /** 並列はこれをまたがない。セミコロンの前後は別の節。 */
16
+ const CLAUSE_BREAK = new Set([";", ":", "—"]);
17
+
18
+ /** 各 token の前で閉じていない括弧の数。括弧の中の読点(external users (e.g., guests), and ...)は外の並列を切らない。 */
19
+ const PAREN_STEP: ReadonlyMap<string, number> = new Map([
20
+ ["(", 1],
21
+ [")", -1],
22
+ ]);
23
+
24
+ export const depthsOf = (tokens: readonly Token[]): number[] => {
25
+ let open = 0;
26
+ return tokens.map((token) => {
27
+ const before = open;
28
+ open = Math.max(0, open + (PAREN_STEP.get(token.surface) ?? 0));
29
+ return before;
30
+ });
31
+ };
32
+
33
+ /** 冠詞や引用符を飛ばした、項目の頭の品詞。the parser と an exporter と samples を同じ形と見る。 */
34
+ export const NOMINAL = new Set(["NOUN", "PRON", "PROPN", "NUM", "ADJ"]);
35
+ export const VERBAL = new Set(["VERB", "AUX"]);
36
+ const NOUN_PHRASE_TAIL = new Set(["ADJ", "NOUN", "PROPN"]);
37
+ export const APPOSITIVE_ANCHOR = new Set(["NOUN", "PROPN"]);
38
+
39
+ export const isContent = (token: Token): boolean => token.pos !== "DET" && token.pos !== "PUNCT" && token.pos !== "X";
40
+
41
+ const isOpen = (token: Token): boolean => token.pos !== "PUNCT" && token.pos !== "X";
42
+
43
+ /** -ing 形(VerbForm=Ger)と過去分詞(Part)。filling the gaps と sentenced to prison は並べても並列にならない。 */
44
+ const VERB_FORMS = new Set(["Ger", "Part"]);
45
+
46
+ export const verbFormOf = (token: Token): string | undefined => {
47
+ const form = token.features?.["VerbForm"];
48
+ return form !== undefined && VERB_FORMS.has(form) ? form : undefined;
49
+ };
50
+
51
+ /** 同じ深さにある語の位置を、深さごとに左から。 */
52
+ const byDepth = (depths: readonly number[], test: (index: number) => boolean): ReadonlyMap<number, readonly number[]> =>
53
+ depths.reduce((found, depth, index) => {
54
+ if (!test(index)) return found;
55
+ const list = found.get(depth);
56
+ if (list === undefined) found.set(depth, [index]);
57
+ else list.push(index);
58
+ return found;
59
+ }, new Map<number, number[]>());
60
+
61
+ const isComma = (token: Token): boolean => token.surface === ",";
62
+
63
+ /** 項目への問いの列。読点は項目に入ったり入らなかったりするので、脇に置いて問いごとに数える(token-column.ts)。 */
64
+ const columnsOf = (tokens: readonly Token[], depths: readonly number[]) => {
65
+ const commaDepth = (token: Token, index: number): number | undefined => (isComma(token) ? depths[index] : undefined);
66
+ const of = (test: (token: Token) => boolean): Column => columnOf(tokens, test, commaDepth);
67
+ return {
68
+ content: of(isContent),
69
+ open: of(isOpen),
70
+ verbal: of((token) => VERBAL.has(token.pos)),
71
+ adposition: of((token) => token.pos === "ADP"),
72
+ determiner: of((token) => token.pos === "DET"),
73
+ conjunction: of((token) => LIST_CONJUNCTION.has(token.surface.toLowerCase())),
74
+ gerund: of((token) => verbFormOf(token) === "Ger"),
75
+ participle: of((token) => verbFormOf(token) === "Part"),
76
+ nounPhraseTail: of((token) => NOUN_PHRASE_TAIL.has(token.pos)),
77
+ noun: of((token) => APPOSITIVE_ANCHOR.has(token.pos)),
78
+ contentNotAdverb: of((token) => isContent(token) && token.pos !== "ADV"),
79
+ notPunctuationOrAdverb: of((token) => token.pos !== "PUNCT" && token.pos !== "ADV"),
80
+ notComma: columnOf(tokens, (token) => !isComma(token)),
81
+ itemEnd: columnOf(tokens, (token) => isComma(token) || CLAUSE_BREAK.has(token.surface)),
82
+ clauseBreak: columnOf(tokens, (token) => CLAUSE_BREAK.has(token.surface)),
83
+ };
84
+ };
85
+
86
+ export type Columns = ReturnType<typeof columnsOf>;
87
+
88
+ /** 文を一度だけ読んで作る、項目の問いに答えるための表。 */
89
+ export type ListSentence = {
90
+ readonly tokens: readonly Token[];
91
+ readonly depths: readonly number[];
92
+ readonly words: ListWords;
93
+ readonly column: Columns;
94
+ /** 各位置から始まる例の句の、最後の語の位置。語彙表の順に。 */
95
+ readonly exampleEnds: readonly (readonly number[])[];
96
+ /** 例の句の始まる位置。深さごとに。 */
97
+ readonly exampleStarts: ReadonlyMap<number, readonly number[]>;
98
+ /** 2 つだけを結ぶ語の位置。組む接続詞ごと、深さごとに。 */
99
+ readonly pairOpeners: ReadonlyMap<string, ReadonlyMap<number, readonly number[]>>;
100
+ /** 読点の位置。深さごとに。 */
101
+ readonly commas: ReadonlyMap<number, readonly number[]>;
102
+ readonly inCitedTitle: (at: number) => boolean;
103
+ };
104
+
105
+ /**
106
+ * start から例の句の語を読んだときの、最後の語の位置。無ければ -1。項目は同じ深さの読点を持たないので、start と同じ深さの読点は
107
+ * 飛ばす。続いた読点は同じ深さなので、まとめて飛ぶ。
108
+ */
109
+ const phraseEnd = (tokens: readonly Token[], depths: readonly number[], notComma: Column, start: number, words: readonly Token[]): number =>
110
+ words.reduce((at, word, offset) => {
111
+ if (at === -1) return -1;
112
+ const next = offset === 0 ? start : at + 1;
113
+ const kept = tokens[next]?.surface === "," && depths[next] === depths[start] ? (notComma.next[next] ?? tokens.length) : next;
114
+ return tokens[kept]?.surface === word.surface ? kept : -1;
115
+ }, start);
116
+
117
+ const exampleEndsOf = (tokens: readonly Token[], depths: readonly number[], column: Columns, example: Lexicon): number[][] =>
118
+ tokens.map((token, start) =>
119
+ token.surface === ","
120
+ ? []
121
+ : example.flatMap(({ tokens: words = [] }) => {
122
+ const end = words.length > 0 ? phraseEnd(tokens, depths, column.notComma, start, words) : -1;
123
+ return end === -1 ? [] : [end];
124
+ }),
125
+ );
126
+
127
+ const pairOpenersOf = (tokens: readonly Token[], depths: readonly number[], pair: ReadonlySet<string>): Map<string, ReadonlyMap<number, readonly number[]>> =>
128
+ new Map(
129
+ [...LIST_CONJUNCTION].map((conjunction) => [
130
+ conjunction,
131
+ byDepth(depths, (index) => tokens[index]?.surface !== "," && pair.has(`${tokens[index]?.surface.toLowerCase() ?? ""} ${conjunction}`)),
132
+ ]),
133
+ );
134
+
135
+ /**
136
+ * 1 つの and / or の深さから見た文。その深さの読点は項目の区切りで、項目の中には無い。ほかの深さの読点(括弧の中)は項目の語。
137
+ */
138
+ export type ItemScope = { readonly sentence: ListSentence; readonly level: number };
139
+
140
+ export const scopeOf = (sentence: ListSentence, level: number): ItemScope => ({ sentence, level });
141
+
142
+ export const listSentenceOf = (tokens: readonly Token[], words: ListWords, source: string): ListSentence => {
143
+ const depths = depthsOf(tokens);
144
+ const column = columnsOf(tokens, depths);
145
+ const exampleEnds = exampleEndsOf(tokens, depths, column, words.example);
146
+ return {
147
+ tokens,
148
+ depths,
149
+ words,
150
+ column,
151
+ exampleEnds,
152
+ exampleStarts: byDepth(depths, (index) => (exampleEnds[index]?.length ?? 0) > 0),
153
+ pairOpeners: pairOpenersOf(tokens, depths, words.pair),
154
+ commas: byDepth(depths, (index) => tokens[index]?.surface === ","),
155
+ inCitedTitle: citedTitles(tokens, source),
156
+ };
157
+ };
@@ -0,0 +1,157 @@
1
+ import { hasContent, shapeOf } from "./list-item.ts";
2
+ import { FLAG_TESTS, type Flag, type ItemList } from "./list-items.ts";
3
+ import { lowerBound, type TokenRange } from "./token-column.ts";
4
+
5
+ // 並びを切り直したもの。並びの頭を外す、途中の項目のあとから読む、中身の無い項目を除く、の 3 つだけで作れるので、
6
+ // 「先頭に置いた項目(pre)+ 並びの from 番目から後ろ(contentOnly なら中身のある項目だけ)」で表す。項目の配列は作らない。
7
+
8
+ export type View = { readonly list: ItemList; readonly pre: TokenRange | undefined; readonly from: number; readonly contentOnly: boolean };
9
+
10
+ /** 並びの中の項目。j は並びの中の位置で、pre は -1。 */
11
+ export type Member = { readonly item: TokenRange; readonly j: number };
12
+
13
+ export const wholeList = (list: ItemList): View => ({ list, pre: undefined, from: 0, contentOnly: false });
14
+
15
+ const frozenCount = (list: ItemList): number => list.frozen.items.length;
16
+
17
+ const listCount = (list: ItemList): number => frozenCount(list) + list.tail.length;
18
+
19
+ const itemAt = (list: ItemList, j: number): TokenRange | undefined => (j < frozenCount(list) ? list.frozen.items[j] : list.tail[j - frozenCount(list)]);
20
+
21
+ const contentAt = (list: ItemList, j: number): boolean => {
22
+ const item = itemAt(list, j);
23
+ if (j < frozenCount(list)) return list.frozen.content[j] ?? false;
24
+ return item !== undefined && hasContent(list.scope, item);
25
+ };
26
+
27
+ const kept = (view: View, j: number): boolean => !view.contentOnly || contentAt(view.list, j);
28
+
29
+ const flagAt = (list: ItemList, j: number, flag: Flag): boolean => {
30
+ const item = itemAt(list, j);
31
+ if (j < frozenCount(list)) return list.frozen.flags[flag][j] ?? false;
32
+ return item !== undefined && FLAG_TESTS[flag](list.scope, item);
33
+ };
34
+
35
+ const tailPositions = (list: ItemList, from: number): number[] => list.tail.map((__item, offset) => frozenCount(list) + offset).filter((j) => j >= from);
36
+
37
+ const member = (list: ItemList, j: number): Member | undefined => {
38
+ const item = j === -1 ? undefined : itemAt(list, j);
39
+ return item === undefined ? undefined : { item, j };
40
+ };
41
+
42
+ /** from 以後の、閉じた項目の最初の位置。無ければ -1。 */
43
+ const firstFrozenFrom = (view: View, from: number): number => {
44
+ const { frozen } = view.list;
45
+ if (view.contentOnly) return frozen.contentAt[lowerBound(frozen.contentAt, from)] ?? -1;
46
+ return from < frozen.items.length ? from : -1;
47
+ };
48
+
49
+ /** from 以後の最初の項目の位置。無ければ -1。 */
50
+ const firstFrom = (view: View, from: number): number => {
51
+ const frozen = firstFrozenFrom(view, from);
52
+ if (frozen !== -1) return frozen;
53
+ return tailPositions(view.list, from).find((j) => kept(view, j)) ?? -1;
54
+ };
55
+
56
+ /** before より前の、view.from 以後の最後の項目の位置。無ければ -1。 */
57
+ const lastBefore = (view: View, before: number): number => {
58
+ const { list } = view;
59
+ const fromTail = tailPositions(list, view.from)
60
+ .filter((j) => j < before && kept(view, j))
61
+ .at(-1);
62
+ if (fromTail !== undefined) return fromTail;
63
+ const end = Math.min(before, frozenCount(list));
64
+ const frozen = view.contentOnly ? (list.frozen.contentAt[lowerBound(list.frozen.contentAt, end) - 1] ?? -1) : end - 1;
65
+ return frozen >= view.from ? frozen : -1;
66
+ };
67
+
68
+ const preMember = (view: View): Member | undefined => (view.pre === undefined ? undefined : { item: view.pre, j: -1 });
69
+
70
+ export const firstOf = (view: View): Member | undefined => preMember(view) ?? member(view.list, firstFrom(view, view.from));
71
+
72
+ export const secondOf = (view: View): Member | undefined => {
73
+ const first = view.pre === undefined ? firstFrom(view, view.from) : view.from - 1;
74
+ return first === -1 ? undefined : member(view.list, firstFrom(view, first + 1));
75
+ };
76
+
77
+ export const lastOf = (view: View): Member | undefined => member(view.list, lastBefore(view, listCount(view.list))) ?? preMember(view);
78
+
79
+ export const secondLastOf = (view: View): Member | undefined => {
80
+ const last = lastBefore(view, listCount(view.list));
81
+ if (last === -1) return undefined;
82
+ return member(view.list, lastBefore(view, last)) ?? preMember(view);
83
+ };
84
+
85
+ export const sizeOf = (view: View): number => {
86
+ const { list } = view;
87
+ const frozen = view.contentOnly ? list.frozen.contentAt.length - lowerBound(list.frozen.contentAt, view.from) : Math.max(0, frozenCount(list) - view.from);
88
+ const tail = tailPositions(list, view.from).filter((j) => kept(view, j)).length;
89
+ return (view.pre === undefined ? 0 : 1) + frozen + tail;
90
+ };
91
+
92
+ /** 先頭の項目を外す。 */
93
+ export const withoutFirst = (view: View): View => {
94
+ if (view.pre !== undefined) return { ...view, pre: undefined };
95
+ const first = firstFrom(view, view.from);
96
+ return { ...view, from: first === -1 ? listCount(view.list) : first + 1 };
97
+ };
98
+
99
+ /** その項目より後ろ。 */
100
+ export const after = (view: View, at: Member): View => ({ ...view, pre: undefined, from: at.j === -1 ? view.from : at.j + 1 });
101
+
102
+ /** 先頭に項目を置いた、中身のある項目だけの並び。 */
103
+ export const contentOnlyWith = (view: View, pre: TokenRange | undefined): View => ({
104
+ ...view,
105
+ pre: pre !== undefined && hasContent(view.list.scope, pre) ? pre : undefined,
106
+ contentOnly: true,
107
+ });
108
+
109
+ const holdsFor = (view: View, flag: Flag, item: TokenRange): boolean => FLAG_TESTS[flag](view.list.scope, item);
110
+
111
+ /** 問いが真になる最後の項目。 */
112
+ export const findLast = (view: View, flag: Flag): Member | undefined => {
113
+ const { list } = view;
114
+ const fromTail = tailPositions(list, view.from)
115
+ .filter((j) => kept(view, j) && flagAt(list, j, flag))
116
+ .at(-1);
117
+ if (fromTail !== undefined) return member(list, fromTail);
118
+ const frozen = (view.contentOnly ? list.frozen.trueWithContentAt : list.frozen.trueAt)[flag].at(-1) ?? -1;
119
+ if (frozen >= view.from) return member(list, frozen);
120
+ return view.pre !== undefined && holdsFor(view, flag, view.pre) ? preMember(view) : undefined;
121
+ };
122
+
123
+ /** 2 番目以後で、問いが真になる最初の項目。 */
124
+ export const findAfterFirst = (view: View, flag: Flag): Member | undefined => {
125
+ const { list } = view;
126
+ const first = view.pre === undefined ? firstFrom(view, view.from) : view.from - 1;
127
+ if (first === -1) return undefined;
128
+ const found = view.contentOnly ? list.frozen.trueWithContentAt[flag] : list.frozen.trueAt[flag];
129
+ const frozen = found[lowerBound(found, first + 1)];
130
+ if (frozen !== undefined) return member(list, frozen);
131
+ return member(list, tailPositions(list, first + 1).find((j) => kept(view, j) && flagAt(list, j, flag)) ?? -1);
132
+ };
133
+
134
+ export const some = (view: View, flag: Flag): boolean => findLast(view, flag) !== undefined;
135
+
136
+ export const every = (view: View, flag: Flag): boolean => {
137
+ const { list } = view;
138
+ if (view.pre !== undefined && !holdsFor(view, flag, view.pre)) return false;
139
+ if ((view.contentOnly ? list.frozen.lastFalseWithContent : list.frozen.lastFalse)[flag] >= view.from) return false;
140
+ return tailPositions(list, view.from).every((j) => !kept(view, j) || flagAt(list, j, flag));
141
+ };
142
+
143
+ /** 中身のある項目の頭の形が、1 種類以下か。 */
144
+ export const sameShapes = (view: View): boolean => {
145
+ const { list } = view;
146
+ const { frozen } = list;
147
+ const lastFrozen = frozen.contentAt.at(-1) ?? -1;
148
+ if (lastFrozen >= view.from && frozen.lastShapeChange >= view.from) return false;
149
+ const shapes = new Set([
150
+ ...(view.pre === undefined || !hasContent(list.scope, view.pre) ? [] : [shapeOf(list.scope, view.pre)]),
151
+ ...(lastFrozen >= view.from ? [frozen.shapes[lastFrozen]] : []),
152
+ ...tailPositions(list, view.from)
153
+ .filter((j) => contentAt(list, j))
154
+ .map((j) => shapeOf(list.scope, itemAt(list, j) ?? { start: 0, end: 0 })),
155
+ ]);
156
+ return shapes.size <= 1;
157
+ };