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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isTotalLabel, leadingText } from "./total.ts";
|
|
1
|
+
import { isTotalLabel, leadingText, withoutLeadingBlankCells } from "./total.ts";
|
|
2
2
|
import { CELL_SEPARATOR } from "./bare-numbers.ts";
|
|
3
3
|
import { outsideBrackets } from "./connection-times.ts";
|
|
4
4
|
|
|
@@ -45,7 +45,13 @@ const labelText = (lead: string): string => {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
/** 行頭の見出しを語に分ける。括弧の注記((incl. tax))と強調の印は除く。 */
|
|
48
|
-
const
|
|
48
|
+
const leadingLabelWords = (text: string): string[] => wordsOf(outsideBrackets(labelText(leadingText(text))).replace(EMPHASIS, ""));
|
|
49
|
+
|
|
50
|
+
/** 行の見出しの語。表の行は、前の升がどれも空なら、最初の空でない升の見出しを読む。 */
|
|
51
|
+
const labelWords = (text: string): string[] => leadingLabelWords(withoutLeadingBlankCells(text));
|
|
52
|
+
|
|
53
|
+
/** 見出しの語で始まる行か。表の行は、前の升がどれも空なら、最初の空でない升に書いた見出しも読む(| | 合計 | 12,000円 |)。 */
|
|
54
|
+
const startsWithLabel = (text: string, labels: readonly string[]): boolean => isTotalLabel(withoutLeadingBlankCells(text), labels);
|
|
49
55
|
|
|
50
56
|
const startsAt = (words: readonly string[], label: readonly string[], index: number): boolean => label.every((word, offset) => words[index + offset] === word);
|
|
51
57
|
|
|
@@ -153,8 +159,8 @@ const isUnsummed = (nouns: readonly string[], unsummedNouns: readonly string[]):
|
|
|
153
159
|
*/
|
|
154
160
|
const isNamedTotal = (text: string, words: TotalLineWords, header: string): boolean => {
|
|
155
161
|
const label = labelWords(text).join(" ");
|
|
156
|
-
const firstColumn =
|
|
157
|
-
const columns = summedColumnHeaders(text, header).map(
|
|
162
|
+
const firstColumn = leadingLabelWords(header);
|
|
163
|
+
const columns = summedColumnHeaders(text, header).map(leadingLabelWords);
|
|
158
164
|
const namesTotal = (nouns: readonly string[]): boolean =>
|
|
159
165
|
!isUnsummed(nouns, words.unsummedNouns ?? []) &&
|
|
160
166
|
(namesEachOther(nouns, firstColumn) || (columns.length > 0 && columns.every((headerWords) => namesEachOther(nouns, headerWords))));
|
|
@@ -163,7 +169,7 @@ const isNamedTotal = (text: string, words: TotalLineWords, header: string): bool
|
|
|
163
169
|
|
|
164
170
|
/** 合計の語だけか、合計の語に添える語だけを前後に置いた見出しか。 */
|
|
165
171
|
const isPlainTotal = (text: string, words: TotalLineWords): boolean => {
|
|
166
|
-
if (
|
|
172
|
+
if (startsWithLabel(text, words.labels)) return true;
|
|
167
173
|
if (words.qualifiers.length === 0) return false;
|
|
168
174
|
const label = labelWords(text);
|
|
169
175
|
return words.labels.some((total) => isQualifiedLabel(label, wordsOf(total), words.qualifiers));
|
|
@@ -189,7 +195,7 @@ export const withoutPeriod = (label: string, qualifier: TotalQualifier): string
|
|
|
189
195
|
* 前の年の合計(前年合計、Prior-year total)は、期間の語が頭にも尻にも無いので読まない。
|
|
190
196
|
*/
|
|
191
197
|
export const isPeriodTotalLine = (text: string, words: TotalLineWords): boolean => {
|
|
192
|
-
if (
|
|
198
|
+
if (startsWithLabel(text, words.periodLabels ?? [])) return true;
|
|
193
199
|
const label = labelWords(text).join(" ");
|
|
194
200
|
return (words.periodQualifiers ?? []).some((qualifier) => {
|
|
195
201
|
const rest = withoutPeriod(label, qualifier);
|
package/src/structure/total.ts
CHANGED
|
@@ -53,15 +53,54 @@ export const leadingText = (text: string): string =>
|
|
|
53
53
|
.replace(/^[*_]+/u, "")
|
|
54
54
|
.trimStart();
|
|
55
55
|
|
|
56
|
+
/** 表の行の頭に並ぶ空の升(| | 合計 |)。最初の区切りは残す。 */
|
|
57
|
+
const LEADING_BLANK_CELLS = /^([ \t]*\|)(?:[ \t]*\|)+/u;
|
|
58
|
+
|
|
59
|
+
/** 表の行から頭の空の升を除いたもの。合計の語を最初の空でない升に書いた行を、最初の升に書いた行と同じに読むため。 */
|
|
60
|
+
export const withoutLeadingBlankCells = (row: string): string => row.replace(LEADING_BLANK_CELLS, "$1");
|
|
61
|
+
|
|
56
62
|
/**
|
|
57
|
-
* 合計の語のすぐ後ろ。行や列の終わり、区切り(:
|
|
63
|
+
* 合計の語のすぐ後ろ。行や列の終わり、区切り(: |)、金額。括弧の注記は endsLabel が飛ばす。
|
|
58
64
|
* 「計画」や「Total conversion: 25%」のように語が続くものは合計の行ではない。
|
|
59
65
|
*/
|
|
60
|
-
const AFTER_LABEL = /^[*_]*[ \t\u3000]*(?:$|[
|
|
66
|
+
const AFTER_LABEL = /^[*_]*[ \t\u3000]*(?:$|[::|]|[-−▲△$€£¥¥\p{N}])/u;
|
|
67
|
+
|
|
68
|
+
/** 見出しのすぐ後ろの括弧の注記(合計(税込)、Total (incl. tax))の開き。 */
|
|
69
|
+
const NOTE_OPEN = /^[*_]*[ \t\u3000]*[((]/u;
|
|
70
|
+
const OPENERS = new Set(["(", "("]);
|
|
71
|
+
const CLOSERS = new Set([")", ")"]);
|
|
72
|
+
|
|
73
|
+
type NoteScan = { readonly depth: number; readonly end: number | undefined; readonly stopped: boolean };
|
|
74
|
+
|
|
75
|
+
/** 開きの括弧(start)に対応する閉じの次の位置。中の括弧は何段でもよい。升の区切り(\| でない |)までに閉じなければ undefined。 */
|
|
76
|
+
const noteEnd = (text: string, start: number): number | undefined =>
|
|
77
|
+
text
|
|
78
|
+
.slice(start)
|
|
79
|
+
.split("")
|
|
80
|
+
.reduce<NoteScan>(
|
|
81
|
+
(scan, char, offset) => {
|
|
82
|
+
if (scan.end !== undefined || scan.stopped) return scan;
|
|
83
|
+
if (char === "|" && text[start + offset - 1] !== "\\") return { ...scan, stopped: true };
|
|
84
|
+
const depth = scan.depth + (OPENERS.has(char) ? 1 : 0) - (CLOSERS.has(char) ? 1 : 0);
|
|
85
|
+
return { depth, end: depth === 0 ? start + offset + 1 : undefined, stopped: false };
|
|
86
|
+
},
|
|
87
|
+
{ depth: 0, end: undefined, stopped: false },
|
|
88
|
+
).end;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 見出しの語の後ろが見出しの終わりか。括弧の注記は飛ばして、その後ろを同じに読む。注記の後ろに語が続けば(Tax (10%) workshop、
|
|
92
|
+
* 合計(第1期)設計)、注記の付いた項目の名前。升の中で閉じない括弧は、そこからを注記とみなす。
|
|
93
|
+
*/
|
|
94
|
+
const endsLabel = (rest: string): boolean => {
|
|
95
|
+
const open = NOTE_OPEN.exec(rest);
|
|
96
|
+
if (open === null) return AFTER_LABEL.test(rest);
|
|
97
|
+
const end = noteEnd(rest, open[0].length - 1);
|
|
98
|
+
return end === undefined || endsLabel(rest.slice(end));
|
|
99
|
+
};
|
|
61
100
|
|
|
62
101
|
export const isTotalLabel = (text: string, labels: readonly string[]): boolean => {
|
|
63
102
|
const lead = leadingText(text).toLowerCase();
|
|
64
|
-
return labels.some((label) => lead.startsWith(label.toLowerCase()) &&
|
|
103
|
+
return labels.some((label) => lead.startsWith(label.toLowerCase()) && endsLabel(lead.slice(label.length)));
|
|
65
104
|
};
|
|
66
105
|
|
|
67
106
|
const centsOf = (source: string, line: Line, amount: Amount): number | undefined => {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A label naming the version it is about: the version after the label and a word (End of support for 5.0.0:), or before
|
|
3
|
+
* it with a word (3.0.0 のサポート終了日:). The words come from the language's lexicon; a version is digits joined by dots,
|
|
4
|
+
* with or without a leading v. Pure.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** The words that join a version to a label: after for the label, word, version order; before for version, word, label. */
|
|
8
|
+
export type VersionWords = { readonly after: readonly string[]; readonly before: readonly string[] };
|
|
9
|
+
|
|
10
|
+
/** A list marker, a table cell's bar and emphasis before the label. A numbered marker needs its space: 3.0.0 is a version, not item 3. */
|
|
11
|
+
const LINE_LEAD = /^[ \t]*(?:(?:[-*+]|\d{1,3}[.)])[ \t]+)?(?:\|[ \t]*)?[*_]*/u;
|
|
12
|
+
const VERSION = /^v?\d+(?:\.\d+)+/iu;
|
|
13
|
+
/** After the label's version, only the label's end: a colon or a table cell's bar. */
|
|
14
|
+
const VERSION_END = /^[ \t]*[::|]/u;
|
|
15
|
+
const SPACES = /^[ \t\u3000]*/u;
|
|
16
|
+
|
|
17
|
+
const spacesAt = (text: string): number => SPACES.exec(text)?.[0].length ?? 0;
|
|
18
|
+
|
|
19
|
+
const versionAt = (text: string): number => VERSION.exec(text)?.[0].length ?? 0;
|
|
20
|
+
|
|
21
|
+
/** After the label: one word, spaces on both sides, a version and the label's end. Returns the label's end on. */
|
|
22
|
+
const afterVersion = (rest: string, word: string): string | undefined => {
|
|
23
|
+
const gap = spacesAt(rest);
|
|
24
|
+
if (gap === 0 || !rest.slice(gap).toLowerCase().startsWith(`${word.toLowerCase()} `)) return undefined;
|
|
25
|
+
const from = gap + word.length + spacesAt(rest.slice(gap + word.length));
|
|
26
|
+
const version = versionAt(rest.slice(from));
|
|
27
|
+
const tail = rest.slice(from + version);
|
|
28
|
+
return version > 0 && VERSION_END.test(tail) ? tail : undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Before the label: a version, the word and the label, spaces allowed between. Returns the text from the label on. */
|
|
32
|
+
const beforeVersion = (lead: string, word: string, label: string): string | undefined => {
|
|
33
|
+
const version = versionAt(lead);
|
|
34
|
+
if (version === 0) return undefined;
|
|
35
|
+
const atWord = version + spacesAt(lead.slice(version));
|
|
36
|
+
if (!lead.slice(atWord).startsWith(word)) return undefined;
|
|
37
|
+
const atLabel = atWord + word.length + spacesAt(lead.slice(atWord + word.length));
|
|
38
|
+
return lead.slice(atLabel).toLowerCase().startsWith(label.toLowerCase()) ? lead.slice(atLabel) : undefined;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The line read as the bare label: "End of support for 5.0.0: …" as "End of support: …", "3.0.0 のサポート終了日:…" as
|
|
43
|
+
* "サポート終了日:…". undefined when the line does not start with the label carrying a version that way.
|
|
44
|
+
*/
|
|
45
|
+
export const withoutLabelVersion = (text: string, label: string, words: VersionWords): string | undefined => {
|
|
46
|
+
const lead = text.replace(LINE_LEAD, "");
|
|
47
|
+
const after = lead.toLowerCase().startsWith(label.toLowerCase())
|
|
48
|
+
? words.after.map((word) => afterVersion(lead.slice(label.length), word)).find((tail) => tail !== undefined)
|
|
49
|
+
: undefined;
|
|
50
|
+
if (after !== undefined) return `${lead.slice(0, label.length)}${after}`;
|
|
51
|
+
return words.before.map((word) => beforeVersion(lead, word, label)).find((rest) => rest !== undefined);
|
|
52
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// 平文の契約の見出し。Markdown の見出しを使わない契約(.txt)は、行の頭や文の切れ目に「9. Indemnification.」
|
|
2
|
+
// 「Section 2.3 Appraisal Shares.」と番号と題を書く。木は本文の番号と見分けられないのでこれを番地にしないが、
|
|
3
|
+
// 参照の行き先としては読める。目次の行(「Section 2.3 Appraisal Shares 4」)は題が点で閉じないので見出しにしない。
|
|
4
|
+
|
|
5
|
+
/** 書かれた見出し。address は参照の target と同じ形(「6.1」)。start は見出しの位置。 */
|
|
6
|
+
export type WrittenHeading = { readonly address: string; readonly start: number };
|
|
7
|
+
|
|
8
|
+
/** 参照の位置と行き先。木の reference の節点から取る。 */
|
|
9
|
+
export type ReferenceSpan = { readonly start: number; readonly end: number; readonly target: string };
|
|
10
|
+
|
|
11
|
+
/** 題の語の数の上限。見出しの題は短い。 */
|
|
12
|
+
const MAX_TITLE_WORDS = 15;
|
|
13
|
+
/** 題の語: 文字で始まり、文字・アポストロフィ・アンパサンド・ハイフンが続き、読点やセミコロンで終わってもよい。数字は入らない。 */
|
|
14
|
+
const TITLE_WORD = /^\p{L}[\p{L}’'&-]*[,;]?$/u;
|
|
15
|
+
const CAPITAL = /^\p{Lu}/u;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Title Case の題か(「Effect on Capital Stock of the Company and Merger Sub」)。最初の語が大文字で始まり、語の半分より多くが
|
|
19
|
+
* 大文字で始まり、数字を含まない。文(「The Company shall comply」)は小文字の語が多いので当たらない。Pure.
|
|
20
|
+
*/
|
|
21
|
+
export const isTitle = (title: string): boolean => {
|
|
22
|
+
const words = title.trim().split(/\s+/u);
|
|
23
|
+
const [first] = words;
|
|
24
|
+
if (first === undefined || first === "" || words.length > MAX_TITLE_WORDS || !words.every((word) => TITLE_WORD.test(word))) return false;
|
|
25
|
+
return CAPITAL.test(first) && words.filter((word) => CAPITAL.test(word)).length * 2 > words.length;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** 点で閉じた題(「Appraisal Shares. As used」の「Appraisal Shares」)。点の後ろは空白か行末。無ければ undefined。 */
|
|
29
|
+
const MAX_TITLE_LENGTH = 120;
|
|
30
|
+
const titleClosedByDot = (text: string): string | undefined => {
|
|
31
|
+
const dot = text.slice(0, MAX_TITLE_LENGTH).search(/\.(?:\s|$)/u);
|
|
32
|
+
return dot <= 0 ? undefined : text.slice(0, dot);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** 前の語が番号(「Section 8.07. Section 16 Matters」の 8.07.)なら、後ろはその見出しの題で、見出しではない。 */
|
|
36
|
+
const NUMBER_BEFORE = /\d[.:]?$/u;
|
|
37
|
+
const SENTENCE_END = /[.;:]$/u;
|
|
38
|
+
const isSpace = (char: string | undefined): boolean => char === " " || char === "\t";
|
|
39
|
+
|
|
40
|
+
/** 見出しが始まれる位置: 行の頭、文の終わり(. ; :)の後ろの空白、2 つ以上の空白の後ろ。前が番号なら始まらない。 */
|
|
41
|
+
const startsHeading = (source: string, at: number): boolean => {
|
|
42
|
+
const before = source.slice(Math.max(source.lastIndexOf("\n", at - 1) + 1, at - MAX_TITLE_LENGTH), at);
|
|
43
|
+
let spaces = 0;
|
|
44
|
+
while (isSpace(before[before.length - 1 - spaces])) spaces += 1;
|
|
45
|
+
if (spaces === before.length) return true;
|
|
46
|
+
const word =
|
|
47
|
+
before
|
|
48
|
+
.slice(0, before.length - spaces)
|
|
49
|
+
.split(/[ \t]/u)
|
|
50
|
+
.at(-1) ?? "";
|
|
51
|
+
if (NUMBER_BEFORE.test(word)) return false;
|
|
52
|
+
return spaces >= 2 || (spaces >= 1 && SENTENCE_END.test(word));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** 参照のすぐ後ろが題か(「Section 4.12. Compliance with Laws.」「Section 1.1 Closing. The Parties」)。 */
|
|
56
|
+
const NUMBER_CLOSE = /^\.?[ \t]+/u;
|
|
57
|
+
/** 番号と題のあいだの空白の長さの上限(データセットの契約は十数個の空白を置く)。 */
|
|
58
|
+
const MAX_NUMBER_CLOSE = 24;
|
|
59
|
+
const titledAfter = (source: string, end: number): boolean => {
|
|
60
|
+
const rest = source.slice(end, end + MAX_TITLE_LENGTH + MAX_NUMBER_CLOSE);
|
|
61
|
+
const close = NUMBER_CLOSE.exec(rest)?.[0];
|
|
62
|
+
const title = close === undefined ? undefined : titleClosedByDot(rest.slice(close.length));
|
|
63
|
+
return title !== undefined && isTitle(title);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** 参照の形で書かれた見出し(「… Effect. Section 4.12. Compliance with Laws.」)。 */
|
|
67
|
+
const headingsAtReferences = (references: readonly ReferenceSpan[], source: string): WrittenHeading[] =>
|
|
68
|
+
references
|
|
69
|
+
.filter((reference) => startsHeading(source, reference.start) && titledAfter(source, reference.end))
|
|
70
|
+
.map((reference) => ({ address: reference.target, start: reference.start }));
|
|
71
|
+
|
|
72
|
+
/** 行の頭の番号(「9. Indemnification.」「4 Intellectual Property. 4.1 Each」「6.1 eGain warrants」「2 Quality and Food Safety」)。 */
|
|
73
|
+
const LINE_NUMBER = /^[ \t]{0,3}(?<number>\d{1,3}(?:\.\d{1,3}){0,5})\.?[ \t]+(?<rest>\S.*)$/u;
|
|
74
|
+
/** 語のどこかに大文字があるか(「eGain」も名前)。 */
|
|
75
|
+
const HAS_CAPITAL = /\p{Lu}/u;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 行の頭の番号が見出しか。題が点で閉じ、同じ行に本文が続けば見出し(「9. Indemnification. Each party …」)。題だけの行
|
|
79
|
+
* (「1. Introduction」)は箇条書きと見分けられないので読まない。点を含む番号(6.1)は、最初の語に大文字があり、題より長い
|
|
80
|
+
* 段落が続けば段落の番号(「6.1 eGain warrants …」)。本文の折り返しの「2.5 percent」は小文字、目次の「3.17 Reserves 33」は短いので当たらない。
|
|
81
|
+
*/
|
|
82
|
+
const isLineHeading = (number: string, rest: string): boolean => {
|
|
83
|
+
const title = titleClosedByDot(rest);
|
|
84
|
+
if (title !== undefined && rest.slice(title.length + 1).trim() !== "" && isTitle(title)) return true;
|
|
85
|
+
const words = rest.split(/\s+/u);
|
|
86
|
+
return number.includes(".") && words.length > MAX_TITLE_WORDS && HAS_CAPITAL.test(words[0] ?? "");
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const headingsAtLineStarts = (source: string): WrittenHeading[] => {
|
|
90
|
+
const found: WrittenHeading[] = [];
|
|
91
|
+
let start = 0;
|
|
92
|
+
source.split("\n").forEach((line) => {
|
|
93
|
+
const groups = LINE_NUMBER.exec(line)?.groups;
|
|
94
|
+
const number = groups?.["number"];
|
|
95
|
+
if (number !== undefined && isLineHeading(number, groups?.["rest"] ?? "")) found.push({ address: number, start });
|
|
96
|
+
start += line.length + 1;
|
|
97
|
+
});
|
|
98
|
+
return found;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/** 文書に平文で書かれた見出しを、文書の順に。Pure. */
|
|
102
|
+
export const writtenHeadings = (references: readonly ReferenceSpan[], source: string): WrittenHeading[] =>
|
|
103
|
+
[...headingsAtReferences(references, source), ...headingsAtLineStarts(source)].toSorted((left, right) => left.start - right.start);
|
|
104
|
+
|
|
105
|
+
/** 括弧の小見出し(「(i)」「(b)」「(3)」)。参照の一部(「Section 2.02(b)」「(a)(i)」)は、前が文字・数字・括弧なので読まない。 */
|
|
106
|
+
const SUBDIVISION_LABEL = /(?<![\p{L}\p{N})\]])\((?<label>[a-zA-Z]{1,4}|\d{1,3})\)/gu;
|
|
107
|
+
|
|
108
|
+
/** 本文に書かれた括弧の小見出しの札。Pure. */
|
|
109
|
+
export const writtenSubdivisions = (body: string): ReadonlySet<string> =>
|
|
110
|
+
new Set([...body.matchAll(SUBDIVISION_LABEL)].flatMap((match) => (match.groups?.["label"] === undefined ? [] : [match.groups["label"]])));
|
|
111
|
+
|
|
112
|
+
/** 参照の札(「Section 2.1(a)(i)」の a と i)。 */
|
|
113
|
+
const LABEL_IN_REFERENCE = /\((?<label>[a-zA-Z]{1,4}|\d{1,3})\)/gu;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 参照の番地「2.1.a.i」を、親「2.1」と、参照が括弧で書いた札「a」「i」に分ける。札を括弧で書いていない参照(Section 2.1)や、
|
|
117
|
+
* 番地の末尾が書いた札と合わなければ undefined。Pure.
|
|
118
|
+
*/
|
|
119
|
+
export const parentAndLabels = (target: string, written: string): { readonly parent: string; readonly labels: readonly string[] } | undefined => {
|
|
120
|
+
const labels = [...written.matchAll(LABEL_IN_REFERENCE)].flatMap((match) => (match.groups?.["label"] === undefined ? [] : [match.groups["label"]]));
|
|
121
|
+
const parts = target.split(".");
|
|
122
|
+
const cut = parts.length - labels.length;
|
|
123
|
+
if (labels.length === 0 || cut <= 0 || parts.slice(cut).join(".") !== labels.join(".")) return undefined;
|
|
124
|
+
return { parent: parts.slice(0, cut).join("."), labels };
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** 書かれた見出しごとの範囲(次の書かれた見出しまで)。同じ番地が二度あれば、どちらの範囲もその番地のもの。Pure. */
|
|
128
|
+
export const headingRegions = (headings: readonly WrittenHeading[], length: number): ReadonlyMap<string, readonly (readonly [number, number])[]> => {
|
|
129
|
+
const regions = new Map<string, (readonly [number, number])[]>();
|
|
130
|
+
headings.forEach((heading, index) => {
|
|
131
|
+
const end = headings[index + 1]?.start ?? length;
|
|
132
|
+
const found = regions.get(heading.address) ?? [];
|
|
133
|
+
found.push([heading.start, end]);
|
|
134
|
+
regions.set(heading.address, found);
|
|
135
|
+
});
|
|
136
|
+
return regions;
|
|
137
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { StructureNode } from "../plugin.ts";
|
|
2
|
+
import { headingRegions, parentAndLabels, writtenHeadings, writtenSubdivisions, type WrittenHeading } from "./written-headings.ts";
|
|
3
|
+
|
|
4
|
+
// 木が番地にしない平文の見出しと、本文の中に書いた括弧の小見出し(「6.1 … that (i) the Software …」)を、参照の行き先として引く。
|
|
5
|
+
|
|
6
|
+
type Region = readonly [number, number];
|
|
7
|
+
|
|
8
|
+
/** addresses: 平文で書かれた見出しの番地。subdivision: 参照の札が、親の範囲の本文に書かれているか。 */
|
|
9
|
+
export type WrittenReading = { readonly addresses: readonly string[]; readonly subdivision: (reference: StructureNode) => boolean };
|
|
10
|
+
|
|
11
|
+
const targetOf = (node: StructureNode): string => String(node.attrs["target"] ?? "");
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 括弧の小見出しを読む範囲。木の条は、項や号を一つも読まなかったときだけ、その条の始まりから次の平文の見出しまで。
|
|
15
|
+
* 項や号を読んでいれば、無い札は本当に無い。
|
|
16
|
+
*/
|
|
17
|
+
const treeRegions = (nodes: readonly StructureNode[], headings: readonly WrittenHeading[]): Map<string, Region[]> => {
|
|
18
|
+
const regions = new Map<string, Region[]>();
|
|
19
|
+
// 条も見出しも文書の順なので、次の見出しは前へ進めるだけで見つかる。
|
|
20
|
+
let next = 0;
|
|
21
|
+
nodes
|
|
22
|
+
.filter((node) => node.kind === "article" && !node.children.some((child) => child.kind === "item"))
|
|
23
|
+
.toSorted((left, right) => left.span.start - right.span.start)
|
|
24
|
+
.forEach((node) => {
|
|
25
|
+
while ((headings[next]?.start ?? Infinity) <= node.span.start) next += 1;
|
|
26
|
+
const end = Math.min(headings[next]?.start ?? node.span.end, node.span.end);
|
|
27
|
+
const found = regions.get(node.address) ?? [];
|
|
28
|
+
found.push([node.span.start, end]);
|
|
29
|
+
regions.set(node.address, found);
|
|
30
|
+
});
|
|
31
|
+
return regions;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 平文の見出しの番地と、参照(Section 6.1(i))の親(6.1)が木の条か平文の見出しとしてあり、その範囲の本文に札「(i)」が
|
|
36
|
+
* 書かれているかを引く関数。範囲ごとの札は、要るときに一度だけ読む。Pure.
|
|
37
|
+
*/
|
|
38
|
+
export const writtenReading = (nodes: readonly StructureNode[], source: string): WrittenReading => {
|
|
39
|
+
const references = nodes.filter((node) => node.kind === "reference").map((node) => ({ start: node.span.start, end: node.span.end, target: targetOf(node) }));
|
|
40
|
+
const headings = writtenHeadings(references, source);
|
|
41
|
+
const written = headingRegions(headings, source.length);
|
|
42
|
+
const tree = treeRegions(nodes, headings);
|
|
43
|
+
const labels = new Map<string, ReadonlySet<string>>();
|
|
44
|
+
const labelsIn = ([start, end]: Region): ReadonlySet<string> => {
|
|
45
|
+
const key = `${String(start)}:${String(end)}`;
|
|
46
|
+
const found = labels.get(key) ?? writtenSubdivisions(source.slice(start, end));
|
|
47
|
+
labels.set(key, found);
|
|
48
|
+
return found;
|
|
49
|
+
};
|
|
50
|
+
const regionsOf = (address: string): Region[] => [...(tree.get(address) ?? []), ...(written.get(address) ?? [])];
|
|
51
|
+
const subdivision = (reference: StructureNode): boolean => {
|
|
52
|
+
const wanted = parentAndLabels(targetOf(reference), String(reference.attrs["label"] ?? ""));
|
|
53
|
+
if (wanted === undefined) return false;
|
|
54
|
+
return regionsOf(wanted.parent).some((region) => wanted.labels.every((label) => labelsIn(region).has(label)));
|
|
55
|
+
};
|
|
56
|
+
return { addresses: headings.map((heading) => heading.address), subdivision };
|
|
57
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// The one code a product document is about (a recall's or a warranty's model): named in its title, or labelled on a line
|
|
2
|
+
// of its own or in a table (型番:NH-805, | Model | MW-4120S |), and written once elsewhere with two neighbours swapped
|
|
3
|
+
// (NH-850). Only when the document names no other code in those places: a catalog naming two is about two items. Pure.
|
|
4
|
+
import type { LexiconEntry, Span } from "./plugin.ts";
|
|
5
|
+
import { labelBefore, swapsNeighbours, withoutUrls } from "./phone-numbers.ts";
|
|
6
|
+
import { charactersOf, LABEL_TO_NUMBER, REFERENCE_SHAPE, type ReferenceNumber, type ReferenceVariant } from "./reference-numbers.ts";
|
|
7
|
+
import { isCodeWith } from "./unlabelled-references.ts";
|
|
8
|
+
|
|
9
|
+
/** Digits enough for a model's code (FT-38); the two letters a short code must hold keep out form names (A-12, B-21). */
|
|
10
|
+
export const MIN_SUBJECT_DIGITS = 2;
|
|
11
|
+
const MIN_SUBJECT_LETTERS = 2;
|
|
12
|
+
const LETTER = /[A-Z]/gu;
|
|
13
|
+
const FIRST_PART = /^[^-‐−-]*/u;
|
|
14
|
+
const TITLE_GROUP = "title";
|
|
15
|
+
|
|
16
|
+
/** A short code: two letters or more before its hyphen, and two digits or more (FT-38, KR-M230; not A-12B). */
|
|
17
|
+
export const isSubjectCode = (written: string): boolean =>
|
|
18
|
+
isCodeWith(MIN_SUBJECT_DIGITS)(written) && (charactersOf(FIRST_PART.exec(written)?.[0] ?? "").match(LETTER)?.length ?? 0) >= MIN_SUBJECT_LETTERS;
|
|
19
|
+
|
|
20
|
+
/** What the document gives: its prose (tables masked), its title as written (the prose masks it), its labels, the groups that name an item, the codes its tables label, and every code in a table. */
|
|
21
|
+
export type SubjectCodeInput = {
|
|
22
|
+
readonly prose: string;
|
|
23
|
+
readonly title: { readonly start: number; readonly text: string } | undefined;
|
|
24
|
+
readonly labels: readonly LexiconEntry[];
|
|
25
|
+
readonly listed: ReadonlySet<string>;
|
|
26
|
+
readonly tabled: readonly ReferenceNumber[];
|
|
27
|
+
readonly known: ReadonlySet<string>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type CodeWriting = ReferenceNumber & { readonly anchor: boolean; readonly group: string | undefined };
|
|
31
|
+
|
|
32
|
+
const lineAround = (text: string, offset: number): Span => {
|
|
33
|
+
const start = text.lastIndexOf("\n", offset - 1) + 1;
|
|
34
|
+
const end = text.indexOf("\n", offset);
|
|
35
|
+
return { start, end: end === -1 ? text.length : end };
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Whether a code's line holds a label of the given labels, the separators and the code, and nothing else (型番:NH-805). */
|
|
39
|
+
const isFieldLine = (text: string, offset: number, written: string, between: string, labels: readonly LexiconEntry[]): boolean => {
|
|
40
|
+
const line = lineAround(text, offset);
|
|
41
|
+
const head = text
|
|
42
|
+
.slice(line.start, offset - between.length)
|
|
43
|
+
.trim()
|
|
44
|
+
.toLowerCase();
|
|
45
|
+
const rest = text.slice(offset + written.length, line.end).trim();
|
|
46
|
+
return rest === "" && labels.some((label) => label.pattern.toLowerCase() === head);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const shortCodes = (text: string): RegExpExecArray[] => [...text.matchAll(REFERENCE_SHAPE)].filter((match) => isSubjectCode(match[0]));
|
|
50
|
+
|
|
51
|
+
/** Every short code of the title, each an anchor. */
|
|
52
|
+
const titleWritings = (title: SubjectCodeInput["title"]): CodeWriting[] =>
|
|
53
|
+
title === undefined
|
|
54
|
+
? []
|
|
55
|
+
: shortCodes(title.text).map((match) => ({
|
|
56
|
+
offset: title.start + match.index,
|
|
57
|
+
written: match[0],
|
|
58
|
+
characters: charactersOf(match[0]),
|
|
59
|
+
label: TITLE_GROUP,
|
|
60
|
+
anchor: true,
|
|
61
|
+
group: undefined,
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
/** Every short code of the prose, as an anchor when a field line of a listed kind labels it. */
|
|
65
|
+
const proseWritings = (text: string, input: SubjectCodeInput): CodeWriting[] =>
|
|
66
|
+
shortCodes(text).map((match) => {
|
|
67
|
+
const written = match[0];
|
|
68
|
+
const offset = match.index;
|
|
69
|
+
const label = labelBefore(text, offset, input.labels);
|
|
70
|
+
const group = label !== undefined && LABEL_TO_NUMBER.test(label.between) ? label.group : undefined;
|
|
71
|
+
const onField = group !== undefined && input.listed.has(group) && isFieldLine(text, offset, written, label?.between ?? "", input.labels);
|
|
72
|
+
return { offset, written, characters: charactersOf(written), label: group ?? TITLE_GROUP, anchor: onField, group };
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
/** The title's codes and the prose's, one writing per place. */
|
|
76
|
+
const writingsOf = (text: string, input: SubjectCodeInput): CodeWriting[] => {
|
|
77
|
+
const inTitle = titleWritings(input.title);
|
|
78
|
+
return [...inTitle, ...proseWritings(text, input).filter((writing) => !inTitle.some((title) => title.offset === writing.offset))];
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** The writings of the document's one code with two neighbours swapped, each written once, of a listed kind or unlabelled, on a line that does not name the code itself. */
|
|
82
|
+
export const subjectCodeVariants = (input: SubjectCodeInput): ReferenceVariant[] => {
|
|
83
|
+
const text = withoutUrls(input.prose);
|
|
84
|
+
const writings = writingsOf(text, input);
|
|
85
|
+
const anchors = [
|
|
86
|
+
...writings.filter((writing) => writing.anchor),
|
|
87
|
+
...input.tabled.filter((code) => input.listed.has(code.label) && isSubjectCode(code.written)),
|
|
88
|
+
];
|
|
89
|
+
const subject = anchors[0];
|
|
90
|
+
if (subject === undefined || anchors.some((anchor) => anchor.characters !== subject.characters)) return [];
|
|
91
|
+
const timesWritten = (characters: string): number => writings.filter((writing) => writing.characters === characters).length;
|
|
92
|
+
return writings.flatMap((writing) => {
|
|
93
|
+
const line = lineAround(text, writing.offset);
|
|
94
|
+
const slip =
|
|
95
|
+
!writing.anchor &&
|
|
96
|
+
(writing.group === undefined || input.listed.has(writing.group)) &&
|
|
97
|
+
!input.known.has(writing.characters) &&
|
|
98
|
+
timesWritten(writing.characters) === 1 &&
|
|
99
|
+
swapsNeighbours(subject.characters, writing.characters) &&
|
|
100
|
+
!writings.some((other) => other.characters === subject.characters && other.offset >= line.start && other.offset < line.end);
|
|
101
|
+
if (!slip) return [];
|
|
102
|
+
const { offset, written, characters } = writing;
|
|
103
|
+
return [{ number: { offset, written, characters, label: subject.label }, other: subject }];
|
|
104
|
+
});
|
|
105
|
+
};
|
|
@@ -8,16 +8,22 @@ import { withoutEdgeMarks } from "./facts/trim-marks.ts";
|
|
|
8
8
|
import { charactersOf, MAX_CHARACTERS, MIN_DIGITS, REFERENCE_SHAPE, type ReferenceNumber, type ReferenceVariant } from "./reference-numbers.ts";
|
|
9
9
|
|
|
10
10
|
const SEPARATOR = /[-‐−-]/u;
|
|
11
|
+
|
|
12
|
+
type CodeShape = (written: string) => boolean;
|
|
11
13
|
const LATIN_LETTER = /[A-Z]/u;
|
|
12
14
|
const DIGIT = /\d/gu;
|
|
13
15
|
|
|
14
|
-
/** A code: letters, a hyphen and
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
/** A code: letters, a hyphen and the given digits or more (GP-0512). A plain number (48215, 2026-118) is never one. */
|
|
17
|
+
export const isCodeWith =
|
|
18
|
+
(minDigits: number) =>
|
|
19
|
+
(written: string): boolean => {
|
|
20
|
+
const characters = charactersOf(written);
|
|
21
|
+
return (
|
|
22
|
+
SEPARATOR.test(written) && LATIN_LETTER.test(characters) && (characters.match(DIGIT)?.length ?? 0) >= minDigits && characters.length <= MAX_CHARACTERS
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const isCode = isCodeWith(MIN_DIGITS);
|
|
21
27
|
|
|
22
28
|
const keyOf = (text: string): string => withoutEdgeMarks(text).normalize("NFKC").toLowerCase();
|
|
23
29
|
|
|
@@ -29,10 +35,10 @@ const labelOfCell = (cell: Cell | undefined, labels: readonly LexiconEntry[]): s
|
|
|
29
35
|
};
|
|
30
36
|
|
|
31
37
|
/** A cell holding one code and nothing else, as a reference number of the group. */
|
|
32
|
-
const codeOfCell = (cell: Cell | undefined, group: string): ReferenceNumber[] => {
|
|
38
|
+
const codeOfCell = (cell: Cell | undefined, group: string, isCodeShape: CodeShape): ReferenceNumber[] => {
|
|
33
39
|
if (cell === undefined) return [];
|
|
34
40
|
const written = withoutEdgeMarks(cell.text);
|
|
35
|
-
if (!
|
|
41
|
+
if (!isCodeShape(written) || [...written.matchAll(REFERENCE_SHAPE)].length !== 1) return [];
|
|
36
42
|
return [{ offset: cell.start + cell.text.indexOf(written), written, characters: charactersOf(written), label: group }];
|
|
37
43
|
};
|
|
38
44
|
|
|
@@ -40,28 +46,30 @@ const codeOfCell = (cell: Cell | undefined, group: string): ReferenceNumber[] =>
|
|
|
40
46
|
* The codes a table labels: in a row whose first cell is a label (| 品番 | GP-0512 |), and in a column whose heading is
|
|
41
47
|
* one (| 品番 | 品名 | over | GP-0512 | …). Pass the text with its tables (proseAndTablesOf).
|
|
42
48
|
*/
|
|
43
|
-
export const tableLabelledCodes = (text: string, labels: readonly LexiconEntry[]): ReferenceNumber[] =>
|
|
49
|
+
export const tableLabelledCodes = (text: string, labels: readonly LexiconEntry[], isCodeShape: CodeShape = isCode): ReferenceNumber[] =>
|
|
44
50
|
tablesOf(linesOf(text)).flatMap((table) => {
|
|
45
51
|
const headings = cellsOf(table.header).map((cell) => labelOfCell(cell, labels));
|
|
46
52
|
return table.rows.flatMap((row) => {
|
|
47
53
|
const cells = cellsOf(row);
|
|
48
54
|
const rowGroup = labelOfCell(cells[0], labels);
|
|
49
|
-
const byRow = rowGroup === undefined ? [] : codeOfCell(cells[1], rowGroup);
|
|
55
|
+
const byRow = rowGroup === undefined ? [] : codeOfCell(cells[1], rowGroup, isCodeShape);
|
|
50
56
|
const byColumn = cells.flatMap((cell, index) => {
|
|
51
57
|
const group = headings[index];
|
|
52
|
-
return group === undefined ? [] : codeOfCell(cell, group);
|
|
58
|
+
return group === undefined ? [] : codeOfCell(cell, group, isCodeShape);
|
|
53
59
|
});
|
|
54
60
|
return [...byRow, ...byColumn];
|
|
55
61
|
});
|
|
56
62
|
});
|
|
57
63
|
|
|
58
64
|
/** The letters and digits of every code a cell holds. */
|
|
59
|
-
const codesInCell = (cell: Cell): string[] =>
|
|
60
|
-
[...cell.text.matchAll(REFERENCE_SHAPE)].filter((match) =>
|
|
65
|
+
const codesInCell = (cell: Cell, isCodeShape: CodeShape): string[] =>
|
|
66
|
+
[...cell.text.matchAll(REFERENCE_SHAPE)].filter((match) => isCodeShape(match[0])).map((match) => charactersOf(match[0]));
|
|
61
67
|
|
|
62
68
|
/** Every code written anywhere in a table, its heading row too, labelled or not: a code a table lists is an item of its own, never a slip. */
|
|
63
|
-
export const tableCodes = (text: string): Set<string> =>
|
|
64
|
-
new Set(
|
|
69
|
+
export const tableCodes = (text: string, isCodeShape: CodeShape = isCode): Set<string> =>
|
|
70
|
+
new Set(
|
|
71
|
+
tablesOf(linesOf(text)).flatMap((table) => [table.header, ...table.rows].flatMap((row) => cellsOf(row).flatMap((cell) => codesInCell(cell, isCodeShape)))),
|
|
72
|
+
);
|
|
65
73
|
|
|
66
74
|
/**
|
|
67
75
|
* Every code of the prose written with no label that is one labelled code with two neighbours swapped. Only when exactly
|