chaffjs 0.33.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.
- package/dist/api.d.ts +7 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js.map +1 -1
- package/dist/cli-text.d.ts.map +1 -1
- package/dist/cli-text.js +4 -2
- package/dist/cli-text.js.map +1 -1
- package/dist/commands/grade.d.ts.map +1 -1
- package/dist/commands/grade.js +66 -21
- package/dist/commands/grade.js.map +1 -1
- package/dist/company-kana-spelling.d.ts +6 -1
- package/dist/company-kana-spelling.d.ts.map +1 -1
- package/dist/company-kana-spelling.js +19 -2
- package/dist/company-kana-spelling.js.map +1 -1
- package/dist/company-name-ending.d.ts +7 -0
- package/dist/company-name-ending.d.ts.map +1 -0
- package/dist/company-name-ending.js +44 -0
- package/dist/company-name-ending.js.map +1 -0
- package/dist/company-names.d.ts +11 -3
- package/dist/company-names.d.ts.map +1 -1
- package/dist/company-names.js +27 -14
- package/dist/company-names.js.map +1 -1
- package/dist/custom/no-rewrite.d.ts +3 -0
- package/dist/custom/no-rewrite.d.ts.map +1 -0
- package/dist/custom/no-rewrite.js +3 -0
- package/dist/custom/no-rewrite.js.map +1 -0
- package/dist/custom/parse.d.ts.map +1 -1
- package/dist/custom/parse.js +14 -2
- package/dist/custom/parse.js.map +1 -1
- package/dist/detectors/age-words.d.ts +5 -0
- package/dist/detectors/age-words.d.ts.map +1 -0
- package/dist/detectors/age-words.js +8 -0
- package/dist/detectors/age-words.js.map +1 -0
- package/dist/detectors/annual-pay-mismatch.d.ts.map +1 -1
- package/dist/detectors/annual-pay-mismatch.js +2 -12
- package/dist/detectors/annual-pay-mismatch.js.map +1 -1
- package/dist/detectors/blank-structure.d.ts.map +1 -1
- package/dist/detectors/blank-structure.js +4 -3
- package/dist/detectors/blank-structure.js.map +1 -1
- package/dist/detectors/closing-balance-mismatch.d.ts.map +1 -1
- package/dist/detectors/closing-balance-mismatch.js +1 -0
- package/dist/detectors/closing-balance-mismatch.js.map +1 -1
- package/dist/detectors/code-fences.d.ts +5 -0
- package/dist/detectors/code-fences.d.ts.map +1 -1
- package/dist/detectors/code-fences.js +9 -0
- package/dist/detectors/code-fences.js.map +1 -1
- package/dist/detectors/condition-toki.d.ts +16 -0
- package/dist/detectors/condition-toki.d.ts.map +1 -0
- package/dist/detectors/condition-toki.js +42 -0
- package/dist/detectors/condition-toki.js.map +1 -0
- package/dist/detectors/conjugated-entry.d.ts +17 -0
- package/dist/detectors/conjugated-entry.d.ts.map +1 -0
- package/dist/detectors/conjugated-entry.js +50 -0
- package/dist/detectors/conjugated-entry.js.map +1 -0
- package/dist/detectors/content-morphemes.d.ts +2 -0
- package/dist/detectors/content-morphemes.d.ts.map +1 -1
- package/dist/detectors/content-morphemes.js +1 -1
- package/dist/detectors/content-morphemes.js.map +1 -1
- package/dist/detectors/cross-facts.d.ts.map +1 -1
- package/dist/detectors/cross-facts.js +2 -1
- package/dist/detectors/cross-facts.js.map +1 -1
- package/dist/detectors/custom.d.ts.map +1 -1
- package/dist/detectors/custom.js +8 -2
- package/dist/detectors/custom.js.map +1 -1
- package/dist/detectors/document-shape.d.ts.map +1 -1
- package/dist/detectors/document-shape.js +6 -0
- package/dist/detectors/document-shape.js.map +1 -1
- package/dist/detectors/due-date.d.ts.map +1 -1
- package/dist/detectors/due-date.js +12 -2
- package/dist/detectors/due-date.js.map +1 -1
- package/dist/detectors/fact-consistency.d.ts.map +1 -1
- package/dist/detectors/fact-consistency.js +12 -13
- package/dist/detectors/fact-consistency.js.map +1 -1
- package/dist/detectors/form-line.d.ts +9 -0
- package/dist/detectors/form-line.d.ts.map +1 -0
- package/dist/detectors/form-line.js +36 -0
- package/dist/detectors/form-line.js.map +1 -0
- package/dist/detectors/formula-amount.d.ts.map +1 -1
- package/dist/detectors/formula-amount.js +2 -12
- package/dist/detectors/formula-amount.js.map +1 -1
- package/dist/detectors/heading-claim.d.ts +14 -0
- package/dist/detectors/heading-claim.d.ts.map +1 -0
- package/dist/detectors/heading-claim.js +49 -0
- package/dist/detectors/heading-claim.js.map +1 -0
- package/dist/detectors/heading-echo.d.ts.map +1 -1
- package/dist/detectors/heading-echo.js +29 -1
- package/dist/detectors/heading-echo.js.map +1 -1
- package/dist/detectors/installment-total-mismatch.d.ts.map +1 -1
- package/dist/detectors/installment-total-mismatch.js +2 -12
- package/dist/detectors/installment-total-mismatch.js.map +1 -1
- package/dist/detectors/list-parallel.d.ts +5 -2
- package/dist/detectors/list-parallel.d.ts.map +1 -1
- package/dist/detectors/list-parallel.js +45 -7
- package/dist/detectors/list-parallel.js.map +1 -1
- package/dist/detectors/name-variant.d.ts.map +1 -1
- package/dist/detectors/name-variant.js +34 -7
- package/dist/detectors/name-variant.js.map +1 -1
- package/dist/detectors/number-unit.d.ts +10 -0
- package/dist/detectors/number-unit.d.ts.map +1 -1
- package/dist/detectors/number-unit.js +28 -8
- package/dist/detectors/number-unit.js.map +1 -1
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +16 -7
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/per-unit-words.d.ts +7 -0
- package/dist/detectors/per-unit-words.d.ts.map +1 -0
- package/dist/detectors/per-unit-words.js +17 -0
- package/dist/detectors/per-unit-words.js.map +1 -0
- package/dist/detectors/period-multiple-mismatch.d.ts.map +1 -1
- package/dist/detectors/period-multiple-mismatch.js +2 -12
- package/dist/detectors/period-multiple-mismatch.js.map +1 -1
- package/dist/detectors/reference-number-variant.d.ts.map +1 -1
- package/dist/detectors/reference-number-variant.js +21 -3
- package/dist/detectors/reference-number-variant.js.map +1 -1
- package/dist/detectors/registry/condition-toki.d.ts +3 -0
- package/dist/detectors/registry/condition-toki.d.ts.map +1 -0
- package/dist/detectors/registry/condition-toki.js +3 -0
- package/dist/detectors/registry/condition-toki.js.map +1 -0
- package/dist/detectors/rent-multiple-mismatch.d.ts.map +1 -1
- package/dist/detectors/rent-multiple-mismatch.js +2 -12
- package/dist/detectors/rent-multiple-mismatch.js.map +1 -1
- package/dist/detectors/row-sentence-amounts.d.ts.map +1 -1
- package/dist/detectors/row-sentence-amounts.js +5 -10
- package/dist/detectors/row-sentence-amounts.js.map +1 -1
- package/dist/detectors/stated-amounts.d.ts +4 -0
- package/dist/detectors/stated-amounts.d.ts.map +1 -0
- package/dist/detectors/stated-amounts.js +12 -0
- package/dist/detectors/stated-amounts.js.map +1 -0
- package/dist/detectors/step-time-sum.d.ts.map +1 -1
- package/dist/detectors/step-time-sum.js +2 -1
- package/dist/detectors/step-time-sum.js.map +1 -1
- package/dist/detectors/structure-tree.d.ts.map +1 -1
- package/dist/detectors/structure-tree.js +3 -0
- package/dist/detectors/structure-tree.js.map +1 -1
- package/dist/detectors/team.d.ts.map +1 -1
- package/dist/detectors/team.js +10 -6
- package/dist/detectors/team.js.map +1 -1
- package/dist/detectors/time-order.d.ts.map +1 -1
- package/dist/detectors/time-order.js +17 -13
- package/dist/detectors/time-order.js.map +1 -1
- package/dist/detectors/unknown-word.d.ts +4 -1
- package/dist/detectors/unknown-word.d.ts.map +1 -1
- package/dist/detectors/unknown-word.js +18 -2
- package/dist/detectors/unknown-word.js.map +1 -1
- package/dist/detectors/use-interval.d.ts +1 -0
- package/dist/detectors/use-interval.d.ts.map +1 -1
- package/dist/detectors/use-interval.js +15 -10
- package/dist/detectors/use-interval.js.map +1 -1
- package/dist/detectors/use-maximum.d.ts.map +1 -1
- package/dist/detectors/use-maximum.js +3 -1
- package/dist/detectors/use-maximum.js.map +1 -1
- package/dist/extension/document-view.d.ts +2 -2
- package/dist/extension/document-view.d.ts.map +1 -1
- package/dist/extension/document-view.js +17 -8
- package/dist/extension/document-view.js.map +1 -1
- package/dist/extension/entry-genres.d.ts +5 -0
- package/dist/extension/entry-genres.d.ts.map +1 -0
- package/dist/extension/entry-genres.js +13 -0
- package/dist/extension/entry-genres.js.map +1 -0
- package/dist/extension/module-detector.d.ts.map +1 -1
- package/dist/extension/module-detector.js +4 -4
- package/dist/extension/module-detector.js.map +1 -1
- package/dist/extension/plugin-parse.d.ts +1 -1
- package/dist/extension/plugin-parse.d.ts.map +1 -1
- package/dist/extension/plugin-parse.js +24 -7
- package/dist/extension/plugin-parse.js.map +1 -1
- package/dist/extension/problem-text.d.ts.map +1 -1
- package/dist/extension/problem-text.js +2 -0
- package/dist/extension/problem-text.js.map +1 -1
- package/dist/facts/age-values.d.ts.map +1 -1
- package/dist/facts/age-values.js +20 -2
- package/dist/facts/age-values.js.map +1 -1
- package/dist/facts/column-units.d.ts +31 -0
- package/dist/facts/column-units.d.ts.map +1 -0
- package/dist/facts/column-units.js +37 -0
- package/dist/facts/column-units.js.map +1 -0
- package/dist/facts/fact-values.d.ts +4 -0
- package/dist/facts/fact-values.d.ts.map +1 -1
- package/dist/facts/fact-values.js +3 -1
- package/dist/facts/fact-values.js.map +1 -1
- package/dist/facts/labelled-facts.d.ts +10 -0
- package/dist/facts/labelled-facts.d.ts.map +1 -1
- package/dist/facts/labelled-facts.js +6 -1
- package/dist/facts/labelled-facts.js.map +1 -1
- package/dist/facts/per-unit.d.ts +36 -0
- package/dist/facts/per-unit.d.ts.map +1 -0
- package/dist/facts/per-unit.js +56 -0
- package/dist/facts/per-unit.js.map +1 -0
- package/dist/facts/row-sentence-amounts.d.ts +3 -12
- package/dist/facts/row-sentence-amounts.d.ts.map +1 -1
- package/dist/facts/row-sentence-amounts.js +1 -15
- package/dist/facts/row-sentence-amounts.js.map +1 -1
- package/dist/facts/table-facts.d.ts +1 -1
- package/dist/facts/table-facts.d.ts.map +1 -1
- package/dist/facts/table-facts.js +13 -9
- package/dist/facts/table-facts.js.map +1 -1
- package/dist/facts/term-values.d.ts +13 -1
- package/dist/facts/term-values.d.ts.map +1 -1
- package/dist/facts/term-values.js +71 -12
- package/dist/facts/term-values.js.map +1 -1
- package/dist/grade/baseline.d.ts +4 -2
- package/dist/grade/baseline.d.ts.map +1 -1
- package/dist/grade/baseline.js +13 -11
- package/dist/grade/baseline.js.map +1 -1
- package/dist/grade/expect-read.d.ts +16 -0
- package/dist/grade/expect-read.d.ts.map +1 -0
- package/dist/grade/expect-read.js +52 -0
- package/dist/grade/expect-read.js.map +1 -0
- package/dist/grade/expect.d.ts +50 -0
- package/dist/grade/expect.d.ts.map +1 -0
- package/dist/grade/expect.js +53 -0
- package/dist/grade/expect.js.map +1 -0
- package/dist/grade/grade-item.d.ts +1 -1
- package/dist/grade/grade-item.d.ts.map +1 -1
- package/dist/grade/grade-item.js +13 -3
- package/dist/grade/grade-item.js.map +1 -1
- package/dist/grade/item.d.ts +9 -1
- package/dist/grade/item.d.ts.map +1 -1
- package/dist/grade/item.js +32 -7
- package/dist/grade/item.js.map +1 -1
- package/dist/grade/result.d.ts +5 -0
- package/dist/grade/result.d.ts.map +1 -1
- package/dist/grade/results-read.d.ts.map +1 -1
- package/dist/grade/results-read.js +4 -2
- package/dist/grade/results-read.js.map +1 -1
- package/dist/grade/rubric-file.d.ts +23 -0
- package/dist/grade/rubric-file.d.ts.map +1 -0
- package/dist/grade/rubric-file.js +35 -0
- package/dist/grade/rubric-file.js.map +1 -0
- package/dist/grade/rubric.d.ts +2 -0
- package/dist/grade/rubric.d.ts.map +1 -1
- package/dist/grade/rubric.js +75 -47
- package/dist/grade/rubric.js.map +1 -1
- package/dist/grade/setup.d.ts +2 -1
- package/dist/grade/setup.d.ts.map +1 -1
- package/dist/grade/setup.js +2 -2
- package/dist/grade/setup.js.map +1 -1
- package/dist/grade/stamp.d.ts +2 -0
- package/dist/grade/stamp.d.ts.map +1 -1
- package/dist/grade/stamp.js +8 -2
- package/dist/grade/stamp.js.map +1 -1
- package/dist/grade/task-rubric.d.ts +16 -0
- package/dist/grade/task-rubric.d.ts.map +1 -0
- package/dist/grade/task-rubric.js +34 -0
- package/dist/grade/task-rubric.js.map +1 -0
- package/dist/grade/text.d.ts +5 -1
- package/dist/grade/text.d.ts.map +1 -1
- package/dist/grade/text.js +16 -4
- package/dist/grade/text.js.map +1 -1
- package/dist/name-char-reading.d.ts +5 -0
- package/dist/name-char-reading.d.ts.map +1 -1
- package/dist/name-char-reading.js +15 -0
- package/dist/name-char-reading.js.map +1 -1
- package/dist/name-end-letter.d.ts +19 -0
- package/dist/name-end-letter.d.ts.map +1 -0
- package/dist/name-end-letter.js +37 -0
- package/dist/name-end-letter.js.map +1 -0
- package/dist/name-neighbours.d.ts.map +1 -1
- package/dist/name-neighbours.js +2 -1
- package/dist/name-neighbours.js.map +1 -1
- package/dist/name-separator.d.ts +6 -0
- package/dist/name-separator.d.ts.map +1 -1
- package/dist/name-separator.js +29 -0
- package/dist/name-separator.js.map +1 -1
- package/dist/name-variants.d.ts +6 -3
- package/dist/name-variants.d.ts.map +1 -1
- package/dist/name-variants.js +37 -10
- package/dist/name-variants.js.map +1 -1
- package/dist/number-name.d.ts.map +1 -1
- package/dist/number-name.js +11 -2
- package/dist/number-name.js.map +1 -1
- package/dist/profile/cue-lines.d.ts +6 -0
- package/dist/profile/cue-lines.d.ts.map +1 -0
- package/dist/profile/cue-lines.js +13 -0
- package/dist/profile/cue-lines.js.map +1 -0
- package/dist/profile/parse.d.ts +1 -1
- package/dist/profile/parse.d.ts.map +1 -1
- package/dist/profile/parse.js +3 -2
- package/dist/profile/parse.js.map +1 -1
- package/dist/reference-numbers.d.ts +2 -0
- package/dist/reference-numbers.d.ts.map +1 -1
- package/dist/reference-numbers.js +1 -1
- package/dist/reference-numbers.js.map +1 -1
- package/dist/spaced-person-name.d.ts.map +1 -1
- package/dist/spaced-person-name.js +26 -1
- package/dist/spaced-person-name.js.map +1 -1
- package/dist/spacing-code.d.ts.map +1 -1
- package/dist/spacing-code.js +10 -1
- package/dist/spacing-code.js.map +1 -1
- package/dist/spacing-minority.d.ts +7 -0
- package/dist/spacing-minority.d.ts.map +1 -1
- package/dist/spacing-minority.js +14 -0
- package/dist/spacing-minority.js.map +1 -1
- package/dist/structure/closing-balance.d.ts +9 -0
- package/dist/structure/closing-balance.d.ts.map +1 -1
- package/dist/structure/closing-balance.js +34 -7
- package/dist/structure/closing-balance.js.map +1 -1
- package/dist/structure/definition-use.d.ts.map +1 -1
- package/dist/structure/definition-use.js +20 -1
- package/dist/structure/definition-use.js.map +1 -1
- package/dist/structure/document-context.d.ts +2 -0
- package/dist/structure/document-context.d.ts.map +1 -0
- package/dist/structure/document-context.js +42 -0
- package/dist/structure/document-context.js.map +1 -0
- package/dist/structure/fenced-lines.d.ts +7 -0
- package/dist/structure/fenced-lines.d.ts.map +1 -0
- package/dist/structure/fenced-lines.js +27 -0
- package/dist/structure/fenced-lines.js.map +1 -0
- package/dist/structure/labelled-date-order.d.ts +31 -9
- package/dist/structure/labelled-date-order.d.ts.map +1 -1
- package/dist/structure/labelled-date-order.js +60 -15
- package/dist/structure/labelled-date-order.js.map +1 -1
- package/dist/structure/labelled-order.d.ts +7 -1
- package/dist/structure/labelled-order.d.ts.map +1 -1
- package/dist/structure/labelled-order.js +10 -3
- package/dist/structure/labelled-order.js.map +1 -1
- package/dist/structure/line-amount-label.d.ts.map +1 -1
- package/dist/structure/line-amount-label.js +2 -1
- package/dist/structure/line-amount-label.js.map +1 -1
- package/dist/structure/line-amount.d.ts +0 -5
- package/dist/structure/line-amount.d.ts.map +1 -1
- package/dist/structure/line-amount.js +1 -10
- package/dist/structure/line-amount.js.map +1 -1
- package/dist/structure/prose-total.d.ts +8 -0
- package/dist/structure/prose-total.d.ts.map +1 -1
- package/dist/structure/prose-total.js +70 -2
- package/dist/structure/prose-total.js.map +1 -1
- package/dist/structure/runs.d.ts.map +1 -1
- package/dist/structure/runs.js +9 -1
- package/dist/structure/runs.js.map +1 -1
- package/dist/structure/signed-date-line.d.ts +15 -0
- package/dist/structure/signed-date-line.d.ts.map +1 -0
- package/dist/structure/signed-date-line.js +68 -0
- package/dist/structure/signed-date-line.js.map +1 -0
- package/dist/structure/tax.d.ts.map +1 -1
- package/dist/structure/tax.js +5 -3
- package/dist/structure/tax.js.map +1 -1
- package/dist/structure/total-line.d.ts.map +1 -1
- package/dist/structure/total-line.js +10 -6
- package/dist/structure/total-line.js.map +1 -1
- package/dist/structure/total.d.ts +2 -0
- package/dist/structure/total.d.ts.map +1 -1
- package/dist/structure/total.js +34 -3
- package/dist/structure/total.js.map +1 -1
- package/dist/subject-codes.d.ts +21 -0
- package/dist/subject-codes.d.ts.map +1 -0
- package/dist/subject-codes.js +79 -0
- package/dist/subject-codes.js.map +1 -0
- package/dist/unlabelled-references.d.ts +6 -2
- package/dist/unlabelled-references.d.ts.map +1 -1
- package/dist/unlabelled-references.js +11 -10
- package/dist/unlabelled-references.js.map +1 -1
- package/genres.yaml +17 -0
- package/package.json +3 -3
- package/profiles/listing.yaml +1 -1
- package/rules/closing-balance-mismatch.yaml +3 -3
- package/rules/due-before-issue.yaml +9 -5
- package/rules/fact-conflict.yaml +2 -2
- package/rules/heading-echo.yaml +2 -2
- package/rules/internal-jargon.yaml +2 -2
- package/rules/latin-spacing.yaml +4 -4
- package/rules/list-item-form-mix.yaml +1 -1
- package/rules/name-variant.yaml +5 -2
- package/rules/no-lead.yaml +2 -2
- package/rules/number-without-unit.yaml +2 -2
- package/rules/reference-number-variant.yaml +3 -3
- package/rules/toki-as-condition.yaml +71 -0
- package/rules/total-mismatch.yaml +4 -4
- package/rules/unknown-word.yaml +2 -2
- package/rules/use-before-definition.yaml +2 -2
- package/src/api.ts +11 -2
- package/src/cli-text.ts +4 -2
- package/src/commands/grade.ts +75 -23
- package/src/company-kana-spelling.ts +22 -2
- package/src/company-name-ending.ts +50 -0
- package/src/company-names.ts +52 -17
- package/src/custom/no-rewrite.ts +2 -0
- package/src/custom/parse.ts +18 -2
- package/src/detectors/age-words.ts +12 -0
- package/src/detectors/annual-pay-mismatch.ts +3 -18
- package/src/detectors/blank-structure.ts +4 -3
- package/src/detectors/closing-balance-mismatch.ts +1 -0
- package/src/detectors/code-fences.ts +10 -0
- package/src/detectors/condition-toki.ts +60 -0
- package/src/detectors/conjugated-entry.ts +53 -0
- package/src/detectors/content-morphemes.ts +2 -1
- package/src/detectors/cross-facts.ts +2 -1
- package/src/detectors/custom.ts +9 -2
- package/src/detectors/document-shape.ts +8 -0
- package/src/detectors/due-date.ts +17 -7
- package/src/detectors/fact-consistency.ts +13 -17
- package/src/detectors/form-line.ts +47 -0
- package/src/detectors/formula-amount.ts +2 -18
- package/src/detectors/heading-claim.ts +76 -0
- package/src/detectors/heading-echo.ts +32 -1
- package/src/detectors/installment-total-mismatch.ts +3 -18
- package/src/detectors/list-parallel.ts +46 -7
- package/src/detectors/name-variant.ts +45 -8
- package/src/detectors/number-unit.ts +35 -9
- package/src/detectors/orthography.ts +17 -8
- package/src/detectors/per-unit-words.ts +24 -0
- package/src/detectors/period-multiple-mismatch.ts +2 -18
- package/src/detectors/reference-number-variant.ts +27 -5
- package/src/detectors/registry/condition-toki.ts +4 -0
- package/src/detectors/rent-multiple-mismatch.ts +2 -18
- package/src/detectors/row-sentence-amounts.ts +5 -20
- package/src/detectors/stated-amounts.ts +20 -0
- package/src/detectors/step-time-sum.ts +2 -1
- package/src/detectors/structure-tree.ts +3 -0
- package/src/detectors/team.ts +13 -7
- package/src/detectors/time-order.ts +6 -3
- package/src/detectors/unknown-word.ts +20 -2
- package/src/detectors/use-interval.ts +8 -4
- package/src/detectors/use-maximum.ts +3 -1
- package/src/extension/document-view.ts +18 -9
- package/src/extension/entry-genres.ts +15 -0
- package/src/extension/module-detector.ts +9 -4
- package/src/extension/plugin-parse.ts +29 -7
- package/src/extension/problem-text.ts +4 -0
- package/src/facts/age-values.ts +24 -2
- package/src/facts/column-units.ts +67 -0
- package/src/facts/fact-values.ts +11 -1
- package/src/facts/labelled-facts.ts +16 -2
- package/src/facts/per-unit.ts +105 -0
- package/src/facts/row-sentence-amounts.ts +4 -26
- package/src/facts/table-facts.ts +7 -4
- package/src/facts/term-values.ts +94 -13
- package/src/grade/baseline.ts +20 -12
- package/src/grade/expect-read.ts +65 -0
- package/src/grade/expect.ts +74 -0
- package/src/grade/grade-item.ts +14 -3
- package/src/grade/item.ts +48 -8
- package/src/grade/result.ts +5 -0
- package/src/grade/results-read.ts +7 -2
- package/src/grade/rubric-file.ts +46 -0
- package/src/grade/rubric.ts +77 -47
- package/src/grade/setup.ts +3 -3
- package/src/grade/stamp.ts +10 -2
- package/src/grade/task-rubric.ts +39 -0
- package/src/grade/text.ts +27 -5
- package/src/name-char-reading.ts +16 -0
- package/src/name-end-letter.ts +52 -0
- package/src/name-neighbours.ts +2 -1
- package/src/name-separator.ts +32 -0
- package/src/name-variants.ts +54 -13
- package/src/number-name.ts +12 -3
- package/src/profile/cue-lines.ts +14 -0
- package/src/profile/parse.ts +3 -2
- package/src/reference-numbers.ts +1 -1
- package/src/spaced-person-name.ts +27 -2
- package/src/spacing-code.ts +13 -2
- package/src/spacing-minority.ts +17 -0
- package/src/structure/closing-balance.ts +46 -8
- package/src/structure/definition-use.ts +24 -1
- package/src/structure/document-context.ts +46 -0
- package/src/structure/fenced-lines.ts +28 -0
- package/src/structure/labelled-date-order.ts +105 -21
- package/src/structure/labelled-order.ts +21 -10
- package/src/structure/line-amount-label.ts +2 -1
- package/src/structure/line-amount.ts +1 -11
- package/src/structure/prose-total.ts +81 -2
- package/src/structure/runs.ts +10 -1
- package/src/structure/signed-date-line.ts +78 -0
- package/src/structure/tax.ts +6 -3
- package/src/structure/total-line.ts +12 -6
- package/src/structure/total.ts +42 -3
- package/src/subject-codes.ts +105 -0
- package/src/unlabelled-references.ts +24 -16
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import type { Detector, Finding, ProseDocument, Sentence, Span } from "../plugin.ts";
|
|
1
|
+
import type { Detector, Finding, LexiconEntry, ProseDocument, Sentence, Span } from "../plugin.ts";
|
|
2
|
+
import { conjugatedStartsOutside } from "./conjugated-entry.ts";
|
|
2
3
|
import { calendarRuns, calendarUnitsOf, type CalendarUnits } from "../calendar-number.ts";
|
|
3
4
|
import { escapeRegExp, latinBoundaries, occurrencesOutside, type Boundary, type SpacingKind } from "../orthography.ts";
|
|
4
|
-
import { minorityReport } from "../spacing-minority.ts";
|
|
5
|
+
import { minorityReport, withoutSideOnTie } from "../spacing-minority.ts";
|
|
5
6
|
import { isWithinAny, quotedSpans } from "../quoted-span.ts";
|
|
6
7
|
import { digitRunAround, endsWithDivisionLabel, isNumberName, sequenceLabelStarts, type NameContext } from "../number-name.ts";
|
|
7
8
|
import { isSpacedLocationPart, type FloorWords } from "../location-part.ts";
|
|
8
|
-
import { isNameSeparator, type OrganizationWords } from "../name-separator.ts";
|
|
9
|
+
import { isFieldSeparator, isNameSeparator, type OrganizationWords } from "../name-separator.ts";
|
|
9
10
|
import { addressSpans, clockTimeSpans, identifierSpans, isInsideSpan } from "../spacing-code.ts";
|
|
10
11
|
|
|
12
|
+
/** 書いた形の出現に、動詞の活用した形(行う → 行います)を足したもの。同じ位置は一度だけ。 */
|
|
13
|
+
const avoidedStarts = (sentence: Sentence, entry: LexiconEntry, use: string): number[] => {
|
|
14
|
+
const written = occurrencesOutside(sentence.text, entry.pattern, use);
|
|
15
|
+
const conjugated = conjugatedStartsOutside(sentence, entry, use).filter((at) => !written.includes(at));
|
|
16
|
+
return [...written, ...conjugated].toSorted((left, right) => left - right);
|
|
17
|
+
};
|
|
18
|
+
|
|
11
19
|
/** チームが chaff.yaml の prefer に書いた「使わない書き方」。書いていなければ何も言わない。 */
|
|
12
20
|
export const preferredTerm: Detector = (doc, options): Finding[] => {
|
|
13
|
-
const pairs = (options.lexicon ?? []).flatMap((entry) => (entry.instead_of === undefined ? [] : [{ avoid: entry.pattern, use: entry.instead_of }]));
|
|
21
|
+
const pairs = (options.lexicon ?? []).flatMap((entry) => (entry.instead_of === undefined ? [] : [{ entry, avoid: entry.pattern, use: entry.instead_of }]));
|
|
14
22
|
const hits = doc.sentences.flatMap((sentence) =>
|
|
15
|
-
pairs.flatMap((pair) =>
|
|
23
|
+
pairs.flatMap((pair) => avoidedStarts(sentence, pair.entry, pair.use).map((at) => ({ sentence, at, pair }))),
|
|
16
24
|
);
|
|
17
25
|
if (hits.length === 0 || hits.length < options.limit) return [];
|
|
18
26
|
return hits.map((hit) => ({
|
|
@@ -91,7 +99,7 @@ type SentenceCodes = {
|
|
|
91
99
|
* 日付・時刻は前の境目(「は 9月」「午後3時」「令和 3 年」)も数えない。日付はまとめて一つの書き方で、数量の空け方の票にはしない。コロンで書いた時刻(13:30)も同じ。
|
|
92
100
|
* メールアドレス・URL の前後の境目も数えない(spacing-code.ts)。「予約番号 MN-48215 を」の番号の前後も、番号を文から区切る空白なので数えない。
|
|
93
101
|
* 「本社 5階」のように名前の後ろに空白で区切った階・部屋の番号の前の空白も、所在の組の区切りなので数えない(location-part.ts)。
|
|
94
|
-
* 「経営企画部 IR
|
|
102
|
+
* 「経営企画部 IR担当」のように名前だけを並べた行で、名前と名前を分ける空白も、「所属:経済学科 1年」のように項目の値の組を分ける空白も数えない(name-separator.ts)。
|
|
95
103
|
*/
|
|
96
104
|
const isCounted = (sentence: Sentence, boundary: Boundary, context: NumberContext, codes: SentenceCodes): boolean => {
|
|
97
105
|
if (followsItemNumber(sentence.text, boundary, context.itemNumbers) || besideSpan(codes.identifiers, boundary)) return false;
|
|
@@ -103,6 +111,7 @@ const isCounted = (sentence: Sentence, boundary: Boundary, context: NumberContex
|
|
|
103
111
|
if (run === undefined) return true;
|
|
104
112
|
if (codes.calendar.has(run.start)) return false;
|
|
105
113
|
if (boundary.kind === "before-digit" && isSpacedLocationPart(sentence.text, run, sentence.tokens, sentence.span.start, context.floors)) return false;
|
|
114
|
+
if (isFieldSeparator(sentence.text, boundary, sentence.tokens, sentence.span.start)) return false;
|
|
106
115
|
return !isNumberName(sentence.text, run, sentence.tokens, sentence.span.start, context);
|
|
107
116
|
};
|
|
108
117
|
|
|
@@ -135,9 +144,9 @@ const findingAt = (entry: Located, values: Finding["values"], variant?: string):
|
|
|
135
144
|
values: { ...values, offset: entry.sentence.span.start + entry.offset },
|
|
136
145
|
});
|
|
137
146
|
|
|
138
|
-
/** 一つの種類の境目の指摘。少ないほうを 1 箇所ずつか、書き方が二通りあれば 1 件で(spacing-minority.ts
|
|
147
|
+
/** 一つの種類の境目の指摘。少ないほうを 1 箇所ずつか、書き方が二通りあれば 1 件で(spacing-minority.ts)。同数ならどちらの側にも立たない。 */
|
|
139
148
|
const findingsOf = (kind: SpacingKind, ofKind: readonly Located[], limit: number): Finding[] => {
|
|
140
|
-
const report = minorityReport(ofKind, limit);
|
|
149
|
+
const report = withoutSideOnTie(minorityReport(ofKind, limit), ofKind);
|
|
141
150
|
if (report === undefined) return [];
|
|
142
151
|
if (report.mode === "mixed") {
|
|
143
152
|
const { first, odd, spaced, touching } = report;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProseDocument, StructureNode } from "../plugin.ts";
|
|
2
|
+
import { withPerUnits, type PerUnitMark, type PerUnitTemplate, type PerUnitWords } from "../facts/per-unit.ts";
|
|
3
|
+
import { factValues, type FactValue } from "../facts/fact-values.ts";
|
|
4
|
+
import { nameSpans } from "../compare/proper-nouns.ts";
|
|
5
|
+
|
|
6
|
+
const marksOf = (doc: ProseDocument, id: string): PerUnitMark[] =>
|
|
7
|
+
(doc.lexicons[id] ?? []).map((entry): PerUnitMark => ({ pattern: entry.pattern, group: entry.group ?? entry.pattern }));
|
|
8
|
+
|
|
9
|
+
/** 何あたりかの語: 決まった印(per-unit-mark)、型(fact-per-unit)、単位の語(rate-unit)、読まない百分率(percent-unit)、単価の列の見出し(unit-price-column)。 */
|
|
10
|
+
const perUnitWordsOf = (doc: ProseDocument): PerUnitWords => ({
|
|
11
|
+
marks: marksOf(doc, "per-unit-mark"),
|
|
12
|
+
templates: (doc.lexicons["fact-per-unit"] ?? []).map((entry): PerUnitTemplate => ({ pattern: entry.pattern, position: entry.position ?? "before" })),
|
|
13
|
+
units: marksOf(doc, "rate-unit"),
|
|
14
|
+
percentUnits: (doc.lexicons["percent-unit"] ?? []).map((entry) => entry.pattern),
|
|
15
|
+
priceHeadings: (doc.lexicons["unit-price-column"] ?? []).map((entry) =>
|
|
16
|
+
entry.group === undefined ? { pattern: entry.pattern } : { pattern: entry.pattern, group: entry.group },
|
|
17
|
+
),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/** 文書の値に、何あたりか(1kmあたり15円 の km)を付ける。 */
|
|
21
|
+
export const perUnitsOf = <T extends FactValue>(doc: ProseDocument, values: readonly T[]): T[] => withPerUnits(doc.source, values, perUnitWordsOf(doc));
|
|
22
|
+
|
|
23
|
+
/** 木の数量と日付と固有名詞(factValues)に、何あたりかを付けたもの。 */
|
|
24
|
+
export const perUnitValues = (doc: ProseDocument, tree: StructureNode): FactValue[] => perUnitsOf(doc, factValues(tree, doc.source, nameSpans(doc)));
|
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
// number-word (digit), and a range of counts is joined by range-connector or amount-range-word.
|
|
5
5
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
6
6
|
import { periodMultipleMismatches, type PeriodMultipleWords } from "../structure/period-multiple.ts";
|
|
7
|
-
import type { StatedAmount } from "../structure/stated-multiple.ts";
|
|
8
|
-
import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
|
|
9
|
-
import { amountsIn, formsOf } from "./currency-notation.ts";
|
|
10
7
|
import { proseAndTablesOf } from "../table-text.ts";
|
|
11
8
|
import { quoteAround } from "./quote-around.ts";
|
|
9
|
+
import { statedAmountsOf } from "./stated-amounts.ts";
|
|
12
10
|
|
|
13
11
|
const patternsOf = (doc: ProseDocument, lexicon: string, group?: string): string[] =>
|
|
14
12
|
(doc.lexicons[lexicon] ?? []).filter((entry) => group === undefined || entry.group === group).map((entry) => entry.pattern);
|
|
@@ -27,23 +25,9 @@ const wordsOf = (doc: ProseDocument): PeriodMultipleWords => ({
|
|
|
27
25
|
numberWords: numberWordsOf(doc),
|
|
28
26
|
});
|
|
29
27
|
|
|
30
|
-
const amountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
|
|
31
|
-
const scales = scaleWordsOf(doc);
|
|
32
|
-
return amountsIn(
|
|
33
|
-
text,
|
|
34
|
-
formsOf(doc),
|
|
35
|
-
scales.map((scale) => scale.word),
|
|
36
|
-
).flatMap((amount) => {
|
|
37
|
-
const read = scaledAmountOf(text, amount, scales);
|
|
38
|
-
return read === undefined
|
|
39
|
-
? []
|
|
40
|
-
: [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
|
-
|
|
44
28
|
export const periodMultipleMismatch: Detector = (doc): Finding[] => {
|
|
45
29
|
const text = proseAndTablesOf(doc);
|
|
46
|
-
return periodMultipleMismatches(text,
|
|
30
|
+
return periodMultipleMismatches(text, statedAmountsOf(text, doc), wordsOf(doc)).map((issue) => ({
|
|
47
31
|
rule: "period-multiple-mismatch",
|
|
48
32
|
severity: "warning",
|
|
49
33
|
line: 0,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// reference-number-variant: a document's own reference number written with two neighbouring characters swapped somewhere
|
|
2
2
|
// else in the document, after a label of the same kind (reference-numbers.ts), or with no label where only one labelled
|
|
3
|
-
// code swaps to it (unlabelled-references.ts); and the document's one vehicle plate written
|
|
3
|
+
// code swaps to it (unlabelled-references.ts), or as the one code a product document is about (subject-codes.ts); and the document's one vehicle plate written
|
|
4
4
|
// once with one character of its serial changed (vehicle-plates.ts).
|
|
5
|
-
import { labelledReferenceNumbers, referenceVariants, type ReferenceNumber } from "../reference-numbers.ts";
|
|
5
|
+
import { labelledReferenceNumbers, referenceVariants, type ReferenceNumber, type ReferenceVariant } from "../reference-numbers.ts";
|
|
6
6
|
import { labelledPlates, plateVariants } from "../vehicle-plates.ts";
|
|
7
|
-
import { tableCodes, tableLabelledCodes, unlabelledVariants } from "../unlabelled-references.ts";
|
|
7
|
+
import { isCodeWith, tableCodes, tableLabelledCodes, unlabelledVariants } from "../unlabelled-references.ts";
|
|
8
|
+
import { isSubjectCode, MIN_SUBJECT_DIGITS, subjectCodeVariants } from "../subject-codes.ts";
|
|
8
9
|
import { proseAndTablesOf } from "../table-text.ts";
|
|
9
10
|
import { quoteAt } from "./structure-tree.ts";
|
|
10
|
-
import type { Detector, Finding, OptionValue } from "../plugin.ts";
|
|
11
|
+
import type { Detector, Finding, OptionValue, ProseDocument } from "../plugin.ts";
|
|
11
12
|
|
|
12
13
|
const PLATE_SHAPES = "vehicle-plate";
|
|
13
14
|
const SUBSTITUTED = "substituted";
|
|
@@ -25,6 +26,18 @@ const finding = (number: ReferenceNumber, other: ReferenceNumber, source: string
|
|
|
25
26
|
/** Kinds a document lists many of (item codes): two labelled ones are two things, so only a code with no label is compared with them. */
|
|
26
27
|
const listedKindsOf = (value: OptionValue | undefined): readonly string[] => (typeof value === "object" ? value : []);
|
|
27
28
|
|
|
29
|
+
const TITLE_DEPTH = 1;
|
|
30
|
+
|
|
31
|
+
/** The title as the source writes it, where it starts: the prose masks a heading's line. */
|
|
32
|
+
const titleOf = (doc: ProseDocument): { start: number; text: string } | undefined => {
|
|
33
|
+
const title = doc.markup?.headings.find((heading) => heading.depth === TITLE_DEPTH);
|
|
34
|
+
return title === undefined ? undefined : { start: title.start, text: doc.source.slice(title.start, title.end) };
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** One finding per place, the first reading kept: a code may be read both as an unlabelled item code and as the document's own. */
|
|
38
|
+
const firstAtEachOffset = (variants: readonly ReferenceVariant[]): ReferenceVariant[] =>
|
|
39
|
+
variants.filter((variant, index) => variants.findIndex((other) => other.number.offset === variant.number.offset) === index);
|
|
40
|
+
|
|
28
41
|
export const referenceNumberVariant: Detector = (doc, options): Finding[] => {
|
|
29
42
|
const labels = options.lexicon ?? [];
|
|
30
43
|
if (labels.length === 0) return [];
|
|
@@ -36,9 +49,18 @@ export const referenceNumberVariant: Detector = (doc, options): Finding[] => {
|
|
|
36
49
|
const listed = new Set(listedKindsOf(options.settings?.["listed_kinds"]));
|
|
37
50
|
const withTables = proseAndTablesOf(doc);
|
|
38
51
|
const labelled = [...numbers, ...tableLabelledCodes(withTables, labels)];
|
|
52
|
+
const subjectCodes = subjectCodeVariants({
|
|
53
|
+
prose: text,
|
|
54
|
+
title: titleOf(doc),
|
|
55
|
+
labels,
|
|
56
|
+
listed,
|
|
57
|
+
tabled: tableLabelledCodes(withTables, labels, isSubjectCode),
|
|
58
|
+
known: tableCodes(withTables, isCodeWith(MIN_SUBJECT_DIGITS)),
|
|
59
|
+
});
|
|
60
|
+
const unlabelled = firstAtEachOffset([...unlabelledVariants(text, labelled, tableCodes(withTables)), ...subjectCodes]);
|
|
39
61
|
return [
|
|
40
62
|
...referenceVariants(numbers.filter((number) => !listed.has(number.label))).map(({ number, other }) => finding(number, other, doc.source)),
|
|
41
|
-
...
|
|
63
|
+
...unlabelled.map(({ number, other }) => finding(number, other, doc.source)),
|
|
42
64
|
...plateVariants(plates).map(({ number, other }) => finding(number, other, doc.source, SUBSTITUTED)),
|
|
43
65
|
].toSorted((a, b) => Number(a.values["offset"]) - Number(b.values["offset"]));
|
|
44
66
|
};
|
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
// range of rent is joined by range-connector or amount-range-word.
|
|
5
5
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
6
6
|
import { rentMultipleMismatches, type RentMultipleWords } from "../structure/rent-multiple.ts";
|
|
7
|
-
import type { StatedAmount } from "../structure/stated-multiple.ts";
|
|
8
|
-
import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
|
|
9
|
-
import { amountsIn, formsOf } from "./currency-notation.ts";
|
|
10
7
|
import { proseAndTablesOf } from "../table-text.ts";
|
|
11
8
|
import { quoteAround } from "./quote-around.ts";
|
|
9
|
+
import { statedAmountsOf } from "./stated-amounts.ts";
|
|
12
10
|
|
|
13
11
|
const patternsOf = (doc: ProseDocument, lexicon: string, group?: string): string[] =>
|
|
14
12
|
(doc.lexicons[lexicon] ?? []).filter((entry) => group === undefined || entry.group === group).map((entry) => entry.pattern);
|
|
@@ -30,23 +28,9 @@ const wordsOf = (doc: ProseDocument): RentMultipleWords => ({
|
|
|
30
28
|
numberWords: numberWordsOf(doc),
|
|
31
29
|
});
|
|
32
30
|
|
|
33
|
-
const amountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
|
|
34
|
-
const scales = scaleWordsOf(doc);
|
|
35
|
-
return amountsIn(
|
|
36
|
-
text,
|
|
37
|
-
formsOf(doc),
|
|
38
|
-
scales.map((scale) => scale.word),
|
|
39
|
-
).flatMap((amount) => {
|
|
40
|
-
const read = scaledAmountOf(text, amount, scales);
|
|
41
|
-
return read === undefined
|
|
42
|
-
? []
|
|
43
|
-
: [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
|
|
47
31
|
export const rentMultipleMismatch: Detector = (doc): Finding[] => {
|
|
48
32
|
const text = proseAndTablesOf(doc);
|
|
49
|
-
return rentMultipleMismatches(text,
|
|
33
|
+
return rentMultipleMismatches(text, statedAmountsOf(text, doc), wordsOf(doc)).map((issue) => ({
|
|
50
34
|
rule: "rent-multiple-mismatch",
|
|
51
35
|
severity: "warning",
|
|
52
36
|
line: 0,
|
|
@@ -4,15 +4,8 @@ import { factValues, type FactValue } from "../facts/fact-values.ts";
|
|
|
4
4
|
import { cellsOf, tablesOf } from "../facts/table-facts.ts";
|
|
5
5
|
import { scopedFacts, type ScopedFact } from "../facts/fact-scope.ts";
|
|
6
6
|
import { withoutEdgeMarks } from "../facts/trim-marks.ts";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
rowSentenceConflicts,
|
|
10
|
-
type Amount,
|
|
11
|
-
type AmountRow,
|
|
12
|
-
type PeriodMark,
|
|
13
|
-
type SubjectSentence,
|
|
14
|
-
type SubjectWords,
|
|
15
|
-
} from "../facts/row-sentence-amounts.ts";
|
|
7
|
+
import { rowSentenceConflicts, type Amount, type AmountRow, type SubjectSentence, type SubjectWords } from "../facts/row-sentence-amounts.ts";
|
|
8
|
+
import { perUnitsOf } from "./per-unit-words.ts";
|
|
16
9
|
import { linesOf, type Line } from "../structure/lines.ts";
|
|
17
10
|
import { quoteAt } from "./structure-tree.ts";
|
|
18
11
|
|
|
@@ -57,19 +50,11 @@ const subjectWordsOf = (doc: ProseDocument): SubjectWords => ({
|
|
|
57
50
|
conditions: patternsOf(doc, "fact-amount-condition"),
|
|
58
51
|
});
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
(doc.lexicons["per-unit-mark"] ?? []).map((entry): PeriodMark => ({ pattern: entry.pattern, group: entry.group ?? entry.pattern }));
|
|
62
|
-
|
|
63
|
-
/** 金額: 通貨の語彙表の印を単位に書いた数量。前後に期間あたりの印があれば、その期間も。 */
|
|
53
|
+
/** 金額: 通貨の語彙表の印を単位に書いた数量。何あたりの金額(日額、1kmあたり)は、その単位も。 */
|
|
64
54
|
const amountsOf = (doc: ProseDocument, tree: StructureNode): Amount[] => {
|
|
65
55
|
const currencies = new Set(patternsOf(doc, "currency-notation").map((pattern) => pattern.normalize("NFKC")));
|
|
66
|
-
const
|
|
67
|
-
return
|
|
68
|
-
.filter((value) => value.kind === "quantity" && currencies.has(value.unit))
|
|
69
|
-
.map((value): Amount => {
|
|
70
|
-
const period = periodOf(doc.source, value, marks);
|
|
71
|
-
return period === undefined ? value : { ...value, period };
|
|
72
|
-
});
|
|
56
|
+
const amounts = factValues(tree, doc.source, nameSpans(doc)).filter((value) => value.kind === "quantity" && currencies.has(value.unit));
|
|
57
|
+
return perUnitsOf(doc, amounts);
|
|
73
58
|
};
|
|
74
59
|
|
|
75
60
|
/** 表の行の金額と、その行の見出しを主語にした文の金額の食い違い。名前付きの値として読めた文の値は、ほかの読みが比べる。 */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The amounts a document states, as the multiple and total checks read them: currency-notation's written amounts, each
|
|
2
|
+
// read with amount-multiplier's words of scale (1億2,000万円 is one amount), the ones that cannot be read left out.
|
|
3
|
+
import type { ProseDocument } from "../plugin.ts";
|
|
4
|
+
import type { StatedAmount } from "../structure/stated-multiple.ts";
|
|
5
|
+
import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
|
|
6
|
+
import { amountsIn, formsOf } from "./currency-notation.ts";
|
|
7
|
+
|
|
8
|
+
export const statedAmountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
|
|
9
|
+
const scales = scaleWordsOf(doc);
|
|
10
|
+
return amountsIn(
|
|
11
|
+
text,
|
|
12
|
+
formsOf(doc),
|
|
13
|
+
scales.map((scale) => scale.word),
|
|
14
|
+
).flatMap((amount) => {
|
|
15
|
+
const read = scaledAmountOf(text, amount, scales);
|
|
16
|
+
return read === undefined
|
|
17
|
+
? []
|
|
18
|
+
: [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { stepTimeSlip, type StepTimeWords } from "../structure/step-times.ts";
|
|
4
4
|
import type { Mark } from "../structure/time-marks.ts";
|
|
5
5
|
import { quoteAt } from "./structure-tree.ts";
|
|
6
|
+
import { withoutCodeBlocks } from "./code-fences.ts";
|
|
6
7
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
7
8
|
|
|
8
9
|
const SECONDS_PER_HOUR = 3600;
|
|
@@ -35,7 +36,7 @@ const wordsOf = (doc: ProseDocument): StepTimeWords => {
|
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
export const stepTimeSumMismatch: Detector = (doc): Finding[] => {
|
|
38
|
-
const slip = stepTimeSlip(doc.source, wordsOf(doc));
|
|
39
|
+
const slip = stepTimeSlip(withoutCodeBlocks(doc.source), wordsOf(doc));
|
|
39
40
|
if (slip === undefined) return [];
|
|
40
41
|
return [
|
|
41
42
|
{
|
|
@@ -265,6 +265,9 @@ const totalIssues = (doc: ProseDocument, tree: NonNullable<ProseDocument["struct
|
|
|
265
265
|
breakdowns: patternsOf(doc, "breakdown-phrase"),
|
|
266
266
|
discounts: patternsOf(doc, "discount-word"),
|
|
267
267
|
joiners: patternsOf(doc, "breakdown-gap-joiner"),
|
|
268
|
+
leads: patternsOf(doc, "total-breakdown-lead"),
|
|
269
|
+
partials: patternsOf(doc, "breakdown-partial-word"),
|
|
270
|
+
backReferences: patternsOf(doc, "total-back-reference"),
|
|
268
271
|
};
|
|
269
272
|
const prose = proseTotalMismatches(
|
|
270
273
|
doc.source,
|
package/src/detectors/team.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { proseText } from "../measure.ts";
|
|
|
2
2
|
import { joinWords } from "./word-list.ts";
|
|
3
3
|
import { wordsOf } from "./structure.ts";
|
|
4
4
|
import { nameSpans } from "../team-names.ts";
|
|
5
|
-
import
|
|
5
|
+
import { conjugatedSpans } from "./conjugated-entry.ts";
|
|
6
|
+
import type { Detector, Finding, LexiconEntry, ProseDocument, Sentence, Span, Token } from "../plugin.ts";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* チームの言葉。社内でしか通じない語を、チームが chaff.yaml に自分で並べる。
|
|
@@ -12,19 +13,24 @@ import type { Detector, Finding, ProseDocument, Sentence, Span, Token } from "..
|
|
|
12
13
|
*/
|
|
13
14
|
/**
|
|
14
15
|
* 表層でも原形でも当てる。利用者は辞書形で書く(「握る」)が、本文は活用している(「握った」)。
|
|
16
|
+
* 複合動詞(「巻き取る」)は語に割れるので、語の並びで原形に照らす(「巻き取ります」)。
|
|
15
17
|
* 品詞解析があれば原形で当たり、無くても表層で当たる。要求はしない。
|
|
16
18
|
*/
|
|
17
|
-
const matches = (sentence: Sentence,
|
|
19
|
+
const matches = (sentence: Sentence, entry: LexiconEntry): boolean => {
|
|
18
20
|
// 大文字小文字は区別しない。英語の文頭の「Circle back」も「circle back」として当てる。
|
|
19
|
-
const wanted =
|
|
20
|
-
return
|
|
21
|
+
const wanted = entry.pattern.toLowerCase();
|
|
22
|
+
return (
|
|
23
|
+
sentence.text.toLowerCase().includes(wanted) ||
|
|
24
|
+
(sentence.tokens ?? []).some((token) => token.lemma?.toLowerCase() === wanted) ||
|
|
25
|
+
conjugatedSpans(sentence, entry).length > 0
|
|
26
|
+
);
|
|
21
27
|
};
|
|
22
28
|
|
|
23
29
|
export const internalJargon: Detector = (doc, options): Finding[] => {
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
30
|
+
const entries = options.lexicon ?? [];
|
|
31
|
+
if (entries.length === 0) return [];
|
|
26
32
|
const hits = doc.sentences.flatMap((sentence) => {
|
|
27
|
-
const matched =
|
|
33
|
+
const matched = entries.find((entry) => matches(sentence, entry))?.pattern;
|
|
28
34
|
return matched === undefined ? [] : [{ sentence, matched }];
|
|
29
35
|
});
|
|
30
36
|
if (hits.length < options.limit) return [];
|
|
@@ -11,6 +11,7 @@ import { reversedTimeRanges } from "../structure/time-range.ts";
|
|
|
11
11
|
import { cellMinutes, reversedShiftRows, showsOvernightWork } from "../structure/shift-times.ts";
|
|
12
12
|
import { pairedTimesOutOfOrder } from "../structure/labelled-time-order.ts";
|
|
13
13
|
import { quoteAt, rangeWordsOf } from "./structure-tree.ts";
|
|
14
|
+
import { withoutCodeBlocks } from "./code-fences.ts";
|
|
14
15
|
|
|
15
16
|
// 一日の予定の時刻の順番と、語の決まった二つの時刻の順番(time-order)、発より前の着(arrival-before-departure)、移動の時間より短い乗り継ぎ(connection-time-short)。時刻は compare/clock-time.ts が読み、
|
|
16
17
|
// 発着・翌日・時間帯の語は言語パッケージの語彙表(leg-mark、leg-column、day-shift-mark、time-zone、local-time-mark)から取る。
|
|
@@ -43,11 +44,12 @@ const variantOf = (issue: StructureIssue, variant: string | undefined): string |
|
|
|
43
44
|
return "end_label" in issue.values ? "columns" : undefined;
|
|
44
45
|
};
|
|
45
46
|
|
|
46
|
-
/** 表と箇条書きを行のまま読むので、原文を渡す(doc.prose
|
|
47
|
+
/** 表と箇条書きを行のまま読むので、原文を渡す(doc.prose は表を覆う)。コードブロックは例なので覆う。 */
|
|
47
48
|
const detectorOf =
|
|
48
49
|
(rule: string, find: Finder, variant?: string): Detector =>
|
|
49
|
-
(doc): Finding[] =>
|
|
50
|
-
|
|
50
|
+
(doc): Finding[] => {
|
|
51
|
+
const source = withoutCodeBlocks(doc.source);
|
|
52
|
+
return find(source, timesOf(source), datesOf(doc), timeWordsOf(doc), doc).map((issue) => {
|
|
51
53
|
const named = variantOf(issue, variant);
|
|
52
54
|
return {
|
|
53
55
|
rule,
|
|
@@ -59,6 +61,7 @@ const detectorOf =
|
|
|
59
61
|
...(named === undefined ? {} : { variant: named }),
|
|
60
62
|
};
|
|
61
63
|
});
|
|
64
|
+
};
|
|
62
65
|
|
|
63
66
|
const timeOrderInList: Detector = detectorOf("time-order", timeOrderBreaks);
|
|
64
67
|
/** 語の決まった二つの時刻(開場と開演)。語は語彙表 timed-pair-label から取る。 */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
2
2
|
import { isKnownWord, isSplitWord, suggestionFor, wordsToCheck, type CheckedWord, type Speller } from "../spelling.ts";
|
|
3
|
+
import { parse } from "../markdown-read.ts";
|
|
4
|
+
import { eachPreOrder } from "../tree-walk.ts";
|
|
3
5
|
import { quoteAt } from "./structure-tree.ts";
|
|
4
6
|
|
|
5
7
|
/** これより短い語は見ない。短い語は一字違いの語が多すぎて言い直しが決まらず(tost は test か toast か)、略した語(impl)も多い。 */
|
|
@@ -24,14 +26,30 @@ const usedOnce = (words: readonly CheckedWord[]): CheckedWord[] => {
|
|
|
24
26
|
return words.filter(({ word }) => counts.get(word) === 1);
|
|
25
27
|
};
|
|
26
28
|
|
|
29
|
+
const LETTERS = /\p{L}+/gu;
|
|
30
|
+
|
|
31
|
+
/** 文書がコード(コードの区画と `…`)に書いた語。コードに書いた名前(`tidyq check` の tidyq)は、地の文でも打ち間違いではない。 */
|
|
32
|
+
export const codeWordsOf = (source: string): Set<string> => {
|
|
33
|
+
const words = new Set<string>();
|
|
34
|
+
eachPreOrder(parse(source), (node) => {
|
|
35
|
+
if (node.type === "code" || node.type === "inlineCode")
|
|
36
|
+
(node.value ?? "")
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.match(LETTERS)
|
|
39
|
+
?.forEach((word) => words.add(word));
|
|
40
|
+
});
|
|
41
|
+
return words;
|
|
42
|
+
};
|
|
43
|
+
|
|
27
44
|
/**
|
|
28
45
|
* 辞書に無い英語の語で、一字違いの辞書の語があるもの(recieve → receive)。辞書は adapter が持ち、無い言語では動かない。
|
|
29
|
-
* 大文字を含む語(固有名詞・略語)、コード・URL
|
|
46
|
+
* 大文字を含む語(固有名詞・略語)、コード・URL の中、頭の字を分けた語の残り、二度以上使う語、言い直しの無い語、
|
|
47
|
+
* 文書がコードにも書いた語は言わない。
|
|
30
48
|
*/
|
|
31
49
|
export const unknownWord: Detector = (doc): Finding[] => {
|
|
32
50
|
if (doc.dictionary === undefined) return [];
|
|
33
51
|
const speller = spellerOf(doc, doc.dictionary());
|
|
34
|
-
const known = new Set(patternsOf(doc, "known-misspelling"));
|
|
52
|
+
const known = new Set([...patternsOf(doc, "known-misspelling"), ...codeWordsOf(doc.source)]);
|
|
35
53
|
const words = wordsToCheck(doc.prose ?? doc.source, MIN_LENGTH, MAX_LENGTH).filter(({ offset }) => !isSplitWord(doc.source, offset));
|
|
36
54
|
const used = new Set(words.map(({ word }) => word).filter((word) => isKnownWord(word, speller)));
|
|
37
55
|
return usedOnce(words).flatMap(({ offset, word }) => {
|
|
@@ -4,6 +4,7 @@ import { paragraphsOf } from "../derived/period-counts.ts";
|
|
|
4
4
|
import { timeLengths, type TimeLength } from "../derived/time-lengths.ts";
|
|
5
5
|
import { limitWordsOf, marksOf, periodCountWordsOf } from "./use-count-words.ts";
|
|
6
6
|
import { quoteAt } from "./structure-tree.ts";
|
|
7
|
+
import { withoutCodeBlocks } from "./code-fences.ts";
|
|
7
8
|
|
|
8
9
|
// 使う間隔の下限と期間あたりの回数の上限が両立しない、または表の回数と合わない(interval-count-mismatch)。
|
|
9
10
|
// 語は use-count-word と use-interval-word、長さの単位は unit-time から取る。
|
|
@@ -14,8 +15,8 @@ const SECONDS_PER_MINUTE = 60;
|
|
|
14
15
|
const patternsOf = (doc: ProseDocument, lexicon: string, weight?: number): string[] =>
|
|
15
16
|
(doc.lexicons[lexicon] ?? []).filter((entry) => weight === undefined || entry.weight === weight).map((entry) => entry.pattern);
|
|
16
17
|
|
|
17
|
-
const lengthsOf = (doc: ProseDocument): TimeLength[] =>
|
|
18
|
-
timeLengths(
|
|
18
|
+
const lengthsOf = (doc: ProseDocument, text: string): TimeLength[] =>
|
|
19
|
+
timeLengths(text, {
|
|
19
20
|
hourUnits: patternsOf(doc, "unit-time", SECONDS_PER_HOUR),
|
|
20
21
|
minuteUnits: patternsOf(doc, "unit-time", SECONDS_PER_MINUTE),
|
|
21
22
|
halves: patternsOf(doc, "length-half"),
|
|
@@ -39,8 +40,10 @@ const valuesOf = (doc: ProseDocument, mismatch: IntervalMismatch): Record<string
|
|
|
39
40
|
? { count: written(doc, mismatch.count), interval: written(doc, mismatch.interval), needed: mismatch.neededHours, hours: mismatch.count.hours }
|
|
40
41
|
: { count: written(doc, mismatch.count), column: mismatch.column, table: mismatch.tableCount };
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
/** コードブロックの中の用法は例なので、覆って読む。 */
|
|
44
|
+
export const intervalCountMismatch: Detector = (doc): Finding[] => {
|
|
45
|
+
const text = withoutCodeBlocks(doc.source);
|
|
46
|
+
return intervalCountMismatches(text, paragraphsOf(text), lengthsOf(doc, text), wordsOf(doc)).map((mismatch) => ({
|
|
44
47
|
rule: "interval-count-mismatch",
|
|
45
48
|
severity: "warning",
|
|
46
49
|
line: 0,
|
|
@@ -49,3 +52,4 @@ export const intervalCountMismatch: Detector = (doc): Finding[] =>
|
|
|
49
52
|
values: { ...valuesOf(doc, mismatch), offset: mismatch.count.start },
|
|
50
53
|
...(mismatch.kind === "table" ? { variant: "table" } : {}),
|
|
51
54
|
}));
|
|
55
|
+
};
|
|
@@ -3,6 +3,7 @@ import { exceededMaxima } from "../derived/use-maximum.ts";
|
|
|
3
3
|
import { paragraphsOf } from "../derived/period-counts.ts";
|
|
4
4
|
import { limitWordsOf, marksOf, periodCountWordsOf } from "./use-count-words.ts";
|
|
5
5
|
import { quoteAt } from "./structure-tree.ts";
|
|
6
|
+
import { withoutCodeBlocks } from "./code-fences.ts";
|
|
6
7
|
import { isMoneySpan, type CurrencyMark } from "../derived/money-span.ts";
|
|
7
8
|
|
|
8
9
|
// 1回の量 × 期間あたりの回数が、その期間の上限を超える(product-exceeds-maximum)。語は use-count-word と use-amount-word から取る。
|
|
@@ -19,7 +20,8 @@ export const productExceedsMaximum: Detector = (doc): Finding[] => {
|
|
|
19
20
|
const marks = currencyMarksOf(doc);
|
|
20
21
|
const unitOf = (span: Span): string => written(doc, span).replace(LEADING_NUMBER, "");
|
|
21
22
|
const isMoney = (span: Span): boolean => isMoneySpan(doc.source, span, unitOf(span), marks);
|
|
22
|
-
const
|
|
23
|
+
const text = withoutCodeBlocks(doc.source);
|
|
24
|
+
const amounts = exceededMaxima(text, paragraphsOf(text), words).filter((exceeded) => !isMoney(exceeded.maximum) && !isMoney(exceeded.perUse));
|
|
23
25
|
return amounts.map((exceeded) => ({
|
|
24
26
|
rule: "product-exceeds-maximum",
|
|
25
27
|
severity: "warning",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type * as Api from "../api.ts";
|
|
2
2
|
import type { BulletList, Lexicon, Markup, Paragraph, ProseDocument, Section, Sentence, Span, Token } from "../plugin.ts";
|
|
3
|
+
import { entriesForGenre } from "../lexicon-genres.ts";
|
|
3
4
|
|
|
4
5
|
// The document as the plugin API shows it (api.ts RuleDocument): copies of only the public fields, frozen. A copy, so
|
|
5
6
|
// chaff's own shapes can change without breaking a plugin; frozen, so a plugin's rule cannot change what the next rule reads.
|
|
@@ -55,7 +56,12 @@ const sectionOf = (section: Section, copy: SentenceCopies): Api.Section => ({
|
|
|
55
56
|
const listOf = (list: BulletList): Api.List => ({ span: spanOf(list.span), itemLengths: [...list.items] });
|
|
56
57
|
|
|
57
58
|
const lexiconOf = (lexicon: Lexicon): Api.Lexicon =>
|
|
58
|
-
lexicon.map((entry) => ({
|
|
59
|
+
lexicon.map((entry) => ({
|
|
60
|
+
pattern: entry.pattern,
|
|
61
|
+
...(entry.instead_of === undefined ? {} : { instead_of: entry.instead_of }),
|
|
62
|
+
...(entry.rewrite === undefined ? {} : { rewrite: entry.rewrite }),
|
|
63
|
+
...(entry.genres === undefined ? {} : { genres: [...entry.genres] }),
|
|
64
|
+
}));
|
|
59
65
|
|
|
60
66
|
const markupOf = (markup: Markup): Api.Markup => ({
|
|
61
67
|
markdown: markup.markdown,
|
|
@@ -68,7 +74,7 @@ const markupOf = (markup: Markup): Api.Markup => ({
|
|
|
68
74
|
|
|
69
75
|
const EMPTY_MARKUP: Markup = { markdown: false, headings: [], images: [], links: [], ids: new Set(), texts: [] };
|
|
70
76
|
|
|
71
|
-
const viewOf = (doc: ProseDocument): Api.RuleDocument => {
|
|
77
|
+
const viewOf = (doc: ProseDocument, genre: string | undefined): Api.RuleDocument => {
|
|
72
78
|
const copy = sentenceCopier();
|
|
73
79
|
const fields = deepFreeze({
|
|
74
80
|
path: doc.path,
|
|
@@ -81,7 +87,7 @@ const viewOf = (doc: ProseDocument): Api.RuleDocument => {
|
|
|
81
87
|
lists: doc.lists.map(listOf),
|
|
82
88
|
listItems: doc.listSpans.map(spanOf),
|
|
83
89
|
links: doc.links.map(spanOf),
|
|
84
|
-
lexicons: Object.fromEntries(Object.entries(doc.lexicons).map(([name, lexicon]) => [name, lexiconOf(lexicon)])),
|
|
90
|
+
lexicons: Object.fromEntries(Object.entries(doc.lexicons).map(([name, lexicon]) => [name, lexiconOf(entriesForGenre(lexicon, genre))])),
|
|
85
91
|
});
|
|
86
92
|
// The markup is read from the Markdown tree only when a rule asks for it, as chaff's own rules do.
|
|
87
93
|
const markup: { value: Api.Markup | undefined } = { value: undefined };
|
|
@@ -97,13 +103,16 @@ const viewOf = (doc: ProseDocument): Api.RuleDocument => {
|
|
|
97
103
|
/** A word list as a detector is given it (DetectorOptions.lexicon): public fields only, frozen. */
|
|
98
104
|
export const frozenLexiconOf = (lexicon: Lexicon): Api.Lexicon => deepFreeze(lexiconOf(lexicon));
|
|
99
105
|
|
|
100
|
-
|
|
106
|
+
// By genre too: the run, not the document, carries the genre, so one document may be run under several.
|
|
107
|
+
const views = new WeakMap<ProseDocument, Map<string | undefined, Api.RuleDocument>>();
|
|
101
108
|
|
|
102
|
-
/** The document as a plugin's detector sees it. Made once per document
|
|
103
|
-
export const ruleDocumentOf = (doc: ProseDocument): Api.RuleDocument => {
|
|
104
|
-
const
|
|
109
|
+
/** The document as a plugin's detector sees it in a genre, its word lists holding that genre's entries. Made once per document and genre. */
|
|
110
|
+
export const ruleDocumentOf = (doc: ProseDocument, genre: string | undefined): Api.RuleDocument => {
|
|
111
|
+
const byGenre = views.get(doc) ?? new Map<string | undefined, Api.RuleDocument>();
|
|
112
|
+
views.set(doc, byGenre);
|
|
113
|
+
const known = byGenre.get(genre);
|
|
105
114
|
if (known !== undefined) return known;
|
|
106
|
-
const view = viewOf(doc);
|
|
107
|
-
|
|
115
|
+
const view = viewOf(doc, genre);
|
|
116
|
+
byGenre.set(genre, view);
|
|
108
117
|
return view;
|
|
109
118
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// A word-list entry's genres as a plugin writes them: a non-empty list of the genres and groups chaff knows (legal,
|
|
2
|
+
// blog/tech). Pure: the known ids come in.
|
|
3
|
+
|
|
4
|
+
const printed = (value: unknown): string => JSON.stringify(value) ?? String(value);
|
|
5
|
+
|
|
6
|
+
/** What cannot be read in genres, printed: the whole value when it is not a non-empty list, else its unknown items. undefined when it reads. */
|
|
7
|
+
export const genresProblemOf = (genres: unknown, known: ReadonlySet<string>): string | undefined => {
|
|
8
|
+
if (!Array.isArray(genres) || genres.length === 0) return printed(genres);
|
|
9
|
+
const unknown = genres.filter((genre: unknown) => typeof genre !== "string" || !known.has(genre));
|
|
10
|
+
return unknown.length === 0 ? undefined : printed(unknown);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** genres when they read, as a list of ids. */
|
|
14
|
+
export const readGenres = (genres: unknown, known: ReadonlySet<string>): string[] | undefined =>
|
|
15
|
+
Array.isArray(genres) && genresProblemOf(genres, known) === undefined ? genres.filter((genre: unknown) => typeof genre === "string") : undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as Api from "../api.ts";
|
|
2
2
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
3
3
|
import { frozenLexiconOf, ruleDocumentOf } from "./document-view.ts";
|
|
4
|
+
import { entriesForGenre } from "../lexicon-genres.ts";
|
|
4
5
|
import { returnedFindings, type ShapeProblem } from "./returned-findings.ts";
|
|
5
6
|
|
|
6
7
|
// A detector a team or a plugin wrote, run as one of chaff's. It reads the document through the plugin API, and what it
|
|
@@ -38,8 +39,12 @@ const messageOf = (error: unknown): string => {
|
|
|
38
39
|
* What the detector returned, as findings, or how it failed. Reading the return can run the plugin's code too (a getter,
|
|
39
40
|
* a Proxy), so it is checked inside the try. A Promise is a wrong return; its rejection must not end the run later.
|
|
40
41
|
*/
|
|
41
|
-
const findingsOf = (
|
|
42
|
-
|
|
42
|
+
const findingsOf = (
|
|
43
|
+
detect: UntrustedDetector,
|
|
44
|
+
view: Api.RuleDocument,
|
|
45
|
+
doc: ProseDocument,
|
|
46
|
+
options: Api.DetectorOptions,
|
|
47
|
+
): { findings: Finding[] } | { failure: RuleFailure } => {
|
|
43
48
|
try {
|
|
44
49
|
const returned: unknown = detect(view, options);
|
|
45
50
|
if (returned instanceof Promise) returned.catch(() => undefined);
|
|
@@ -54,8 +59,8 @@ const findingsOf = (detect: UntrustedDetector, doc: ProseDocument, options: Api.
|
|
|
54
59
|
export const moduleDetector =
|
|
55
60
|
(detect: UntrustedDetector, origin: string): Detector =>
|
|
56
61
|
(doc, options): Finding[] => {
|
|
57
|
-
const lexicon = options.lexicon === undefined ? undefined : frozenLexiconOf(options.lexicon);
|
|
58
|
-
const outcome = findingsOf(detect, doc, Object.freeze({ lexicon }));
|
|
62
|
+
const lexicon = options.lexicon === undefined ? undefined : frozenLexiconOf(entriesForGenre(options.lexicon, options.genre));
|
|
63
|
+
const outcome = findingsOf(detect, ruleDocumentOf(doc, options.genre), doc, Object.freeze({ lexicon }));
|
|
59
64
|
if ("failure" in outcome) throw new PluginRuleFailure(outcome.failure, origin);
|
|
60
65
|
return outcome.findings;
|
|
61
66
|
};
|