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
|
@@ -11,7 +11,11 @@ import { amountOf, isExact, shown, type LabelledLine, type NetAmount, type NetCe
|
|
|
11
11
|
export const BALANCE_ROLES = ["opening", "inflow", "outflow", "closing"] as const;
|
|
12
12
|
export type BalanceRole = (typeof BALANCE_ROLES)[number];
|
|
13
13
|
|
|
14
|
-
export type BalanceWords = Pick<NetWords, "magnitudes" | "percentUnits"> & {
|
|
14
|
+
export type BalanceWords = Pick<NetWords, "magnitudes" | "percentUnits"> & {
|
|
15
|
+
readonly labels: Readonly<Record<BalanceRole, readonly string[]>>;
|
|
16
|
+
/** Words that make a label's note the date the balance is taken on (時点, as of): such a note is not a unit. */
|
|
17
|
+
readonly asOf?: readonly string[] | undefined;
|
|
18
|
+
};
|
|
15
19
|
|
|
16
20
|
export type BalanceAmount = NetAmount & { readonly role: BalanceRole };
|
|
17
21
|
|
|
@@ -54,12 +58,46 @@ export const closingMismatch = (amounts: readonly BalanceAmount[], words: Balanc
|
|
|
54
58
|
return { offset: closing.start, values: { written: closing.written, expected: shown(expected, closing, decimals) } };
|
|
55
59
|
};
|
|
56
60
|
|
|
57
|
-
const
|
|
61
|
+
const DIGIT = /\d/u;
|
|
62
|
+
|
|
63
|
+
/** A note naming the date a balance is taken on ((2026年6月30日時点), (as of June 30, 2026)): a date, not a unit. */
|
|
64
|
+
export const isDatedNote = (note: string, asOf: readonly string[]): boolean => {
|
|
65
|
+
const key = keyOf(note);
|
|
66
|
+
return DIGIT.test(key) && asOf.some((word) => key.includes(keyOf(word)));
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const CURRENCY_CODE = /\b[A-Z]{3}\b/u;
|
|
70
|
+
|
|
71
|
+
/** A note that names a scale or a currency besides the date ((thousand yen, as of June 30, 2026)) still names a unit. */
|
|
72
|
+
const namesUnitToo = (note: string, words: BalanceWords): boolean =>
|
|
73
|
+
CURRENCY_CODE.test(note.normalize("NFKC")) || words.magnitudes.some((word) => keyOf(note).includes(keyOf(word)));
|
|
74
|
+
|
|
75
|
+
/** The note of a label that may give its amount a unit: a note that only dates it gives none, so dated and undated rows compare. */
|
|
76
|
+
const unitNoteOf = (label: string, words: BalanceWords): string => {
|
|
77
|
+
const note = noteOf(label);
|
|
78
|
+
return isDatedNote(note, words.asOf ?? []) && !namesUnitToo(note, words) ? "" : note;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** A column heading that is a word with no digit or bracket (ポイント, Points): the unit of the bare numbers under it. */
|
|
82
|
+
const UNIT_HEADING = /^[^\d()[\]()]+$/u;
|
|
83
|
+
const BARE_MARKS = "||";
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A bare number under a heading naming its unit compares with the cells that write the unit out (14,310 under ポイント,
|
|
87
|
+
* against 4,960ポイント). Its marks stay empty, so it is still read as possibly rounded.
|
|
88
|
+
*/
|
|
89
|
+
export const withHeadingUnit = (amount: NetAmount, heading: string | undefined): NetAmount => {
|
|
90
|
+
const unit = keyOf(heading ?? "");
|
|
91
|
+
if (amount.prefix + amount.suffix !== "" || !UNIT_HEADING.test(unit)) return amount;
|
|
92
|
+
return { ...amount, unit: `|${unit}|${amount.unit.slice(BARE_MARKS.length)}` };
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const labelledCells = (labels: readonly NetCell[], values: readonly NetCell[], words: BalanceWords, heading?: string): BalanceAmount[] =>
|
|
58
96
|
labels.flatMap((label, column) => {
|
|
59
97
|
const role = balanceRoleOf(label.text, words);
|
|
60
98
|
const value = values[column];
|
|
61
|
-
const amount = role === undefined || value === undefined ? undefined : amountOf(value.text, value.start,
|
|
62
|
-
return role === undefined || amount === undefined ? [] : [{ ...amount, role }];
|
|
99
|
+
const amount = role === undefined || value === undefined ? undefined : amountOf(value.text, value.start, unitNoteOf(label.text, words), words);
|
|
100
|
+
return role === undefined || amount === undefined ? [] : [{ ...withHeadingUnit(amount, heading), role }];
|
|
63
101
|
});
|
|
64
102
|
|
|
65
103
|
const issuesOf = (scopes: readonly (readonly BalanceAmount[])[], words: BalanceWords): NetIssue[] =>
|
|
@@ -75,14 +113,14 @@ const byColumns = (header: readonly NetCell[], rows: readonly (readonly NetCell[
|
|
|
75
113
|
words,
|
|
76
114
|
);
|
|
77
115
|
|
|
78
|
-
/** A table whose rows are labelled in their first cell: each column after the labels is one scope. */
|
|
79
|
-
const byRows = (rows: readonly (readonly NetCell[])[], words: BalanceWords): NetIssue[] => {
|
|
116
|
+
/** A table whose rows are labelled in their first cell: each column after the labels is one scope, under its heading. */
|
|
117
|
+
const byRows = (header: readonly NetCell[], rows: readonly (readonly NetCell[])[], words: BalanceWords): NetIssue[] => {
|
|
80
118
|
const labelled = rows.filter((row) => row[0] !== undefined && balanceRoleOf(row[0].text, words) !== undefined);
|
|
81
119
|
const width = labelled[0]?.length ?? 0;
|
|
82
120
|
if (labelled.length === 0 || labelled.some((row) => row.length !== width)) return [];
|
|
83
121
|
const columns = Array.from({ length: width - 1 }, (_, index) => index + 1);
|
|
84
122
|
return issuesOf(
|
|
85
|
-
columns.map((column) => labelled.flatMap((row) => labelledCells(row.slice(0, 1), row.slice(column, column + 1), words))),
|
|
123
|
+
columns.map((column) => labelled.flatMap((row) => labelledCells(row.slice(0, 1), row.slice(column, column + 1), words, header[column]?.text))),
|
|
86
124
|
words,
|
|
87
125
|
);
|
|
88
126
|
};
|
|
@@ -92,7 +130,7 @@ const byRows = (rows: readonly (readonly NetCell[])[], words: BalanceWords): Net
|
|
|
92
130
|
* four totals in its header or its first column, so it gives no scope; running-balance-mismatch reads it row by row.
|
|
93
131
|
*/
|
|
94
132
|
export const tableClosingMismatches = (header: readonly NetCell[], rows: readonly (readonly NetCell[])[], words: BalanceWords): NetIssue[] => {
|
|
95
|
-
const issues = [...byColumns(header, rows, words), ...byRows(rows, words)];
|
|
133
|
+
const issues = [...byColumns(header, rows, words), ...byRows(header, rows, words)];
|
|
96
134
|
return issues.filter((issue, index) => issues.findIndex((other) => other.offset === issue.offset) === index);
|
|
97
135
|
};
|
|
98
136
|
|
|
@@ -200,6 +200,27 @@ const echoesLongName = (texts: readonly BodyText[], defined: DefinedTerm, offset
|
|
|
200
200
|
return name.endsWith(defined.term) && sharedTail(name, written) >= defined.term.length + MIN_ECHO;
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
+
/** What may follow a word inside a name up to a definition's bracket: capitalised words (Services Agreement), or kanji and katakana (本サービス利用契約). */
|
|
204
|
+
const NAME_RUN = /^(?:['’]?s)?(?:\s+\p{Lu}[\p{L}\p{N}&.'’-]*)*$|^[\p{Script=Han}\p{Script=Katakana}ー・・]*$/u;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* 別の語を定義する括弧の前の名前の中の現れ(This Services Agreement (this "Agreement") の Services、
|
|
208
|
+
* 本サービス利用契約(以下「本契約」という。)の本サービス)。文書が自分に付けた名前で、後で定義する語の使用ではない。
|
|
209
|
+
*/
|
|
210
|
+
const insideDefiningName = (texts: readonly BodyText[], inline: readonly DefinedTerm[], defined: DefinedTerm, offset: number): boolean => {
|
|
211
|
+
const body = sentenceAt(texts, offset);
|
|
212
|
+
if (body === undefined) return false;
|
|
213
|
+
const from = offset + defined.term.length;
|
|
214
|
+
const bodyEnd = body.start + body.text.length;
|
|
215
|
+
return inline.some(
|
|
216
|
+
(other) =>
|
|
217
|
+
other.term !== defined.term &&
|
|
218
|
+
other.span.start >= from &&
|
|
219
|
+
other.span.start <= bodyEnd &&
|
|
220
|
+
NAME_RUN.test(nameBefore(body.text.slice(from - body.start, other.span.start - body.start))),
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
|
|
203
224
|
const CAPITAL_OR_NON_LATIN = /\p{Lu}|[^\p{Script=Latin}\p{N}\s\p{P}]/u;
|
|
204
225
|
|
|
205
226
|
/**
|
|
@@ -226,6 +247,7 @@ export const usesBeforeDefinition = (
|
|
|
226
247
|
groupsOf(terms)
|
|
227
248
|
.filter((group) => group.first.inline && isDistinctive(group.first.term))
|
|
228
249
|
.flatMap(({ first: defined, spans }) => {
|
|
250
|
+
const inline = terms.filter((term) => term.inline);
|
|
229
251
|
const defining = sentenceAt(texts, defined.span.start)?.start ?? defined.span.start;
|
|
230
252
|
const uses = usesOf(defined.term, texts, spans, "exact", defined.bare === true ? mentioned : NEVER_MENTIONED);
|
|
231
253
|
const first = uses.find(
|
|
@@ -234,7 +256,8 @@ export const usesBeforeDefinition = (
|
|
|
234
256
|
!isTitle(offset) &&
|
|
235
257
|
!continuesInHan(texts, defined.term, offset) &&
|
|
236
258
|
!insideKatakanaName(texts, defined.term, offset) &&
|
|
237
|
-
!echoesLongName(texts, defined, offset)
|
|
259
|
+
!echoesLongName(texts, defined, offset) &&
|
|
260
|
+
!insideDefiningName(texts, inline, defined, offset),
|
|
238
261
|
);
|
|
239
262
|
return first !== undefined && first < defining ? [{ term: defined, offset: first }] : [];
|
|
240
263
|
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { linesOf } from "./lines.ts";
|
|
2
|
+
import { withoutEdgeMarks } from "../facts/trim-marks.ts";
|
|
3
|
+
import { leadingText } from "./total.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether a document says what kind of document it is with one of the words: its title contains one (会議室ご利用御見積書,
|
|
7
|
+
* Meeting Room Quote), or a field's label is one (見積番号:MR-0733, Quote number: Q-1). The title is the first line with
|
|
8
|
+
* text after any front matter, and the first heading; a table row is neither. A label only starting with a word does not
|
|
9
|
+
* count (Withholding tax: on an invoice), nor does a word in a sentence. Width and case are ignored. Pure.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const LABEL_SEPARATOR = /[::|]/u;
|
|
13
|
+
const HEADING = /^[ \t]*#+[ \t]*/u;
|
|
14
|
+
const TABLE_ROW = /^[ \t]*\|/u;
|
|
15
|
+
const FRONT_MATTER_FENCE = /^---[ \t]*$/u;
|
|
16
|
+
|
|
17
|
+
const keyOf = (text: string): string => text.normalize("NFKC").toLowerCase().replace(/\s+/gu, " ").trim();
|
|
18
|
+
|
|
19
|
+
/** The lines after a front matter block (--- … --- at the very top); all of them when there is none. */
|
|
20
|
+
const afterFrontMatter = (lines: readonly string[]): readonly string[] => {
|
|
21
|
+
if (!FRONT_MATTER_FENCE.test(lines[0] ?? "")) return lines;
|
|
22
|
+
const close = lines.findIndex((line, index) => index > 0 && FRONT_MATTER_FENCE.test(line));
|
|
23
|
+
return close === -1 ? lines : lines.slice(close + 1);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const titlesOf = (lines: readonly string[]): string[] => {
|
|
27
|
+
const first = lines.find((line) => line.trim().length > 0 && !TABLE_ROW.test(line));
|
|
28
|
+
const heading = lines.find((line) => HEADING.test(line));
|
|
29
|
+
return [first, heading].flatMap((line) => (line === undefined ? [] : [keyOf(line.replace(HEADING, ""))]));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const labelOf = (line: string): string | undefined => {
|
|
33
|
+
const lead = leadingText(line);
|
|
34
|
+
const separator = LABEL_SEPARATOR.exec(lead);
|
|
35
|
+
return separator === null ? undefined : keyOf(withoutEdgeMarks(lead.slice(0, separator.index)));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const namesDocumentKind = (source: string, words: readonly string[]): boolean => {
|
|
39
|
+
const keys = words.map(keyOf);
|
|
40
|
+
const lines = afterFrontMatter(linesOf(source).map((line) => line.text));
|
|
41
|
+
if (titlesOf(lines).some((title) => keys.some((key) => title.includes(key)))) return true;
|
|
42
|
+
return lines.some((line) => {
|
|
43
|
+
const label = labelOf(line);
|
|
44
|
+
return label !== undefined && keys.includes(label);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { codeFences } from "../detectors/code-fences.ts";
|
|
2
|
+
|
|
3
|
+
const FENCE_MARK = /`{3}|~{3}/u;
|
|
4
|
+
|
|
5
|
+
const NONE: ReadonlySet<number> = new Set();
|
|
6
|
+
|
|
7
|
+
/** The index of the line holding an offset of the joined lines. */
|
|
8
|
+
const lineIndexAt = (starts: readonly number[], offset: number): number => starts.findLastIndex((start) => start <= offset);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The indexes of the lines of fenced code blocks (``` or ~~~), the fences included. A table or a list written in one is an
|
|
12
|
+
* example, not the document's own values. The blocks are the ones the Markdown parser reads (code-fences.ts): a fence in
|
|
13
|
+
* a list item is one, a line indented as code or a fence in a quotation is not, and an unclosed fence runs to the end.
|
|
14
|
+
*/
|
|
15
|
+
export const fencedLineIndexes = (texts: readonly string[]): ReadonlySet<number> => {
|
|
16
|
+
if (!texts.some((text) => FENCE_MARK.test(text))) return NONE;
|
|
17
|
+
const starts: number[] = [];
|
|
18
|
+
texts.reduce((start, text) => {
|
|
19
|
+
starts.push(start);
|
|
20
|
+
return start + text.length + 1;
|
|
21
|
+
}, 0);
|
|
22
|
+
const fenced = new Set<number>();
|
|
23
|
+
codeFences(texts.join("\n")).forEach((fence) => {
|
|
24
|
+
const last = lineIndexAt(starts, Math.max(fence.start, fence.end - 1));
|
|
25
|
+
for (let index = lineIndexAt(starts, fence.start); index <= last; index += 1) fenced.add(index);
|
|
26
|
+
});
|
|
27
|
+
return fenced;
|
|
28
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readMarkdown } from "../markdown-read.ts";
|
|
2
|
+
import { spanOf, type MarkdownNode } from "../markdown-node.ts";
|
|
3
|
+
import type { Span } from "../plugin.ts";
|
|
4
|
+
|
|
5
|
+
const COMMENT = /<!--[\s\S]*?(?:-->|$)/gu;
|
|
6
|
+
const INLINE_CONTAINERS = new Set(["paragraph", "heading", "tableCell"]);
|
|
7
|
+
const ENTITY = /&(?:#\d+|#x[\da-f]+|[a-z]+\d*);/giu;
|
|
8
|
+
|
|
9
|
+
type TagScan = { readonly kept: string[]; inTag: boolean; quote: string | undefined };
|
|
10
|
+
|
|
11
|
+
/** Reads one character of HTML: text outside a tag is kept. A quoted attribute may hold `>` (`<div title=">">`). */
|
|
12
|
+
const scanned = (scan: TagScan, char: string): TagScan => {
|
|
13
|
+
if (!scan.inTag) {
|
|
14
|
+
if (char === "<") scan.inTag = true;
|
|
15
|
+
else scan.kept.push(char);
|
|
16
|
+
} else if (scan.quote !== undefined) {
|
|
17
|
+
if (char === scan.quote) scan.quote = undefined;
|
|
18
|
+
} else if (char === '"' || char === "'") scan.quote = char;
|
|
19
|
+
else if (char === ">") scan.inTag = false;
|
|
20
|
+
return scan;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const withoutTags = (html: string): string => [...html].reduce<TagScan>(scanned, { kept: [], inTag: false, quote: undefined }).kept.join("");
|
|
24
|
+
|
|
25
|
+
/** What an HTML block shows the reader: its text without tags, comments and character references such as ` `. */
|
|
26
|
+
const showsText = (html: string): boolean => withoutTags(html.replace(COMMENT, "")).replace(ENTITY, "").trim() !== "";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Markdown's HTML blocks that show text. CommonMark runs a block that starts with a tag alone on its line (`<br/>`) to
|
|
30
|
+
* the next blank line, so a `第11条` written right under it is raw HTML: the reader sees it, chaff's structure does not.
|
|
31
|
+
* Only blocks are returned; an inline tag inside a paragraph (`text<br/>`) leaves the text beside it readable.
|
|
32
|
+
*/
|
|
33
|
+
export const htmlTextBlocks = (source: string): Span[] => {
|
|
34
|
+
if (!source.includes("<")) return [];
|
|
35
|
+
const blocks: Span[] = [];
|
|
36
|
+
const visit = (node: MarkdownNode, inParagraph: boolean): void => {
|
|
37
|
+
if (node.type === "html" && !inParagraph && showsText(node.value ?? "")) {
|
|
38
|
+
const span = spanOf(node);
|
|
39
|
+
if (span !== undefined) blocks.push(span);
|
|
40
|
+
}
|
|
41
|
+
(node.children ?? []).forEach((child) => visit(child, inParagraph || INLINE_CONTAINERS.has(node.type)));
|
|
42
|
+
};
|
|
43
|
+
visit(readMarkdown(source).root, false);
|
|
44
|
+
return blocks.toSorted((left, right) => left.start - right.start);
|
|
45
|
+
};
|
package/src/structure/issues.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { StructureNode } from "../plugin.ts";
|
|
2
|
+
import { writtenReading } from "./written-resolve.ts";
|
|
3
|
+
import { namedTargets, pointsToNamedSection } from "./section-names.ts";
|
|
2
4
|
import { listedTags } from "./listed-tags.ts";
|
|
3
5
|
import { namesAbsentUnit } from "./unit-word.ts";
|
|
6
|
+
import { isListedParagraph, listedParagraphsByArticle } from "./listed-paragraph.ts";
|
|
7
|
+
import { referencesInCitedDocuments } from "./cited-document-section.ts";
|
|
4
8
|
|
|
5
9
|
// 木だけで決まる誤り。参照先が無い、番号が飛ぶ・重なる、同じ語を二度定義する。
|
|
6
10
|
// 意味の食い違いは判定しない。書いてあることから機械で決まるものだけを出す。
|
|
@@ -111,7 +115,7 @@ const numbering = (node: StructureNode): unknown => node.attrs["numbering"];
|
|
|
111
115
|
* 参照の番地が木に無い。他の文書の名前が付いた参照(民法第709条、Section 9 of the Master Agreement)は引かない。
|
|
112
116
|
* 条を 1 つも持たない文書も見ない。他の文書を指しているだけかもしれない。
|
|
113
117
|
*/
|
|
114
|
-
export const danglingReferences = (tree: StructureNode, source: string): StructureIssue[] => {
|
|
118
|
+
export const danglingReferences = (tree: StructureNode, source: string, nameNouns: readonly string[] = []): StructureIssue[] => {
|
|
115
119
|
const nodes = inDocumentOrder(tree);
|
|
116
120
|
// 参照は条を指す。条を一つも持たない文書(契約書に付ける承諾書のひな形など)の「契約書第6条」は、別の文書の条。
|
|
117
121
|
if (!nodes.some((node) => node.kind === "article")) return [];
|
|
@@ -127,10 +131,21 @@ export const danglingReferences = (tree: StructureNode, source: string): Structu
|
|
|
127
131
|
const articleLabels = nodes.filter((node) => node.kind === "article").map((node) => textOf(node, "label"));
|
|
128
132
|
const chapters = chaptersOf(nodes);
|
|
129
133
|
const elsewhere = elsewhereReferences(nodes, source);
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
const quoted = referencesInCitedDocuments(tree);
|
|
135
|
+
const references = nodes.filter((node) => node.kind === "reference");
|
|
136
|
+
const named = namedTargets(references, source, nameNouns);
|
|
137
|
+
const unresolved = references
|
|
138
|
+
.filter((node) => !citesOther(node) && !otherNumbering(node) && !pointsToNamedSection(node, named))
|
|
132
139
|
.filter((node) => !namesAbsentUnit(node, articleLabels) && !elsewhere.has(node))
|
|
133
|
-
.filter((node) => !resolves(node, addresses, chapters))
|
|
140
|
+
.filter((node) => !quoted.has(node) && !resolves(node, addresses, chapters));
|
|
141
|
+
// 規程は条の下の項を箇条書き(「1. 」「2.」)で書くことがあり、木はそれを項として読まない。条の本文は、要るときに一度だけ読む。
|
|
142
|
+
const listed = unresolved.length === 0 ? new Map() : listedParagraphsByArticle(nodes, source);
|
|
143
|
+
// 平文の契約は見出しを「9. Indemnification.」と本文の形で書き、木はそれを番地にしない。残った参照があるときだけ読む。
|
|
144
|
+
const written = unresolved.length === 0 ? undefined : writtenReading(nodes, source);
|
|
145
|
+
const writtenAddresses = new Set(written?.addresses);
|
|
146
|
+
return unresolved
|
|
147
|
+
.filter((node) => !isListedParagraph(textOf(node, "target"), listed))
|
|
148
|
+
.filter((node) => !writtenAddresses.has(textOf(node, "target")) && written?.subdivision(node) !== true)
|
|
134
149
|
.map((node) => ({ offset: node.span.start, values: { label: textOf(node, "label"), target: textOf(node, "target") } }));
|
|
135
150
|
};
|
|
136
151
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { namesDocumentKind } from "./document-context.ts";
|
|
1
2
|
import type { DatedPoint } from "./due-date.ts";
|
|
2
3
|
import type { StructureIssue } from "./issues.ts";
|
|
3
4
|
import type { Line } from "./lines.ts";
|
|
4
5
|
import { labelPairsOf, pointsOutOfOrder, type OrderLabel, type PairWords, type PointOf } from "./labelled-order.ts";
|
|
5
6
|
import { TABLE_ROW } from "./runs.ts";
|
|
7
|
+
import type { VersionWords } from "./versioned-label.ts";
|
|
8
|
+
import { isSignedDateLine } from "./signed-date-line.ts";
|
|
6
9
|
import { statedPeriod, type DateMention, type PeriodWords } from "./stated-period.ts";
|
|
7
10
|
|
|
8
11
|
/**
|
|
@@ -10,11 +13,13 @@ import { statedPeriod, type DateMention, type PeriodWords } from "./stated-perio
|
|
|
10
13
|
* earlier-date word and one starting with a later-date word, each with one full date on it. A later date before the
|
|
11
14
|
* first earlier date, and written near it, is out of order. A line with a passed word (期限切れ, overdue) reports on a
|
|
12
15
|
* date rather than setting one and is not read. A span word (対象期間, Reporting period) labels a period, and the
|
|
13
|
-
* period's end is its date. Pure.
|
|
16
|
+
* period's end is its date, or its start for a span word in fromStart. Pure.
|
|
14
17
|
*/
|
|
15
18
|
export type DateOrderWords = PairWords & {
|
|
16
19
|
/** The words whose line states a period rather than one date (labels), with the range signs and names to read it. */
|
|
17
20
|
readonly spans?: PeriodWords | undefined;
|
|
21
|
+
/** The span words whose period's start is the date: the later date may fall anywhere in the period (a pay date in its pay period). */
|
|
22
|
+
readonly fromStart?: readonly string[] | undefined;
|
|
18
23
|
};
|
|
19
24
|
|
|
20
25
|
/** A date from the tree; end is where its text ends, needed only to read a period. */
|
|
@@ -30,12 +35,14 @@ const FULL_DATE = /^\d{4}-\d{2}-\d{2}$/u;
|
|
|
30
35
|
const mentionsOf = (dates: readonly OrderDate[]): DateMention[] => dates.flatMap((date) => (date.end === undefined ? [] : [{ ...date, end: date.end }]));
|
|
31
36
|
|
|
32
37
|
/**
|
|
33
|
-
* The end of the period a span word's line states (対象期間:2026年4月1日〜9月30日
|
|
34
|
-
* A period without a year, or a line that states no period, gives undefined. tableOf gives
|
|
35
|
-
* (| 対象期間 | 2026年4月1日〜9月30日 |), read when the row is the table's only row labelled
|
|
36
|
-
* both Reporting period and Period covered rows lists periods. A row's label cell is the
|
|
38
|
+
* The start or the end of the period a span word's line states (対象期間:2026年4月1日〜9月30日 starts 2026-04-01 and
|
|
39
|
+
* ends 2026-09-30), with its year. A period without a year, or a line that states no period, gives undefined. tableOf gives
|
|
40
|
+
* the table the line is a row of (| 対象期間 | 2026年4月1日〜9月30日 |), read when the row is the table's only row labelled
|
|
41
|
+
* with any span word: a table with both Reporting period and Period covered rows lists periods. A row's label cell is the
|
|
42
|
+
* span word itself, so all of them are passed.
|
|
37
43
|
*/
|
|
38
|
-
|
|
44
|
+
const periodBoundOf = (
|
|
45
|
+
bound: "start" | "end",
|
|
39
46
|
line: Line,
|
|
40
47
|
label: string,
|
|
41
48
|
dates: readonly OrderDate[],
|
|
@@ -44,24 +51,54 @@ export const periodEndOf = (
|
|
|
44
51
|
): DatedPoint | undefined => {
|
|
45
52
|
const labels = TABLE_ROW.test(line.text) ? spans.labels : [label];
|
|
46
53
|
const period = statedPeriod(line.text, line.start, mentionsOf(dates), { ...spans, labels }, tableOf);
|
|
47
|
-
return period === undefined || !FULL_DATE.test(period
|
|
54
|
+
return period === undefined || !FULL_DATE.test(period[bound]) ? undefined : { offset: line.start, value: period[bound] };
|
|
48
55
|
};
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
/** The end of the period a span word's line states. */
|
|
58
|
+
export const periodEndOf = (
|
|
59
|
+
line: Line,
|
|
60
|
+
label: string,
|
|
61
|
+
dates: readonly OrderDate[],
|
|
62
|
+
spans: PeriodWords,
|
|
63
|
+
tableOf?: () => readonly string[],
|
|
64
|
+
): DatedPoint | undefined => periodBoundOf("end", line, label, dates, spans, tableOf);
|
|
65
|
+
|
|
66
|
+
/** The start of the period a span word's line states. */
|
|
67
|
+
export const periodStartOf = (
|
|
68
|
+
line: Line,
|
|
69
|
+
label: string,
|
|
70
|
+
dates: readonly OrderDate[],
|
|
71
|
+
spans: PeriodWords,
|
|
72
|
+
tableOf?: () => readonly string[],
|
|
73
|
+
): DatedPoint | undefined => periodBoundOf("start", line, label, dates, spans, tableOf);
|
|
74
|
+
|
|
75
|
+
const oneDateOf = (line: Line, dates: readonly OrderDate[]): OrderDate | undefined => {
|
|
51
76
|
const end = line.start + line.text.length;
|
|
52
77
|
const onLine = dates.filter((date) => date.offset >= line.start && date.offset <= end && FULL_DATE.test(date.value));
|
|
53
78
|
return onLine.length === 1 ? onLine[0] : undefined;
|
|
54
79
|
};
|
|
55
80
|
|
|
81
|
+
/** The one date on a signature line (2026年4月12日 会計監査 戸川 隆): the line holds that date, the role and a name, nothing else. */
|
|
82
|
+
const signedDateOf = (line: Line, role: string, dates: readonly OrderDate[]): DatedPoint | undefined => {
|
|
83
|
+
const date = oneDateOf(line, dates);
|
|
84
|
+
if (date?.end === undefined) return undefined;
|
|
85
|
+
const span = { start: date.offset - line.start, end: date.end - line.start };
|
|
86
|
+
return isSignedDateLine(line.text, role, span) ? date : undefined;
|
|
87
|
+
};
|
|
88
|
+
|
|
56
89
|
const dateOf =
|
|
57
|
-
(dates: readonly OrderDate[], spans: PeriodWords | undefined): PointOf =>
|
|
90
|
+
(dates: readonly OrderDate[], spans: PeriodWords | undefined, fromStart: readonly string[], signers: readonly string[]): PointOf =>
|
|
58
91
|
(line, label, tableOf) => {
|
|
92
|
+
if (signers.includes(label)) {
|
|
93
|
+
const date = signedDateOf(line, label, dates);
|
|
94
|
+
return date === undefined ? undefined : { point: date, span: false };
|
|
95
|
+
}
|
|
59
96
|
if (spans === undefined || !spans.labels.includes(label)) {
|
|
60
97
|
const date = oneDateOf(line, dates);
|
|
61
98
|
return date === undefined ? undefined : { point: date, span: false };
|
|
62
99
|
}
|
|
63
|
-
const
|
|
64
|
-
return
|
|
100
|
+
const bound = fromStart.includes(label) ? periodStartOf(line, label, dates, spans, tableOf) : periodEndOf(line, label, dates, spans, tableOf);
|
|
101
|
+
return bound === undefined ? undefined : { point: bound, span: true };
|
|
65
102
|
};
|
|
66
103
|
|
|
67
104
|
/**
|
|
@@ -70,18 +107,61 @@ const dateOf =
|
|
|
70
107
|
* record's. A later date written once (an issue date below the records) belongs to the whole document and keeps the first.
|
|
71
108
|
*/
|
|
72
109
|
export const datesOutOfOrder = (source: string, dates: readonly OrderDate[], words: DateOrderWords): OutOfOrder[] =>
|
|
73
|
-
pointsOutOfOrder(source, words, dateOf(dates, words.spans)).map(({ earlier, later }) => ({
|
|
110
|
+
pointsOutOfOrder(source, words, dateOf(dates, words.spans, words.fromStart ?? [], words.signers ?? [])).map(({ earlier, later }) => ({
|
|
74
111
|
earlier: { label: earlier.label, date: earlier.point, line: earlier.line, span: earlier.span },
|
|
75
112
|
later: { label: later.label, date: later.point, line: later.line, span: later.span },
|
|
76
113
|
}));
|
|
77
114
|
|
|
78
|
-
/** An out-of-order pair; period is set when the earlier date is
|
|
79
|
-
export type PairedIssue = StructureIssue & { readonly period: boolean };
|
|
115
|
+
/** An out-of-order pair; period is set when the earlier date is a stated period's end, or its start when fromStart is set. */
|
|
116
|
+
export type PairedIssue = StructureIssue & { readonly period: boolean; readonly fromStart?: boolean | undefined };
|
|
117
|
+
|
|
118
|
+
/** The span words with the range signs and names to read them, and the dated-span lexicon's entries they come from. */
|
|
119
|
+
export type PairSpans = PeriodWords & { readonly entries: readonly OrderLabel[] };
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The span words a dated-span lexicon reads by the period's start in one group: its entries naming that group with
|
|
123
|
+
* position before. An entry without a group is read by the period's end in every group.
|
|
124
|
+
*/
|
|
125
|
+
export const spanStartsOf = (spanLabels: readonly OrderLabel[], group: string): string[] =>
|
|
126
|
+
spanLabels.filter((label) => label.group === group && label.position === "before").map((label) => label.pattern);
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The span words to read periods with, the whole document (its headings too) to read the words naming its kind, and the
|
|
130
|
+
* role words whose signature line gives a group's later date (a dated-signer lexicon's entries with position after).
|
|
131
|
+
*/
|
|
132
|
+
export type PairedReading = {
|
|
133
|
+
readonly spans?: PairSpans | undefined;
|
|
134
|
+
readonly whole?: string | undefined;
|
|
135
|
+
readonly signers?: readonly OrderLabel[] | undefined;
|
|
136
|
+
/** The words that join a version to a label (End of support for 5.0.0, 3.0.0 のサポート終了日). */
|
|
137
|
+
readonly versions?: VersionWords | undefined;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const signersOf = (signers: readonly OrderLabel[], group: string): string[] =>
|
|
141
|
+
signers.filter((label) => label.group === group && label.position === "after").map((label) => label.pattern);
|
|
142
|
+
|
|
143
|
+
/** The words a group names its kind of document with: the group's entries without a position (見積, Quote). */
|
|
144
|
+
const contextOf = (labels: readonly OrderLabel[], group: string): string[] =>
|
|
145
|
+
labels.filter((label) => label.group === group && label.position === undefined).map((label) => label.pattern);
|
|
146
|
+
|
|
147
|
+
const sameDates = (one: PairedIssue, other: PairedIssue): boolean =>
|
|
148
|
+
one.offset === other.offset && one.values["later"] === other.values["later"] && one.values["earlier"] === other.values["earlier"];
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The issues, two groups comparing one later date with the same earlier date reported once (a leaver's issue date before
|
|
152
|
+
* both the leaving date and the end of the period covered, which is the same day). Different earlier dates are kept.
|
|
153
|
+
*/
|
|
154
|
+
const withoutRepeats = (issues: readonly PairedIssue[]): PairedIssue[] =>
|
|
155
|
+
issues.filter((issue, index) => issues.findIndex((other) => sameDates(other, issue)) === index);
|
|
80
156
|
|
|
81
157
|
/**
|
|
82
158
|
* Every pair of a dated-pair lexicon: the entries of one group with position before label the earlier date, those with
|
|
83
159
|
* position after the later one. The values name both labels, so the message can quote them. The issue is on whichever
|
|
84
160
|
* of the two dates is written second: a reader meets the contradiction there (a cancellation deadline below check-in).
|
|
161
|
+
* A group with entries without a position is read only in a document whose title or a field's label names one of them
|
|
162
|
+
* (namesDocumentKind, over reading.whole: the document with its headings, which source blanks out): ご利用日 before 有効期限 is a
|
|
163
|
+
* quote's mistake and a points statement's normal order.
|
|
164
|
+
* reading.spans.entries are the dated-span lexicon's entries, for the span words a group reads by the period's start.
|
|
85
165
|
*/
|
|
86
166
|
export const pairedDatesOutOfOrder = (
|
|
87
167
|
source: string,
|
|
@@ -89,12 +169,19 @@ export const pairedDatesOutOfOrder = (
|
|
|
89
169
|
labels: readonly OrderLabel[],
|
|
90
170
|
passed: readonly string[],
|
|
91
171
|
maxLineGap: number,
|
|
92
|
-
spans
|
|
172
|
+
{ spans, whole = source, signers = [], versions }: PairedReading = {},
|
|
93
173
|
): PairedIssue[] =>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
174
|
+
withoutRepeats(
|
|
175
|
+
labelPairsOf(labels).flatMap((pair) => {
|
|
176
|
+
const context = contextOf(labels, pair.group);
|
|
177
|
+
if (context.length > 0 && !namesDocumentKind(whole, context)) return [];
|
|
178
|
+
const fromStart = spanStartsOf(spans?.entries ?? [], pair.group);
|
|
179
|
+
const words = { ...pair, passed, maxLineGap, spans, fromStart, signers: signersOf(signers, pair.group), versions };
|
|
180
|
+
return datesOutOfOrder(source, dates, words).map(({ earlier, later }) => ({
|
|
181
|
+
offset: Math.max(later.date.offset, earlier.date.offset),
|
|
182
|
+
values: { later: later.date.value, earlier: earlier.date.value, later_label: later.label, earlier_label: earlier.label },
|
|
183
|
+
period: earlier.span,
|
|
184
|
+
...(earlier.span && fromStart.includes(earlier.label) ? { fromStart: true } : {}),
|
|
185
|
+
}));
|
|
186
|
+
}),
|
|
100
187
|
);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { linesOf, type Line } from "./lines.ts";
|
|
2
2
|
import { tableAround } from "./key-value-row.ts";
|
|
3
|
+
import { signerRoleOf } from "./signed-date-line.ts";
|
|
3
4
|
import { isTotalLabel } from "./total.ts";
|
|
5
|
+
import { withoutLabelVersion, type VersionWords } from "./versioned-label.ts";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Two labelled points that must come in order: a line (or a list item, or a table's first column) starting with an
|
|
@@ -18,6 +20,13 @@ export type PairWords = {
|
|
|
18
20
|
readonly passed: readonly string[];
|
|
19
21
|
/** How many lines from the earlier point a later point may be and still be read as the same record's. */
|
|
20
22
|
readonly maxLineGap: number;
|
|
23
|
+
/**
|
|
24
|
+
* Role words whose line, when no label heads it, may give a later point (a signature: 2026年4月12日 会計監査 戸川 隆).
|
|
25
|
+
* pointOf decides whether the line is one. A signature closes the whole document, so it is read at any distance.
|
|
26
|
+
*/
|
|
27
|
+
readonly signers?: readonly string[] | undefined;
|
|
28
|
+
/** The words that join a version to a label (End of support for 5.0.0, 3.0.0 のサポート終了日). */
|
|
29
|
+
readonly versions?: VersionWords | undefined;
|
|
21
30
|
};
|
|
22
31
|
|
|
23
32
|
/** A labelled point: the word that labels it, as the lexicon writes it. span is set when the point ends a stated period. */
|
|
@@ -28,17 +37,30 @@ export type PointPair = { readonly earlier: LabelledPoint; readonly later: Label
|
|
|
28
37
|
/** The point a labelled line gives, or undefined when it gives none. tableOf gives the table the line is a row of. */
|
|
29
38
|
export type PointOf = (line: Line, label: string, tableOf: () => readonly string[]) => Pick<LabelledPoint, "point" | "span"> | undefined;
|
|
30
39
|
|
|
31
|
-
type Read = LabelledPoint & { readonly kind: "earlier" | "later" };
|
|
40
|
+
type Read = LabelledPoint & { readonly kind: "earlier" | "later"; readonly signed?: boolean | undefined };
|
|
41
|
+
|
|
42
|
+
const isVersionedLabel = (text: string, word: string, versions: VersionWords | undefined): boolean => {
|
|
43
|
+
const bare = versions === undefined ? undefined : withoutLabelVersion(text, word, versions);
|
|
44
|
+
return bare !== undefined && isTotalLabel(bare, [word]);
|
|
45
|
+
};
|
|
32
46
|
|
|
33
|
-
const labelOf = (text: string, words: readonly string[]): string | undefined =>
|
|
47
|
+
const labelOf = (text: string, words: readonly string[], versions?: VersionWords): string | undefined =>
|
|
48
|
+
words.find((word) => isTotalLabel(text, [word]) || isVersionedLabel(text, word, versions));
|
|
34
49
|
|
|
35
|
-
const
|
|
36
|
-
const
|
|
50
|
+
const signerOf = (text: string, words: PairWords): Pick<Read, "kind" | "label" | "signed"> | undefined => {
|
|
51
|
+
const role = signerRoleOf(text, words.signers ?? []);
|
|
52
|
+
return role === undefined ? undefined : { kind: "later", label: role, signed: true };
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const kindOf = (text: string, words: PairWords): Pick<Read, "kind" | "label" | "signed"> | undefined => {
|
|
56
|
+
const earlier = labelOf(text, words.earlier, words.versions);
|
|
37
57
|
if (earlier !== undefined) return { kind: "earlier", label: earlier };
|
|
38
|
-
const later = labelOf(text, words.later);
|
|
39
|
-
return later === undefined ?
|
|
58
|
+
const later = labelOf(text, words.later, words.versions);
|
|
59
|
+
return later === undefined ? signerOf(text, words) : { kind: "later", label: later };
|
|
40
60
|
};
|
|
41
61
|
|
|
62
|
+
const withinGap = (later: Read, earlier: Read, maxLineGap: number): boolean => later.signed === true || Math.abs(later.line - earlier.line) < maxLineGap;
|
|
63
|
+
|
|
42
64
|
const labelledPoints = (source: string, words: PairWords, pointOf: PointOf): Read[] => {
|
|
43
65
|
const lines = linesOf(source);
|
|
44
66
|
const texts = lines.map((line) => line.text);
|
|
@@ -75,7 +97,7 @@ export type PairReading = {
|
|
|
75
97
|
const nearestOutOfOrder = (labelled: readonly Read[], earliers: readonly Read[], maxLineGap: number): PointPair[] =>
|
|
76
98
|
labelled.flatMap((later) => {
|
|
77
99
|
const earlier = later.kind === "later" ? nearestEarlier(earliers, later) : undefined;
|
|
78
|
-
return earlier !== undefined && later.point.value < earlier.point.value &&
|
|
100
|
+
return earlier !== undefined && later.point.value < earlier.point.value && withinGap(later, earlier, maxLineGap) ? [{ earlier, later }] : [];
|
|
79
101
|
});
|
|
80
102
|
|
|
81
103
|
/**
|
|
@@ -89,10 +111,7 @@ const firstOutOfOrder = (labelled: readonly Read[], earliers: readonly Read[], m
|
|
|
89
111
|
const records = labelled.filter((entry) => entry.kind === "later").length > 1;
|
|
90
112
|
const beforeOwnRecord = (later: Read): boolean => !records || later.point.value < (nearestEarlier(earliers, later) ?? earlier).point.value;
|
|
91
113
|
return labelled
|
|
92
|
-
.filter(
|
|
93
|
-
(entry) =>
|
|
94
|
-
entry.kind === "later" && entry.point.value < earlier.point.value && Math.abs(entry.line - earlier.line) < maxLineGap && beforeOwnRecord(entry),
|
|
95
|
-
)
|
|
114
|
+
.filter((entry) => entry.kind === "later" && entry.point.value < earlier.point.value && withinGap(entry, earlier, maxLineGap) && beforeOwnRecord(entry))
|
|
96
115
|
.map((later) => ({ earlier, later }));
|
|
97
116
|
};
|
|
98
117
|
|
|
@@ -108,8 +127,8 @@ export const pointsOutOfOrder = (source: string, words: PairWords, pointOf: Poin
|
|
|
108
127
|
/** A lexicon entry naming its pair (group) and its side: before for the earlier point, after for the later one. */
|
|
109
128
|
export type OrderLabel = { readonly pattern: string; readonly group?: string | undefined; readonly position?: "before" | "after" | undefined };
|
|
110
129
|
|
|
111
|
-
/** One pair of a lexicon: the words of
|
|
112
|
-
export type LabelPair = { readonly earlier: string[]; readonly later: string[] };
|
|
130
|
+
/** One pair of a lexicon: its group, the words of the group that label the earlier point, and those that label the later one. */
|
|
131
|
+
export type LabelPair = { readonly group: string; readonly earlier: string[]; readonly later: string[] };
|
|
113
132
|
|
|
114
133
|
const sideOf = (labels: readonly OrderLabel[], group: string, position: "before" | "after"): string[] =>
|
|
115
134
|
labels.filter((label) => label.group === group && label.position === position).map((label) => label.pattern);
|
|
@@ -117,6 +136,7 @@ const sideOf = (labels: readonly OrderLabel[], group: string, position: "before"
|
|
|
117
136
|
/** Every pair a lexicon names, in the order its groups first appear. */
|
|
118
137
|
export const labelPairsOf = (labels: readonly OrderLabel[]): LabelPair[] =>
|
|
119
138
|
[...new Set(labels.flatMap((label) => (label.group === undefined ? [] : [label.group])))].map((group) => ({
|
|
139
|
+
group,
|
|
120
140
|
earlier: sideOf(labels, group, "before"),
|
|
121
141
|
later: sideOf(labels, group, "after"),
|
|
122
142
|
}));
|
|
@@ -3,7 +3,8 @@ import { linesOf, type Line } from "./lines.ts";
|
|
|
3
3
|
import { escapeRegExp } from "../orthography.ts";
|
|
4
4
|
import { roundedMatches } from "./tax.ts";
|
|
5
5
|
import { hasSuperscriptPower } from "../facts/superscript-power.ts";
|
|
6
|
-
import { cellNumber, cellsOf, plain, shownExpected,
|
|
6
|
+
import { cellNumber, cellsOf, plain, shownExpected, type Cell, type CellNumber } from "./line-amount.ts";
|
|
7
|
+
import { tablesOf } from "../facts/table-facts.ts";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* line-amount-mismatch, the product written in an item cell: 「| 会費(3,000円×24名) | 72,000円 |」,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StructureIssue } from "./issues.ts";
|
|
2
2
|
import { linesOf, type Line } from "./lines.ts";
|
|
3
3
|
import { CELL_SEPARATOR } from "./bare-numbers.ts";
|
|
4
|
-
import {
|
|
4
|
+
import { tablesOf } from "../facts/table-facts.ts";
|
|
5
5
|
import { roundedMatches } from "./tax.ts";
|
|
6
6
|
import { holds } from "./change-rate-table.ts";
|
|
7
7
|
import { roleOf, type QuantityRole, type QuantityWord } from "./order-quantity.ts";
|
|
@@ -297,16 +297,6 @@ const rowIssue = (row: Line, table: Table, words: LineAmountWords): StructureIss
|
|
|
297
297
|
return [{ offset: amount.offset, values }];
|
|
298
298
|
};
|
|
299
299
|
|
|
300
|
-
/** Each table: its header row and its body rows. */
|
|
301
|
-
export const tablesOf = (lines: readonly Line[]): { header: Line; rows: Line[] }[] =>
|
|
302
|
-
lines.flatMap((line, index) => {
|
|
303
|
-
const header = lines[index - 1];
|
|
304
|
-
if (!TABLE_RULE.test(line.text) || header === undefined || !header.text.includes("|")) return [];
|
|
305
|
-
const after = lines.slice(index + 1);
|
|
306
|
-
const end = after.findIndex((row) => !row.text.includes("|"));
|
|
307
|
-
return [{ header, rows: end === -1 ? after : after.slice(0, end) }];
|
|
308
|
-
});
|
|
309
|
-
|
|
310
300
|
export const lineAmountMismatches = (source: string, words: LineAmountWords): StructureIssue[] =>
|
|
311
301
|
tablesOf(linesOf(source)).flatMap(({ header, rows }) => {
|
|
312
302
|
const readings = [tableOf(cellsOf(header), words), packTableOf(cellsOf(header), words)];
|