chaffjs 0.33.0 → 0.35.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/capitals-passage.d.ts +3 -0
- package/dist/capitals-passage.d.ts.map +1 -0
- package/dist/capitals-passage.js +26 -0
- package/dist/capitals-passage.js.map +1 -0
- 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/coined-hyphen-name.d.ts +13 -0
- package/dist/coined-hyphen-name.d.ts.map +1 -0
- package/dist/coined-hyphen-name.js +21 -0
- package/dist/coined-hyphen-name.js.map +1 -0
- 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 +17 -4
- package/dist/company-names.d.ts.map +1 -1
- package/dist/company-names.js +49 -17
- 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/acronym-context.d.ts +1 -1
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +4 -4
- package/dist/detectors/acronym-context.js.map +1 -1
- package/dist/detectors/acronym-definition.d.ts +13 -0
- package/dist/detectors/acronym-definition.d.ts.map +1 -0
- package/dist/detectors/acronym-definition.js +90 -0
- package/dist/detectors/acronym-definition.js.map +1 -0
- package/dist/detectors/acronym-lone.d.ts +13 -0
- package/dist/detectors/acronym-lone.d.ts.map +1 -0
- package/dist/detectors/acronym-lone.js +22 -0
- package/dist/detectors/acronym-lone.js.map +1 -0
- package/dist/detectors/acronym-name.d.ts +55 -0
- package/dist/detectors/acronym-name.d.ts.map +1 -0
- package/dist/detectors/acronym-name.js +75 -0
- package/dist/detectors/acronym-name.js.map +1 -0
- 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/capitalised-term.d.ts +14 -2
- package/dist/detectors/capitalised-term.d.ts.map +1 -1
- package/dist/detectors/capitalised-term.js +115 -4
- package/dist/detectors/capitalised-term.js.map +1 -1
- package/dist/detectors/caps-caption.d.ts +11 -0
- package/dist/detectors/caps-caption.d.ts.map +1 -0
- package/dist/detectors/caps-caption.js +51 -0
- package/dist/detectors/caps-caption.js.map +1 -0
- package/dist/detectors/char-shape.d.ts.map +1 -1
- package/dist/detectors/char-shape.js +47 -18
- package/dist/detectors/char-shape.js.map +1 -1
- package/dist/detectors/clause-shape.d.ts +1 -1
- package/dist/detectors/clause-shape.d.ts.map +1 -1
- package/dist/detectors/clause-shape.js +9 -4
- package/dist/detectors/clause-shape.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/concrete-evidence.d.ts +13 -1
- package/dist/detectors/concrete-evidence.d.ts.map +1 -1
- package/dist/detectors/concrete-evidence.js +59 -0
- package/dist/detectors/concrete-evidence.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/contraction-minority.d.ts +11 -0
- package/dist/detectors/contraction-minority.d.ts.map +1 -0
- package/dist/detectors/contraction-minority.js +10 -0
- package/dist/detectors/contraction-minority.js.map +1 -0
- package/dist/detectors/counter-edge.d.ts +5 -0
- package/dist/detectors/counter-edge.d.ts.map +1 -1
- package/dist/detectors/counter-edge.js +23 -0
- package/dist/detectors/counter-edge.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/date-any-year.d.ts +6 -3
- package/dist/detectors/date-any-year.d.ts.map +1 -1
- package/dist/detectors/date-any-year.js +47 -10
- package/dist/detectors/date-any-year.js.map +1 -1
- package/dist/detectors/date-heading-year.d.ts +18 -0
- package/dist/detectors/date-heading-year.d.ts.map +1 -0
- package/dist/detectors/date-heading-year.js +38 -0
- package/dist/detectors/date-heading-year.js.map +1 -0
- package/dist/detectors/date-year.d.ts +12 -2
- package/dist/detectors/date-year.d.ts.map +1 -1
- package/dist/detectors/date-year.js +31 -6
- package/dist/detectors/date-year.js.map +1 -1
- package/dist/detectors/defined-term-form.d.ts.map +1 -1
- package/dist/detectors/defined-term-form.js +26 -5
- package/dist/detectors/defined-term-form.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 +18 -2
- package/dist/detectors/due-date.js.map +1 -1
- package/dist/detectors/en-shape.d.ts.map +1 -1
- package/dist/detectors/en-shape.js +5 -1
- package/dist/detectors/en-shape.js.map +1 -1
- package/dist/detectors/fact-consistency.d.ts.map +1 -1
- package/dist/detectors/fact-consistency.js +15 -15
- 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/gram-passages.d.ts +11 -0
- package/dist/detectors/gram-passages.d.ts.map +1 -0
- package/dist/detectors/gram-passages.js +26 -0
- package/dist/detectors/gram-passages.js.map +1 -0
- 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/heading-end-mark.d.ts +8 -3
- package/dist/detectors/heading-end-mark.d.ts.map +1 -1
- package/dist/detectors/heading-end-mark.js +18 -8
- package/dist/detectors/heading-end-mark.js.map +1 -1
- package/dist/detectors/heading-names.d.ts +7 -0
- package/dist/detectors/heading-names.d.ts.map +1 -0
- package/dist/detectors/heading-names.js +24 -0
- package/dist/detectors/heading-names.js.map +1 -0
- package/dist/detectors/heading-numbering.d.ts.map +1 -1
- package/dist/detectors/heading-numbering.js +7 -2
- package/dist/detectors/heading-numbering.js.map +1 -1
- package/dist/detectors/inch-mark.d.ts +10 -0
- package/dist/detectors/inch-mark.d.ts.map +1 -0
- package/dist/detectors/inch-mark.js +48 -0
- package/dist/detectors/inch-mark.js.map +1 -0
- 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/lexicon.d.ts +0 -1
- package/dist/detectors/lexicon.d.ts.map +1 -1
- package/dist/detectors/lexicon.js +29 -23
- package/dist/detectors/lexicon.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/mark-shape.d.ts +6 -3
- package/dist/detectors/mark-shape.d.ts.map +1 -1
- package/dist/detectors/mark-shape.js +12 -6
- package/dist/detectors/mark-shape.js.map +1 -1
- package/dist/detectors/name-variant-apart.d.ts +27 -0
- package/dist/detectors/name-variant-apart.d.ts.map +1 -0
- package/dist/detectors/name-variant-apart.js +51 -0
- package/dist/detectors/name-variant-apart.js.map +1 -0
- package/dist/detectors/name-variant.d.ts.map +1 -1
- package/dist/detectors/name-variant.js +51 -17
- 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/numeral-word.d.ts +15 -0
- package/dist/detectors/numeral-word.d.ts.map +1 -0
- package/dist/detectors/numeral-word.js +26 -0
- package/dist/detectors/numeral-word.js.map +1 -0
- package/dist/detectors/organisation-run.d.ts +14 -0
- package/dist/detectors/organisation-run.d.ts.map +1 -0
- package/dist/detectors/organisation-run.js +73 -0
- package/dist/detectors/organisation-run.js.map +1 -0
- package/dist/detectors/orthographic-variant.d.ts.map +1 -1
- package/dist/detectors/orthographic-variant.js +13 -5
- package/dist/detectors/orthographic-variant.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/outline-label.d.ts +14 -0
- package/dist/detectors/outline-label.d.ts.map +1 -0
- package/dist/detectors/outline-label.js +32 -0
- package/dist/detectors/outline-label.js.map +1 -0
- package/dist/detectors/page-marker.d.ts +6 -0
- package/dist/detectors/page-marker.d.ts.map +1 -0
- package/dist/detectors/page-marker.js +19 -0
- package/dist/detectors/page-marker.js.map +1 -0
- package/dist/detectors/parallel-definition.d.ts +16 -0
- package/dist/detectors/parallel-definition.d.ts.map +1 -0
- package/dist/detectors/parallel-definition.js +51 -0
- package/dist/detectors/parallel-definition.js.map +1 -0
- 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/reference-text.d.ts.map +1 -1
- package/dist/detectors/reference-text.js +1 -0
- package/dist/detectors/reference-text.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/registry/unfilled-placeholder.d.ts.map +1 -1
- package/dist/detectors/registry/unfilled-placeholder.js +2 -2
- package/dist/detectors/registry/unfilled-placeholder.js.map +1 -1
- package/dist/detectors/registry/vague-density.js +1 -1
- package/dist/detectors/registry/vague-density.js.map +1 -1
- 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/request-owner.d.ts +6 -2
- package/dist/detectors/request-owner.d.ts.map +1 -1
- package/dist/detectors/request-owner.js +57 -7
- package/dist/detectors/request-owner.js.map +1 -1
- package/dist/detectors/requirement-smell.d.ts.map +1 -1
- package/dist/detectors/requirement-smell.js +10 -2
- package/dist/detectors/requirement-smell.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/sentence-length.d.ts.map +1 -1
- package/dist/detectors/sentence-length.js +24 -16
- package/dist/detectors/sentence-length.js.map +1 -1
- package/dist/detectors/sentence-rhythm.d.ts.map +1 -1
- package/dist/detectors/sentence-rhythm.js +6 -3
- package/dist/detectors/sentence-rhythm.js.map +1 -1
- package/dist/detectors/series-label.d.ts +2 -1
- package/dist/detectors/series-label.d.ts.map +1 -1
- package/dist/detectors/series-label.js +10 -4
- package/dist/detectors/series-label.js.map +1 -1
- package/dist/detectors/signals.d.ts +4 -0
- package/dist/detectors/signals.d.ts.map +1 -1
- package/dist/detectors/signals.js +95 -36
- package/dist/detectors/signals.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 +11 -7
- 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/template-sections.d.ts +14 -0
- package/dist/detectors/template-sections.d.ts.map +1 -0
- package/dist/detectors/template-sections.js +25 -0
- package/dist/detectors/template-sections.js.map +1 -0
- 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/titled-run.d.ts +22 -0
- package/dist/detectors/titled-run.d.ts.map +1 -0
- package/dist/detectors/titled-run.js +34 -0
- package/dist/detectors/titled-run.js.map +1 -0
- package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
- package/dist/detectors/unbalanced-bracket.js +4 -0
- package/dist/detectors/unbalanced-bracket.js.map +1 -1
- package/dist/detectors/undefined-term.d.ts.map +1 -1
- package/dist/detectors/undefined-term.js +8 -0
- package/dist/detectors/undefined-term.js.map +1 -1
- package/dist/detectors/unfilled-placeholder.d.ts +4 -0
- package/dist/detectors/unfilled-placeholder.d.ts.map +1 -0
- package/dist/detectors/unfilled-placeholder.js +9 -0
- package/dist/detectors/unfilled-placeholder.js.map +1 -0
- 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/detectors/vague-density.d.ts +5 -0
- package/dist/detectors/vague-density.d.ts.map +1 -0
- package/dist/detectors/vague-density.js +52 -0
- package/dist/detectors/vague-density.js.map +1 -0
- 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-scope.d.ts +10 -1
- package/dist/facts/fact-scope.d.ts.map +1 -1
- package/dist/facts/fact-scope.js +34 -3
- package/dist/facts/fact-scope.js.map +1 -1
- 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 +13 -3
- package/dist/facts/table-facts.d.ts.map +1 -1
- package/dist/facts/table-facts.js +35 -13
- 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/grade-api.d.ts +9 -2
- package/dist/grade-api.d.ts.map +1 -1
- package/dist/grade-api.js +31 -15
- package/dist/grade-api.js.map +1 -1
- package/dist/heading-numbering.d.ts +5 -2
- package/dist/heading-numbering.d.ts.map +1 -1
- package/dist/heading-numbering.js +27 -6
- package/dist/heading-numbering.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 +24 -0
- package/dist/name-end-letter.d.ts.map +1 -0
- package/dist/name-end-letter.js +45 -0
- package/dist/name-end-letter.js.map +1 -0
- package/dist/name-given-before.d.ts +15 -0
- package/dist/name-given-before.d.ts.map +1 -0
- package/dist/name-given-before.js +30 -0
- package/dist/name-given-before.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 +80 -0
- package/dist/name-separator.js.map +1 -1
- package/dist/name-variants.d.ts +8 -3
- package/dist/name-variants.d.ts.map +1 -1
- package/dist/name-variants.js +40 -12
- package/dist/name-variants.js.map +1 -1
- package/dist/name-word-order.d.ts +9 -5
- package/dist/name-word-order.d.ts.map +1 -1
- package/dist/name-word-order.js +47 -15
- package/dist/name-word-order.js.map +1 -1
- package/dist/nominal-stem.d.ts +13 -0
- package/dist/nominal-stem.d.ts.map +1 -0
- package/dist/nominal-stem.js +32 -0
- package/dist/nominal-stem.js.map +1 -0
- 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/sentence-load.d.ts +2 -1
- package/dist/sentence-load.d.ts.map +1 -1
- package/dist/sentence-load.js +6 -2
- package/dist/sentence-load.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/cited-document-section.d.ts +7 -0
- package/dist/structure/cited-document-section.d.ts.map +1 -0
- package/dist/structure/cited-document-section.js +33 -0
- package/dist/structure/cited-document-section.js.map +1 -0
- 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/html-text-blocks.d.ts +8 -0
- package/dist/structure/html-text-blocks.d.ts.map +1 -0
- package/dist/structure/html-text-blocks.js +47 -0
- package/dist/structure/html-text-blocks.js.map +1 -0
- package/dist/structure/issues.d.ts +1 -1
- package/dist/structure/issues.d.ts.map +1 -1
- package/dist/structure/issues.js +19 -4
- package/dist/structure/issues.js.map +1 -1
- package/dist/structure/labelled-date-order.d.ts +34 -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 +10 -1
- package/dist/structure/labelled-order.d.ts.map +1 -1
- package/dist/structure/labelled-order.js +18 -6
- 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/list-numbering.d.ts +20 -4
- package/dist/structure/list-numbering.d.ts.map +1 -1
- package/dist/structure/list-numbering.js +65 -9
- package/dist/structure/list-numbering.js.map +1 -1
- package/dist/structure/listed-paragraph.d.ts +16 -0
- package/dist/structure/listed-paragraph.d.ts.map +1 -0
- package/dist/structure/listed-paragraph.js +37 -0
- package/dist/structure/listed-paragraph.js.map +1 -0
- package/dist/structure/numbering.d.ts +3 -2
- package/dist/structure/numbering.d.ts.map +1 -1
- package/dist/structure/numbering.js +31 -6
- package/dist/structure/numbering.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/reference-text.d.ts +9 -1
- package/dist/structure/reference-text.d.ts.map +1 -1
- package/dist/structure/reference-text.js +21 -3
- package/dist/structure/reference-text.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/section-names.d.ts +12 -0
- package/dist/structure/section-names.d.ts.map +1 -0
- package/dist/structure/section-names.js +26 -0
- package/dist/structure/section-names.js.map +1 -0
- 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/structure/versioned-label.d.ts +16 -0
- package/dist/structure/versioned-label.d.ts.map +1 -0
- package/dist/structure/versioned-label.js +48 -0
- package/dist/structure/versioned-label.js.map +1 -0
- package/dist/structure/written-headings.d.ts +31 -0
- package/dist/structure/written-headings.d.ts.map +1 -0
- package/dist/structure/written-headings.js +119 -0
- package/dist/structure/written-headings.js.map +1 -0
- package/dist/structure/written-resolve.d.ts +12 -0
- package/dist/structure/written-resolve.d.ts.map +1 -0
- package/dist/structure/written-resolve.js +49 -0
- package/dist/structure/written-resolve.js.map +1 -0
- 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/all-caps-shouting.yaml +2 -2
- package/rules/closing-balance-mismatch.yaml +3 -3
- package/rules/concrete-evidence-density.yaml +2 -2
- package/rules/contraction-consistency.yaml +13 -13
- package/rules/dangling-reference.yaml +2 -2
- package/rules/date-without-year.yaml +2 -2
- package/rules/defined-name-repeated.yaml +2 -2
- package/rules/due-before-issue.yaml +9 -5
- package/rules/fact-conflict.yaml +2 -2
- package/rules/heading-echo.yaml +2 -2
- package/rules/heading-end-punctuation-mix.yaml +2 -2
- package/rules/heading-numbering-mix.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/max-kanji-continuous.yaml +5 -3
- package/rules/max-sentence-length.yaml +3 -2
- package/rules/name-variant.yaml +5 -2
- package/rules/ngram-repetition.yaml +2 -2
- package/rules/no-lead.yaml +2 -2
- package/rules/number-without-unit.yaml +2 -2
- package/rules/numbering-gap.yaml +2 -2
- package/rules/orthographic-variant.yaml +2 -2
- package/rules/reference-number-variant.yaml +3 -3
- package/rules/reference-title-mismatch.yaml +2 -2
- package/rules/repeated-sentence-ending.yaml +3 -2
- package/rules/request-without-deadline.yaml +2 -2
- package/rules/requirement-smell.yaml +2 -2
- package/rules/sentence-rhythm.yaml +2 -2
- package/rules/title-case-consistency.yaml +2 -2
- package/rules/toki-as-condition.yaml +71 -0
- package/rules/total-mismatch.yaml +4 -4
- package/rules/unbalanced-bracket.yaml +2 -2
- package/rules/undefined-acronym.yaml +11 -2
- package/rules/undefined-term.yaml +2 -2
- package/rules/unfilled-placeholder.yaml +2 -2
- package/rules/unknown-word.yaml +2 -2
- package/rules/use-before-definition.yaml +2 -2
- package/rules/vague-word-density.yaml +2 -2
- package/src/api.ts +11 -2
- package/src/capitals-passage.ts +31 -0
- package/src/cli-text.ts +4 -2
- package/src/coined-hyphen-name.ts +27 -0
- 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 +76 -20
- package/src/custom/no-rewrite.ts +2 -0
- package/src/custom/parse.ts +18 -2
- package/src/detectors/acronym-context.ts +5 -6
- package/src/detectors/acronym-definition.ts +123 -0
- package/src/detectors/acronym-lone.ts +26 -0
- package/src/detectors/acronym-name.ts +117 -0
- 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/capitalised-term.ts +154 -4
- package/src/detectors/caps-caption.ts +61 -0
- package/src/detectors/char-shape.ts +74 -22
- package/src/detectors/clause-shape.ts +14 -4
- package/src/detectors/closing-balance-mismatch.ts +1 -0
- package/src/detectors/code-fences.ts +10 -0
- package/src/detectors/concrete-evidence.ts +77 -1
- 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/contraction-minority.ts +11 -0
- package/src/detectors/counter-edge.ts +23 -0
- package/src/detectors/cross-facts.ts +2 -1
- package/src/detectors/custom.ts +9 -2
- package/src/detectors/date-any-year.ts +56 -10
- package/src/detectors/date-heading-year.ts +55 -0
- package/src/detectors/date-year.ts +54 -9
- package/src/detectors/defined-term-form.ts +26 -5
- package/src/detectors/document-shape.ts +8 -0
- package/src/detectors/due-date.ts +26 -7
- package/src/detectors/en-shape.ts +5 -1
- package/src/detectors/fact-consistency.ts +16 -19
- package/src/detectors/form-line.ts +47 -0
- package/src/detectors/formula-amount.ts +2 -18
- package/src/detectors/gram-passages.ts +36 -0
- package/src/detectors/heading-claim.ts +76 -0
- package/src/detectors/heading-echo.ts +32 -1
- package/src/detectors/heading-end-mark.ts +23 -10
- package/src/detectors/heading-names.ts +31 -0
- package/src/detectors/heading-numbering.ts +7 -2
- package/src/detectors/inch-mark.ts +49 -0
- package/src/detectors/installment-total-mismatch.ts +3 -18
- package/src/detectors/lexicon.ts +32 -21
- package/src/detectors/list-parallel.ts +46 -7
- package/src/detectors/mark-shape.ts +12 -6
- package/src/detectors/name-variant-apart.ts +63 -0
- package/src/detectors/name-variant.ts +73 -18
- package/src/detectors/number-unit.ts +35 -9
- package/src/detectors/numeral-word.ts +33 -0
- package/src/detectors/organisation-run.ts +86 -0
- package/src/detectors/orthographic-variant.ts +22 -6
- package/src/detectors/orthography.ts +17 -8
- package/src/detectors/outline-label.ts +48 -0
- package/src/detectors/page-marker.ts +26 -0
- package/src/detectors/parallel-definition.ts +64 -0
- 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/reference-text.ts +1 -0
- package/src/detectors/registry/condition-toki.ts +4 -0
- package/src/detectors/registry/unfilled-placeholder.ts +2 -2
- package/src/detectors/registry/vague-density.ts +1 -1
- package/src/detectors/rent-multiple-mismatch.ts +2 -18
- package/src/detectors/request-owner.ts +71 -8
- package/src/detectors/requirement-smell.ts +15 -2
- package/src/detectors/row-sentence-amounts.ts +5 -20
- package/src/detectors/sentence-length.ts +14 -6
- package/src/detectors/sentence-rhythm.ts +8 -4
- package/src/detectors/series-label.ts +13 -4
- package/src/detectors/signals.ts +94 -26
- package/src/detectors/stated-amounts.ts +20 -0
- package/src/detectors/step-time-sum.ts +2 -1
- package/src/detectors/structure-tree.ts +13 -8
- package/src/detectors/team.ts +13 -7
- package/src/detectors/template-sections.ts +37 -0
- package/src/detectors/time-order.ts +6 -3
- package/src/detectors/titled-run.ts +43 -0
- package/src/detectors/unbalanced-bracket.ts +3 -0
- package/src/detectors/undefined-term.ts +8 -0
- package/src/detectors/unfilled-placeholder.ts +10 -0
- 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/detectors/vague-density.ts +68 -0
- 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-scope.ts +53 -4
- 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 +50 -10
- 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/grade-api.ts +38 -16
- package/src/heading-numbering.ts +35 -8
- package/src/name-char-reading.ts +16 -0
- package/src/name-end-letter.ts +61 -0
- package/src/name-given-before.ts +40 -0
- package/src/name-neighbours.ts +2 -1
- package/src/name-separator.ts +93 -0
- package/src/name-variants.ts +69 -18
- package/src/name-word-order.ts +62 -17
- package/src/nominal-stem.ts +36 -0
- 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/sentence-load.ts +7 -2
- 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/cited-document-section.ts +42 -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/html-text-blocks.ts +45 -0
- package/src/structure/issues.ts +19 -4
- package/src/structure/labelled-date-order.ts +108 -21
- package/src/structure/labelled-order.ts +33 -13
- package/src/structure/line-amount-label.ts +2 -1
- package/src/structure/line-amount.ts +1 -11
- package/src/structure/list-numbering.ts +100 -11
- package/src/structure/listed-paragraph.ts +45 -0
- package/src/structure/numbering.ts +48 -19
- package/src/structure/prose-total.ts +81 -2
- package/src/structure/reference-text.ts +25 -3
- package/src/structure/runs.ts +10 -1
- package/src/structure/section-names.ts +32 -0
- 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/structure/versioned-label.ts +52 -0
- package/src/structure/written-headings.ts +137 -0
- package/src/structure/written-resolve.ts +57 -0
- package/src/subject-codes.ts +105 -0
- package/src/unlabelled-references.ts +24 -16
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// The year a section's heading gives the dates under it: "FY27-Q2 (May 1)", 「2026年度の予定」, 「令和8年の行事」. A yearless
|
|
2
|
+
// date in such a section has its year. Pure.
|
|
3
|
+
import type { StructureNode } from "../plugin.ts";
|
|
4
|
+
|
|
5
|
+
/** A fiscal-year name with its year as a number: "FY{y}" of the language's reporting-period-frame lexicon. */
|
|
6
|
+
export type YearLabel = { readonly before: string; readonly after: string };
|
|
7
|
+
|
|
8
|
+
/** The words that name a year in a heading: era names (令和) and fiscal-year labels ("FY{y}"). */
|
|
9
|
+
export type HeadingYearWords = { readonly eras: readonly string[]; readonly labels: readonly YearLabel[] };
|
|
10
|
+
|
|
11
|
+
/** A year written as figures: 2024年度, "2024 events". */
|
|
12
|
+
const YEAR_FIGURES = /(?<![0-90-9])(?:1[89]|20)\d{2}(?![0-90-9])/u;
|
|
13
|
+
/** An era's year after its name: 8年 of 令和8年, 元年 of 令和元年度 (not 8月). */
|
|
14
|
+
const ERA_YEAR_NUMBER = /^[ \t]?(?:[0-90-9]{1,2}|元)[ \t]?年/u;
|
|
15
|
+
/** A fiscal year's number: two figures (FY27) or four (FY2027). */
|
|
16
|
+
const LABEL_YEAR = /^(?:\d{2}|\d{4})(?!\d)/u;
|
|
17
|
+
const LETTER = /\p{L}/u;
|
|
18
|
+
|
|
19
|
+
/** "FY{y}" as the lexicon writes it: the words before and after the year. A name with no {y} names no year. */
|
|
20
|
+
export const yearLabelOf = (pattern: string): YearLabel | undefined => {
|
|
21
|
+
const at = pattern.indexOf("{y}");
|
|
22
|
+
return at === -1 || pattern.includes("{", at + 1) ? undefined : { before: pattern.slice(0, at).toLowerCase(), after: pattern.slice(at + 3).toLowerCase() };
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const startsAt = (text: string, index: number): boolean => index === 0 || !LETTER.test(text.charAt(index - 1));
|
|
26
|
+
|
|
27
|
+
const indicesOf = (text: string, word: string, from = 0): number[] => {
|
|
28
|
+
const at = word === "" ? -1 : text.indexOf(word, from);
|
|
29
|
+
return at === -1 ? [] : [at, ...indicesOf(text, word, at + 1)];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const namesLabelYear = (heading: string, label: YearLabel): boolean => {
|
|
33
|
+
const text = heading.toLowerCase();
|
|
34
|
+
return indicesOf(text, label.before).some((at) => {
|
|
35
|
+
if (!startsAt(text, at)) return false;
|
|
36
|
+
const year = LABEL_YEAR.exec(text.slice(at + label.before.length))?.[0];
|
|
37
|
+
return year !== undefined && text.startsWith(label.after, at + label.before.length + year.length);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const namesEraYear = (heading: string, era: string): boolean => indicesOf(heading, era).some((at) => ERA_YEAR_NUMBER.test(heading.slice(at + era.length)));
|
|
42
|
+
|
|
43
|
+
/** The heading names a year: figures (2026年度), an era's year (令和8年), or a fiscal year (FY27). */
|
|
44
|
+
export const headingNamesYear = (heading: string, words: HeadingYearWords): boolean =>
|
|
45
|
+
YEAR_FIGURES.test(heading) || words.eras.some((era) => namesEraYear(heading, era)) || words.labels.some((label) => namesLabelYear(heading, label));
|
|
46
|
+
|
|
47
|
+
const sectionHeading = (node: StructureNode, current: string): string =>
|
|
48
|
+
node.kind === "section" && node.attrs["heading"] !== undefined ? String(node.attrs["heading"]) : current;
|
|
49
|
+
|
|
50
|
+
/** The offsets of the dates whose own section, the innermost one they are in, has a heading that names a year. */
|
|
51
|
+
export const datesUnderYearHeadings = (tree: StructureNode, words: HeadingYearWords, heading = ""): number[] => {
|
|
52
|
+
const own = sectionHeading(tree, heading);
|
|
53
|
+
if (tree.kind === "date") return headingNamesYear(own, words) ? [tree.span.start] : [];
|
|
54
|
+
return tree.children.flatMap((child) => datesUnderYearHeadings(child, words, own));
|
|
55
|
+
};
|
|
@@ -3,15 +3,27 @@
|
|
|
3
3
|
import type { Detector, Finding, LexiconEntry, ProseDocument, StructureNode } from "../plugin.ts";
|
|
4
4
|
import { inDocumentOrder } from "../structure/issues.ts";
|
|
5
5
|
import { quoteAt } from "./structure-tree.ts";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ANY_YEAR_MARKER_LEXICON,
|
|
8
|
+
MARKER_REACHES,
|
|
9
|
+
YEAR_SPAN_JOINER_LEXICON,
|
|
10
|
+
anyYearDate,
|
|
11
|
+
opensSpan,
|
|
12
|
+
type AnyYearMarker,
|
|
13
|
+
type MarkerReach,
|
|
14
|
+
} from "./date-any-year.ts";
|
|
15
|
+
import { datesUnderYearHeadings, yearLabelOf, type HeadingYearWords } from "./date-heading-year.ts";
|
|
7
16
|
|
|
8
17
|
/** The words that make a yearless date any year's (毎年, 例えば, "each") and that join a period's two ends (から, "to"). */
|
|
9
18
|
export type AnyYearWords = { readonly markers: readonly AnyYearMarker[]; readonly joiners: readonly string[] };
|
|
10
19
|
|
|
11
20
|
const NO_ANY_YEAR_WORDS: AnyYearWords = { markers: [], joiners: [] };
|
|
12
21
|
|
|
13
|
-
/**
|
|
14
|
-
|
|
22
|
+
/**
|
|
23
|
+
* A date as the tree reads it: "2026-10-14" with its year, "10-14" without. `yearHeaded`: the heading of its section
|
|
24
|
+
* names a year ("FY27-Q2 (May 1)", 「2026年度の予定」), which the date takes.
|
|
25
|
+
*/
|
|
26
|
+
export type DatePoint = { readonly offset: number; readonly end: number; readonly value: string; readonly yearHeaded?: boolean };
|
|
15
27
|
|
|
16
28
|
/** The first and the last year of the document's dated dates. */
|
|
17
29
|
export type YearSpan = { readonly from: number; readonly to: number };
|
|
@@ -106,9 +118,23 @@ const hasYearWord = (point: DatePoint, source: string, yearWords: readonly YearW
|
|
|
106
118
|
*/
|
|
107
119
|
const yearGiven = (point: DatePoint, anchors: readonly DatePoint[], source: string, yearWords: readonly YearWord[]): boolean => {
|
|
108
120
|
const start = lineStart(source, point.offset);
|
|
109
|
-
return hasYearWord(point, source, yearWords) || anchors.some((other) => other.offset >= start && other.offset < point.offset);
|
|
121
|
+
return point.yearHeaded === true || hasYearWord(point, source, yearWords) || anchors.some((other) => other.offset >= start && other.offset < point.offset);
|
|
110
122
|
};
|
|
111
123
|
|
|
124
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
125
|
+
const COMMON_YEAR_MS = 365 * DAY_MS;
|
|
126
|
+
/** A year with no 29 February, so that "03-01" follows "02-28" as it does in most years. */
|
|
127
|
+
const COMMON_YEAR = 2025;
|
|
128
|
+
|
|
129
|
+
const dayOf = (value: string): number => Date.UTC(COMMON_YEAR, Number(value.slice(0, 2)) - 1, Number(value.slice(3, 5)));
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* A period of one whole year: its end is the day before its start (January 1 to December 31, 4月1日から3月31日). Without
|
|
133
|
+
* a year it is every year's, like a calendar or a fiscal year.
|
|
134
|
+
*/
|
|
135
|
+
export const wholeYear = (start: string, end: string): boolean =>
|
|
136
|
+
MONTH_DAY.test(start) && MONTH_DAY.test(end) && (dayOf(end) + DAY_MS - dayOf(start)) % COMMON_YEAR_MS === 0;
|
|
137
|
+
|
|
112
138
|
/**
|
|
113
139
|
* The yearless dates whose year the reader cannot tell. Where most dates carry a year (at least two, and more than the
|
|
114
140
|
* yearless ones) and those years differ, every yearless one is reported: in a one-year document the year is plain. Where
|
|
@@ -124,9 +150,13 @@ export const yearGaps = (
|
|
|
124
150
|
const dated = points.filter((point) => FULL.test(point.value));
|
|
125
151
|
const anchors = [...dated, ...points.filter((point) => hasYearWord(point, source, yearWords))];
|
|
126
152
|
const nextOf = new Map(points.map((point, index) => [point, points[index + 1]]));
|
|
153
|
+
const previousOf = new Map(points.map((point, index) => [point, points[index - 1]]));
|
|
154
|
+
const yearlySpan = (start: DatePoint | undefined, end: DatePoint | undefined): boolean =>
|
|
155
|
+
start !== undefined && end !== undefined && wholeYear(start.value, end.value) && opensSpan(start, end, source, anyYear.joiners);
|
|
127
156
|
const yearOfAny = (point: DatePoint): boolean => {
|
|
128
157
|
const next = nextOf.get(point);
|
|
129
158
|
if (anyYearDate(point, source, anyYear.markers)) return true;
|
|
159
|
+
if (yearlySpan(point, next) || yearlySpan(previousOf.get(point), point)) return true;
|
|
130
160
|
return next !== undefined && opensSpan(point, next, source, anyYear.joiners) && hasYearWord(next, source, yearWords);
|
|
131
161
|
};
|
|
132
162
|
// A recurring day or an example's date has no year to write, and is not the document's way of writing dates either.
|
|
@@ -134,20 +164,35 @@ export const yearGaps = (
|
|
|
134
164
|
const span = spanOf(dated);
|
|
135
165
|
const unclear = dated.length >= 2 && yearless.length < dated.length && span !== undefined && span.to > span.from;
|
|
136
166
|
const datedSides = new Set(dated.flatMap((point) => sideOf(monthOf(FULL, point.value)) ?? []));
|
|
137
|
-
const previousOf = new Map(points.map((point, index) => [point, points[index - 1]]));
|
|
138
167
|
return yearless.flatMap((point): YearGap[] => {
|
|
139
168
|
if (unclear) return [{ point, kind: "years", span }];
|
|
140
169
|
return crossesYear(point, previousOf.get(point), datedSides) ? [{ point, kind: "boundary", span }] : [];
|
|
141
170
|
});
|
|
142
171
|
};
|
|
143
172
|
|
|
144
|
-
|
|
145
|
-
|
|
173
|
+
const NO_HEADING_YEAR_WORDS: HeadingYearWords = { eras: [], labels: [] };
|
|
174
|
+
|
|
175
|
+
export const datePoints = (tree: StructureNode, headingWords: HeadingYearWords = NO_HEADING_YEAR_WORDS): DatePoint[] => {
|
|
176
|
+
const yearHeaded = new Set(datesUnderYearHeadings(tree, headingWords));
|
|
177
|
+
return inDocumentOrder(tree).flatMap((node) =>
|
|
178
|
+
node.kind === "date"
|
|
179
|
+
? [{ offset: node.span.start, end: node.span.end, value: String(node.attrs["value"]), yearHeaded: yearHeaded.has(node.span.start) }]
|
|
180
|
+
: [],
|
|
181
|
+
);
|
|
182
|
+
};
|
|
146
183
|
|
|
147
184
|
const yearWordsOf = (doc: ProseDocument): YearWord[] =>
|
|
148
185
|
(doc.lexicons[YEAR_REFERENCE_LEXICON] ?? []).map((entry: LexiconEntry) => ({ word: entry.pattern, position: entry.position }));
|
|
149
186
|
|
|
150
|
-
|
|
187
|
+
/** The era names (calendar-era) and the fiscal-year names ("FY{y}" of reporting-period-frame) a heading may give a year with. */
|
|
188
|
+
const headingYearWordsOf = (doc: ProseDocument): HeadingYearWords => ({
|
|
189
|
+
eras: (doc.lexicons["calendar-era"] ?? []).map((entry: LexiconEntry) => entry.pattern),
|
|
190
|
+
labels: (doc.lexicons["reporting-period-frame"] ?? []).flatMap((entry: LexiconEntry) =>
|
|
191
|
+
entry.group === "fiscal-year" ? (yearLabelOf(entry.pattern) ?? []) : [],
|
|
192
|
+
),
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const reachOf = (group: string | undefined): MarkerReach => MARKER_REACHES.find((reach) => reach === group) ?? "sentence";
|
|
151
196
|
|
|
152
197
|
const anyYearWordsOf = (doc: ProseDocument): AnyYearWords => ({
|
|
153
198
|
markers: (doc.lexicons[ANY_YEAR_MARKER_LEXICON] ?? []).map((entry: LexiconEntry) => ({ word: entry.pattern, reach: reachOf(entry.group) })),
|
|
@@ -157,7 +202,7 @@ const anyYearWordsOf = (doc: ProseDocument): AnyYearWords => ({
|
|
|
157
202
|
export const dateWithoutYear: Detector = (doc: ProseDocument): Finding[] =>
|
|
158
203
|
doc.structure === undefined
|
|
159
204
|
? []
|
|
160
|
-
: yearGaps(datePoints(doc.structure), doc.source, yearWordsOf(doc), anyYearWordsOf(doc)).map((gap) => ({
|
|
205
|
+
: yearGaps(datePoints(doc.structure, headingYearWordsOf(doc)), doc.source, yearWordsOf(doc), anyYearWordsOf(doc)).map((gap) => ({
|
|
161
206
|
rule: "date-without-year",
|
|
162
207
|
severity: "warning",
|
|
163
208
|
line: 0,
|
|
@@ -199,11 +199,31 @@ const MIN_NAME_CHARS = 4;
|
|
|
199
199
|
/** In English a long name has two words or more (Acme Corporation); one capitalised word is the term's own kind of word. */
|
|
200
200
|
const MIN_NAME_WORDS = 2;
|
|
201
201
|
const LATIN = /\p{Script=Latin}/u;
|
|
202
|
+
const LETTER = /\p{L}/u;
|
|
203
|
+
const JAPANESE = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u;
|
|
202
204
|
|
|
203
205
|
const isNamePart = (token: Token): boolean => NAME_PARTS.has(token.pos) || NAME_MARKS.has(token.surface);
|
|
204
206
|
|
|
207
|
+
/**
|
|
208
|
+
* A label for each of several things or for all of them together ((each, a "Certificate"), (collectively, the "Plans"))
|
|
209
|
+
* names the head of the clause before it (a certificate that represented any share of Common Stock), not its last words.
|
|
210
|
+
*/
|
|
211
|
+
const LABELS_THE_CLAUSE = /^[((](?:each|collectively)\b/iu;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Whether the words make a long name. In English, two words with letters, one of them capitalised: a figure is not a word
|
|
215
|
+
* of a name (as amended on January 26, 2015 (the "Indenture"), a par value of $1.00 (the "Preference Stock")), and lower-case
|
|
216
|
+
* words (with respect thereto) are used in their own sense. A name with Japanese in it (株式会社ABC), four characters or more.
|
|
217
|
+
*/
|
|
218
|
+
const isLongName = (name: string): boolean => {
|
|
219
|
+
const words = name.split(/\s+/u).filter((word) => LETTER.test(word));
|
|
220
|
+
if (words.length === 0 || [...name].length < MIN_NAME_CHARS) return false;
|
|
221
|
+
return !LATIN.test(name) || JAPANESE.test(name) || (words.length >= MIN_NAME_WORDS && words.some((word) => UPPER_START.test(word)));
|
|
222
|
+
};
|
|
223
|
+
|
|
205
224
|
/** The long name written right before an inline definition: the run of name words that ends at its opening bracket. */
|
|
206
225
|
export const nameBefore = (sentence: Sentence, bracket: number): string | undefined => {
|
|
226
|
+
if (LABELS_THE_CLAUSE.test(sentence.text.slice(bracket - sentence.span.start))) return undefined;
|
|
207
227
|
const tokens = (sentence.tokens ?? []).filter((token) => token.span.end <= bracket);
|
|
208
228
|
const firstOfRun = tokens.findLastIndex((token) => !isNamePart(token)) + 1;
|
|
209
229
|
if (isModifier(tokens[firstOfRun - 1])) return undefined;
|
|
@@ -212,16 +232,17 @@ export const nameBefore = (sentence: Sentence, bracket: number): string | undefi
|
|
|
212
232
|
const end = run.at(-1);
|
|
213
233
|
if (first === undefined || end === undefined || bracket - end.span.end > 1) return undefined;
|
|
214
234
|
const name = withoutTrailingMarks(sentence.text.slice(first.span.start - sentence.span.start, end.span.end - sentence.span.start));
|
|
215
|
-
|
|
216
|
-
return [...name].length < MIN_NAME_CHARS || (LATIN.test(name) && words < MIN_NAME_WORDS) ? undefined : name;
|
|
235
|
+
return isLongName(name) ? name : undefined;
|
|
217
236
|
};
|
|
218
237
|
|
|
219
238
|
/**
|
|
220
|
-
* A word that narrows the name before it: an article, an adjective, a verb, or
|
|
221
|
-
* The words then name a kind of thing the definition picks out, not one
|
|
239
|
+
* A word that narrows the name before it: an article, an adjective, a verb, or a possessive (妊娠中の女性従業員, the Beta
|
|
240
|
+
* Preview, 本利用規約, users of Customer's Web site). The words then name a kind of thing the definition picks out, not one
|
|
241
|
+
* party, and are used in their own sense again.
|
|
222
242
|
*/
|
|
223
243
|
const MODIFIERS = new Set(["DET", "ADJ", "VERB", "AUX"]);
|
|
224
|
-
const
|
|
244
|
+
const POSSESSIVES = new Set(["の", "'s", "’s", "'", "’"]);
|
|
245
|
+
const isModifier = (token: Token | undefined): boolean => token !== undefined && (MODIFIERS.has(token.pos) || POSSESSIVES.has(token.surface));
|
|
225
246
|
|
|
226
247
|
const TRAILING_MARKS = new Set([",", ".", " "]);
|
|
227
248
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// The shape of a document's top: whether the lead says anything the title does not, and whether a title or heading
|
|
2
2
|
// runs too long to scan. Pure; both read only the sections, paragraphs and tokens chaff has already built.
|
|
3
3
|
import { newContentMorphemes } from "./content-morphemes.ts";
|
|
4
|
+
import { formValueTokens, isFormBlock } from "./form-line.ts";
|
|
4
5
|
import { trigrams } from "./heading-overlap.ts";
|
|
5
6
|
import { findingAt, writtenHeadings } from "./markup-finding.ts";
|
|
6
7
|
import type { Detector, Finding, LengthUnit, MarkupHeading, Paragraph, ProseDocument, Section } from "../plugin.ts";
|
|
@@ -38,6 +39,13 @@ const leadOf = (doc: ProseDocument): Lead | undefined => {
|
|
|
38
39
|
const lead = title === undefined ? undefined : leadParagraphOf(doc, title);
|
|
39
40
|
if (title === undefined || lead === undefined || title.headingTokens === undefined) return undefined;
|
|
40
41
|
const leadTokens = lead.sentences.flatMap((sentence) => sentence.tokens ?? []);
|
|
42
|
+
// A form or a letter opens with fields or a letterhead, not a lead (Invoice number: INV-2026-0318). A line that only copies the title is still one.
|
|
43
|
+
const leadSource = doc.source.slice(lead.span.start, lead.span.end);
|
|
44
|
+
if (
|
|
45
|
+
isFormBlock(leadSource, lead.span.start, leadTokens) &&
|
|
46
|
+
newContentMorphemes(title.headingTokens, formValueTokens(leadSource, lead.span.start, leadTokens)) > 0
|
|
47
|
+
)
|
|
48
|
+
return undefined;
|
|
41
49
|
const leadText = lead.sentences.map((sentence) => sentence.text).join(" ");
|
|
42
50
|
return { title, lead, fresh: newContentMorphemes(title.headingTokens, leadTokens), echo: echoPercent(title.heading, leadText) };
|
|
43
51
|
};
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
// due-before-issue: the reading half. The issue-date and due-date words come from the language's lexicons
|
|
2
2
|
// (issue-date-label, due-date-label, deadline-passed-word), and so do the words of minutes (minutes-title-word, meeting-date-label,
|
|
3
3
|
// action-section-heading, earlier-section-word, action-due-label, item-done-word) and the other pairs of dates that must come in
|
|
4
|
-
// order (dated-pair-label, date-now-word, and dated-span-label for the words whose line states a period, read up to its end
|
|
5
|
-
//
|
|
4
|
+
// order (dated-pair-label, date-now-word, and dated-span-label for the words whose line states a period, read up to its end,
|
|
5
|
+
// or from its start in the group a dated-span-label entry names;
|
|
6
|
+
// a table whose header names both columns of a pair, from dated-pair-label and the header-only dated-column-label;
|
|
7
|
+
// a signature line giving a pair's later date, from the role words of dated-signer-label;
|
|
8
|
+
// a pair's label naming a version, End of support for 5.0.0 or 3.0.0 のサポート終了日, from dated-pair-version-word);
|
|
6
9
|
// the dates are the structure tree's, and the lines are read with code masked.
|
|
7
10
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
8
11
|
import { actionDueBeforeMeeting, type ActionWords } from "../structure/action-due.ts";
|
|
9
12
|
import { columnDatesOutOfOrder } from "../structure/column-date-order.ts";
|
|
10
|
-
import { pairedDatesOutOfOrder, type OrderDate } from "../structure/labelled-date-order.ts";
|
|
13
|
+
import { pairedDatesOutOfOrder, type OrderDate, type PairedIssue } from "../structure/labelled-date-order.ts";
|
|
11
14
|
import { dueBeforeIssue, type DueWords } from "../structure/due-date.ts";
|
|
12
15
|
import { inDocumentOrder, type StructureIssue } from "../structure/issues.ts";
|
|
13
16
|
import { proseAndTablesOf } from "../table-text.ts";
|
|
14
17
|
import { periodWordsOf } from "./range-words.ts";
|
|
15
18
|
import { quoteAt } from "./structure-tree.ts";
|
|
19
|
+
import type { VersionWords } from "../structure/versioned-label.ts";
|
|
16
20
|
import { readableDates, withReadableDates } from "./readable-dates.ts";
|
|
17
21
|
|
|
18
22
|
/** A record's facts table can sit well below its header date (a listing date above the table holding the move-in date). */
|
|
@@ -35,6 +39,12 @@ const actionWordsOf = (doc: ProseDocument): ActionWords => ({
|
|
|
35
39
|
minutes: patternsOf(doc, "minutes-title-word"),
|
|
36
40
|
});
|
|
37
41
|
|
|
42
|
+
const versionWordsOf = (doc: ProseDocument): VersionWords => {
|
|
43
|
+
const entries = doc.lexicons["dated-pair-version-word"] ?? [];
|
|
44
|
+
const at = (position: "before" | "after"): string[] => entries.filter((entry) => entry.position === position).map((entry) => entry.pattern);
|
|
45
|
+
return { after: at("after"), before: at("before") };
|
|
46
|
+
};
|
|
47
|
+
|
|
38
48
|
const orderAsidesOf = (doc: ProseDocument): string[] => [...patternsOf(doc, "deadline-passed-word"), ...patternsOf(doc, "date-now-word")];
|
|
39
49
|
|
|
40
50
|
const treeDates = (tree: NonNullable<ProseDocument["structure"]>): OrderDate[] =>
|
|
@@ -50,17 +60,26 @@ const findingOf = (doc: ProseDocument, issue: StructureIssue, variant?: string):
|
|
|
50
60
|
...(variant === undefined ? {} : { variant }),
|
|
51
61
|
});
|
|
52
62
|
|
|
63
|
+
const variantOf = (issue: PairedIssue): string => {
|
|
64
|
+
if (issue.fromStart === true) return "period-start";
|
|
65
|
+
return issue.period ? "period" : "order";
|
|
66
|
+
};
|
|
67
|
+
|
|
53
68
|
export const dueDate: Detector = (doc): Finding[] => {
|
|
54
69
|
if (doc.structure === undefined) return [];
|
|
55
70
|
const text = proseAndTablesOf(doc);
|
|
56
71
|
const dates = treeDates(doc.structure);
|
|
57
72
|
const pairs = doc.lexicons["dated-pair-label"] ?? [];
|
|
58
|
-
const
|
|
73
|
+
const spanEntries = doc.lexicons["dated-span-label"] ?? [];
|
|
74
|
+
const spans = { ...periodWordsOf(doc, [...new Set(spanEntries.map((entry) => entry.pattern))]), entries: spanEntries };
|
|
59
75
|
return [
|
|
60
76
|
...dueBeforeIssue(text, dates, wordsOf(doc)).map((issue) => findingOf(doc, issue)),
|
|
61
|
-
...pairedDatesOutOfOrder(text, dates, pairs, orderAsidesOf(doc), MAX_RECORD_LINE_GAP,
|
|
62
|
-
|
|
63
|
-
|
|
77
|
+
...pairedDatesOutOfOrder(text, dates, pairs, orderAsidesOf(doc), MAX_RECORD_LINE_GAP, {
|
|
78
|
+
spans,
|
|
79
|
+
whole: doc.source,
|
|
80
|
+
signers: doc.lexicons["dated-signer-label"] ?? [],
|
|
81
|
+
versions: versionWordsOf(doc),
|
|
82
|
+
}).map((issue) => findingOf(doc, issue, variantOf(issue))),
|
|
64
83
|
...columnDatesOutOfOrder(text, dates, [...pairs, ...(doc.lexicons["dated-column-label"] ?? [])], orderAsidesOf(doc)).map((issue) =>
|
|
65
84
|
findingOf(doc, issue, "order"),
|
|
66
85
|
),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { lengthOf } from "../measure.ts";
|
|
2
2
|
import { isClosed } from "../sentence-shape.ts";
|
|
3
3
|
import { isTitleCase, minorityCase, pageTitleOf } from "./heading-case.ts";
|
|
4
|
+
import { namesWrittenMidSentence } from "./heading-names.ts";
|
|
4
5
|
import type { Detector, Finding, Lexicon, ProseDocument, Section, Sentence, Token } from "../plugin.ts";
|
|
5
6
|
import { entryOpens } from "./lexicon-match.ts";
|
|
6
7
|
|
|
@@ -137,7 +138,10 @@ const headingsOf = (sections: readonly Section[], fixedCase: ReadonlySet<string>
|
|
|
137
138
|
* 見るのは文書の中で揃っているかだけで、少数派のほうを指摘する。題名は指摘しない(minorityCase)。
|
|
138
139
|
*/
|
|
139
140
|
export const titleCaseMix: Detector = (doc, options): Finding[] => {
|
|
140
|
-
const fixedCase = new Set(
|
|
141
|
+
const fixedCase = new Set([
|
|
142
|
+
...FIXED_CASE_LISTS.flatMap((id) => (doc.lexicons[id] ?? []).map((entry) => entry.pattern)),
|
|
143
|
+
...namesWrittenMidSentence(doc.sentences.map((sentence) => sentence.text)),
|
|
144
|
+
]);
|
|
141
145
|
const pageTitle = pageTitleOf(doc.sections);
|
|
142
146
|
const judged = headingsOf(
|
|
143
147
|
doc.sections.filter((section) => section !== pageTitle),
|
|
@@ -2,7 +2,7 @@ import type { Detector, Finding, ProseDocument, StructureNode } from "../plugin.
|
|
|
2
2
|
import { countedFacts, countedPhraseAt, type CountedPhrase } from "../facts/counted-facts.ts";
|
|
3
3
|
import { nameSpans } from "../compare/proper-nouns.ts";
|
|
4
4
|
import { factValues, type FactValue } from "../facts/fact-values.ts";
|
|
5
|
-
import {
|
|
5
|
+
import { attributePhrasesOf, labelledFacts, type Fact, type FactWords } from "../facts/labelled-facts.ts";
|
|
6
6
|
import { tableFacts, type TotalColumns } from "../facts/table-facts.ts";
|
|
7
7
|
import { withCellKeys } from "../facts/cell-keys.ts";
|
|
8
8
|
import { verbQuantityFacts, type VerbQuantityWords } from "../facts/verb-quantity-facts.ts";
|
|
@@ -21,11 +21,13 @@ import { overlapsAny, spanIndex } from "../compare/spans.ts";
|
|
|
21
21
|
import { documentTermConflicts, isTermName, termHomes, type TermWord, type TermWords } from "../facts/document-terms.ts";
|
|
22
22
|
import { termValues, type PlacedWord, type TermValueWords } from "../facts/term-values.ts";
|
|
23
23
|
import { inDocumentOrder } from "../structure/issues.ts";
|
|
24
|
-
import { ageValues
|
|
24
|
+
import { ageValues } from "../facts/age-values.ts";
|
|
25
|
+
import { ageWordsOf } from "./age-words.ts";
|
|
25
26
|
import { qualifiedKeyOf, qualifiedKeys, type QualifierWords } from "../facts/qualified-labels.ts";
|
|
26
27
|
import { rowSentenceFindings } from "./row-sentence-amounts.ts";
|
|
27
28
|
import type { RateWord, RateWords } from "../facts/rate-values.ts";
|
|
28
29
|
import { wholeCountFindings } from "./whole-count-findings.ts";
|
|
30
|
+
import { perUnitsOf, perUnitValues } from "./per-unit-words.ts";
|
|
29
31
|
|
|
30
32
|
const patternsOf = (doc: ProseDocument, id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
|
|
31
33
|
|
|
@@ -51,7 +53,7 @@ export const factWordsOf = (doc: ProseDocument): FactWords => ({
|
|
|
51
53
|
leads: patternsOf(doc, "fact-label-lead"),
|
|
52
54
|
rates: rateWordsOf(doc),
|
|
53
55
|
readings: { verbs: patternsOf(doc, "fact-reading-verb"), gauges: patternsOf(doc, "fact-reading-gauge"), clauses: patternsOf(doc, "fact-reading-clause") },
|
|
54
|
-
attributes: (doc.lexicons["fact-attribute"] ?? [])
|
|
56
|
+
attributes: attributePhrasesOf(doc.lexicons["fact-attribute"] ?? []),
|
|
55
57
|
});
|
|
56
58
|
|
|
57
59
|
const placedWordsOf = (doc: ProseDocument, id: string): PlacedWord[] =>
|
|
@@ -71,6 +73,10 @@ const termValueWordsOf = (doc: ProseDocument): TermValueWords => ({
|
|
|
71
73
|
selves: placedWordsOf(doc, "fact-term-self"),
|
|
72
74
|
starts: placedWordsOf(doc, "fact-term-start"),
|
|
73
75
|
valueEnds: patternsOf(doc, "fact-value-end"),
|
|
76
|
+
restating: patternsOf(doc, "fact-term-restating"),
|
|
77
|
+
frames: patternsOf(doc, "fact-term-frame"),
|
|
78
|
+
conditions: patternsOf(doc, "fact-amount-condition"),
|
|
79
|
+
qualifiers: qualifierWordsOf(doc),
|
|
74
80
|
});
|
|
75
81
|
|
|
76
82
|
const totalColumnsOf = (doc: ProseDocument): TotalColumns => {
|
|
@@ -89,15 +95,6 @@ const durationWordsOf = (doc: ProseDocument): DurationWord[] => [
|
|
|
89
95
|
),
|
|
90
96
|
];
|
|
91
97
|
|
|
92
|
-
const ageWordsAt = (doc: ProseDocument, id: string): AgeWord[] =>
|
|
93
|
-
(doc.lexicons[id] ?? []).map((entry): AgeWord => ({ pattern: entry.pattern, position: entry.position ?? "before" }));
|
|
94
|
-
|
|
95
|
-
const ageWordsOf = (doc: ProseDocument): AgeWords => ({
|
|
96
|
-
marks: ageWordsAt(doc, "fact-age-mark"),
|
|
97
|
-
limits: ageWordsAt(doc, "fact-age-limit"),
|
|
98
|
-
joiners: patternsOf(doc, "fact-age-joiner"),
|
|
99
|
-
});
|
|
100
|
-
|
|
101
98
|
const qualifierWordsOf = (doc: ProseDocument): QualifierWords => ({
|
|
102
99
|
templates: patternsOf(doc, "fact-label-qualifier"),
|
|
103
100
|
determiners: patternsOf(doc, "fact-label-drop"),
|
|
@@ -123,6 +120,7 @@ const withQualifiedKeys = <T extends Fact>(doc: ProseDocument, facts: readonly T
|
|
|
123
120
|
/**
|
|
124
121
|
* 単位の語彙表の量(410 g、1.2 kg)と期間(3 months)と年齢(満70歳まで、aged 20 to 70)も値として読む。木が単位を読まない量は、
|
|
125
122
|
* 数だけでは升や文の値にならない。年齢と重なる期間(30 years old の 30 years)と、期間と重なる量(3 months の 3 m)は読まない。
|
|
123
|
+
* 数量には何あたりか(1kmあたり15円)を付ける。何あたりの値は、それを掛けた金額とは比べない。
|
|
126
124
|
*/
|
|
127
125
|
const readFacts = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
|
|
128
126
|
const tagged = factValues(tree, doc.source, nameSpans(doc));
|
|
@@ -134,7 +132,7 @@ const readFacts = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
|
|
|
134
132
|
durationWordsOf(doc),
|
|
135
133
|
);
|
|
136
134
|
const taken = spanIndex([...ages, ...durations]);
|
|
137
|
-
const values = valuesWith(tree, doc, [...measuredOf(doc).filter((value) => !overlapsAny(taken, value)), ...ages, ...durations]);
|
|
135
|
+
const values = perUnitsOf(doc, valuesWith(tree, doc, [...measuredOf(doc).filter((value) => !overlapsAny(taken, value)), ...ages, ...durations]));
|
|
138
136
|
const terms = termValues(doc.source, values, termValueWordsOf(doc));
|
|
139
137
|
const termed = new Set(terms.map((fact) => fact.value.start));
|
|
140
138
|
const labelled = labelledFacts(doc.source, values, { ...factWordsOf(doc), qualifiers: qualifierWordsOf(doc) }).filter(
|
|
@@ -142,9 +140,10 @@ const readFacts = (doc: ProseDocument, tree: StructureNode): ScopedFact[] => {
|
|
|
142
140
|
);
|
|
143
141
|
const read = new Set([...termed, ...labelled.map((fact) => fact.value.start)]);
|
|
144
142
|
const verbs = verbQuantityFacts(doc.source, values, verbQuantityWordsOf(doc)).filter((fact) => !read.has(fact.value.start));
|
|
145
|
-
const tabled = tableFacts(doc.source, values, totalColumnsOf(doc), countLabelWordsOf(doc.lexicons));
|
|
143
|
+
const tabled = tableFacts(doc.source, values, totalColumnsOf(doc), countLabelWordsOf(doc.lexicons), { columnGroups: true });
|
|
146
144
|
const facts = withQualifiedKeys(doc, [...labelled, ...terms, ...verbs, ...tabled]);
|
|
147
|
-
|
|
145
|
+
const scoped = scopedFacts(facts, tree, doc.source, patternsOf(doc, "summary-heading"), { paragraphHeads: true });
|
|
146
|
+
return withCellKeys(scoped, qualifierWordsOf(doc));
|
|
148
147
|
};
|
|
149
148
|
|
|
150
149
|
/** 文書の名前付きの値。二つの rule が読むので、文書ごとに一度だけ読む。 */
|
|
@@ -263,8 +262,7 @@ const countedPhrasesOf = (doc: ProseDocument): CountedPhrase[] =>
|
|
|
263
262
|
const countedFactsOf = (doc: ProseDocument): ScopedFact[] => {
|
|
264
263
|
const tree = doc.structure;
|
|
265
264
|
if (tree === undefined) return [];
|
|
266
|
-
|
|
267
|
-
return scopedFacts(countedFacts(doc.source, values, countedPhrasesOf(doc)), tree, doc.source, patternsOf(doc, "summary-heading"));
|
|
265
|
+
return scopedFacts(countedFacts(doc.source, perUnitValues(doc, tree), countedPhrasesOf(doc)), tree, doc.source, patternsOf(doc, "summary-heading"));
|
|
268
266
|
};
|
|
269
267
|
|
|
270
268
|
const wordsAt = (doc: ProseDocument, id: string): WordAt[] =>
|
|
@@ -319,8 +317,7 @@ const pairFinding =
|
|
|
319
317
|
const conditionPairFindings = (doc: ProseDocument): Finding[] => {
|
|
320
318
|
const tree = doc.structure;
|
|
321
319
|
if (tree === undefined) return [];
|
|
322
|
-
|
|
323
|
-
return conditionPairConflicts(doc.source, changeSentencesOf(doc, tree), values, changeWordsOf(doc)).map(pairFinding(doc));
|
|
320
|
+
return conditionPairConflicts(doc.source, changeSentencesOf(doc, tree), perUnitValues(doc, tree), changeWordsOf(doc)).map(pairFinding(doc));
|
|
324
321
|
};
|
|
325
322
|
|
|
326
323
|
const eventWordsOf = (doc: ProseDocument): EventWord[] =>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Lines at the top of a form or a letter that are not sentences: a field ("Invoice number: INV-2026-0318",
|
|
2
|
+
// 「見積番号:RF-731852」) or a name standing alone (a letterhead, 「有限会社つばめ野リフォーム」). Pure.
|
|
3
|
+
import { labelLine } from "./number-unit.ts";
|
|
4
|
+
import type { Token } from "../plugin.ts";
|
|
5
|
+
|
|
6
|
+
/** Parts of speech a name is made of: no verb, adjective, determiner or particle. */
|
|
7
|
+
const NAME_POS: ReadonlySet<string> = new Set(["NOUN", "PROPN", "NUM", "PUNCT", "SYM", "X"]);
|
|
8
|
+
/** A value with one of these says something ("Note: this page is a sample."); it is a sentence behind a label. */
|
|
9
|
+
const PREDICATE_POS: ReadonlySet<string> = new Set(["VERB", "AUX"]);
|
|
10
|
+
|
|
11
|
+
const isNameOnly = (tokens: readonly Token[]): boolean => tokens.some((token) => token.pos !== "PUNCT") && tokens.every((token) => NAME_POS.has(token.pos));
|
|
12
|
+
|
|
13
|
+
/** "Label: value" whose value states nothing: a number, a date, a name. */
|
|
14
|
+
const isField = (line: string, start: number, tokens: readonly Token[]): boolean => {
|
|
15
|
+
const field = labelLine(line, start);
|
|
16
|
+
return field !== undefined && !tokens.some((token) => token.span.start >= field.at && PREDICATE_POS.has(token.pos));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type Line = { readonly text: string; readonly start: number };
|
|
20
|
+
|
|
21
|
+
const linesOf = (text: string, start: number): Line[] =>
|
|
22
|
+
text.split("\n").reduce<Line[]>((lines, line) => {
|
|
23
|
+
const last = lines.at(-1);
|
|
24
|
+
return [...lines, { text: line, start: last === undefined ? start : last.start + last.text.length + 1 }];
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
const isFormLine = (line: Line, tokens: readonly Token[]): boolean => {
|
|
28
|
+
const inLine = tokens.filter((token) => token.span.start >= line.start && token.span.start < line.start + line.text.length);
|
|
29
|
+
return isNameOnly(inLine) || isField(line.text, line.start, inLine);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Every line of the block gives a field and its value, or only a name: the top of a form or a letterhead, not a sentence.
|
|
34
|
+
* `start` is where the text starts in the coordinates of the tokens' spans. Without tokens no block is read as a form.
|
|
35
|
+
*/
|
|
36
|
+
export const isFormBlock = (text: string, start: number, tokens: readonly Token[] | undefined): boolean => {
|
|
37
|
+
const lines = linesOf(text, start).filter((line) => line.text.trim() !== "");
|
|
38
|
+
return tokens !== undefined && lines.length > 0 && lines.every((line) => isFormLine(line, tokens));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** What a form block gives: the tokens after each field's label, and every token of a name line. */
|
|
42
|
+
export const formValueTokens = (text: string, start: number, tokens: readonly Token[]): Token[] =>
|
|
43
|
+
linesOf(text, start).flatMap((line) => {
|
|
44
|
+
const field = labelLine(line.text, line.start);
|
|
45
|
+
const from = field?.at ?? line.start;
|
|
46
|
+
return tokens.filter((token) => token.span.start >= from && token.span.start < line.start + line.text.length);
|
|
47
|
+
});
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
// currency-notation's, read with amount-multiplier's words of scale. The profile may give the tax rate a document leaves out.
|
|
5
5
|
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
6
6
|
import { formulaAmountMismatches, type FormulaWords } from "../structure/formula-amount.ts";
|
|
7
|
-
import type { StatedAmount } from "../structure/stated-multiple.ts";
|
|
8
7
|
import type { TaxPriceRole, TaxPriceWord } from "../structure/tax-price.ts";
|
|
9
|
-
import { scaledAmountOf, scaleWordsOf } from "./amount-scale.ts";
|
|
10
|
-
import { amountsIn, formsOf } from "./currency-notation.ts";
|
|
11
8
|
import { proseAndTablesOf } from "../table-text.ts";
|
|
12
9
|
import { quoteAround } from "./quote-around.ts";
|
|
10
|
+
import { statedAmountsOf } from "./stated-amounts.ts";
|
|
13
11
|
|
|
14
12
|
const TAX_ROLES: readonly string[] = ["excluded", "included", "rate"] satisfies readonly TaxPriceRole[];
|
|
15
13
|
const isTaxRole = (group: string | undefined): group is TaxPriceRole => group !== undefined && TAX_ROLES.includes(group);
|
|
@@ -31,23 +29,9 @@ const wordsOf = (doc: ProseDocument): FormulaWords => ({
|
|
|
31
29
|
notIncluded: patternsOf(doc, "formula-amount-word", "not-included"),
|
|
32
30
|
});
|
|
33
31
|
|
|
34
|
-
const amountsOf = (text: string, doc: ProseDocument): StatedAmount[] => {
|
|
35
|
-
const scales = scaleWordsOf(doc);
|
|
36
|
-
return amountsIn(
|
|
37
|
-
text,
|
|
38
|
-
formsOf(doc),
|
|
39
|
-
scales.map((scale) => scale.word),
|
|
40
|
-
).flatMap((amount) => {
|
|
41
|
-
const read = scaledAmountOf(text, amount, scales);
|
|
42
|
-
return read === undefined
|
|
43
|
-
? []
|
|
44
|
-
: [{ offset: read.offset, end: amount.offset + amount.written.length, currency: read.currency, value: read.value, scale: read.unit }];
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
|
|
48
32
|
export const formulaAmount: Detector = (doc): Finding[] => {
|
|
49
33
|
const text = proseAndTablesOf(doc);
|
|
50
|
-
const input = { text, amounts:
|
|
34
|
+
const input = { text, amounts: statedAmountsOf(text, doc), defaultTaxRate: doc.profile?.taxRate };
|
|
51
35
|
return formulaAmountMismatches(input, wordsOf(doc)).map((issue) => ({
|
|
52
36
|
rule: "formula-amount-mismatch",
|
|
53
37
|
severity: "warning",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Section, Sentence } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 問いの印で終わる見出し。後ろに括弧の注記((updated Nov. 14, 2024))が付いてもよい。
|
|
5
|
+
* 「Q1」の札だけでは問いと見ない。四半期(Q1 2024)の見出しと見分けられない。
|
|
6
|
+
*/
|
|
7
|
+
const QUESTION_END = /[??]\s*(?:[((][^()()]*[))])?$/u;
|
|
8
|
+
|
|
9
|
+
export const isQuestionHeading = (heading: string): boolean => QUESTION_END.test(heading.trim());
|
|
10
|
+
|
|
11
|
+
/** 範囲を決めるのに見るのは、見出しと深さと文だけ。 */
|
|
12
|
+
type Heading = Pick<Section, "depth" | "heading" | "sentences">;
|
|
13
|
+
|
|
14
|
+
type Answer = { readonly depth: number; readonly sentences: Sentence[] };
|
|
15
|
+
type Passages = { readonly rest: Sentence[]; readonly answers: Answer[]; readonly open: readonly Answer[] };
|
|
16
|
+
|
|
17
|
+
/** 節は、それを囲む一番内側の問いの答えに入る。同じ深さか浅い見出しが来れば、その問いは閉じている。 */
|
|
18
|
+
const place = (passages: Passages, section: Heading): Passages => {
|
|
19
|
+
const open = passages.open.filter((answer) => answer.depth < section.depth);
|
|
20
|
+
if (isQuestionHeading(section.heading)) {
|
|
21
|
+
const answer = { depth: section.depth, sentences: [...section.sentences] };
|
|
22
|
+
return { ...passages, answers: [...passages.answers, answer], open: [...open, answer] };
|
|
23
|
+
}
|
|
24
|
+
const owner = open.at(-1);
|
|
25
|
+
(owner?.sentences ?? passages.rest).push(...section.sentences);
|
|
26
|
+
return { ...passages, open };
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 言い回しを数える範囲。問いの見出しの下(より深い見出しの「A1」も含む)はそれぞれ一つの答えで、読み手は答えを一つずつ読む。
|
|
31
|
+
* 別の答えで同じ案内(〜をご覧ください)を繰り返しても、書き手が言い直したのではない。問いでない節は、文書全体で一つの範囲。
|
|
32
|
+
*/
|
|
33
|
+
export const gramPassagesOf = (sections: readonly Heading[]): Sentence[][] => {
|
|
34
|
+
const passages = sections.reduce<Passages>(place, { rest: [], answers: [], open: [] });
|
|
35
|
+
return [passages.rest, ...passages.answers.map((answer) => answer.sentences)].filter((sentences) => sentences.length > 0);
|
|
36
|
+
};
|