chaffjs 0.32.0 → 0.34.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 (535) hide show
  1. package/README.md +7 -0
  2. package/dist/api.d.ts +7 -1
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js.map +1 -1
  5. package/dist/cli-text.d.ts.map +1 -1
  6. package/dist/cli-text.js +6 -4
  7. package/dist/cli-text.js.map +1 -1
  8. package/dist/commands/grade.d.ts.map +1 -1
  9. package/dist/commands/grade.js +66 -21
  10. package/dist/commands/grade.js.map +1 -1
  11. package/dist/company-kana-spelling.d.ts +6 -1
  12. package/dist/company-kana-spelling.d.ts.map +1 -1
  13. package/dist/company-kana-spelling.js +19 -2
  14. package/dist/company-kana-spelling.js.map +1 -1
  15. package/dist/company-name-ending.d.ts +7 -0
  16. package/dist/company-name-ending.d.ts.map +1 -0
  17. package/dist/company-name-ending.js +44 -0
  18. package/dist/company-name-ending.js.map +1 -0
  19. package/dist/company-names.d.ts +11 -3
  20. package/dist/company-names.d.ts.map +1 -1
  21. package/dist/company-names.js +27 -14
  22. package/dist/company-names.js.map +1 -1
  23. package/dist/cross-run.d.ts.map +1 -1
  24. package/dist/cross-run.js +1 -0
  25. package/dist/cross-run.js.map +1 -1
  26. package/dist/custom/no-rewrite.d.ts +3 -0
  27. package/dist/custom/no-rewrite.d.ts.map +1 -0
  28. package/dist/custom/no-rewrite.js +3 -0
  29. package/dist/custom/no-rewrite.js.map +1 -0
  30. package/dist/custom/parse.d.ts.map +1 -1
  31. package/dist/custom/parse.js +14 -2
  32. package/dist/custom/parse.js.map +1 -1
  33. package/dist/detectors/age-words.d.ts +5 -0
  34. package/dist/detectors/age-words.d.ts.map +1 -0
  35. package/dist/detectors/age-words.js +8 -0
  36. package/dist/detectors/age-words.js.map +1 -0
  37. package/dist/detectors/agreement-slip.d.ts.map +1 -1
  38. package/dist/detectors/agreement-slip.js +4 -0
  39. package/dist/detectors/agreement-slip.js.map +1 -1
  40. package/dist/detectors/annual-pay-mismatch.d.ts.map +1 -1
  41. package/dist/detectors/annual-pay-mismatch.js +2 -12
  42. package/dist/detectors/annual-pay-mismatch.js.map +1 -1
  43. package/dist/detectors/blank-structure.d.ts.map +1 -1
  44. package/dist/detectors/blank-structure.js +4 -3
  45. package/dist/detectors/blank-structure.js.map +1 -1
  46. package/dist/detectors/closing-balance-mismatch.d.ts.map +1 -1
  47. package/dist/detectors/closing-balance-mismatch.js +1 -0
  48. package/dist/detectors/closing-balance-mismatch.js.map +1 -1
  49. package/dist/detectors/code-fences.d.ts +5 -0
  50. package/dist/detectors/code-fences.d.ts.map +1 -1
  51. package/dist/detectors/code-fences.js +9 -0
  52. package/dist/detectors/code-fences.js.map +1 -1
  53. package/dist/detectors/condition-toki.d.ts +16 -0
  54. package/dist/detectors/condition-toki.d.ts.map +1 -0
  55. package/dist/detectors/condition-toki.js +42 -0
  56. package/dist/detectors/condition-toki.js.map +1 -0
  57. package/dist/detectors/conjugated-entry.d.ts +17 -0
  58. package/dist/detectors/conjugated-entry.d.ts.map +1 -0
  59. package/dist/detectors/conjugated-entry.js +50 -0
  60. package/dist/detectors/conjugated-entry.js.map +1 -0
  61. package/dist/detectors/content-morphemes.d.ts +2 -0
  62. package/dist/detectors/content-morphemes.d.ts.map +1 -1
  63. package/dist/detectors/content-morphemes.js +1 -1
  64. package/dist/detectors/content-morphemes.js.map +1 -1
  65. package/dist/detectors/cross-facts.d.ts.map +1 -1
  66. package/dist/detectors/cross-facts.js +2 -1
  67. package/dist/detectors/cross-facts.js.map +1 -1
  68. package/dist/detectors/custom.d.ts.map +1 -1
  69. package/dist/detectors/custom.js +8 -2
  70. package/dist/detectors/custom.js.map +1 -1
  71. package/dist/detectors/document-shape.d.ts.map +1 -1
  72. package/dist/detectors/document-shape.js +6 -0
  73. package/dist/detectors/document-shape.js.map +1 -1
  74. package/dist/detectors/due-date.d.ts.map +1 -1
  75. package/dist/detectors/due-date.js +12 -2
  76. package/dist/detectors/due-date.js.map +1 -1
  77. package/dist/detectors/fact-consistency.d.ts.map +1 -1
  78. package/dist/detectors/fact-consistency.js +12 -13
  79. package/dist/detectors/fact-consistency.js.map +1 -1
  80. package/dist/detectors/form-line.d.ts +9 -0
  81. package/dist/detectors/form-line.d.ts.map +1 -0
  82. package/dist/detectors/form-line.js +36 -0
  83. package/dist/detectors/form-line.js.map +1 -0
  84. package/dist/detectors/formula-amount.d.ts +3 -0
  85. package/dist/detectors/formula-amount.d.ts.map +1 -0
  86. package/dist/detectors/formula-amount.js +31 -0
  87. package/dist/detectors/formula-amount.js.map +1 -0
  88. package/dist/detectors/heading-claim.d.ts +14 -0
  89. package/dist/detectors/heading-claim.d.ts.map +1 -0
  90. package/dist/detectors/heading-claim.js +49 -0
  91. package/dist/detectors/heading-claim.js.map +1 -0
  92. package/dist/detectors/heading-echo.d.ts.map +1 -1
  93. package/dist/detectors/heading-echo.js +29 -1
  94. package/dist/detectors/heading-echo.js.map +1 -1
  95. package/dist/detectors/installment-total-mismatch.d.ts.map +1 -1
  96. package/dist/detectors/installment-total-mismatch.js +28 -19
  97. package/dist/detectors/installment-total-mismatch.js.map +1 -1
  98. package/dist/detectors/list-parallel.d.ts +5 -2
  99. package/dist/detectors/list-parallel.d.ts.map +1 -1
  100. package/dist/detectors/list-parallel.js +45 -7
  101. package/dist/detectors/list-parallel.js.map +1 -1
  102. package/dist/detectors/name-variant.d.ts.map +1 -1
  103. package/dist/detectors/name-variant.js +34 -7
  104. package/dist/detectors/name-variant.js.map +1 -1
  105. package/dist/detectors/number-unit.d.ts +10 -0
  106. package/dist/detectors/number-unit.d.ts.map +1 -1
  107. package/dist/detectors/number-unit.js +28 -8
  108. package/dist/detectors/number-unit.js.map +1 -1
  109. package/dist/detectors/orthographic-variant.d.ts.map +1 -1
  110. package/dist/detectors/orthographic-variant.js +4 -3
  111. package/dist/detectors/orthographic-variant.js.map +1 -1
  112. package/dist/detectors/orthography.d.ts.map +1 -1
  113. package/dist/detectors/orthography.js +16 -7
  114. package/dist/detectors/orthography.js.map +1 -1
  115. package/dist/detectors/per-unit-words.d.ts +7 -0
  116. package/dist/detectors/per-unit-words.d.ts.map +1 -0
  117. package/dist/detectors/per-unit-words.js +17 -0
  118. package/dist/detectors/per-unit-words.js.map +1 -0
  119. package/dist/detectors/period-multiple-mismatch.d.ts.map +1 -1
  120. package/dist/detectors/period-multiple-mismatch.js +2 -12
  121. package/dist/detectors/period-multiple-mismatch.js.map +1 -1
  122. package/dist/detectors/reference-number-variant.d.ts.map +1 -1
  123. package/dist/detectors/reference-number-variant.js +21 -3
  124. package/dist/detectors/reference-number-variant.js.map +1 -1
  125. package/dist/detectors/registry/condition-toki.d.ts +3 -0
  126. package/dist/detectors/registry/condition-toki.d.ts.map +1 -0
  127. package/dist/detectors/registry/condition-toki.js +3 -0
  128. package/dist/detectors/registry/condition-toki.js.map +1 -0
  129. package/dist/detectors/registry/formula-amount.d.ts +3 -0
  130. package/dist/detectors/registry/formula-amount.d.ts.map +1 -0
  131. package/dist/detectors/registry/formula-amount.js +3 -0
  132. package/dist/detectors/registry/formula-amount.js.map +1 -0
  133. package/dist/detectors/rent-multiple-mismatch.d.ts.map +1 -1
  134. package/dist/detectors/rent-multiple-mismatch.js +2 -12
  135. package/dist/detectors/rent-multiple-mismatch.js.map +1 -1
  136. package/dist/detectors/row-sentence-amounts.d.ts.map +1 -1
  137. package/dist/detectors/row-sentence-amounts.js +5 -10
  138. package/dist/detectors/row-sentence-amounts.js.map +1 -1
  139. package/dist/detectors/stated-amounts.d.ts +4 -0
  140. package/dist/detectors/stated-amounts.d.ts.map +1 -0
  141. package/dist/detectors/stated-amounts.js +12 -0
  142. package/dist/detectors/stated-amounts.js.map +1 -0
  143. package/dist/detectors/step-time-sum.d.ts.map +1 -1
  144. package/dist/detectors/step-time-sum.js +2 -1
  145. package/dist/detectors/step-time-sum.js.map +1 -1
  146. package/dist/detectors/structure-tree.d.ts +1 -1
  147. package/dist/detectors/structure-tree.d.ts.map +1 -1
  148. package/dist/detectors/structure-tree.js +7 -2
  149. package/dist/detectors/structure-tree.js.map +1 -1
  150. package/dist/detectors/team.d.ts.map +1 -1
  151. package/dist/detectors/team.js +10 -6
  152. package/dist/detectors/team.js.map +1 -1
  153. package/dist/detectors/time-order.d.ts.map +1 -1
  154. package/dist/detectors/time-order.js +17 -13
  155. package/dist/detectors/time-order.js.map +1 -1
  156. package/dist/detectors/unknown-word.d.ts +4 -1
  157. package/dist/detectors/unknown-word.d.ts.map +1 -1
  158. package/dist/detectors/unknown-word.js +18 -2
  159. package/dist/detectors/unknown-word.js.map +1 -1
  160. package/dist/detectors/use-interval.d.ts +1 -0
  161. package/dist/detectors/use-interval.d.ts.map +1 -1
  162. package/dist/detectors/use-interval.js +15 -10
  163. package/dist/detectors/use-interval.js.map +1 -1
  164. package/dist/detectors/use-maximum.d.ts.map +1 -1
  165. package/dist/detectors/use-maximum.js +3 -1
  166. package/dist/detectors/use-maximum.js.map +1 -1
  167. package/dist/eval.js +3 -3
  168. package/dist/eval.js.map +1 -1
  169. package/dist/extension/document-view.d.ts +2 -2
  170. package/dist/extension/document-view.d.ts.map +1 -1
  171. package/dist/extension/document-view.js +17 -8
  172. package/dist/extension/document-view.js.map +1 -1
  173. package/dist/extension/entry-genres.d.ts +5 -0
  174. package/dist/extension/entry-genres.d.ts.map +1 -0
  175. package/dist/extension/entry-genres.js +13 -0
  176. package/dist/extension/entry-genres.js.map +1 -0
  177. package/dist/extension/module-detector.d.ts.map +1 -1
  178. package/dist/extension/module-detector.js +4 -4
  179. package/dist/extension/module-detector.js.map +1 -1
  180. package/dist/extension/plugin-parse.d.ts +1 -1
  181. package/dist/extension/plugin-parse.d.ts.map +1 -1
  182. package/dist/extension/plugin-parse.js +24 -7
  183. package/dist/extension/plugin-parse.js.map +1 -1
  184. package/dist/extension/problem-text.d.ts.map +1 -1
  185. package/dist/extension/problem-text.js +2 -0
  186. package/dist/extension/problem-text.js.map +1 -1
  187. package/dist/facts/age-values.d.ts.map +1 -1
  188. package/dist/facts/age-values.js +20 -2
  189. package/dist/facts/age-values.js.map +1 -1
  190. package/dist/facts/column-units.d.ts +31 -0
  191. package/dist/facts/column-units.d.ts.map +1 -0
  192. package/dist/facts/column-units.js +37 -0
  193. package/dist/facts/column-units.js.map +1 -0
  194. package/dist/facts/fact-values.d.ts +4 -0
  195. package/dist/facts/fact-values.d.ts.map +1 -1
  196. package/dist/facts/fact-values.js +3 -1
  197. package/dist/facts/fact-values.js.map +1 -1
  198. package/dist/facts/labelled-facts.d.ts +10 -0
  199. package/dist/facts/labelled-facts.d.ts.map +1 -1
  200. package/dist/facts/labelled-facts.js +6 -1
  201. package/dist/facts/labelled-facts.js.map +1 -1
  202. package/dist/facts/per-unit.d.ts +36 -0
  203. package/dist/facts/per-unit.d.ts.map +1 -0
  204. package/dist/facts/per-unit.js +56 -0
  205. package/dist/facts/per-unit.js.map +1 -0
  206. package/dist/facts/row-sentence-amounts.d.ts +3 -12
  207. package/dist/facts/row-sentence-amounts.d.ts.map +1 -1
  208. package/dist/facts/row-sentence-amounts.js +1 -15
  209. package/dist/facts/row-sentence-amounts.js.map +1 -1
  210. package/dist/facts/table-facts.d.ts +1 -1
  211. package/dist/facts/table-facts.d.ts.map +1 -1
  212. package/dist/facts/table-facts.js +13 -9
  213. package/dist/facts/table-facts.js.map +1 -1
  214. package/dist/facts/term-values.d.ts +13 -1
  215. package/dist/facts/term-values.d.ts.map +1 -1
  216. package/dist/facts/term-values.js +71 -12
  217. package/dist/facts/term-values.js.map +1 -1
  218. package/dist/fix-plan/text.js +2 -2
  219. package/dist/fix-plan/text.js.map +1 -1
  220. package/dist/grade/baseline.d.ts +4 -2
  221. package/dist/grade/baseline.d.ts.map +1 -1
  222. package/dist/grade/baseline.js +13 -11
  223. package/dist/grade/baseline.js.map +1 -1
  224. package/dist/grade/expect-read.d.ts +16 -0
  225. package/dist/grade/expect-read.d.ts.map +1 -0
  226. package/dist/grade/expect-read.js +52 -0
  227. package/dist/grade/expect-read.js.map +1 -0
  228. package/dist/grade/expect.d.ts +50 -0
  229. package/dist/grade/expect.d.ts.map +1 -0
  230. package/dist/grade/expect.js +53 -0
  231. package/dist/grade/expect.js.map +1 -0
  232. package/dist/grade/grade-item.d.ts +1 -1
  233. package/dist/grade/grade-item.d.ts.map +1 -1
  234. package/dist/grade/grade-item.js +13 -3
  235. package/dist/grade/grade-item.js.map +1 -1
  236. package/dist/grade/item.d.ts +9 -1
  237. package/dist/grade/item.d.ts.map +1 -1
  238. package/dist/grade/item.js +32 -7
  239. package/dist/grade/item.js.map +1 -1
  240. package/dist/grade/result.d.ts +5 -0
  241. package/dist/grade/result.d.ts.map +1 -1
  242. package/dist/grade/results-read.d.ts.map +1 -1
  243. package/dist/grade/results-read.js +4 -2
  244. package/dist/grade/results-read.js.map +1 -1
  245. package/dist/grade/rubric-file.d.ts +23 -0
  246. package/dist/grade/rubric-file.d.ts.map +1 -0
  247. package/dist/grade/rubric-file.js +35 -0
  248. package/dist/grade/rubric-file.js.map +1 -0
  249. package/dist/grade/rubric.d.ts +2 -0
  250. package/dist/grade/rubric.d.ts.map +1 -1
  251. package/dist/grade/rubric.js +75 -47
  252. package/dist/grade/rubric.js.map +1 -1
  253. package/dist/grade/setup.d.ts +2 -1
  254. package/dist/grade/setup.d.ts.map +1 -1
  255. package/dist/grade/setup.js +2 -2
  256. package/dist/grade/setup.js.map +1 -1
  257. package/dist/grade/stamp.d.ts +2 -0
  258. package/dist/grade/stamp.d.ts.map +1 -1
  259. package/dist/grade/stamp.js +8 -2
  260. package/dist/grade/stamp.js.map +1 -1
  261. package/dist/grade/task-rubric.d.ts +16 -0
  262. package/dist/grade/task-rubric.d.ts.map +1 -0
  263. package/dist/grade/task-rubric.js +34 -0
  264. package/dist/grade/task-rubric.js.map +1 -0
  265. package/dist/grade/text.d.ts +5 -1
  266. package/dist/grade/text.d.ts.map +1 -1
  267. package/dist/grade/text.js +16 -4
  268. package/dist/grade/text.js.map +1 -1
  269. package/dist/lexicon-genres.d.ts +7 -0
  270. package/dist/lexicon-genres.d.ts.map +1 -0
  271. package/dist/lexicon-genres.js +8 -0
  272. package/dist/lexicon-genres.js.map +1 -0
  273. package/dist/name-char-reading.d.ts +5 -0
  274. package/dist/name-char-reading.d.ts.map +1 -1
  275. package/dist/name-char-reading.js +15 -0
  276. package/dist/name-char-reading.js.map +1 -1
  277. package/dist/name-end-letter.d.ts +19 -0
  278. package/dist/name-end-letter.d.ts.map +1 -0
  279. package/dist/name-end-letter.js +37 -0
  280. package/dist/name-end-letter.js.map +1 -0
  281. package/dist/name-neighbours.d.ts.map +1 -1
  282. package/dist/name-neighbours.js +2 -1
  283. package/dist/name-neighbours.js.map +1 -1
  284. package/dist/name-separator.d.ts +6 -0
  285. package/dist/name-separator.d.ts.map +1 -1
  286. package/dist/name-separator.js +29 -0
  287. package/dist/name-separator.js.map +1 -1
  288. package/dist/name-variants.d.ts +6 -3
  289. package/dist/name-variants.d.ts.map +1 -1
  290. package/dist/name-variants.js +37 -10
  291. package/dist/name-variants.js.map +1 -1
  292. package/dist/number-name.d.ts.map +1 -1
  293. package/dist/number-name.js +11 -2
  294. package/dist/number-name.js.map +1 -1
  295. package/dist/plugin.d.ts +6 -0
  296. package/dist/plugin.d.ts.map +1 -1
  297. package/dist/profile/cue-lines.d.ts +6 -0
  298. package/dist/profile/cue-lines.d.ts.map +1 -0
  299. package/dist/profile/cue-lines.js +13 -0
  300. package/dist/profile/cue-lines.js.map +1 -0
  301. package/dist/profile/parse.d.ts +1 -1
  302. package/dist/profile/parse.d.ts.map +1 -1
  303. package/dist/profile/parse.js +8 -2
  304. package/dist/profile/parse.js.map +1 -1
  305. package/dist/reference-numbers.d.ts +2 -0
  306. package/dist/reference-numbers.d.ts.map +1 -1
  307. package/dist/reference-numbers.js +1 -1
  308. package/dist/reference-numbers.js.map +1 -1
  309. package/dist/run.d.ts.map +1 -1
  310. package/dist/run.js +1 -0
  311. package/dist/run.js.map +1 -1
  312. package/dist/spaced-person-name.d.ts.map +1 -1
  313. package/dist/spaced-person-name.js +26 -1
  314. package/dist/spaced-person-name.js.map +1 -1
  315. package/dist/spacing-code.d.ts.map +1 -1
  316. package/dist/spacing-code.js +10 -1
  317. package/dist/spacing-code.js.map +1 -1
  318. package/dist/spacing-minority.d.ts +7 -0
  319. package/dist/spacing-minority.d.ts.map +1 -1
  320. package/dist/spacing-minority.js +14 -0
  321. package/dist/spacing-minority.js.map +1 -1
  322. package/dist/structure/closing-balance.d.ts +9 -0
  323. package/dist/structure/closing-balance.d.ts.map +1 -1
  324. package/dist/structure/closing-balance.js +34 -7
  325. package/dist/structure/closing-balance.js.map +1 -1
  326. package/dist/structure/date-range.d.ts +3 -2
  327. package/dist/structure/date-range.d.ts.map +1 -1
  328. package/dist/structure/date-range.js +4 -4
  329. package/dist/structure/date-range.js.map +1 -1
  330. package/dist/structure/definition-use.d.ts.map +1 -1
  331. package/dist/structure/definition-use.js +20 -1
  332. package/dist/structure/definition-use.js.map +1 -1
  333. package/dist/structure/document-context.d.ts +2 -0
  334. package/dist/structure/document-context.d.ts.map +1 -0
  335. package/dist/structure/document-context.js +42 -0
  336. package/dist/structure/document-context.js.map +1 -0
  337. package/dist/structure/fenced-lines.d.ts +7 -0
  338. package/dist/structure/fenced-lines.d.ts.map +1 -0
  339. package/dist/structure/fenced-lines.js +27 -0
  340. package/dist/structure/fenced-lines.js.map +1 -0
  341. package/dist/structure/formula-amount.d.ts +38 -0
  342. package/dist/structure/formula-amount.d.ts.map +1 -0
  343. package/dist/structure/formula-amount.js +187 -0
  344. package/dist/structure/formula-amount.js.map +1 -0
  345. package/dist/structure/installment-fee.d.ts +52 -0
  346. package/dist/structure/installment-fee.d.ts.map +1 -0
  347. package/dist/structure/installment-fee.js +110 -0
  348. package/dist/structure/installment-fee.js.map +1 -0
  349. package/dist/structure/installment-total.d.ts +7 -0
  350. package/dist/structure/installment-total.d.ts.map +1 -1
  351. package/dist/structure/installment-total.js +6 -6
  352. package/dist/structure/installment-total.js.map +1 -1
  353. package/dist/structure/labelled-date-order.d.ts +31 -9
  354. package/dist/structure/labelled-date-order.d.ts.map +1 -1
  355. package/dist/structure/labelled-date-order.js +60 -15
  356. package/dist/structure/labelled-date-order.js.map +1 -1
  357. package/dist/structure/labelled-order.d.ts +7 -1
  358. package/dist/structure/labelled-order.d.ts.map +1 -1
  359. package/dist/structure/labelled-order.js +10 -3
  360. package/dist/structure/labelled-order.js.map +1 -1
  361. package/dist/structure/line-amount-label.d.ts.map +1 -1
  362. package/dist/structure/line-amount-label.js +2 -1
  363. package/dist/structure/line-amount-label.js.map +1 -1
  364. package/dist/structure/line-amount.d.ts +0 -5
  365. package/dist/structure/line-amount.d.ts.map +1 -1
  366. package/dist/structure/line-amount.js +1 -10
  367. package/dist/structure/line-amount.js.map +1 -1
  368. package/dist/structure/prose-total.d.ts +8 -0
  369. package/dist/structure/prose-total.d.ts.map +1 -1
  370. package/dist/structure/prose-total.js +70 -2
  371. package/dist/structure/prose-total.js.map +1 -1
  372. package/dist/structure/runs.d.ts.map +1 -1
  373. package/dist/structure/runs.js +9 -1
  374. package/dist/structure/runs.js.map +1 -1
  375. package/dist/structure/signed-date-line.d.ts +15 -0
  376. package/dist/structure/signed-date-line.d.ts.map +1 -0
  377. package/dist/structure/signed-date-line.js +68 -0
  378. package/dist/structure/signed-date-line.js.map +1 -0
  379. package/dist/structure/start-end-range.d.ts +30 -0
  380. package/dist/structure/start-end-range.d.ts.map +1 -0
  381. package/dist/structure/start-end-range.js +79 -0
  382. package/dist/structure/start-end-range.js.map +1 -0
  383. package/dist/structure/tax.d.ts.map +1 -1
  384. package/dist/structure/tax.js +5 -3
  385. package/dist/structure/tax.js.map +1 -1
  386. package/dist/structure/total-line.d.ts.map +1 -1
  387. package/dist/structure/total-line.js +10 -6
  388. package/dist/structure/total-line.js.map +1 -1
  389. package/dist/structure/total.d.ts +2 -0
  390. package/dist/structure/total.d.ts.map +1 -1
  391. package/dist/structure/total.js +34 -3
  392. package/dist/structure/total.js.map +1 -1
  393. package/dist/subject-codes.d.ts +21 -0
  394. package/dist/subject-codes.d.ts.map +1 -0
  395. package/dist/subject-codes.js +79 -0
  396. package/dist/subject-codes.js.map +1 -0
  397. package/dist/unlabelled-references.d.ts +6 -2
  398. package/dist/unlabelled-references.d.ts.map +1 -1
  399. package/dist/unlabelled-references.js +11 -10
  400. package/dist/unlabelled-references.js.map +1 -1
  401. package/genres.yaml +17 -0
  402. package/package.json +4 -4
  403. package/profiles/listing.yaml +1 -1
  404. package/profiles/property-sale.yaml +21 -0
  405. package/rules/closing-balance-mismatch.yaml +3 -3
  406. package/rules/date-range-reversed.yaml +4 -4
  407. package/rules/due-before-issue.yaml +9 -5
  408. package/rules/fact-conflict.yaml +2 -2
  409. package/rules/formula-amount-mismatch.yaml +67 -0
  410. package/rules/heading-echo.yaml +2 -2
  411. package/rules/installment-total-mismatch.yaml +9 -4
  412. package/rules/internal-jargon.yaml +2 -2
  413. package/rules/latin-spacing.yaml +4 -4
  414. package/rules/list-item-form-mix.yaml +1 -1
  415. package/rules/name-variant.yaml +5 -2
  416. package/rules/no-lead.yaml +2 -2
  417. package/rules/number-without-unit.yaml +2 -2
  418. package/rules/orthographic-variant.yaml +3 -3
  419. package/rules/reference-number-variant.yaml +3 -3
  420. package/rules/toki-as-condition.yaml +71 -0
  421. package/rules/total-mismatch.yaml +4 -4
  422. package/rules/unknown-word.yaml +2 -2
  423. package/rules/use-before-definition.yaml +2 -2
  424. package/src/api.ts +11 -2
  425. package/src/cli-text.ts +6 -4
  426. package/src/commands/grade.ts +75 -23
  427. package/src/company-kana-spelling.ts +22 -2
  428. package/src/company-name-ending.ts +50 -0
  429. package/src/company-names.ts +52 -17
  430. package/src/cross-run.ts +1 -0
  431. package/src/custom/no-rewrite.ts +2 -0
  432. package/src/custom/parse.ts +18 -2
  433. package/src/detectors/age-words.ts +12 -0
  434. package/src/detectors/agreement-slip.ts +3 -0
  435. package/src/detectors/annual-pay-mismatch.ts +3 -18
  436. package/src/detectors/blank-structure.ts +4 -3
  437. package/src/detectors/closing-balance-mismatch.ts +1 -0
  438. package/src/detectors/code-fences.ts +10 -0
  439. package/src/detectors/condition-toki.ts +60 -0
  440. package/src/detectors/conjugated-entry.ts +53 -0
  441. package/src/detectors/content-morphemes.ts +2 -1
  442. package/src/detectors/cross-facts.ts +2 -1
  443. package/src/detectors/custom.ts +9 -2
  444. package/src/detectors/document-shape.ts +8 -0
  445. package/src/detectors/due-date.ts +17 -7
  446. package/src/detectors/fact-consistency.ts +13 -17
  447. package/src/detectors/form-line.ts +47 -0
  448. package/src/detectors/formula-amount.ts +43 -0
  449. package/src/detectors/heading-claim.ts +76 -0
  450. package/src/detectors/heading-echo.ts +32 -1
  451. package/src/detectors/installment-total-mismatch.ts +35 -24
  452. package/src/detectors/list-parallel.ts +46 -7
  453. package/src/detectors/name-variant.ts +45 -8
  454. package/src/detectors/number-unit.ts +35 -9
  455. package/src/detectors/orthographic-variant.ts +5 -3
  456. package/src/detectors/orthography.ts +17 -8
  457. package/src/detectors/per-unit-words.ts +24 -0
  458. package/src/detectors/period-multiple-mismatch.ts +2 -18
  459. package/src/detectors/reference-number-variant.ts +27 -5
  460. package/src/detectors/registry/condition-toki.ts +4 -0
  461. package/src/detectors/registry/formula-amount.ts +4 -0
  462. package/src/detectors/rent-multiple-mismatch.ts +2 -18
  463. package/src/detectors/row-sentence-amounts.ts +5 -20
  464. package/src/detectors/stated-amounts.ts +20 -0
  465. package/src/detectors/step-time-sum.ts +2 -1
  466. package/src/detectors/structure-tree.ts +7 -2
  467. package/src/detectors/team.ts +13 -7
  468. package/src/detectors/time-order.ts +6 -3
  469. package/src/detectors/unknown-word.ts +20 -2
  470. package/src/detectors/use-interval.ts +8 -4
  471. package/src/detectors/use-maximum.ts +3 -1
  472. package/src/eval.ts +3 -3
  473. package/src/extension/document-view.ts +18 -9
  474. package/src/extension/entry-genres.ts +15 -0
  475. package/src/extension/module-detector.ts +9 -4
  476. package/src/extension/plugin-parse.ts +29 -7
  477. package/src/extension/problem-text.ts +4 -0
  478. package/src/facts/age-values.ts +24 -2
  479. package/src/facts/column-units.ts +67 -0
  480. package/src/facts/fact-values.ts +11 -1
  481. package/src/facts/labelled-facts.ts +16 -2
  482. package/src/facts/per-unit.ts +105 -0
  483. package/src/facts/row-sentence-amounts.ts +4 -26
  484. package/src/facts/table-facts.ts +7 -4
  485. package/src/facts/term-values.ts +94 -13
  486. package/src/fix-plan/text.ts +2 -2
  487. package/src/grade/baseline.ts +20 -12
  488. package/src/grade/expect-read.ts +65 -0
  489. package/src/grade/expect.ts +74 -0
  490. package/src/grade/grade-item.ts +14 -3
  491. package/src/grade/item.ts +48 -8
  492. package/src/grade/result.ts +5 -0
  493. package/src/grade/results-read.ts +7 -2
  494. package/src/grade/rubric-file.ts +46 -0
  495. package/src/grade/rubric.ts +77 -47
  496. package/src/grade/setup.ts +3 -3
  497. package/src/grade/stamp.ts +10 -2
  498. package/src/grade/task-rubric.ts +39 -0
  499. package/src/grade/text.ts +27 -5
  500. package/src/lexicon-genres.ts +11 -0
  501. package/src/name-char-reading.ts +16 -0
  502. package/src/name-end-letter.ts +52 -0
  503. package/src/name-neighbours.ts +2 -1
  504. package/src/name-separator.ts +32 -0
  505. package/src/name-variants.ts +54 -13
  506. package/src/number-name.ts +12 -3
  507. package/src/plugin.ts +6 -0
  508. package/src/profile/cue-lines.ts +14 -0
  509. package/src/profile/parse.ts +11 -2
  510. package/src/reference-numbers.ts +1 -1
  511. package/src/run.ts +1 -0
  512. package/src/spaced-person-name.ts +27 -2
  513. package/src/spacing-code.ts +13 -2
  514. package/src/spacing-minority.ts +17 -0
  515. package/src/structure/closing-balance.ts +46 -8
  516. package/src/structure/date-range.ts +4 -3
  517. package/src/structure/definition-use.ts +24 -1
  518. package/src/structure/document-context.ts +46 -0
  519. package/src/structure/fenced-lines.ts +28 -0
  520. package/src/structure/formula-amount.ts +236 -0
  521. package/src/structure/installment-fee.ts +201 -0
  522. package/src/structure/installment-total.ts +6 -6
  523. package/src/structure/labelled-date-order.ts +105 -21
  524. package/src/structure/labelled-order.ts +21 -10
  525. package/src/structure/line-amount-label.ts +2 -1
  526. package/src/structure/line-amount.ts +1 -11
  527. package/src/structure/prose-total.ts +81 -2
  528. package/src/structure/runs.ts +10 -1
  529. package/src/structure/signed-date-line.ts +78 -0
  530. package/src/structure/start-end-range.ts +120 -0
  531. package/src/structure/tax.ts +6 -3
  532. package/src/structure/total-line.ts +12 -6
  533. package/src/structure/total.ts +42 -3
  534. package/src/subject-codes.ts +105 -0
  535. package/src/unlabelled-references.ts +24 -16
@@ -65,8 +65,8 @@ example:
65
65
  | Taxi | $100 |
66
66
 
67
67
  not_flagged:
68
- ja: ほかの値に二つ以上、同じ一つの単位が付いているときだけ指します。単位の無い値のほうが多い列、単位が混ざる列(分と時間)、数でない値(未定)は見ません。表の見出しの単位(「金額(円)」)は読みません。
69
- en: Reported only when at least two other values carry one and the same unit. A column where bare numbers are the majority, one that mixes units (minutes and hours), and values that are not numbers (TBD) are not checked. A unit written in the header ("Amount ($)") is not read.
68
+ ja: ほかの値に二つ以上、同じ一つの単位が付いているときだけ指します。単位の無い値のほうが多い列、単位が混ざる列(分と時間)、数でない値(未定)は見ません。表の見出しの単位(「金額(円)」)は読みません。数量の列で、ほかの値が借りる期間(4日、2泊)のとき、単位の無い整数(チャイルドシート 1)は個数なので指しません。
69
+ en: Reported only when at least two other values carry one and the same unit. A column where bare numbers are the majority, one that mixes units (minutes and hours), and values that are not numbers (TBD) are not checked. A unit written in the header ("Amount ($)") is not read. In a Quantity column whose other values are a hired period (4 days, 2 nights), a bare whole number (Child seat | 1) is a count of pieces and is not reported.
70
70
  rewrite:
71
71
  depth: light
72
72
  ja:
@@ -4,7 +4,7 @@ status: stable
4
4
  how_to_find: orthographic-variant
5
5
  # 語の一覧は持たない。文書の中の語を、日本語は辞書の形の読み(出来る・できる はどちらもデキル)で、カタカナ語は小さい字と「ー」を
6
6
  # ならした形で、英字は大文字小文字とハイフンを外した形で束ね、同じ語の書き方が二つあれば少ないほうを指す。
7
- # 読みが同じで意味の違う語(成る・なる)は lang-ja の orthographic-variant-distinct に並べて外す。
7
+ # 読みが同じで意味の違う語(成る・なる)は lang-ja の orthographic-variant-distinct に並べて外す。genres を付けた語はそのジャンルだけで外す。
8
8
  uses: [pos]
9
9
  severity: info
10
10
 
@@ -56,8 +56,8 @@ example:
56
56
  Send the form by email. We answer every email within a day. Attach the receipt to the email.
57
57
 
58
58
  not_flagged:
59
- ja: 読みが同じでも漢字の違う語(書く・描く)、補助動詞・形式名詞と本来の使い方の書き分け(見て下さい・資料を下さい)、書き分けが意味の違いになる語(成る・なる、言う・いう)、語末の「ー」だけの違い(katakana-long-vowel が見ます)、鉤括弧や引用符の中、語の直後のふりがなの括弧の中(HTTP(えいちてぃーてぃーぴー))、chaff.yaml の names に書いた名前は見ません。名詞に続けて書いたかなの名詞(全員ぶん)と慣用句の動詞(気をつける)は、同じ読みの語(文、名札を付ける)と別に比べます。英字は、頭の字の大文字小文字(Email と email)と、大文字だけの語(強調や略語)、大文字の名前に語尾が付いた語(関数名の SENDs)、同じ文の略語の字を示した語(CLIPER と並ぶ CLImatology)を書き方の違いにしません(HBase のような名前の大文字は比べます)。少ないほうが三分の一を超えるときも言いません。文学のジャンルでは既定で止めています(その時代の書き方のため)。
60
- en: The case of a word's first letter (Email, email; Long-Term, long-term) is not a spelling, nor is a word in capitals only (emphasis or an acronym), nor a name in capitals with an ending (SENDs, OPENed), nor the letters of an acronym picked out beside it (CLImatology next to CLIPER). A name spelled with capitals (HBase) is still compared. Hyphenated words that are another word (re-sign, resign), part of an address (github.com), anything in quotation marks, a Japanese reading in brackets right after a word (HTTP(えいちてぃーてぃーぴー)) and the team's names are not compared. Nothing is reported when the minority is more than a third. The literature preset turns it off, since old spelling belongs to its time.
59
+ ja: 読みが同じでも漢字の違う語(書く・描く)、補助動詞・形式名詞と本来の使い方の書き分け(見て下さい・資料を下さい)、書き分けが意味の違いになる語(成る・なる、言う・いう。法務のジャンルでは、法令の書き方で書き分ける 時・とき と 物・もの も)、語末の「ー」だけの違い(katakana-long-vowel が見ます)、鉤括弧や引用符の中、語の直後のふりがなの括弧の中(HTTP(えいちてぃーてぃーぴー))、chaff.yaml の names に書いた名前は見ません。名詞に続けて書いたかなの名詞(全員ぶん)と慣用句の動詞(気をつける)は、同じ読みの語(文、名札を付ける)と別に比べます。英字は、頭の字の大文字小文字(Email と email)と、大文字だけの語(強調や略語)、大文字の名前に語尾が付いた語(関数名の SENDs)、同じ文の略語の字を示した語(CLIPER と並ぶ CLImatology)を書き方の違いにしません(HBase のような名前の大文字は比べます)。少ないほうが三分の一を超えるときも言いません。文学のジャンルでは既定で止めています(その時代の書き方のため)。
60
+ en: The case of a word's first letter (Email, email; Long-Term, long-term) is not a spelling, nor is a word in capitals only (emphasis or an acronym), nor a name in capitals with an ending (SENDs, OPENed), nor the letters of an acronym picked out beside it (CLImatology next to CLIPER). A name spelled with capitals (HBase) is still compared. In Japanese, words whose kanji and kana forms mean different things (成る and なる) are not compared, and in the legal genres neither are 時 and とき or 物 and もの, which legal drafting writes apart. Hyphenated words that are another word (re-sign, resign), part of an address (github.com), anything in quotation marks, a Japanese reading in brackets right after a word (HTTP(えいちてぃーてぃーぴー)) and the team's names are not compared. Nothing is reported when the minority is more than a third. The literature preset turns it off, since old spelling belongs to its time.
61
61
  level_meaning:
62
62
  ja: 少ないほうが語の {limit}% 以下のとき指摘
63
63
  en: reported when the minority spelling is {limit}% of the word's uses or less
@@ -34,7 +34,7 @@ levels: { strict: error, normal: warning, relaxed: warning }
34
34
  options:
35
35
  listed_kinds:
36
36
  kind: words
37
- default: [item]
37
+ default: [item, model]
38
38
  about:
39
39
  ja: 文書が多くを並べる番号の種類(reference-label の group)。この種類の、語の後ろや表にある番号どうしは比べず、語の無い番号だけを比べる
40
40
  en: Kinds of number a document lists many of (reference-label groups). Two labelled or tabled numbers of such a kind are never compared; only one with no label is
@@ -77,5 +77,5 @@ example:
77
77
  When you call, please give your booking number, MN-48215.
78
78
 
79
79
  not_flagged:
80
- ja: 「予約番号」「受付番号」「予約確認番号」「お問い合わせ番号」「社員番号」「学籍番号」「発注番号」「見積番号」「請求書番号」「患者番号」「契約番号」「登録番号」「口座番号」「証券番号」のような語のすぐ後ろ(間は空白と「:」「、」や開き括弧だけ)にある、数字を4つ以上含む英数字の並びだけを番号と見ます。発注番号は取引先の番号を書き写すこともありますが、同じ種類の語の番号どうしで隣り合う二文字だけが入れ違ったものしか指さないので、別の注文の番号は指しません。「原契約番号」「基本契約番号」「旧契約番号」「変更契約番号」「親契約番号」は別の契約の番号を引く語なので、文書自身の「契約番号」とは比べません。「登録番号」「受講番号」は参加者の登録の番号、「申込番号」は申込みの番号として、互いに比べません。「振込先口座番号」「振込元口座番号」は振込の相手の口座の番号を書く語なので、口座自身の「口座番号」とは比べません。「契約者番号」は契約者その人の番号で、証券番号とは見ません。語の無い番号(下に書く品番の形のものを除く)、種類の違う番号(学籍番号と社員番号、予約番号と受付番号、請求書番号と注文番号、見積番号と注文番号や請求書番号、登録番号と申込番号)、一文字だけ違う番号、離れた文字の入れ違い、二か所以上入れ違った番号は指しません。自動車のナンバー(ひばり野 330 ね 48-15)の形に合う並びは、語が「登録番号」でも自動車のナンバーとして読みます。ナンバーだけは、文書が一台の車のことを書いているとき(その車のナンバーを「登録番号:」のような語と番号だけの行に一つだけ書き、ほかのナンバーは一つだけで、その語が文の初めにあるとき。「代車の登録番号」のように語の前に語があれば別の車と見ます)に限って、地名・分類番号・かなが同じで一連番号が一文字だけ違うものも指します。「ナンバー」だけの語や英語の「Registration」だけの語は、ナンバーの語として読みません。「品番」「商品コード」「品目コード」は商品の番号の語です。表の行や列の見出しにこの語を書いた升の品番も、語の後ろの品番と同じに読みます。語の無い品番(「GP-0521の替芯」)は、英字と「-」と数字4つ以上の形(GP-0521)のときだけ、語の後ろか表にある品番のちょうど一つと隣り合う二文字だけが入れ違っていれば指します。その書き方の品番が文書のどこかで語の後ろか表にあれば、別の商品の品番と見て指しません(カタログの表に並ぶ AB-1234 と AB-1243 は二つの商品です)。語の後ろや表にある品番どうしも、別の商品の品番として比べません(この扱いをする種類は listed_kinds で決めます)。二つ以上の品番のどれとも読めるもの、英字や「-」の無い番号(48251)も指しません。「会員番号」「会員ID」の会員の番号と、「お客様番号」の番号は、別の番号になり得るので比べません。語のすぐ後ろの番号を「HM 5520 8137」のように空白一つずつで区切って書いたときは、続く並びがどれも4文字以上の大文字と数字で数字を含む間を一つの番号と読み、行の終わりや、語(「の方」「2名」)の前で止めます。
81
- en: "Only letters and digits right after a label (booking number, reservation number, confirmation number, reference number, employee number, student number, PO number, quote or estimate number, invoice number, patient number, contract or agreement number, registration number, account number, policy number), with nothing but spaces, a colon, a comma or an opening bracket between, are read, and only when they hold four digits or more. A PO number may be the buyer's, copied from another document, but only two numbers of one kind that differ by two neighbours swapped are reported, so a different order's number is not. An original, master, former, amended or parent contract number (and an amendment number) cites another contract, so it is never compared with the document's own contract number. A registration number labels an attendee's registration and an application number an application, so the two are never compared. A payee's, beneficiary's, payer's or sender's account number labels the other side of a transfer, so it is never compared with the account's own account number; a policyholder number is not read as a policy number. Unlabelled codes (but for item codes, below), numbers of different kinds (a student number and an employee number, a booking number and an order number, an invoice number and an order number, a quote number and an order or invoice number, a registration number and an application number), numbers that differ in one character, swaps of characters that are not neighbours and numbers with more than one swap are not reported. A bare quote is not read as a label, since it is also a verb (quote your PO number). A plate number, number plate or licence plate is a vehicle's and is never compared with a registration number; a bare Registration label is not read as a plate, since an attendee's registration is written so too. An item code, item no., SKU or product code labels an item; a code in a table under such a label, in its row or its column, is read as if written after it. A code with no label (Refills for GP-0521) is reported only in the shape letters, a hyphen and four digits or more, and only when it is exactly one labelled or tabled code with two neighbours swapped. When the document labels or tables that writing itself anywhere, it is another item and is not reported (a catalog's AB-1234 and AB-1243 are two items), and two labelled or tabled item codes are never compared with each other (listed_kinds names the kinds read so); nor is a code two labelled codes swap to, or a number with no letters or hyphen (48251). A member number or member ID and a customer number may be different numbers, so they are never compared. A number written in groups one space apart (HM 5520 8137) is read as one while each further group is four or more capitals and digits holding a digit, stopping at the line's end or before a word or a short count (expires, 100 copies)."
80
+ ja: 「予約番号」「受付番号」「予約確認番号」「お問い合わせ番号」「社員番号」「学籍番号」「発注番号」「見積番号」「請求書番号」「患者番号」「契約番号」「登録番号」「口座番号」「証券番号」のような語のすぐ後ろ(間は空白と「:」「、」や開き括弧だけ)にある、数字を4つ以上含む英数字の並びだけを番号と見ます。発注番号は取引先の番号を書き写すこともありますが、同じ種類の語の番号どうしで隣り合う二文字だけが入れ違ったものしか指さないので、別の注文の番号は指しません。「原契約番号」「基本契約番号」「旧契約番号」「変更契約番号」「親契約番号」は別の契約の番号を引く語なので、文書自身の「契約番号」とは比べません。「登録番号」「受講番号」は参加者の登録の番号、「申込番号」は申込みの番号として、互いに比べません。「振込先口座番号」「振込元口座番号」は振込の相手の口座の番号を書く語なので、口座自身の「口座番号」とは比べません。「契約者番号」は契約者その人の番号で、証券番号とは見ません。語の無い番号(下に書く品番の形のものを除く)、種類の違う番号(学籍番号と社員番号、予約番号と受付番号、請求書番号と注文番号、見積番号と注文番号や請求書番号、登録番号と申込番号)、一文字だけ違う番号、離れた文字の入れ違い、二か所以上入れ違った番号は指しません。自動車のナンバー(ひばり野 330 ね 48-15)の形に合う並びは、語が「登録番号」でも自動車のナンバーとして読みます。ナンバーだけは、文書が一台の車のことを書いているとき(その車のナンバーを「登録番号:」のような語と番号だけの行に一つだけ書き、ほかのナンバーは一つだけで、その語が文の初めにあるとき。「代車の登録番号」のように語の前に語があれば別の車と見ます)に限って、地名・分類番号・かなが同じで一連番号が一文字だけ違うものも指します。「ナンバー」だけの語や英語の「Registration」だけの語は、ナンバーの語として読みません。「品番」「商品コード」「品目コード」は商品の番号の語です。表の行や列の見出しにこの語を書いた升の品番も、語の後ろの品番と同じに読みます。語の無い品番(「GP-0521の替芯」)は、英字と「-」と数字4つ以上の形(GP-0521)のときだけ、語の後ろか表にある品番のちょうど一つと隣り合う二文字だけが入れ違っていれば指します。その書き方の品番が文書のどこかで語の後ろか表にあれば、別の商品の品番と見て指しません(カタログの表に並ぶ AB-1234 と AB-1243 は二つの商品です)。語の後ろや表にある品番どうしも、別の商品の品番として比べません(この扱いをする種類は listed_kinds で決めます)。二つ以上の品番のどれとも読めるもの、英字や「-」の無い番号(48251)も指しません。「会員番号」「会員ID」の会員の番号と、「お客様番号」の番号は、別の番号になり得るので比べません。語のすぐ後ろの番号を「HM 5520 8137」のように空白一つずつで区切って書いたときは、続く並びがどれも4文字以上の大文字と数字で数字を含む間を一つの番号と読み、行の終わりや、語(「の方」「2名」)の前で止めます。「型番」は製品の型番の語で、品番と同じく、語の後ろや表にある型番どうしは比べません。製品の文書(回収のお知らせや保証書)が自分の製品として名指す番号(題名にある番号、「型番:」「商品コード:」のような語と番号だけの行の番号、表で型番や品番の語を書いた升の番号)がちょうど一つのときに限り、「-」の前に英字が二つ以上あり、数字が二つ以上の短い番号(NH-805、FT-38)も読み、文書に一度だけ書いた、その番号の隣り合う二文字が入れ違った番号(NH-850)を指します。そう名指す番号が二つ以上ある文書(カタログ)、表にある番号、二度以上書いた番号、その番号と同じ行にある番号(「NH-805 と NH-850」)、「予約番号」のような別の種類の語の後ろの番号、英字一つの番号(A-12)は指しません。
81
+ en: "Only letters and digits right after a label (booking number, reservation number, confirmation number, reference number, employee number, student number, PO number, quote or estimate number, invoice number, patient number, contract or agreement number, registration number, account number, policy number), with nothing but spaces, a colon, a comma or an opening bracket between, are read, and only when they hold four digits or more. A PO number may be the buyer's, copied from another document, but only two numbers of one kind that differ by two neighbours swapped are reported, so a different order's number is not. An original, master, former, amended or parent contract number (and an amendment number) cites another contract, so it is never compared with the document's own contract number. A registration number labels an attendee's registration and an application number an application, so the two are never compared. A payee's, beneficiary's, payer's or sender's account number labels the other side of a transfer, so it is never compared with the account's own account number; a policyholder number is not read as a policy number. Unlabelled codes (but for item codes, below), numbers of different kinds (a student number and an employee number, a booking number and an order number, an invoice number and an order number, a quote number and an order or invoice number, a registration number and an application number), numbers that differ in one character, swaps of characters that are not neighbours and numbers with more than one swap are not reported. A bare quote is not read as a label, since it is also a verb (quote your PO number). A plate number, number plate or licence plate is a vehicle's and is never compared with a registration number; a bare Registration label is not read as a plate, since an attendee's registration is written so too. An item code, item no., SKU or product code labels an item; a code in a table under such a label, in its row or its column, is read as if written after it. A code with no label (Refills for GP-0521) is reported only in the shape letters, a hyphen and four digits or more, and only when it is exactly one labelled or tabled code with two neighbours swapped. When the document labels or tables that writing itself anywhere, it is another item and is not reported (a catalog's AB-1234 and AB-1243 are two items), and two labelled or tabled item codes are never compared with each other (listed_kinds names the kinds read so); nor is a code two labelled codes swap to, or a number with no letters or hyphen (48251). A member number or member ID and a customer number may be different numbers, so they are never compared. A number written in groups one space apart (HM 5520 8137) is read as one while each further group is four or more capitals and digits holding a digit, stopping at the line's end or before a word or a short count (expires, 100 copies). A model, model number or model no. labels a product's model, and, as with item codes, two labelled or tabled models are never compared. When a product document (a recall, a warranty) names exactly one code as its own (in its title, on a line holding only a model or item label and the code, as Model: SH-710, or in a table under such a label), a shorter code is read too (two letters or more before a hyphen, and two digits or more: SH-710, FT-38), and a code written once that is that code with two neighbours swapped (SH-701) is reported. Not when the document names two codes so (a catalog), nor a code in a table, one written twice or more, one on a line that also names the document's code (the SH-710 replaces the SH-701), one after a label of another kind (booking number), or one with a single letter (A-12)."
@@ -0,0 +1,71 @@
1
+ id: toki-as-condition
2
+ layer: L3
3
+ status: stable
4
+ how_to_find: condition-toki
5
+ word_list: condition-toki
6
+ extra_word_lists: [condition-follower]
7
+ requires: [pos]
8
+ languages: [ja]
9
+ severity: info
10
+
11
+ name:
12
+ ja: 条件を言う「時」
13
+ en: 時 written for a condition (法令用語の「とき」)
14
+
15
+ why:
16
+ ja: 法令の文では、「時」は時点(相続開始の時から)、「とき」は条件(認定を受けたときは)を言います。「認定を受けた時は」と書くと、読み手は「受けた時点で」の意味か「受けた場合に」の意味かを考えます。契約書や規程は法令の書き方にそろえるので、同じ使い分けをします。動詞や助動詞で終わる節の後ろの「時」に、「は」「には」「も」が続くときだけ指します。
17
+ en: Japanese legal drafting writes 時 for a point in time (相続開始の時から, "from the time the succession opens") and とき for a condition (認定を受けたときは, "if the approval is given"). With 認定を受けた時は the reader has to decide whether a moment or a condition is meant. Contracts and internal rules follow the statutes' usage. chaff reports 時 only after a clause that ends in a verb or an auxiliary and before は, には or も.
18
+
19
+ message:
20
+ ja: 条件を言うなら「{matched}」は「{preferred}」と書きます
21
+ en: 'For a condition, legal Japanese writes "{matched}" as "{preferred}"'
22
+
23
+ how_to_fix:
24
+ ja: 条件なら「とき」にしてください(認定を受けた時は → 認定を受けたときは)。時点を言うなら「時から」「時に」のように書けば、時点と読めます。
25
+ en: For a condition, write とき (認定を受けた時は → 認定を受けたときは). For a point in time, write 時から or 時に so that it reads as one.
26
+
27
+ placeholders:
28
+ matched:
29
+ ja: 見つけた語
30
+ en: the word found
31
+ preferred:
32
+ ja: 条件を言う書き方
33
+ en: the word for a condition
34
+
35
+ levels: { strict: warning, normal: info, relaxed: info }
36
+
37
+ use_for: [legal, docs, academic, literature, speech]
38
+ off_for:
39
+ docs: "The 時 / とき split is a convention of legal drafting: outside it, 時は for a condition is not a slip."
40
+ academic: "The 時 / とき split is a convention of legal drafting: outside it, 時は for a condition is not a slip."
41
+ literature: "The 時 / とき split is a convention of legal drafting: outside it, 時は for a condition is not a slip."
42
+ speech: "The 時 / とき split is a convention of legal drafting: outside it, 時は for a condition is not a slip."
43
+
44
+ group: wording
45
+ summary:
46
+ ja: 「認定を受けた時は」のように、条件を「とき」でなく「時」で書いた所
47
+ en: 時 written for a condition (受けた時は) where legal Japanese writes とき
48
+ example:
49
+ ja:
50
+ config: { genre: legal/contract }
51
+ before: |
52
+ 第5条 乙は、許可の取消しを受けた時は、直ちに甲に通知しなければならない。
53
+ after: |
54
+ 第5条 乙は、許可の取消しを受けたときは、直ちに甲に通知しなければならない。
55
+
56
+ not_flagged:
57
+ ja: 時点を言う「時」(相続開始の時から、死亡した時に、契約の終了の時まで)、名詞や「その」「ある」の後ろの「時」(事故の時は、その時は)、「時効」「時間」「同時」「随時」「臨時」「当時」「時点」「時期」のような語、鉤括弧で引いた中は指しません。法務のジャンルだけで動きます。
58
+ en: 時 for a point in time (相続開始の時から, 死亡した時に, 契約の終了の時まで), 時 after a noun or after その and ある (事故の時は, その時は), words such as 時効, 時間, 同時, 随時, 臨時, 当時, 時点 and 時期, and anything quoted in 「」 are not reported. Only the legal genres run this rule.
59
+ rewrite:
60
+ depth: light
61
+ ja:
62
+ direction: 条件を言う「時」を「とき」に替えてください。替えるのはその一語だけです。
63
+ pairs:
64
+ - before: 乙は、許可の取消しを受けた時は、直ちに甲に通知しなければならない。
65
+ after: 乙は、許可の取消しを受けたときは、直ちに甲に通知しなければならない。
66
+ - before: 支払期日を過ぎる時には、年三パーセントの遅延損害金を支払う。
67
+ after: 支払期日を過ぎるときには、年三パーセントの遅延損害金を支払う。
68
+ keep:
69
+ - 条の番号と中身
70
+ avoid:
71
+ - 時点を言う「時」(時から、時まで、時に)まで替える
@@ -10,8 +10,8 @@ name:
10
10
  en: A total that is not the sum of its items
11
11
 
12
12
  why:
13
- ja: 見積や請求の「合計」が、上に並べた金額の和と合わないと、読み手はどちらが正しいのかを計算し直すことになります。行を足したり消したりしたあとに、合計だけ直し忘れると起きます。箇条書きか表で、合計の語(合計・小計)で始まる行を、同じ単位で同じ列の金額の和と比べます。表の最初の列の見出しか、合計の行が数を書いた列の見出しが名指す語を付けた合計(見出しが「控除項目」の表の「控除合計」、「単位数」の列の「修得単位合計」)も合計の行と読みます。合計が足す期間を頭に付けた合計(年間合計、年計、通年合計)も合計の行と読みます。見出しが「項目」の表でも、最後の行の差引合計・控除合計は、上に合計のような行が無く金額の列が一つなら合計の行と読みます。契約書のように一つの文に書いた合計(「保守費60,000円、運用費30,000円とし、合計100,000円とする」「月額150,000円(内訳:…)」)も、その文に並べた同じ単位の金額の和と比べます。小計のあとの総計のように、足し方が何通りかあるときは、どの足し方でも合わないときだけ指します。
14
- en: When the total of a quote or an invoice is not the sum of the amounts listed above it, the reader has to add them up again to find out which is right. It happens when a line is added or removed and the total is not updated. In a list or a table, a line starting with a total word (Total, Subtotal) is compared with the sum of the amounts in the same unit and column above it. A total with a word that the header of the table's first column, or of the column the total holds its number in, names ("Total deductions" under "Deduction", "Total credits earned" in the "Credits" column) is read as a total line too, and so is a total naming the span it covers ("Total for the year", "Year total", "Annual total"). Under a header that names nothing ("Item"), a "Total deductions" on the table's last row is read too, when no row above it is a total or a gross or net amount and the table has one column of amounts. A total written in a sentence, as contracts do ("$6,000 for hosting and $3,000 for support, for a total of $9,000", "$8 per month, made up of …"), is compared with the amounts in the same unit listed in that sentence. When there is more than one way to add them up, such as a grand total after a subtotal and tax, it is pointed out only when none of them matches.
13
+ ja: 見積や請求の「合計」が、上に並べた金額の和と合わないと、読み手はどちらが正しいのかを計算し直すことになります。行を足したり消したりしたあとに、合計だけ直し忘れると起きます。箇条書きか表で、合計の語(合計・小計)で始まる行を、同じ単位で同じ列の金額の和と比べます。表の最初の列の見出しか、合計の行が数を書いた列の見出しが名指す語を付けた合計(見出しが「控除項目」の表の「控除合計」、「単位数」の列の「修得単位合計」)も合計の行と読みます。合計が足す期間を頭に付けた合計(年間合計、年計、通年合計)も合計の行と読みます。見出しが「項目」の表でも、最後の行の差引合計・控除合計は、上に合計のような行が無く金額の列が一つなら合計の行と読みます。契約書のように一つの文に書いた合計(「保守費60,000円、運用費30,000円とし、合計100,000円とする」「月額150,000円(内訳:…)」「総額12,000円:設計5,000円、開発6,000円」)も、その文に並べた同じ単位の金額の和と比べます。合計で終わる文の次の文が「内訳は」で始まるときは、その文の金額と比べます。小計のあとの総計のように、足し方が何通りかあるときは、どの足し方でも合わないときだけ指します。
14
+ en: When the total of a quote or an invoice is not the sum of the amounts listed above it, the reader has to add them up again to find out which is right. It happens when a line is added or removed and the total is not updated. In a list or a table, a line starting with a total word (Total, Subtotal) is compared with the sum of the amounts in the same unit and column above it. A total with a word that the header of the table's first column, or of the column the total holds its number in, names ("Total deductions" under "Deduction", "Total credits earned" in the "Credits" column) is read as a total line too, and so is a total naming the span it covers ("Total for the year", "Year total", "Annual total"). Under a header that names nothing ("Item"), a "Total deductions" on the table's last row is read too, when no row above it is a total or a gross or net amount and the table has one column of amounts. A total written in a sentence, as contracts do ("$6,000 for hosting and $3,000 for support, for a total of $9,000", "$8 per month, made up of …", "a total of $12,000 — $5,000 for design and $6,000 for development"), is compared with the amounts in the same unit listed in that sentence, and with the amounts of the next sentence when it opens with a breakdown phrase ("This consists of …"). When there is more than one way to add them up, such as a grand total after a subtotal and tax, it is pointed out only when none of them matches.
15
15
 
16
16
  message:
17
17
  ja: 合計「{written}」が、内訳の金額の和({sum})と合いません
@@ -61,5 +61,5 @@ example:
61
61
  | Total | $8,000 |
62
62
 
63
63
  not_flagged:
64
- ja: 単位や列の違う金額は足しません。合計の語に表の見出しが名指さない語を付けた行(見出しが「項目」の表の「消費税合計」)は、別の種類の合計かもしれないので比べません。差引合計・控除合計も、表の最後の行でないとき、上に合計の行や総支給額・支給合計の行があるとき、金額の列が二つ以上あるときは比べず、下から続けた行の和か、その上の行の和からそれを引いた額と合えば指しません。面積のように、上の行の和とは限らない量の合計(面積合計)も比べません。前の期間の合計(前年合計)は読まず、期間を付けた合計が内訳の和を一年に直した額(ちょうど4倍・12倍・52倍。月額の内訳に年間合計)なら比べません。重さ・容量・長さ(mg、g、mL、L、cm、km)は、列のどの行も同じ種類の量なら換算して足します(500mg と 0.5g は 1g)。何あたりかを書いた量(300mg/錠)、目安の量(約300mg)、範囲(300〜400mg)がある列は足しません。足し方が何通りもあるとき(小計と税のあとの総計など)は、どれとも合わないときだけ指します。文の中では、合計の語(合計・総額)のすぐ後ろの金額か内訳の語(内訳は)のすぐ前の金額だけを合計と読み、内訳の金額が二つ以上あるときだけ比べます。並びの一部(単価や上限など、合計の語から離れた金額を除いた並び)の和か、一つを引いた額(値引き)と合えば指しません。
65
- en: Amounts in another unit or column are not added. A total with a word the table's header does not name ("Total tax" under "Item") is not compared, as it may be a total of another kind, nor is a total of a quantity that need not be the sum of the rows (Total area). Under such a header, "Total deductions" is not compared when it is not the last row, when a total or a gross or net amount (Gross pay) is above it, or when the table has two columns of amounts; it is not reported when it matches the last few rows, or the rows above those less them. A total for another span ("Prior-year total") is not read, and a total naming its span that is the items scaled to a year (exactly 4, 12 or 52 times their sum, as monthly items under an annual total) is not compared. Mass, volume and length (mg, g, mL, L, cm, km) are converted and added when every row of the column is the same kind of measure (500 mg and 0.5 g make 1 g); a column with an amount per something (300 mg/tablet), a rough amount (about 300 mg) or a range (300-400 mg) is not added. Where there is more than one way to add them up, it is reported only when none matches. In a sentence, only the amount right after a total phrase (a total of) or right before a breakdown phrase (made up of) is read as a total, and only when two or more items in its unit are listed. It is not reported when the items nearest the phrase add up to it, or when it matches with one item taken away (a discount).
64
+ ja: 単位や列の違う金額は足しません。合計の語に表の見出しが名指さない語を付けた行(見出しが「項目」の表の「消費税合計」)は、別の種類の合計かもしれないので比べません。差引合計・控除合計も、表の最後の行でないとき、上に合計の行や総支給額・支給合計の行があるとき、金額の列が二つ以上あるときは比べず、下から続けた行の和か、その上の行の和からそれを引いた額と合えば指しません。面積のように、上の行の和とは限らない量の合計(面積合計)も比べません。前の期間の合計(前年合計)は読まず、期間を付けた合計が内訳の和を一年に直した額(ちょうど4倍・12倍・52倍。月額の内訳に年間合計)なら比べません。重さ・容量・長さ(mg、g、mL、L、cm、km)は、列のどの行も同じ種類の量なら換算して足します(500mg と 0.5g は 1g)。何あたりかを書いた量(300mg/錠)、目安の量(約300mg)、範囲(300〜400mg)がある列は足しません。足し方が何通りもあるとき(小計と税のあとの総計など)は、どれとも合わないときだけ指します。文の中では、合計の語(合計・総額)のすぐ後ろの金額か内訳の語(内訳は)のすぐ前の金額だけを合計と読み、内訳の金額が二つ以上あるときだけ比べます。並びの一部(単価や上限など、合計の語から離れた金額を除いた並び)の和か、一つを引いた額(値引き)と合えば指しません。合計のすぐ後ろの「:」から続く内訳は、「うち」「または」「最大」のように内訳のすべてとは限らない語があるとき、ほかの単位の金額や割合を並べたときは比べません。
65
+ en: Amounts in another unit or column are not added. A total with a word the table's header does not name ("Total tax" under "Item") is not compared, as it may be a total of another kind, nor is a total of a quantity that need not be the sum of the rows (Total area). Under such a header, "Total deductions" is not compared when it is not the last row, when a total or a gross or net amount (Gross pay) is above it, or when the table has two columns of amounts; it is not reported when it matches the last few rows, or the rows above those less them. A total for another span ("Prior-year total") is not read, and a total naming its span that is the items scaled to a year (exactly 4, 12 or 52 times their sum, as monthly items under an annual total) is not compared. Mass, volume and length (mg, g, mL, L, cm, km) are converted and added when every row of the column is the same kind of measure (500 mg and 0.5 g make 1 g); a column with an amount per something (300 mg/tablet), a rough amount (about 300 mg) or a range (300-400 mg) is not added. Where there is more than one way to add them up, it is reported only when none matches. In a sentence, only the amount right after a total phrase (a total of) or right before a breakdown phrase (made up of) is read as a total, and only when two or more items in its unit are listed. It is not reported when the items nearest the phrase add up to it, or when it matches with one item taken away (a discount). Items after a colon or a dash right after a total are not compared when "including", "or" or "up to" shows they may not be every item, when one of them is in another unit, or when they are percentages.
@@ -47,8 +47,8 @@ example:
47
47
  The report is attached to this email.
48
48
 
49
49
  not_flagged:
50
- ja: 大文字を含む語、四字より短い語、コード・URL・メールアドレスの中の語、強調や角括弧で頭の字を分けた語の残り(**G**lobally の lobally、[e]xpressions の xpressions)、文書で二度以上使う語、一字違いの辞書の語が無い語、chaff.yaml の names に並べた語、語彙表 known-misspelling が別に言う語は指しません。
51
- en: Words with a capital letter, words shorter than four letters, words in code, URLs and email addresses, the rest of a word whose first letter is set apart by emphasis or brackets (lobally in **G**lobally, xpressions in [e]xpressions), words used twice or more in the document, words with no dictionary word one letter away, words listed under names in chaff.yaml, and the misspellings known-misspelling reports are not reported.
50
+ ja: 大文字を含む語、四字より短い語、コード・URL・メールアドレスの中の語、強調や角括弧で頭の字を分けた語の残り(**G**lobally の lobally、[e]xpressions の xpressions)、文書で二度以上使う語、一字違いの辞書の語が無い語、chaff.yaml の names に並べた語、語彙表 known-misspelling が別に言う語は指しません。同じ文書がコード(`tidyq check` やコードの区画)にも書いた語も、その文書の名前なので指しません。
51
+ en: Words with a capital letter, words shorter than four letters, words in code, URLs and email addresses, the rest of a word whose first letter is set apart by emphasis or brackets (lobally in **G**lobally, xpressions in [e]xpressions), words used twice or more in the document, words with no dictionary word one letter away, words listed under names in chaff.yaml, and the misspellings known-misspelling reports are not reported. Nor is a word the document also writes in code (`tidyq check`, a code block), since it is a name the document uses.
52
52
  rewrite:
53
53
  depth: light
54
54
  en:
@@ -50,8 +50,8 @@ example:
50
50
  This agreement is between Harbour Ltd (the "Seller") and Hill Ltd (the "Buyer"). The Seller ships within five days.
51
51
 
52
52
  not_flagged:
53
- ja: 定義の条(「X」とは…をいう)で定義した語は、前で使っても言いません。定義の条は文書の頭にも終わりにも置く書き方があるためです。規約やポリシーの丁寧な形(以下「X」といいます)も、法令の形と同じに読みます。見出しの行(章・節の行、条の前の「(買主の義務)」のような見出し)の語と、漢字で終わる語にさらに漢字が続く長い語(「監査委員会」の「監査委員」)と、定義の括弧の前の長い名前をそのまま書いた所(「…作成の手引き(以下「手引き」という。)」より前の「…作成の手引き」)は、使った所に数えません。最初の一か所だけを指します。
54
- en: Terms defined in a definitions clause ("X" means ...) are not checked, since a definitions clause may come first or last. A heading line (a chapter or section line, or the caption above an article) does not count as a use, nor does a longer word that runs on in kanji past a term ending in kanji, nor an earlier copy of the long name written just before the definition's bracket. The polite Japanese form (以下「X」といいます) is read like the statute form. Only the first early use is pointed at.
53
+ ja: 定義の条(「X」とは…をいう)で定義した語は、前で使っても言いません。定義の条は文書の頭にも終わりにも置く書き方があるためです。規約やポリシーの丁寧な形(以下「X」といいます)も、法令の形と同じに読みます。見出しの行(章・節の行、条の前の「(買主の義務)」のような見出し)の語と、漢字で終わる語にさらに漢字が続く長い語(「監査委員会」の「監査委員」)と、定義の括弧の前の長い名前をそのまま書いた所(「…作成の手引き(以下「手引き」という。)」より前の「…作成の手引き」)は、使った所に数えません。最初の一か所だけを指します。別の語を定義する括弧の前の名前の中(This Services Agreement (this "Agreement") の Services、本サービス利用契約(以下「本契約」という。)の本サービス)も、使った所に数えません。
54
+ en: Terms defined in a definitions clause ("X" means ...) are not checked, since a definitions clause may come first or last. A heading line (a chapter or section line, or the caption above an article) does not count as a use, nor does a longer word that runs on in kanji past a term ending in kanji, nor an earlier copy of the long name written just before the definition's bracket. The polite Japanese form (以下「X」といいます) is read like the statute form. Only the first early use is pointed at. A word inside the name written right before another term's defining bracket (Services in This Services Agreement (this "Agreement")) is not a use either.
55
55
  rewrite:
56
56
  depth: structure
57
57
  ja:
package/src/api.ts CHANGED
@@ -31,8 +31,17 @@ export type Section = { readonly depth: number; readonly heading: string; readon
31
31
  /** One bulleted or numbered list, with the length of each item in characters. */
32
32
  export type List = { readonly span: Span; readonly itemLengths: readonly number[] };
33
33
 
34
- /** One entry of a word list. instead_of is another way to write the same thing, for rules that check a document is consistent. */
35
- export type LexiconEntry = { readonly pattern: string; readonly instead_of?: string };
34
+ /**
35
+ * One entry of a word list. instead_of is another way to write the same thing, for rules that check a document is
36
+ * consistent; rewrite, how to rewrite this phrase. genres: the genres or groups it holds in (legal, blog/tech); without
37
+ * them, every genre. options.lexicon and doc.lexicons hold only the entries for the document's genre.
38
+ */
39
+ export type LexiconEntry = {
40
+ readonly pattern: string;
41
+ readonly instead_of?: string;
42
+ readonly rewrite?: string;
43
+ readonly genres?: readonly string[];
44
+ };
36
45
 
37
46
  export type Lexicon = readonly LexiconEntry[];
38
47
 
package/src/cli-text.ts CHANGED
@@ -49,9 +49,10 @@ const USAGE_JA = `chaff — 文章の読みにくいところを見つけます
49
49
  chaff ai-score <file>... [--format text|json] [--json] [--compact]
50
50
  AI らしさの簡易判定(低・中・高)。生成文に多い目印を、同じジャンルの人の文書と比べる(書いたのが AI かは判定しない)
51
51
  --json は --format json と同じ。--compact はファイルごとに 1 行
52
- chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <前の results.jsonl>] [--allow-stamp-mismatch]
52
+ chaff grade <items.jsonl> [--rubric <rubric.yaml|.json>] [--out <results.jsonl>] [--baseline <前の results.jsonl>] [--allow-stamp-mismatch]
53
53
  [--variant-key <欄>] [--format text|json|markdown] [--json] [--compact]
54
54
  AI の出力を JSONL でまとめて採点する(指摘の率・事実・引用・合否。何も送らない)
55
+ --rubric はその回だけ chaff.yaml の grade: の代わりにそのファイル(grade: と同じ形の YAML か JSON)で採点する
55
56
  --allow-stamp-mismatch はルールか設定が前の回と違っても比べる(そのことを先に出す)
56
57
  --variant-key は variant の欄の代わりにその欄で出力を分けて並べる。--json は --format json と同じ。markdown は PR のコメント向け
57
58
  chaff fix-plan <file> [--depth light|structure|register] [--json]
@@ -67,7 +68,7 @@ const USAGE_JA = `chaff — 文章の読みにくいところを見つけます
67
68
  chaff feedback <file> --rule <rule> [--line N] | --missed --line N
68
69
  誤った指摘・見逃しの報告の下書きを作る(何も送らない。--with-config で chaff.yaml 全体も載せる)
69
70
 
70
- --compact エンジニア向けの 1 行形式
71
+ --compact エンジニア向けの短い形式。指摘 1 件を 2 行で出す(位置・重さ・説明、その下に rule の id)
71
72
  --no-guide ジャンルを決めたときに最初に出す、そのジャンルの指針を出さない
72
73
  --experimental 試験中の rule も動かす
73
74
  --genre <ジャンル> この実行だけジャンルを決める(chaff.yaml より優先)
@@ -108,9 +109,10 @@ const USAGE_EN = `chaff — finds what makes writing hard to read. It never rewr
108
109
  chaff ai-score <file>... [--format text|json] [--json] [--compact]
109
110
  quick AI-likeness score (low, medium, high): signs common in generated text against human documents of the genre (not a verdict on who wrote it)
110
111
  --json is --format json; --compact prints one line per file
111
- chaff grade <items.jsonl> [--out <results.jsonl>] [--baseline <earlier results.jsonl>] [--allow-stamp-mismatch]
112
+ chaff grade <items.jsonl> [--rubric <rubric.yaml|.json>] [--out <results.jsonl>] [--baseline <earlier results.jsonl>] [--allow-stamp-mismatch]
112
113
  [--variant-key <field>] [--format text|json|markdown] [--json] [--compact]
113
114
  grade a JSONL file of model outputs (finding rates, facts, quotations, pass or fail; sends nothing)
115
+ --rubric grades by that file (YAML or JSON, shaped like grade:) instead of chaff.yaml's grade: for this run
114
116
  --allow-stamp-mismatch compares with the baseline even when its rules or settings differ, saying so first
115
117
  --variant-key splits the outputs by that field instead of variant; --json is --format json; markdown is for a PR comment
116
118
  chaff fix-plan <file> [--depth light|structure|register] [--json]
@@ -126,7 +128,7 @@ const USAGE_EN = `chaff — finds what makes writing hard to read. It never rewr
126
128
  chaff feedback <file> --rule <rule> [--line N] | --missed --line N
127
129
  draft a report of a wrong or missed finding (sends nothing; --with-config adds all of chaff.yaml)
128
130
 
129
- --compact one line per finding, for engineers
131
+ --compact a short form for engineers: two lines per finding (position, severity, message; the rule id below)
130
132
  --no-guide leave out the genre's guide, which comes first when the genre is set
131
133
  --experimental run the experimental rules too
132
134
  --genre <genre> the genre for this run only (wins over chaff.yaml)
@@ -1,10 +1,11 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
1
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { packageFor } from "../adapter-load.ts";
4
4
  import type { Config } from "../config/load.ts";
5
5
  import { readDocumentFile } from "../files.ts";
6
6
  import { GENRES } from "../genre.ts";
7
7
  import { gradeItem, type GradeSetup } from "../grade/grade-item.ts";
8
+ import { expectProblems } from "../grade/expect-read.ts";
8
9
  import { DEFAULT_VARIANT_FIELD, ITEM_FIELDS, parseItems, type GradeItem, type VariantField } from "../grade/item.ts";
9
10
  import { renderMarkdown } from "../grade/render-markdown.ts";
10
11
  import { renderVariants, renderVariantsCompact } from "../grade/render-variants.ts";
@@ -14,6 +15,8 @@ import { renderCompact, renderSummary } from "../grade/render.ts";
14
15
  import type { GradeResult } from "../grade/result.ts";
15
16
  import { gradeSetup } from "../grade/setup.ts";
16
17
  import { parseRubric, type Rubric } from "../grade/rubric.ts";
18
+ import { parseRubricFile, type RubricFileProblem } from "../grade/rubric-file.ts";
19
+ import { rubricRuleEntries, taskNamesOf, taskRuleIds } from "../grade/task-rubric.ts";
17
20
  import { rulesOf } from "../custom/load.ts";
18
21
  import { summaryOf } from "../grade/summary.ts";
19
22
  import { GRADE_TEXT, type GradeText } from "../grade/text.ts";
@@ -26,7 +29,7 @@ import { chooseBaseline } from "./grade-baseline.ts";
26
29
  /** Exit codes (spec §29.3). 2 keeps "the grader did not run" apart from "an output is bad" at a CI gate. */
27
30
  export const GRADE_EXIT = { passed: 0, failed: 1, unreadable: 2 } as const;
28
31
 
29
- const VALUED: ReadonlySet<string> = new Set(["--out", "--genre", "--baseline", "--format", "--variant-key"]);
32
+ const VALUED: ReadonlySet<string> = new Set(["--out", "--genre", "--baseline", "--format", "--variant-key", "--rubric"]);
30
33
 
31
34
  const FORMATS = ["text", "json", "markdown"] as const;
32
35
 
@@ -56,11 +59,13 @@ export type GradeContext = {
56
59
  readonly ui: UiLanguage;
57
60
  };
58
61
 
59
- const readItems = async (path: string, variantField: VariantField, text: GradeText): Promise<readonly GradeItem[] | undefined> => {
62
+ type ReadItems = { readonly items: readonly GradeItem[]; readonly lines: readonly number[] };
63
+
64
+ const readItems = async (path: string, variantField: VariantField, tasks: readonly string[], text: GradeText): Promise<ReadItems | undefined> => {
60
65
  try {
61
- const vocabulary = { isLanguage: (language: string) => packageFor(language) !== undefined, genres: GENRES };
66
+ const vocabulary = { isLanguage: (language: string) => packageFor(language) !== undefined, genres: GENRES, tasks };
62
67
  const parsed = parseItems(await readDocumentFile(path), vocabulary, variantField);
63
- if ("items" in parsed) return parsed.items;
68
+ if ("items" in parsed) return parsed;
64
69
  parsed.problems.forEach((problem) => console.error(`${path}: ${text.problem(problem)}`));
65
70
  } catch (error) {
66
71
  console.error(text.unreadable(path, error instanceof Error ? error.message : String(error)));
@@ -68,39 +73,75 @@ const readItems = async (path: string, variantField: VariantField, text: GradeTe
68
73
  return undefined;
69
74
  };
70
75
 
71
- /** The `grade:` rubric, or undefined after saying what is wrong with it. `rubric: undefined` is a run with no rubric. */
72
- const readRubric = (config: Config, text: GradeText): { readonly rubric: Rubric | undefined } | undefined => {
76
+ /** The rubric a run grades by, and the --rubric file it came from when it came from one. */
77
+ type RubricRead = { readonly rubric: Rubric | undefined; readonly file?: { readonly path: string; readonly digest: string } | undefined };
78
+
79
+ /** chaff.yaml's `grade:` rubric, or undefined after saying what is wrong with it. `rubric: undefined` is a run with no rubric. */
80
+ const readConfigRubric = (config: Config, text: GradeText): RubricRead | undefined => {
73
81
  const parsed = parseRubric(config.grade);
74
82
  if ("rubric" in parsed) return parsed;
75
83
  parsed.problems.forEach((problem) => console.error(`chaff: ${text.rubricProblem(problem)}`));
76
84
  return undefined;
77
85
  };
78
86
 
79
- /** A rule id under grade.rules that chaff does not know. Said once here; each result also lists it as not run. */
80
- const warnUnknownRules = (rubric: Rubric | undefined, config: Config, text: GradeText): void => {
87
+ const fileProblemText = (path: string, problem: RubricFileProblem, text: GradeText): string => {
88
+ if (problem.kind === "format") return text.rubricFormat(path);
89
+ if (problem.kind === "syntax") return text.rubricSyntax(path, problem.why);
90
+ return text.rubricProblem(problem.problem, path);
91
+ };
92
+
93
+ /** A --rubric file's rubric, which replaces chaff.yaml's `grade:`, or undefined after saying why it cannot be read. */
94
+ const readRubricFile = (path: string, text: GradeText): RubricRead | undefined => {
95
+ try {
96
+ const parsed = parseRubricFile(path, readFileSync(path, "utf8"));
97
+ if ("rubric" in parsed) return { rubric: parsed.rubric, file: { path, digest: parsed.digest } };
98
+ parsed.problems.forEach((problem) => console.error(fileProblemText(path, problem, text)));
99
+ } catch (error) {
100
+ console.error(text.unreadable(path, error instanceof Error ? error.message : String(error)));
101
+ }
102
+ return undefined;
103
+ };
104
+
105
+ const readRubric = (rubricPath: string | undefined, config: Config, text: GradeText): RubricRead | undefined =>
106
+ rubricPath === undefined ? readConfigRubric(config, text) : readRubricFile(rubricPath, text);
107
+
108
+ /** A rule id under the rubric's rules that chaff does not know. Said once here; each result also lists it as not run. */
109
+ const warnUnknownRules = (rubric: RubricRead, config: Config, text: GradeText): void => {
81
110
  const known = new Set(rulesOf(config.language ?? "en", config).map((rule) => rule.id));
82
- Object.keys(rubric?.rules ?? {})
83
- .filter((id) => !known.has(id))
84
- .forEach((id) => console.error(`chaff: grade.rules.${id}: ${text.unknownRule}`));
111
+ const where = rubric.file === undefined ? "chaff: grade." : `${rubric.file.path}: `;
112
+ rubricRuleEntries(rubric.rubric)
113
+ .filter((entry) => !known.has(entry.id))
114
+ .forEach((entry) => console.error(`${where}${entry.path}.${entry.id}: ${text.unknownRule}`));
85
115
  };
86
116
 
87
117
  const setupFor = async (
88
118
  items: readonly GradeItem[],
89
- rubric: Rubric | undefined,
119
+ rubric: RubricRead,
90
120
  argv: readonly string[],
91
121
  context: GradeContext,
92
122
  text: GradeText,
93
123
  ): Promise<GradeSetup | undefined> => {
94
124
  const languages = items.flatMap((item) => (item.language === undefined ? [] : [item.language]));
95
- const run = { experimental: context.config.experimental || argv.includes("--experimental"), genre: context.flag(argv, "--genre") };
125
+ const run = {
126
+ experimental: context.config.experimental || argv.includes("--experimental"),
127
+ genre: context.flag(argv, "--genre"),
128
+ rubricFile: rubric.file?.digest,
129
+ };
96
130
  try {
97
- return await gradeSetup(context.config, run, languages, rubric);
131
+ return await gradeSetup(context.config, run, languages, rubric.rubric);
98
132
  } catch (error) {
99
133
  console.error(text.cannotLoad(error instanceof Error ? error.message : String(error)));
100
134
  return undefined;
101
135
  }
102
136
  };
103
137
 
138
+ /** Whether every expect entry is one fact; else says which are not, on their lines, before anything is graded. */
139
+ const expectReadable = async (path: string, read: ReadItems, setup: GradeSetup, text: GradeText): Promise<boolean> => {
140
+ const problems = (await Promise.all(read.items.map((item, index) => expectProblems(item, read.lines[index] ?? 0, setup)))).flat();
141
+ problems.forEach((problem) => console.error(`${path}: ${text.problem(problem)}`));
142
+ return problems.length === 0;
143
+ };
144
+
104
145
  /** One output after another, in the file's order: the results file lines up with the input. */
105
146
  const gradeInOrder = (items: readonly GradeItem[], setup: GradeSetup): Promise<GradeResult[]> =>
106
147
  items.reduce<Promise<GradeResult[]>>(async (previous, item) => [...(await previous), await gradeItem(item, setup)], Promise.resolve([]));
@@ -144,14 +185,24 @@ const printSummary = (path: string, results: readonly GradeResult[], compared: C
144
185
  } else printText(path, results, variants, compared, printing);
145
186
  };
146
187
 
147
- type RunOptions = { readonly path: string; readonly format: Format; readonly variantField: VariantField };
188
+ type RunOptions = { readonly path: string; readonly format: Format; readonly variantField: VariantField; readonly rubric: string | undefined };
189
+
190
+ /** --rubric's file: undefined when not given, null when given without one (a usage error, not a quiet fall back to chaff.yaml). */
191
+ const rubricPathOf = (argv: readonly string[], context: GradeContext): string | undefined | null => {
192
+ if (!argv.includes("--rubric")) return undefined;
193
+ const path = context.flag(argv, "--rubric");
194
+ return path === undefined || path === "" || path.startsWith("--") ? null : path;
195
+ };
148
196
 
149
197
  /** The file to grade and how to read and print it, or undefined after printing the usage. */
150
198
  const runOptionsOf = (argv: readonly string[], context: GradeContext): RunOptions | undefined => {
151
199
  const [path, ...extra] = gradeTargets(argv);
152
200
  const format = formatOf(argv, context);
153
201
  const variantField = variantFieldOf(argv, context);
154
- if (path !== undefined && extra.length === 0 && format !== undefined && variantField !== undefined) return { path, format, variantField };
202
+ const rubric = rubricPathOf(argv, context);
203
+ if (path !== undefined && extra.length === 0 && format !== undefined && variantField !== undefined && rubric !== null) {
204
+ return { path, format, variantField, rubric };
205
+ }
155
206
  console.error(GRADE_TEXT[context.ui].usage);
156
207
  return undefined;
157
208
  };
@@ -171,16 +222,17 @@ export const runGrade = async (argv: readonly string[], context: GradeContext):
171
222
  const options = runOptionsOf(argv, context);
172
223
  if (options === undefined) return GRADE_EXIT.unreadable;
173
224
  const { path } = options;
174
- const rubric = readRubric(context.config, host);
175
- const items = rubric === undefined ? undefined : await readItems(path, options.variantField, host);
176
- const setup = items === undefined || rubric === undefined ? undefined : await setupFor(items, rubric.rubric, argv, context, host);
177
- if (setup === undefined || items === undefined) return GRADE_EXIT.unreadable;
225
+ const rubric = readRubric(options.rubric, context.config, host);
226
+ const read = rubric === undefined ? undefined : await readItems(path, options.variantField, taskNamesOf(rubric.rubric), host);
227
+ const setup = read === undefined || rubric === undefined ? undefined : await setupFor(read.items, rubric, argv, context, host);
228
+ if (setup === undefined || read === undefined || rubric === undefined || !(await expectReadable(path, read, setup, host))) return GRADE_EXIT.unreadable;
229
+ const { items } = read;
178
230
  const baseline = await chooseBaseline(context.flag(argv, "--baseline"), setup.stamp, argv.includes("--allow-stamp-mismatch"), context.ui);
179
231
  if (baseline.kind === "stop") return GRADE_EXIT.unreadable;
180
- warnUnknownRules(setup.rubric, context.config, host);
232
+ warnUnknownRules(rubric, context.config, host);
181
233
  const results = await gradeInOrder(items, setup);
182
234
  writeResults(context.flag(argv, "--out"), results, host);
183
- const rubricRules = new Set(Object.keys(setup.rubric?.rules ?? {}));
235
+ const rubricRules = (result: GradeResult): ReadonlySet<string> => taskRuleIds(setup.rubric, result.task);
184
236
  const compared = baseline.kind === "compare" ? { path: baseline.path, comparison: compareRuns(baseline.before, results, rubricRules) } : undefined;
185
237
  const ui = sharedLanguage(
186
238
  results.map((result) => result.language),
@@ -42,7 +42,26 @@ export const kanjiReadingOf = (
42
42
  const baseStartOf = (mention: CompanyMention): number =>
43
43
  mention.position === "after" ? mention.offset : mention.offset + mention.surface.length - mention.base.length;
44
44
 
45
- /** 会社の名前の、漢字一字をその読みのひらがなかカタカナで書いた形(みどりの生命保険株式会社、みどりノ生命保険株式会社)。 */
45
+ /** 濁る頭の音(カ行、サ行、タ行、ハ行)。 */
46
+ const VOICEABLE = /^[カキクケコサシスセソタチツテトハヒフヘホ]/u;
47
+ const VOICED_MARK = "゙";
48
+
49
+ /** 名前の中ほどの字の読みは、頭の音を濁らせて書くことがある(こむぎ畑 ハタケ を こむぎばたけ)。頭の音が濁らない読みには無い。 */
50
+ export const voicedReadingOf = (reading: string): string | undefined => {
51
+ const first = VOICEABLE.exec(reading)?.[0];
52
+ return first === undefined ? undefined : `${(first + VOICED_MARK).normalize("NFC")}${reading.slice(first.length)}`;
53
+ };
54
+
55
+ /** 名前の字の読みの、かなの書き方。名前の頭でない字は、頭の音を濁らせた読みも。 */
56
+ const readingsAt = (reading: string, inside: boolean): string[] => {
57
+ const voiced = inside ? voicedReadingOf(reading) : undefined;
58
+ return voiced === undefined ? [reading] : [reading, voiced];
59
+ };
60
+
61
+ /**
62
+ * 会社の名前の、漢字一字をその読みのひらがなかカタカナで書いた形(みどりの生命保険株式会社、みどりノ生命保険株式会社)。
63
+ * 名前の頭でない字は、頭の音を濁らせた読みでも(こむぎばたけベーカリー)。
64
+ */
46
65
  export const kanaSpellingsOf = (mention: CompanyMention, words: readonly ReadWord[]): string[] => {
47
66
  const baseStart = baseStartOf(mention);
48
67
  const baseEnd = baseStart + mention.base.length;
@@ -53,7 +72,8 @@ export const kanaSpellingsOf = (mention: CompanyMention, words: readonly ReadWor
53
72
  if (read === undefined) return [];
54
73
  const at = word.start - mention.offset + read.index;
55
74
  const [before, after] = [mention.surface.slice(0, at), mention.surface.slice(at + read.kanji.length)];
56
- return [toHiragana(read.reading), read.reading].map((kana) => `${before}${kana}${after}`);
75
+ const inside = word.start + read.index > baseStart;
76
+ return readingsAt(read.reading, inside).flatMap((reading) => [toHiragana(reading), reading].map((kana) => `${before}${kana}${after}`));
57
77
  });
58
78
  };
59
79
 
@@ -0,0 +1,50 @@
1
+ // 会社の名前の一語の終わりだけの違い。長い語の終わりの二字まで(Brightmoor と Brightmore、Lumenvale と Lumenvail)と、最後の語の
2
+ // 単数と複数(Water Utility と Water Utilities)。名前のほかの語は同じもの。
3
+
4
+ const LATIN_WORD = /^[a-z]+$/u;
5
+
6
+ /** 終わりの二字の違いを見る語の長さ。短い語(Alpha と Alpine)は別の名前のことが多い。 */
7
+ const MIN_ENDING_WORD_LENGTH = 8;
8
+ /** 頭からそろった字の後ろに残る字の数。 */
9
+ const MAX_ENDING_LENGTH = 2;
10
+
11
+ const wordsOf = (base: string): string[] =>
12
+ base
13
+ .toLowerCase()
14
+ .split(/\s+/u)
15
+ .filter((word) => word !== "");
16
+
17
+ /** 二つの名前の語の数が同じで、違うのが一語だけなら、その語の組と位置。 */
18
+ const differingWord = (left: string, right: string): { readonly pair: readonly [string, string]; readonly last: boolean } | undefined => {
19
+ const [leftWords, rightWords] = [wordsOf(left), wordsOf(right)];
20
+ const differing = leftWords.flatMap((word, index) => (word === rightWords[index] ? [] : [index]));
21
+ const [at] = differing;
22
+ const [leftWord, rightWord] = [leftWords[at ?? -1], rightWords[at ?? -1]];
23
+ if (leftWords.length !== rightWords.length || differing.length !== 1 || leftWord === undefined || rightWord === undefined) return undefined;
24
+ return { pair: [leftWord, rightWord], last: at === leftWords.length - 1 };
25
+ };
26
+
27
+ const sharedPrefix = (left: string, right: string): number => {
28
+ const differ = [...left].findIndex((char, index) => char !== right.charAt(index));
29
+ return differ < 0 ? left.length : differ;
30
+ };
31
+
32
+ /** 八字以上の英字の語の、頭がそろい、終わりの二字までだけが違うか(moor と more)。 */
33
+ export const isEndingApart = (left: string, right: string): boolean => {
34
+ if (left === right || !LATIN_WORD.test(left) || !LATIN_WORD.test(right) || Math.min(left.length, right.length) < MIN_ENDING_WORD_LENGTH) return false;
35
+ const prefix = sharedPrefix(left, right);
36
+ return left.length - prefix <= MAX_ENDING_LENGTH && right.length - prefix <= MAX_ENDING_LENGTH;
37
+ };
38
+
39
+ /** 片方が他方の複数の形か(Tool と Tools、Box と Boxes、Utility と Utilities)。 */
40
+ export const isPluralOf = (singular: string, plural: string): boolean =>
41
+ LATIN_WORD.test(singular) &&
42
+ (plural === `${singular}s` || plural === `${singular}es` || (singular.endsWith("y") && plural === `${singular.slice(0, -1)}ies`));
43
+
44
+ /** 二つの会社の名前の部分が、一語の終わりだけ違うか。長い語の終わりの二字までか、最後の語の単数と複数。 */
45
+ export const isNameEndingSlip = (left: string, right: string): boolean => {
46
+ const differing = differingWord(left, right);
47
+ if (differing === undefined) return false;
48
+ const [leftWord, rightWord] = differing.pair;
49
+ return isEndingApart(leftWord, rightWord) || (differing.last && (isPluralOf(leftWord, rightWord) || isPluralOf(rightWord, leftWord)));
50
+ };