chaffjs 0.28.0 → 0.29.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/ai-score/of-document.d.ts.map +1 -1
- package/dist/ai-score/of-document.js +23 -14
- package/dist/ai-score/of-document.js.map +1 -1
- package/dist/ai-score/render.d.ts.map +1 -1
- package/dist/ai-score/render.js +13 -4
- package/dist/ai-score/render.js.map +1 -1
- package/dist/ai-score/score.d.ts +16 -1
- package/dist/ai-score/score.d.ts.map +1 -1
- package/dist/ai-score/score.js +15 -3
- package/dist/ai-score/score.js.map +1 -1
- package/dist/ai-score/signals.d.ts +2 -4
- package/dist/ai-score/signals.d.ts.map +1 -1
- package/dist/ai-score/signals.js +11 -2
- package/dist/ai-score/signals.js.map +1 -1
- package/dist/ai-score/text.d.ts +2 -0
- package/dist/ai-score/text.d.ts.map +1 -1
- package/dist/ai-score/text.js +4 -2
- package/dist/ai-score/text.js.map +1 -1
- package/dist/announced-count.d.ts +2 -0
- package/dist/announced-count.d.ts.map +1 -1
- package/dist/announced-count.js +14 -7
- package/dist/announced-count.js.map +1 -1
- package/dist/check-source.d.ts +3 -1
- package/dist/check-source.d.ts.map +1 -1
- package/dist/check-source.js +3 -1
- package/dist/check-source.js.map +1 -1
- package/dist/cli-text.d.ts.map +1 -1
- package/dist/cli-text.js +38 -16
- package/dist/cli-text.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/cite-claims.d.ts +36 -0
- package/dist/commands/cite-claims.d.ts.map +1 -0
- package/dist/commands/cite-claims.js +81 -0
- package/dist/commands/cite-claims.js.map +1 -0
- package/dist/commands/cite-page.d.ts +14 -0
- package/dist/commands/cite-page.d.ts.map +1 -0
- package/dist/commands/cite-page.js +47 -0
- package/dist/commands/cite-page.js.map +1 -0
- package/dist/commands/cite-scaffold.d.ts +16 -0
- package/dist/commands/cite-scaffold.d.ts.map +1 -0
- package/dist/commands/cite-scaffold.js +21 -0
- package/dist/commands/cite-scaffold.js.map +1 -0
- package/dist/commands/cite.d.ts +3 -12
- package/dist/commands/cite.d.ts.map +1 -1
- package/dist/commands/cite.js +110 -51
- package/dist/commands/cite.js.map +1 -1
- package/dist/company-names.d.ts +34 -0
- package/dist/company-names.d.ts.map +1 -0
- package/dist/company-names.js +158 -0
- package/dist/company-names.js.map +1 -0
- package/dist/default-values.d.ts +17 -0
- package/dist/default-values.d.ts.map +1 -0
- package/dist/default-values.js +134 -0
- package/dist/default-values.js.map +1 -0
- package/dist/deprecated-use.d.ts +17 -0
- package/dist/deprecated-use.d.ts.map +1 -0
- package/dist/deprecated-use.js +95 -0
- package/dist/deprecated-use.js.map +1 -0
- package/dist/derived/stays.d.ts +43 -0
- package/dist/derived/stays.d.ts.map +1 -0
- package/dist/derived/stays.js +105 -0
- package/dist/derived/stays.js.map +1 -0
- package/dist/detectors/acronym-context.d.ts +2 -2
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +6 -0
- package/dist/detectors/acronym-context.js.map +1 -1
- package/dist/detectors/address-word.d.ts +3 -0
- package/dist/detectors/address-word.d.ts.map +1 -0
- package/dist/detectors/address-word.js +7 -0
- package/dist/detectors/address-word.js.map +1 -0
- package/dist/detectors/agreement-slip.d.ts.map +1 -1
- package/dist/detectors/agreement-slip.js +4 -1
- package/dist/detectors/agreement-slip.js.map +1 -1
- package/dist/detectors/ai-phrasing.d.ts +0 -4
- package/dist/detectors/ai-phrasing.d.ts.map +1 -1
- package/dist/detectors/ai-phrasing.js +5 -1
- package/dist/detectors/ai-phrasing.js.map +1 -1
- package/dist/detectors/amount-range.d.ts +3 -0
- package/dist/detectors/amount-range.d.ts.map +1 -0
- package/dist/detectors/amount-range.js +38 -0
- package/dist/detectors/amount-range.js.map +1 -0
- package/dist/detectors/amount-scale.d.ts +6 -1
- package/dist/detectors/amount-scale.d.ts.map +1 -1
- package/dist/detectors/amount-scale.js +33 -9
- package/dist/detectors/amount-scale.js.map +1 -1
- package/dist/detectors/announced-count.d.ts +1 -1
- package/dist/detectors/announced-count.d.ts.map +1 -1
- package/dist/detectors/announced-count.js +18 -3
- package/dist/detectors/announced-count.js.map +1 -1
- package/dist/detectors/bare-comparative.d.ts.map +1 -1
- package/dist/detectors/bare-comparative.js +4 -1
- package/dist/detectors/bare-comparative.js.map +1 -1
- package/dist/detectors/block-quotation.d.ts +13 -0
- package/dist/detectors/block-quotation.d.ts.map +1 -0
- package/dist/detectors/block-quotation.js +86 -0
- package/dist/detectors/block-quotation.js.map +1 -0
- package/dist/detectors/bracket-label.d.ts +10 -0
- package/dist/detectors/bracket-label.d.ts.map +1 -0
- package/dist/detectors/bracket-label.js +51 -0
- package/dist/detectors/bracket-label.js.map +1 -0
- package/dist/detectors/citation-entry.d.ts +5 -0
- package/dist/detectors/citation-entry.d.ts.map +1 -1
- package/dist/detectors/citation-entry.js +19 -5
- package/dist/detectors/citation-entry.js.map +1 -1
- package/dist/detectors/code-before.d.ts +6 -0
- package/dist/detectors/code-before.d.ts.map +1 -0
- package/dist/detectors/code-before.js +15 -0
- package/dist/detectors/code-before.js.map +1 -0
- package/dist/detectors/connective-hierarchy.d.ts +11 -1
- package/dist/detectors/connective-hierarchy.d.ts.map +1 -1
- package/dist/detectors/connective-hierarchy.js +26 -6
- package/dist/detectors/connective-hierarchy.js.map +1 -1
- package/dist/detectors/currency-notation.d.ts.map +1 -1
- package/dist/detectors/currency-notation.js +2 -1
- package/dist/detectors/currency-notation.js.map +1 -1
- package/dist/detectors/date-outside-period.d.ts +4 -0
- package/dist/detectors/date-outside-period.d.ts.map +1 -0
- package/dist/detectors/date-outside-period.js +34 -0
- package/dist/detectors/date-outside-period.js.map +1 -0
- package/dist/detectors/default-values.d.ts +3 -0
- package/dist/detectors/default-values.d.ts.map +1 -0
- package/dist/detectors/default-values.js +14 -0
- package/dist/detectors/default-values.js.map +1 -0
- package/dist/detectors/defined-term-form.d.ts +6 -2
- package/dist/detectors/defined-term-form.d.ts.map +1 -1
- package/dist/detectors/defined-term-form.js +72 -12
- package/dist/detectors/defined-term-form.js.map +1 -1
- package/dist/detectors/definition-use.d.ts.map +1 -1
- package/dist/detectors/definition-use.js +8 -1
- package/dist/detectors/definition-use.js.map +1 -1
- package/dist/detectors/deprecated-use.d.ts +3 -0
- package/dist/detectors/deprecated-use.d.ts.map +1 -0
- package/dist/detectors/deprecated-use.js +14 -0
- package/dist/detectors/deprecated-use.js.map +1 -0
- package/dist/detectors/derived-numbers.d.ts +1 -1
- package/dist/detectors/derived-numbers.d.ts.map +1 -1
- package/dist/detectors/derived-numbers.js +70 -15
- package/dist/detectors/derived-numbers.js.map +1 -1
- package/dist/detectors/document-shape.d.ts +1 -0
- package/dist/detectors/document-shape.d.ts.map +1 -1
- package/dist/detectors/document-shape.js +4 -1
- package/dist/detectors/document-shape.js.map +1 -1
- package/dist/detectors/due-date.d.ts +3 -0
- package/dist/detectors/due-date.d.ts.map +1 -0
- package/dist/detectors/due-date.js +38 -0
- package/dist/detectors/due-date.js.map +1 -0
- package/dist/detectors/en-shape.d.ts.map +1 -1
- package/dist/detectors/en-shape.js +17 -9
- 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 +76 -2
- package/dist/detectors/fact-consistency.js.map +1 -1
- package/dist/detectors/heading-echo.d.ts.map +1 -1
- package/dist/detectors/heading-echo.js +10 -1
- package/dist/detectors/heading-echo.js.map +1 -1
- package/dist/detectors/kana-function-word.d.ts +12 -0
- package/dist/detectors/kana-function-word.d.ts.map +1 -0
- package/dist/detectors/kana-function-word.js +59 -0
- package/dist/detectors/kana-function-word.js.map +1 -0
- package/dist/detectors/line-amount.d.ts +3 -0
- package/dist/detectors/line-amount.d.ts.map +1 -0
- package/dist/detectors/line-amount.js +22 -0
- package/dist/detectors/line-amount.js.map +1 -0
- package/dist/detectors/location-pointer.d.ts +6 -0
- package/dist/detectors/location-pointer.d.ts.map +1 -0
- package/dist/detectors/location-pointer.js +22 -0
- package/dist/detectors/location-pointer.js.map +1 -0
- package/dist/detectors/mark-shape.d.ts.map +1 -1
- package/dist/detectors/mark-shape.js +13 -1
- package/dist/detectors/mark-shape.js.map +1 -1
- package/dist/detectors/nado-closed-list.d.ts +3 -0
- package/dist/detectors/nado-closed-list.d.ts.map +1 -0
- package/dist/detectors/nado-closed-list.js +21 -0
- package/dist/detectors/nado-closed-list.js.map +1 -0
- package/dist/detectors/name-variant.d.ts.map +1 -1
- package/dist/detectors/name-variant.js +82 -8
- package/dist/detectors/name-variant.js.map +1 -1
- package/dist/detectors/next-word.d.ts.map +1 -1
- package/dist/detectors/next-word.js +41 -8
- package/dist/detectors/next-word.js.map +1 -1
- package/dist/detectors/number-word-figure.d.ts +5 -0
- package/dist/detectors/number-word-figure.d.ts.map +1 -0
- package/dist/detectors/number-word-figure.js +32 -0
- package/dist/detectors/number-word-figure.js.map +1 -0
- package/dist/detectors/obligation-without-deadline.d.ts +39 -0
- package/dist/detectors/obligation-without-deadline.d.ts.map +1 -0
- package/dist/detectors/obligation-without-deadline.js +148 -0
- package/dist/detectors/obligation-without-deadline.js.map +1 -0
- package/dist/detectors/open-end-names.d.ts +23 -0
- package/dist/detectors/open-end-names.d.ts.map +1 -0
- package/dist/detectors/open-end-names.js +95 -0
- package/dist/detectors/open-end-names.js.map +1 -0
- package/dist/detectors/ordinal-run-gaps.d.ts +8 -0
- package/dist/detectors/ordinal-run-gaps.d.ts.map +1 -0
- package/dist/detectors/ordinal-run-gaps.js +80 -0
- package/dist/detectors/ordinal-run-gaps.js.map +1 -0
- package/dist/detectors/orthographic-variant.d.ts.map +1 -1
- package/dist/detectors/orthographic-variant.js +26 -9
- package/dist/detectors/orthographic-variant.js.map +1 -1
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +5 -0
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/parameter-table.d.ts +3 -0
- package/dist/detectors/parameter-table.d.ts.map +1 -0
- package/dist/detectors/parameter-table.js +16 -0
- package/dist/detectors/parameter-table.js.map +1 -0
- package/dist/detectors/phone-number-variant.d.ts +3 -0
- package/dist/detectors/phone-number-variant.d.ts.map +1 -0
- package/dist/detectors/phone-number-variant.js +18 -0
- package/dist/detectors/phone-number-variant.js.map +1 -0
- package/dist/detectors/prerequisite-order.d.ts +3 -0
- package/dist/detectors/prerequisite-order.d.ts.map +1 -0
- package/dist/detectors/prerequisite-order.js +30 -0
- package/dist/detectors/prerequisite-order.js.map +1 -0
- package/dist/detectors/quote-unnamed-speaker.d.ts +3 -0
- package/dist/detectors/quote-unnamed-speaker.d.ts.map +1 -0
- package/dist/detectors/quote-unnamed-speaker.js +18 -0
- package/dist/detectors/quote-unnamed-speaker.js.map +1 -0
- package/dist/detectors/quote-without-source.d.ts +12 -2
- package/dist/detectors/quote-without-source.d.ts.map +1 -1
- package/dist/detectors/quote-without-source.js +45 -11
- package/dist/detectors/quote-without-source.js.map +1 -1
- package/dist/detectors/registry/amount-range.d.ts +3 -0
- package/dist/detectors/registry/amount-range.d.ts.map +1 -0
- package/dist/detectors/registry/amount-range.js +3 -0
- package/dist/detectors/registry/amount-range.js.map +1 -0
- package/dist/detectors/registry/arrival-before-departure.d.ts +3 -0
- package/dist/detectors/registry/arrival-before-departure.d.ts.map +1 -0
- package/dist/detectors/registry/arrival-before-departure.js +3 -0
- package/dist/detectors/registry/arrival-before-departure.js.map +1 -0
- package/dist/detectors/registry/date-outside-period.d.ts +3 -0
- package/dist/detectors/registry/date-outside-period.d.ts.map +1 -0
- package/dist/detectors/registry/date-outside-period.js +3 -0
- package/dist/detectors/registry/date-outside-period.js.map +1 -0
- package/dist/detectors/registry/default-values.d.ts +3 -0
- package/dist/detectors/registry/default-values.d.ts.map +1 -0
- package/dist/detectors/registry/default-values.js +3 -0
- package/dist/detectors/registry/default-values.js.map +1 -0
- package/dist/detectors/registry/deprecated-use.d.ts +3 -0
- package/dist/detectors/registry/deprecated-use.d.ts.map +1 -0
- package/dist/detectors/registry/deprecated-use.js +3 -0
- package/dist/detectors/registry/deprecated-use.js.map +1 -0
- package/dist/detectors/registry/due-date.d.ts +3 -0
- package/dist/detectors/registry/due-date.d.ts.map +1 -0
- package/dist/detectors/registry/due-date.js +3 -0
- package/dist/detectors/registry/due-date.js.map +1 -0
- package/dist/detectors/registry/kana-function-word.d.ts +3 -0
- package/dist/detectors/registry/kana-function-word.d.ts.map +1 -0
- package/dist/detectors/registry/kana-function-word.js +3 -0
- package/dist/detectors/registry/kana-function-word.js.map +1 -0
- package/dist/detectors/registry/line-amount.d.ts +3 -0
- package/dist/detectors/registry/line-amount.d.ts.map +1 -0
- package/dist/detectors/registry/line-amount.js +3 -0
- package/dist/detectors/registry/line-amount.js.map +1 -0
- package/dist/detectors/registry/nado-closed-list.d.ts +3 -0
- package/dist/detectors/registry/nado-closed-list.d.ts.map +1 -0
- package/dist/detectors/registry/nado-closed-list.js +3 -0
- package/dist/detectors/registry/nado-closed-list.js.map +1 -0
- package/dist/detectors/registry/number-word-figure.d.ts +3 -0
- package/dist/detectors/registry/number-word-figure.d.ts.map +1 -0
- package/dist/detectors/registry/number-word-figure.js +3 -0
- package/dist/detectors/registry/number-word-figure.js.map +1 -0
- package/dist/detectors/registry/obligation-without-deadline.d.ts +3 -0
- package/dist/detectors/registry/obligation-without-deadline.d.ts.map +1 -0
- package/dist/detectors/registry/obligation-without-deadline.js +3 -0
- package/dist/detectors/registry/obligation-without-deadline.js.map +1 -0
- package/dist/detectors/registry/parameter-table.d.ts +3 -0
- package/dist/detectors/registry/parameter-table.d.ts.map +1 -0
- package/dist/detectors/registry/parameter-table.js +3 -0
- package/dist/detectors/registry/parameter-table.js.map +1 -0
- package/dist/detectors/registry/phone-number-variant.d.ts +3 -0
- package/dist/detectors/registry/phone-number-variant.d.ts.map +1 -0
- package/dist/detectors/registry/phone-number-variant.js +3 -0
- package/dist/detectors/registry/phone-number-variant.js.map +1 -0
- package/dist/detectors/registry/prerequisite-order.d.ts +3 -0
- package/dist/detectors/registry/prerequisite-order.d.ts.map +1 -0
- package/dist/detectors/registry/prerequisite-order.js +3 -0
- package/dist/detectors/registry/prerequisite-order.js.map +1 -0
- package/dist/detectors/registry/quote-unnamed-speaker.d.ts +3 -0
- package/dist/detectors/registry/quote-unnamed-speaker.d.ts.map +1 -0
- package/dist/detectors/registry/quote-unnamed-speaker.js +3 -0
- package/dist/detectors/registry/quote-unnamed-speaker.js.map +1 -0
- package/dist/detectors/registry/tax-amount.d.ts +3 -0
- package/dist/detectors/registry/tax-amount.d.ts.map +1 -0
- package/dist/detectors/registry/tax-amount.js +3 -0
- package/dist/detectors/registry/tax-amount.js.map +1 -0
- package/dist/detectors/registry/time-order.d.ts +3 -0
- package/dist/detectors/registry/time-order.d.ts.map +1 -0
- package/dist/detectors/registry/time-order.js +3 -0
- package/dist/detectors/registry/time-order.js.map +1 -0
- package/dist/detectors/registry/ui-label.d.ts +3 -0
- package/dist/detectors/registry/ui-label.d.ts.map +1 -0
- package/dist/detectors/registry/ui-label.js +3 -0
- package/dist/detectors/registry/ui-label.js.map +1 -0
- package/dist/detectors/registry/undefined-call.d.ts +3 -0
- package/dist/detectors/registry/undefined-call.d.ts.map +1 -0
- package/dist/detectors/registry/undefined-call.js +3 -0
- package/dist/detectors/registry/undefined-call.js.map +1 -0
- package/dist/detectors/registry/undefined-term.d.ts +3 -0
- package/dist/detectors/registry/undefined-term.d.ts.map +1 -0
- package/dist/detectors/registry/undefined-term.js +3 -0
- package/dist/detectors/registry/undefined-term.js.map +1 -0
- package/dist/detectors/registry/version-order.d.ts +3 -0
- package/dist/detectors/registry/version-order.d.ts.map +1 -0
- package/dist/detectors/registry/version-order.js +3 -0
- package/dist/detectors/registry/version-order.js.map +1 -0
- package/dist/detectors/registry/warning-action.d.ts +3 -0
- package/dist/detectors/registry/warning-action.d.ts.map +1 -0
- package/dist/detectors/registry/warning-action.js +3 -0
- package/dist/detectors/registry/warning-action.js.map +1 -0
- package/dist/detectors/requirement-smell.d.ts.map +1 -1
- package/dist/detectors/requirement-smell.js +25 -8
- package/dist/detectors/requirement-smell.js.map +1 -1
- package/dist/detectors/structure-tree.d.ts +12 -4
- package/dist/detectors/structure-tree.d.ts.map +1 -1
- package/dist/detectors/structure-tree.js +31 -14
- package/dist/detectors/structure-tree.js.map +1 -1
- package/dist/detectors/superlative-scope.d.ts.map +1 -1
- package/dist/detectors/superlative-scope.js +11 -1
- package/dist/detectors/superlative-scope.js.map +1 -1
- package/dist/detectors/tax-amount.d.ts +3 -0
- package/dist/detectors/tax-amount.d.ts.map +1 -0
- package/dist/detectors/tax-amount.js +19 -0
- package/dist/detectors/tax-amount.js.map +1 -0
- package/dist/detectors/technical-docs.d.ts.map +1 -1
- package/dist/detectors/technical-docs.js +5 -1
- package/dist/detectors/technical-docs.js.map +1 -1
- package/dist/detectors/term-extension.d.ts +14 -0
- package/dist/detectors/term-extension.d.ts.map +1 -0
- package/dist/detectors/term-extension.js +67 -0
- package/dist/detectors/term-extension.js.map +1 -0
- package/dist/detectors/time-order.d.ts +4 -0
- package/dist/detectors/time-order.d.ts.map +1 -0
- package/dist/detectors/time-order.js +32 -0
- package/dist/detectors/time-order.js.map +1 -0
- package/dist/detectors/ui-label.d.ts +3 -0
- package/dist/detectors/ui-label.d.ts.map +1 -0
- package/dist/detectors/ui-label.js +16 -0
- package/dist/detectors/ui-label.js.map +1 -0
- package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
- package/dist/detectors/unbalanced-bracket.js +8 -13
- package/dist/detectors/unbalanced-bracket.js.map +1 -1
- package/dist/detectors/undefined-call.d.ts +3 -0
- package/dist/detectors/undefined-call.d.ts.map +1 -0
- package/dist/detectors/undefined-call.js +18 -0
- package/dist/detectors/undefined-call.js.map +1 -0
- package/dist/detectors/undefined-term.d.ts +22 -0
- package/dist/detectors/undefined-term.d.ts.map +1 -0
- package/dist/detectors/undefined-term.js +85 -0
- package/dist/detectors/undefined-term.js.map +1 -0
- package/dist/detectors/unknown-word.d.ts +1 -1
- package/dist/detectors/unknown-word.js +3 -3
- package/dist/detectors/unknown-word.js.map +1 -1
- package/dist/detectors/vague-deadline.d.ts +4 -0
- package/dist/detectors/vague-deadline.d.ts.map +1 -1
- package/dist/detectors/vague-deadline.js +3 -3
- package/dist/detectors/vague-deadline.js.map +1 -1
- package/dist/detectors/version-mismatch.d.ts.map +1 -1
- package/dist/detectors/version-mismatch.js +18 -1
- package/dist/detectors/version-mismatch.js.map +1 -1
- package/dist/detectors/version-order.d.ts +3 -0
- package/dist/detectors/version-order.d.ts.map +1 -0
- package/dist/detectors/version-order.js +43 -0
- package/dist/detectors/version-order.js.map +1 -0
- package/dist/detectors/warning-action.d.ts +3 -0
- package/dist/detectors/warning-action.d.ts.map +1 -0
- package/dist/detectors/warning-action.js +48 -0
- package/dist/detectors/warning-action.js.map +1 -0
- package/dist/facts/condition-pairs.d.ts +51 -0
- package/dist/facts/condition-pairs.d.ts.map +1 -0
- package/dist/facts/condition-pairs.js +203 -0
- package/dist/facts/condition-pairs.js.map +1 -0
- package/dist/facts/event-dates.d.ts +26 -0
- package/dist/facts/event-dates.d.ts.map +1 -0
- package/dist/facts/event-dates.js +38 -0
- package/dist/facts/event-dates.js.map +1 -0
- package/dist/facts/fact-scope.d.ts +2 -0
- package/dist/facts/fact-scope.d.ts.map +1 -1
- package/dist/facts/fact-scope.js +5 -0
- package/dist/facts/fact-scope.js.map +1 -1
- package/dist/facts/labelled-facts.d.ts +2 -0
- package/dist/facts/labelled-facts.d.ts.map +1 -1
- package/dist/facts/labelled-facts.js +9 -1
- package/dist/facts/labelled-facts.js.map +1 -1
- package/dist/facts/table-facts.d.ts +16 -0
- package/dist/facts/table-facts.d.ts.map +1 -1
- package/dist/facts/table-facts.js +2 -2
- package/dist/facts/table-facts.js.map +1 -1
- package/dist/grade/ai-score.d.ts +1 -1
- package/dist/grade/ai-score.d.ts.map +1 -1
- package/dist/grade/text.js +2 -2
- package/dist/grade/text.js.map +1 -1
- package/dist/heading-numbering.js +2 -2
- package/dist/heading-numbering.js.map +1 -1
- package/dist/html/fetch-page.d.ts +20 -0
- package/dist/html/fetch-page.d.ts.map +1 -0
- package/dist/html/fetch-page.js +51 -0
- package/dist/html/fetch-page.js.map +1 -0
- package/dist/html/fetched-text.d.ts +5 -0
- package/dist/html/fetched-text.d.ts.map +1 -0
- package/dist/html/fetched-text.js +25 -0
- package/dist/html/fetched-text.js.map +1 -0
- package/dist/html/html-content-block.d.ts +6 -0
- package/dist/html/html-content-block.d.ts.map +1 -0
- package/dist/html/html-content-block.js +86 -0
- package/dist/html/html-content-block.js.map +1 -0
- package/dist/html/html-elements.d.ts +41 -0
- package/dist/html/html-elements.d.ts.map +1 -0
- package/dist/html/html-elements.js +91 -0
- package/dist/html/html-elements.js.map +1 -0
- package/dist/html/html-footnote-marks.d.ts +2 -0
- package/dist/html/html-footnote-marks.d.ts.map +1 -0
- package/dist/html/html-footnote-marks.js +15 -0
- package/dist/html/html-footnote-marks.js.map +1 -0
- package/dist/html/html-heading-links.d.ts +6 -0
- package/dist/html/html-heading-links.d.ts.map +1 -0
- package/dist/html/html-heading-links.js +71 -0
- package/dist/html/html-heading-links.js.map +1 -0
- package/dist/html/html-lost-tags.d.ts +3 -0
- package/dist/html/html-lost-tags.d.ts.map +1 -0
- package/dist/html/html-lost-tags.js +11 -0
- package/dist/html/html-lost-tags.js.map +1 -0
- package/dist/html/html-markdown.d.ts +2 -0
- package/dist/html/html-markdown.d.ts.map +1 -0
- package/dist/html/html-markdown.js +347 -0
- package/dist/html/html-markdown.js.map +1 -0
- package/dist/html/html-preformatted.d.ts +17 -0
- package/dist/html/html-preformatted.d.ts.map +1 -0
- package/dist/html/html-preformatted.js +82 -0
- package/dist/html/html-preformatted.js.map +1 -0
- package/dist/html/html-reader-only.d.ts +6 -0
- package/dist/html/html-reader-only.d.ts.map +1 -0
- package/dist/html/html-reader-only.js +63 -0
- package/dist/html/html-reader-only.js.map +1 -0
- package/dist/html/html-run-in-headings.d.ts +2 -0
- package/dist/html/html-run-in-headings.d.ts.map +1 -0
- package/dist/html/html-run-in-headings.js +36 -0
- package/dist/html/html-run-in-headings.js.map +1 -0
- package/dist/html/html-tables.d.ts +3 -0
- package/dist/html/html-tables.d.ts.map +1 -0
- package/dist/html/html-tables.js +58 -0
- package/dist/html/html-tables.js.map +1 -0
- package/dist/html/html-widgets.d.ts +3 -0
- package/dist/html/html-widgets.d.ts.map +1 -0
- package/dist/html/html-widgets.js +71 -0
- package/dist/html/html-widgets.js.map +1 -0
- package/dist/html/markup-text.d.ts +5 -0
- package/dist/html/markup-text.d.ts.map +1 -0
- package/dist/html/markup-text.js +32 -0
- package/dist/html/markup-text.js.map +1 -0
- package/dist/html/page-document.d.ts +9 -0
- package/dist/html/page-document.d.ts.map +1 -0
- package/dist/html/page-document.js +19 -0
- package/dist/html/page-document.js.map +1 -0
- package/dist/inline-count.d.ts +19 -0
- package/dist/inline-count.d.ts.map +1 -0
- package/dist/inline-count.js +109 -0
- package/dist/inline-count.js.map +1 -0
- package/dist/kana-spelling.d.ts +5 -0
- package/dist/kana-spelling.d.ts.map +1 -1
- package/dist/kana-spelling.js +5 -0
- package/dist/kana-spelling.js.map +1 -1
- package/dist/location-part.d.ts +13 -0
- package/dist/location-part.d.ts.map +1 -0
- package/dist/location-part.js +24 -0
- package/dist/location-part.js.map +1 -0
- package/dist/nado-closed-list.d.ts +20 -0
- package/dist/nado-closed-list.d.ts.map +1 -0
- package/dist/nado-closed-list.js +72 -0
- package/dist/nado-closed-list.js.map +1 -0
- package/dist/name-cue.d.ts +17 -0
- package/dist/name-cue.d.ts.map +1 -0
- package/dist/name-cue.js +29 -0
- package/dist/name-cue.js.map +1 -0
- package/dist/name-variants.d.ts +23 -1
- package/dist/name-variants.d.ts.map +1 -1
- package/dist/name-variants.js +39 -8
- package/dist/name-variants.js.map +1 -1
- package/dist/paragraph-runs.d.ts +6 -1
- package/dist/paragraph-runs.d.ts.map +1 -1
- package/dist/paragraph-runs.js +9 -2
- package/dist/paragraph-runs.js.map +1 -1
- package/dist/parameter-table.d.ts +19 -0
- package/dist/parameter-table.d.ts.map +1 -0
- package/dist/parameter-table.js +191 -0
- package/dist/parameter-table.js.map +1 -0
- package/dist/phone-numbers.d.ts +23 -0
- package/dist/phone-numbers.d.ts.map +1 -0
- package/dist/phone-numbers.js +83 -0
- package/dist/phone-numbers.js.map +1 -0
- package/dist/place-names.d.ts +55 -0
- package/dist/place-names.d.ts.map +1 -0
- package/dist/place-names.js +196 -0
- package/dist/place-names.js.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prerequisite-order.d.ts +16 -0
- package/dist/prerequisite-order.d.ts.map +1 -0
- package/dist/prerequisite-order.js +29 -0
- package/dist/prerequisite-order.js.map +1 -0
- package/dist/profile/parse.d.ts.map +1 -1
- package/dist/profile/parse.js +10 -1
- package/dist/profile/parse.js.map +1 -1
- package/dist/reasons.d.ts +2 -0
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +2 -0
- package/dist/reasons.js.map +1 -1
- package/dist/render/rules-json.d.ts.map +1 -1
- package/dist/render/rules-json.js +4 -0
- package/dist/render/rules-json.js.map +1 -1
- package/dist/render/rules-table.d.ts.map +1 -1
- package/dist/render/rules-table.js +6 -2
- package/dist/render/rules-table.js.map +1 -1
- package/dist/rule-genres.d.ts +5 -2
- package/dist/rule-genres.d.ts.map +1 -1
- package/dist/rule-genres.js +2 -0
- package/dist/rule-genres.js.map +1 -1
- package/dist/rule-load.d.ts.map +1 -1
- package/dist/rule-load.js +2 -1
- package/dist/rule-load.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +5 -1
- package/dist/run.js.map +1 -1
- package/dist/spelling.d.ts +2 -0
- package/dist/spelling.d.ts.map +1 -1
- package/dist/spelling.js +6 -0
- package/dist/spelling.js.map +1 -1
- package/dist/structure/action-due.d.ts +21 -0
- package/dist/structure/action-due.d.ts.map +1 -0
- package/dist/structure/action-due.js +126 -0
- package/dist/structure/action-due.js.map +1 -0
- package/dist/structure/amount-range.d.ts +30 -0
- package/dist/structure/amount-range.d.ts.map +1 -0
- package/dist/structure/amount-range.js +153 -0
- package/dist/structure/amount-range.js.map +1 -0
- package/dist/structure/amount-scale.d.ts +6 -0
- package/dist/structure/amount-scale.d.ts.map +1 -1
- package/dist/structure/amount-scale.js +13 -0
- package/dist/structure/amount-scale.js.map +1 -1
- package/dist/structure/cite.d.ts +5 -2
- package/dist/structure/cite.d.ts.map +1 -1
- package/dist/structure/cite.js +20 -1
- package/dist/structure/cite.js.map +1 -1
- package/dist/structure/counted-amounts.d.ts +12 -0
- package/dist/structure/counted-amounts.d.ts.map +1 -0
- package/dist/structure/counted-amounts.js +30 -0
- package/dist/structure/counted-amounts.js.map +1 -0
- package/dist/structure/date-order.d.ts +24 -3
- package/dist/structure/date-order.d.ts.map +1 -1
- package/dist/structure/date-order.js +49 -17
- package/dist/structure/date-order.js.map +1 -1
- package/dist/structure/date-outside-period.d.ts +27 -0
- package/dist/structure/date-outside-period.d.ts.map +1 -0
- package/dist/structure/date-outside-period.js +86 -0
- package/dist/structure/date-outside-period.js.map +1 -0
- package/dist/structure/definition-use.d.ts +5 -2
- package/dist/structure/definition-use.d.ts.map +1 -1
- package/dist/structure/definition-use.js +11 -3
- package/dist/structure/definition-use.js.map +1 -1
- package/dist/structure/due-date.d.ts +19 -0
- package/dist/structure/due-date.d.ts.map +1 -0
- package/dist/structure/due-date.js +30 -0
- package/dist/structure/due-date.js.map +1 -0
- package/dist/structure/heading-runs.d.ts +9 -0
- package/dist/structure/heading-runs.d.ts.map +1 -0
- package/dist/structure/heading-runs.js +23 -0
- package/dist/structure/heading-runs.js.map +1 -0
- package/dist/structure/install-pin.d.ts +46 -0
- package/dist/structure/install-pin.d.ts.map +1 -0
- package/dist/structure/install-pin.js +85 -0
- package/dist/structure/install-pin.js.map +1 -0
- package/dist/structure/leg-times.d.ts +34 -0
- package/dist/structure/leg-times.d.ts.map +1 -0
- package/dist/structure/leg-times.js +135 -0
- package/dist/structure/leg-times.js.map +1 -0
- package/dist/structure/line-amount-unit.d.ts +24 -0
- package/dist/structure/line-amount-unit.d.ts.map +1 -0
- package/dist/structure/line-amount-unit.js +24 -0
- package/dist/structure/line-amount-unit.js.map +1 -0
- package/dist/structure/line-amount.d.ts +40 -0
- package/dist/structure/line-amount.d.ts.map +1 -0
- package/dist/structure/line-amount.js +118 -0
- package/dist/structure/line-amount.js.map +1 -0
- package/dist/structure/number-word-figure.d.ts +37 -0
- package/dist/structure/number-word-figure.d.ts.map +1 -0
- package/dist/structure/number-word-figure.js +151 -0
- package/dist/structure/number-word-figure.js.map +1 -0
- package/dist/structure/numbering.d.ts +1 -0
- package/dist/structure/numbering.d.ts.map +1 -1
- package/dist/structure/numbering.js +3 -0
- package/dist/structure/numbering.js.map +1 -1
- package/dist/structure/ordinal-runs.d.ts +45 -0
- package/dist/structure/ordinal-runs.d.ts.map +1 -0
- package/dist/structure/ordinal-runs.js +78 -0
- package/dist/structure/ordinal-runs.js.map +1 -0
- package/dist/structure/percent-sum-prose.d.ts +1 -1
- package/dist/structure/percent-sum-prose.d.ts.map +1 -1
- package/dist/structure/percent-sum-prose.js +45 -3
- package/dist/structure/percent-sum-prose.js.map +1 -1
- package/dist/structure/percent-sum.d.ts +8 -0
- package/dist/structure/percent-sum.d.ts.map +1 -1
- package/dist/structure/percent-sum.js +8 -1
- package/dist/structure/percent-sum.js.map +1 -1
- package/dist/structure/release-list.d.ts +9 -0
- package/dist/structure/release-list.d.ts.map +1 -0
- package/dist/structure/release-list.js +46 -0
- package/dist/structure/release-list.js.map +1 -0
- package/dist/structure/share-column.d.ts +7 -0
- package/dist/structure/share-column.d.ts.map +1 -0
- package/dist/structure/share-column.js +22 -0
- package/dist/structure/share-column.js.map +1 -0
- package/dist/structure/stated-period.d.ts +31 -0
- package/dist/structure/stated-period.d.ts.map +1 -0
- package/dist/structure/stated-period.js +127 -0
- package/dist/structure/stated-period.js.map +1 -0
- package/dist/structure/tax.d.ts +25 -0
- package/dist/structure/tax.d.ts.map +1 -0
- package/dist/structure/tax.js +86 -0
- package/dist/structure/tax.js.map +1 -0
- package/dist/structure/time-marks.d.ts +58 -0
- package/dist/structure/time-marks.d.ts.map +1 -0
- package/dist/structure/time-marks.js +74 -0
- package/dist/structure/time-marks.js.map +1 -0
- package/dist/structure/time-order.d.ts +21 -0
- package/dist/structure/time-order.d.ts.map +1 -0
- package/dist/structure/time-order.js +108 -0
- package/dist/structure/time-order.js.map +1 -0
- package/dist/structure/title-lines.d.ts +8 -0
- package/dist/structure/title-lines.d.ts.map +1 -0
- package/dist/structure/title-lines.js +27 -0
- package/dist/structure/title-lines.js.map +1 -0
- package/dist/structure/total.d.ts.map +1 -1
- package/dist/structure/total.js +3 -1
- package/dist/structure/total.js.map +1 -1
- package/dist/structure/version-mismatch.d.ts +1 -5
- package/dist/structure/version-mismatch.d.ts.map +1 -1
- package/dist/structure/version-mismatch.js +65 -12
- package/dist/structure/version-mismatch.js.map +1 -1
- package/dist/structure/version-order.d.ts +23 -0
- package/dist/structure/version-order.d.ts.map +1 -0
- package/dist/structure/version-order.js +67 -0
- package/dist/structure/version-order.js.map +1 -0
- package/dist/table-text.d.ts +9 -0
- package/dist/table-text.d.ts.map +1 -0
- package/dist/table-text.js +36 -0
- package/dist/table-text.js.map +1 -0
- package/dist/ui-labels.d.ts +16 -0
- package/dist/ui-labels.d.ts.map +1 -0
- package/dist/ui-labels.js +42 -0
- package/dist/ui-labels.js.map +1 -0
- package/dist/undefined-call.d.ts +13 -0
- package/dist/undefined-call.d.ts.map +1 -0
- package/dist/undefined-call.js +55 -0
- package/dist/undefined-call.js.map +1 -0
- package/dist/unnamed-speaker.d.ts +23 -0
- package/dist/unnamed-speaker.d.ts.map +1 -0
- package/dist/unnamed-speaker.js +176 -0
- package/dist/unnamed-speaker.js.map +1 -0
- package/dist/warning-action.d.ts +22 -0
- package/dist/warning-action.d.ts.map +1 -0
- package/dist/warning-action.js +58 -0
- package/dist/warning-action.js.map +1 -0
- package/genres.yaml +2 -0
- package/package.json +4 -3
- package/profiles/statute.yaml +8 -0
- package/rules/agreement-slip.yaml +2 -2
- package/rules/amount-range-reversed.yaml +52 -0
- package/rules/amount-scale-consistency.yaml +4 -4
- package/rules/announced-count-mismatch.yaml +9 -4
- package/rules/arrival-before-departure.yaml +48 -0
- package/rules/connective-hierarchy.yaml +3 -3
- package/rules/currency-notation-consistency.yaml +2 -2
- package/rules/date-order.yaml +9 -4
- package/rules/date-outside-period.yaml +64 -0
- package/rules/default-value-mismatch.yaml +79 -0
- package/rules/defined-term-form.yaml +9 -7
- package/rules/deprecated-option-used.yaml +78 -0
- package/rules/doubled-nado.yaml +28 -12
- package/rules/due-before-issue.yaml +68 -0
- package/rules/duplicate-definition.yaml +2 -2
- package/rules/duration-mismatch.yaml +12 -4
- package/rules/heading-echo.yaml +2 -2
- package/rules/hyphen-as-dash.yaml +2 -2
- package/rules/kana-function-word.yaml +58 -0
- package/rules/latin-spacing.yaml +6 -5
- package/rules/line-amount-mismatch.yaml +58 -0
- package/rules/nado-closed-list.yaml +77 -0
- package/rules/name-variant.yaml +14 -2
- package/rules/number-word-figure-mismatch.yaml +76 -0
- package/rules/numbering-gap.yaml +2 -2
- package/rules/obligation-without-deadline.yaml +95 -0
- package/rules/one-sentence-paragraph-run.yaml +2 -3
- package/rules/parameter-table-mismatch.yaml +90 -0
- package/rules/percent-sum-mismatch.yaml +2 -2
- package/rules/phone-number-variant.yaml +68 -0
- package/rules/prerequisite-after-step.yaml +78 -0
- package/rules/quote-unnamed-speaker.yaml +67 -0
- package/rules/quote-without-source.yaml +6 -6
- package/rules/requirement-smell.yaml +3 -3
- package/rules/sentence-initial-conjunction-run.yaml +13 -7
- package/rules/summary-fact-mismatch.yaml +4 -4
- package/rules/tax-mismatch.yaml +71 -0
- package/rules/time-order.yaml +65 -0
- package/rules/title-length.yaml +2 -2
- package/rules/ui-label-variant.yaml +70 -0
- package/rules/unbalanced-bracket.yaml +4 -4
- package/rules/uncomparable-graded.yaml +29 -10
- package/rules/undefined-function-call.yaml +77 -0
- package/rules/undefined-term.yaml +72 -0
- package/rules/unknown-word.yaml +2 -2
- package/rules/unqualified-superlative.yaml +2 -2
- package/rules/use-before-definition.yaml +2 -2
- package/rules/version-mismatch.yaml +12 -4
- package/rules/version-order.yaml +85 -0
- package/rules/very-adjective.yaml +31 -13
- package/rules/warning-without-action.yaml +64 -0
- package/rules/wordy-phrase.yaml +27 -9
- package/src/ai-score/of-document.ts +19 -9
- package/src/ai-score/render.ts +24 -4
- package/src/ai-score/score.ts +24 -3
- package/src/ai-score/signals.ts +12 -2
- package/src/ai-score/text.ts +7 -2
- package/src/announced-count.ts +19 -12
- package/src/check-source.ts +11 -2
- package/src/cli-text.ts +38 -16
- package/src/cli.ts +2 -1
- package/src/commands/cite-claims.ts +103 -0
- package/src/commands/cite-page.ts +61 -0
- package/src/commands/cite-scaffold.ts +27 -0
- package/src/commands/cite.ts +127 -58
- package/src/company-names.ts +202 -0
- package/src/default-values.ts +158 -0
- package/src/deprecated-use.ts +122 -0
- package/src/derived/stays.ts +145 -0
- package/src/detectors/acronym-context.ts +10 -2
- package/src/detectors/address-word.ts +9 -0
- package/src/detectors/agreement-slip.ts +7 -1
- package/src/detectors/ai-phrasing.ts +6 -1
- package/src/detectors/amount-range.ts +54 -0
- package/src/detectors/amount-scale.ts +50 -17
- package/src/detectors/announced-count.ts +29 -11
- package/src/detectors/bare-comparative.ts +7 -2
- package/src/detectors/block-quotation.ts +95 -0
- package/src/detectors/bracket-label.ts +58 -0
- package/src/detectors/citation-entry.ts +20 -5
- package/src/detectors/code-before.ts +14 -0
- package/src/detectors/connective-hierarchy.ts +39 -11
- package/src/detectors/currency-notation.ts +2 -1
- package/src/detectors/date-outside-period.ts +38 -0
- package/src/detectors/default-values.ts +17 -0
- package/src/detectors/defined-term-form.ts +84 -15
- package/src/detectors/definition-use.ts +10 -2
- package/src/detectors/deprecated-use.ts +17 -0
- package/src/detectors/derived-numbers.ts +106 -15
- package/src/detectors/document-shape.ts +6 -1
- package/src/detectors/due-date.ts +47 -0
- package/src/detectors/en-shape.ts +27 -11
- package/src/detectors/fact-consistency.ts +95 -3
- package/src/detectors/heading-echo.ts +11 -1
- package/src/detectors/kana-function-word.ts +71 -0
- package/src/detectors/line-amount.ts +33 -0
- package/src/detectors/location-pointer.ts +30 -0
- package/src/detectors/mark-shape.ts +18 -1
- package/src/detectors/nado-closed-list.ts +25 -0
- package/src/detectors/name-variant.ts +106 -13
- package/src/detectors/next-word.ts +56 -9
- package/src/detectors/number-word-figure.ts +43 -0
- package/src/detectors/obligation-without-deadline.ts +192 -0
- package/src/detectors/open-end-names.ts +140 -0
- package/src/detectors/ordinal-run-gaps.ts +101 -0
- package/src/detectors/orthographic-variant.ts +39 -14
- package/src/detectors/orthography.ts +6 -1
- package/src/detectors/parameter-table.ts +17 -0
- package/src/detectors/phone-number-variant.ts +18 -0
- package/src/detectors/prerequisite-order.ts +35 -0
- package/src/detectors/quote-unnamed-speaker.ts +19 -0
- package/src/detectors/quote-without-source.ts +57 -10
- package/src/detectors/registry/amount-range.ts +4 -0
- package/src/detectors/registry/arrival-before-departure.ts +4 -0
- package/src/detectors/registry/date-outside-period.ts +4 -0
- package/src/detectors/registry/default-values.ts +4 -0
- package/src/detectors/registry/deprecated-use.ts +4 -0
- package/src/detectors/registry/due-date.ts +4 -0
- package/src/detectors/registry/kana-function-word.ts +4 -0
- package/src/detectors/registry/line-amount.ts +4 -0
- package/src/detectors/registry/nado-closed-list.ts +4 -0
- package/src/detectors/registry/number-word-figure.ts +4 -0
- package/src/detectors/registry/obligation-without-deadline.ts +4 -0
- package/src/detectors/registry/parameter-table.ts +4 -0
- package/src/detectors/registry/phone-number-variant.ts +4 -0
- package/src/detectors/registry/prerequisite-order.ts +4 -0
- package/src/detectors/registry/quote-unnamed-speaker.ts +4 -0
- package/src/detectors/registry/tax-amount.ts +4 -0
- package/src/detectors/registry/time-order.ts +4 -0
- package/src/detectors/registry/ui-label.ts +4 -0
- package/src/detectors/registry/undefined-call.ts +4 -0
- package/src/detectors/registry/undefined-term.ts +4 -0
- package/src/detectors/registry/version-order.ts +4 -0
- package/src/detectors/registry/warning-action.ts +4 -0
- package/src/detectors/requirement-smell.ts +29 -9
- package/src/detectors/structure-tree.ts +43 -21
- package/src/detectors/superlative-scope.ts +13 -1
- package/src/detectors/tax-amount.ts +25 -0
- package/src/detectors/technical-docs.ts +7 -1
- package/src/detectors/term-extension.ts +67 -0
- package/src/detectors/time-order.ts +49 -0
- package/src/detectors/ui-label.ts +17 -0
- package/src/detectors/unbalanced-bracket.ts +7 -14
- package/src/detectors/undefined-call.ts +19 -0
- package/src/detectors/undefined-term.ts +103 -0
- package/src/detectors/unknown-word.ts +3 -3
- package/src/detectors/vague-deadline.ts +3 -3
- package/src/detectors/version-mismatch.ts +26 -5
- package/src/detectors/version-order.ts +50 -0
- package/src/detectors/warning-action.ts +49 -0
- package/src/facts/condition-pairs.ts +289 -0
- package/src/facts/event-dates.ts +63 -0
- package/src/facts/fact-scope.ts +6 -0
- package/src/facts/labelled-facts.ts +13 -1
- package/src/facts/table-facts.ts +3 -3
- package/src/grade/ai-score.ts +1 -1
- package/src/grade/text.ts +2 -2
- package/src/heading-numbering.ts +2 -2
- package/src/html/fetch-page.ts +64 -0
- package/src/html/fetched-text.ts +32 -0
- package/src/html/html-content-block.ts +107 -0
- package/src/html/html-elements.ts +127 -0
- package/src/html/html-footnote-marks.ts +20 -0
- package/src/html/html-heading-links.ts +93 -0
- package/src/html/html-lost-tags.ts +14 -0
- package/src/html/html-markdown.ts +481 -0
- package/src/html/html-preformatted.ts +110 -0
- package/src/html/html-reader-only.ts +82 -0
- package/src/html/html-run-in-headings.ts +43 -0
- package/src/html/html-tables.ts +76 -0
- package/src/html/html-widgets.ts +114 -0
- package/src/html/markup-text.ts +35 -0
- package/src/html/page-document.ts +22 -0
- package/src/inline-count.ts +146 -0
- package/src/kana-spelling.ts +7 -0
- package/src/location-part.ts +30 -0
- package/src/nado-closed-list.ts +106 -0
- package/src/name-cue.ts +35 -0
- package/src/name-variants.ts +57 -11
- package/src/paragraph-runs.ts +12 -2
- package/src/parameter-table.ts +208 -0
- package/src/phone-numbers.ts +98 -0
- package/src/place-names.ts +248 -0
- package/src/plugin.ts +4 -0
- package/src/prerequisite-order.ts +39 -0
- package/src/profile/parse.ts +10 -1
- package/src/reasons.ts +4 -0
- package/src/render/rules-json.ts +4 -0
- package/src/render/rules-table.ts +6 -3
- package/src/rule-genres.ts +5 -2
- package/src/rule-load.ts +3 -2
- package/src/run.ts +3 -1
- package/src/spelling.ts +8 -0
- package/src/structure/action-due.ts +179 -0
- package/src/structure/amount-range.ts +219 -0
- package/src/structure/amount-scale.ts +18 -0
- package/src/structure/cite.ts +21 -2
- package/src/structure/counted-amounts.ts +42 -0
- package/src/structure/date-order.ts +72 -22
- package/src/structure/date-outside-period.ts +127 -0
- package/src/structure/definition-use.ts +24 -3
- package/src/structure/due-date.ts +46 -0
- package/src/structure/heading-runs.ts +24 -0
- package/src/structure/install-pin.ts +115 -0
- package/src/structure/leg-times.ts +198 -0
- package/src/structure/line-amount-unit.ts +35 -0
- package/src/structure/line-amount.ts +162 -0
- package/src/structure/number-word-figure.ts +199 -0
- package/src/structure/numbering.ts +3 -0
- package/src/structure/ordinal-runs.ts +107 -0
- package/src/structure/percent-sum-prose.ts +46 -3
- package/src/structure/percent-sum.ts +16 -2
- package/src/structure/release-list.ts +69 -0
- package/src/structure/share-column.ts +25 -0
- package/src/structure/stated-period.ts +161 -0
- package/src/structure/tax.ts +114 -0
- package/src/structure/time-marks.ts +127 -0
- package/src/structure/time-order.ts +140 -0
- package/src/structure/title-lines.ts +33 -0
- package/src/structure/total.ts +5 -1
- package/src/structure/version-mismatch.ts +67 -13
- package/src/structure/version-order.ts +84 -0
- package/src/table-text.ts +39 -0
- package/src/ui-labels.ts +55 -0
- package/src/undefined-call.ts +65 -0
- package/src/unnamed-speaker.ts +224 -0
- package/src/warning-action.ts +73 -0
- package/styles/koyobun.yaml +7 -4
package/src/cli.ts
CHANGED
|
@@ -50,6 +50,7 @@ import { notRunAmong } from "./not-run.ts";
|
|
|
50
50
|
import { settingProblems } from "./setting-problems.ts";
|
|
51
51
|
import { withExtensions } from "./extension/load.ts";
|
|
52
52
|
import { offOnlyAsExperimental } from "./experimental-alone.ts";
|
|
53
|
+
import { levelFor } from "./run.ts";
|
|
53
54
|
import { DEFAULT_GENRE } from "./init-choice.ts";
|
|
54
55
|
import { stoppingOnYamlFileError } from "./config/yaml-file.ts";
|
|
55
56
|
|
|
@@ -236,7 +237,7 @@ const explain = (config: Config, ruleId: string | undefined, genreFlag: string |
|
|
|
236
237
|
return 1;
|
|
237
238
|
}
|
|
238
239
|
const preset = genre === undefined ? {} : presetLevels(genre);
|
|
239
|
-
const current = config.rules
|
|
240
|
+
const current = levelFor(rule, config.rules, config.experimental, preset);
|
|
240
241
|
const alone = offOnlyAsExperimental(rule, config, genre ?? DEFAULT_GENRE, preset, language);
|
|
241
242
|
console.log(renderExplain(rule, current, language, genre, { ...settingSourcesOf(config, rule.id, language), offOnlyAsExperimental: alone }));
|
|
242
243
|
return 0;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// The claims file `chaff cite` reads: [{ source?, address?, quote }]. Pure: the shape is checked and every problem named,
|
|
2
|
+
// so a half-filled file (a scaffold with a source left empty) stops with a reason instead of passing.
|
|
3
|
+
import { isAnywhere, type Citation } from "../structure/cite.ts";
|
|
4
|
+
import type { Texts, UiLanguage } from "../ui.ts";
|
|
5
|
+
|
|
6
|
+
/** A citation and, when the claims file names it, the source it quotes: a file path, relative to the claims file. */
|
|
7
|
+
export type Claim = Citation & { readonly source?: string };
|
|
8
|
+
|
|
9
|
+
export type ParsedCitations = { readonly citations: readonly Claim[] } | { readonly error: string };
|
|
10
|
+
|
|
11
|
+
type RawClaim = { readonly source?: string; readonly address?: string; readonly quote: string };
|
|
12
|
+
|
|
13
|
+
const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
|
+
|
|
15
|
+
const isOptionalString = (value: unknown): boolean => value === undefined || typeof value === "string";
|
|
16
|
+
|
|
17
|
+
const isRawClaim = (value: unknown): value is RawClaim =>
|
|
18
|
+
isRecord(value) && isOptionalString(value["address"]) && isOptionalString(value["source"]) && typeof value["quote"] === "string";
|
|
19
|
+
|
|
20
|
+
const claimOf = (raw: RawClaim): Claim => ({
|
|
21
|
+
...(raw.source === undefined ? {} : { source: raw.source }),
|
|
22
|
+
address: raw.address ?? "",
|
|
23
|
+
quote: raw.quote,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/** Neither an address nor a quote: saying ✓ would pass an entry nobody filled in. */
|
|
27
|
+
const isEmpty = (claim: Claim): boolean => isAnywhere(claim) && claim.quote.trim() === "";
|
|
28
|
+
|
|
29
|
+
/** The source a claim names, or undefined when it names none (missing, empty or blank). */
|
|
30
|
+
export const sourceOf = (claim: Claim): string | undefined => {
|
|
31
|
+
const source = claim.source?.trim() ?? "";
|
|
32
|
+
return source === "" ? undefined : source;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type ClaimsText = {
|
|
36
|
+
readonly notJson: (why: string) => string;
|
|
37
|
+
readonly notArray: string;
|
|
38
|
+
readonly badEntry: (n: number) => string;
|
|
39
|
+
readonly emptyEntry: (n: number) => string;
|
|
40
|
+
readonly noSource: (n: number) => string;
|
|
41
|
+
readonly twoSources: (n: number) => string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const CLAIMS_TEXT: Texts<ClaimsText> = {
|
|
45
|
+
ja: {
|
|
46
|
+
notJson: (why) => `JSON として読めません: ${why}`,
|
|
47
|
+
notArray: '引用は配列で渡してください: [{ "address": "3.2", "quote": "…" }]',
|
|
48
|
+
badEntry: (n) => `${String(n)} 件目に quote(文字列)が無いか、address か source が文字列ではありません`,
|
|
49
|
+
emptyEntry: (n) => `${String(n)} 件目は address も quote も空で、確かめることがありません`,
|
|
50
|
+
noSource: (n) => `${String(n)} 件目に source がありません。原文を引数で渡さないときは、どの引用にも source(原文のファイル)を書いてください`,
|
|
51
|
+
twoSources: (n) => `${String(n)} 件目が source を書いていますが、原文も引数で渡されています。どちらか一方にしてください`,
|
|
52
|
+
},
|
|
53
|
+
en: {
|
|
54
|
+
notJson: (why) => `Not valid JSON: ${why}`,
|
|
55
|
+
notArray: 'Give the quotations as an array: [{ "address": "3.2", "quote": "…" }]',
|
|
56
|
+
badEntry: (n) => `Entry ${String(n)} needs quote (a string), and its address and source, if it has them, must be strings`,
|
|
57
|
+
emptyEntry: (n) => `Entry ${String(n)} has neither an address nor a quote, so there is nothing to check`,
|
|
58
|
+
noSource: (n) => `Entry ${String(n)} has no source. Without a source on the command line, every quotation needs one (the source's file)`,
|
|
59
|
+
twoSources: (n) => `Entry ${String(n)} names a source, and a source was also given on the command line. Give one or the other`,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const parseJson = (text: string, ui: UiLanguage): { readonly value: unknown } | { readonly error: string } => {
|
|
64
|
+
try {
|
|
65
|
+
return { value: JSON.parse(text) };
|
|
66
|
+
} catch (err) {
|
|
67
|
+
return { error: CLAIMS_TEXT[ui].notJson(err instanceof Error ? err.message : String(err)) };
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** 引用の一覧。[{ source?, address?, quote }] の配列だけを受け取る。address を省けば原文のどこか。形が違えば理由を返す。 */
|
|
72
|
+
export const parseCitations = (text: string, ui: UiLanguage = "ja"): ParsedCitations => {
|
|
73
|
+
const parsed = parseJson(text, ui);
|
|
74
|
+
if ("error" in parsed) return parsed;
|
|
75
|
+
if (!Array.isArray(parsed.value)) return { error: CLAIMS_TEXT[ui].notArray };
|
|
76
|
+
const entries: readonly unknown[] = parsed.value;
|
|
77
|
+
const bad = entries.findIndex((entry) => !isRawClaim(entry));
|
|
78
|
+
if (bad !== -1) return { error: CLAIMS_TEXT[ui].badEntry(bad + 1) };
|
|
79
|
+
const citations = entries.filter(isRawClaim).map(claimOf);
|
|
80
|
+
const empty = citations.findIndex(isEmpty);
|
|
81
|
+
if (empty !== -1) return { error: CLAIMS_TEXT[ui].emptyEntry(empty + 1) };
|
|
82
|
+
return { citations };
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Where each claim's source comes from. With a source on the command line, no claim may name its own; without one,
|
|
87
|
+
* every claim must. undefined when the claims agree with how cite was called, otherwise the reason.
|
|
88
|
+
*/
|
|
89
|
+
export const sourceProblem = (claims: readonly Claim[], sourceGiven: boolean, ui: UiLanguage): string | undefined => {
|
|
90
|
+
const at = claims.findIndex((claim) => (sourceOf(claim) === undefined) !== sourceGiven);
|
|
91
|
+
if (at === -1) return undefined;
|
|
92
|
+
return sourceGiven ? CLAIMS_TEXT[ui].twoSources(at + 1) : CLAIMS_TEXT[ui].noSource(at + 1);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/** The claims of each source, in the order the sources first appear. Every claim names its source (sourceProblem passed). */
|
|
96
|
+
export const bySource = (claims: readonly Claim[]): { readonly source: string; readonly claims: readonly Claim[] }[] => {
|
|
97
|
+
const groups = new Map<string, Claim[]>();
|
|
98
|
+
claims.forEach((claim) => {
|
|
99
|
+
const source = sourceOf(claim) ?? "";
|
|
100
|
+
groups.set(source, [...(groups.get(source) ?? []), claim]);
|
|
101
|
+
});
|
|
102
|
+
return [...groups].map(([source, own]) => ({ source, claims: own }));
|
|
103
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { fetchPage, type Fetcher } from "../html/fetch-page.ts";
|
|
2
|
+
import { pageDocument } from "../html/page-document.ts";
|
|
3
|
+
import { resolveGenre } from "../resolve-genre.ts";
|
|
4
|
+
import { treeFromSource, treeLanguage, type SourceTree, type TreeContext } from "./tree.ts";
|
|
5
|
+
import type { Texts } from "../ui.ts";
|
|
6
|
+
|
|
7
|
+
/** A source on the web: read once, then checked like a file. The network is reached only through fetchPage. */
|
|
8
|
+
export type CiteContext = TreeContext & {
|
|
9
|
+
/** What fetches a page. Tests pass a stand-in; the command line never does. */
|
|
10
|
+
readonly fetcher?: Fetcher;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Long enough for a slow page, short enough that a dead host does not hold up a run of checks. */
|
|
14
|
+
const PAGE_TIMEOUT_MS = 30_000;
|
|
15
|
+
|
|
16
|
+
/** Far beyond any article or statute page; a log or a dump served as text is refused instead of read whole. */
|
|
17
|
+
const MAX_PAGE_BYTES = 20 * 1024 * 1024;
|
|
18
|
+
|
|
19
|
+
const WEB = /^https?:\/\//iu;
|
|
20
|
+
|
|
21
|
+
export const isWebSource = (source: string): boolean => WEB.test(source);
|
|
22
|
+
|
|
23
|
+
const TEXT: Texts<{
|
|
24
|
+
readonly unfetched: (why: string) => string;
|
|
25
|
+
readonly unsupported: (url: string, type: string) => string;
|
|
26
|
+
readonly noStructure: (url: string, language: string) => string;
|
|
27
|
+
}> = {
|
|
28
|
+
ja: {
|
|
29
|
+
unfetched: (why) => `ページを取得できませんでした: ${why}`,
|
|
30
|
+
unsupported: (url, type) => `${url}: ${type} は文字の文書として読めません(HTML、Markdown、テキストのページを渡してください)`,
|
|
31
|
+
noStructure: (url, language) => `${url}: 言語 ${language} のパッケージは文書の構造を読めません(structure がありません)`,
|
|
32
|
+
},
|
|
33
|
+
en: {
|
|
34
|
+
unfetched: (why) => `Could not fetch the page: ${why}`,
|
|
35
|
+
unsupported: (url, type) => `${url}: ${type} cannot be read as a text document (give an HTML, Markdown or plain-text page)`,
|
|
36
|
+
noStructure: (url, language) => `${url}: the ${language} package cannot read a document's structure (it has no structure)`,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A web page as a tree, read as `chaff tree` reads a file: HTML becomes Markdown first, so its headings are addresses.
|
|
42
|
+
* Once fetched, the same page gives the same tree. undefined, after saying why, when it cannot be fetched or read.
|
|
43
|
+
*/
|
|
44
|
+
export const readPageTree = async (url: string, argv: readonly string[], context: CiteContext): Promise<SourceTree | undefined> => {
|
|
45
|
+
const text = TEXT[context.ui ?? "ja"];
|
|
46
|
+
const fetched = await fetchPage(url, { timeout_ms: PAGE_TIMEOUT_MS, max_bytes: MAX_PAGE_BYTES }, context.fetcher).catch((err: unknown) => {
|
|
47
|
+
console.error(text.unfetched(err instanceof Error ? err.message : String(err)));
|
|
48
|
+
return undefined;
|
|
49
|
+
});
|
|
50
|
+
if (fetched === undefined) return undefined;
|
|
51
|
+
const page = pageDocument(fetched.contentType, fetched.text);
|
|
52
|
+
if ("unsupported" in page) {
|
|
53
|
+
console.error(text.unsupported(url, page.unsupported));
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const language = treeLanguage(page.path, page.text, argv, context);
|
|
57
|
+
const genre = resolveGenre(page.path, page.text, context.config, context.flag(argv, "--genre")).genre;
|
|
58
|
+
const tree = await treeFromSource(page.path, page.text, language, genre, context.config);
|
|
59
|
+
if (tree === undefined) console.error(text.noStructure(url, language));
|
|
60
|
+
return tree === undefined ? undefined : { source: page.text, tree };
|
|
61
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { documentQuotesWithoutSource } from "../detectors/quote-without-source.ts";
|
|
2
|
+
import type { ProseDocument } from "../plugin.ts";
|
|
3
|
+
import { readDocument } from "./read-document.ts";
|
|
4
|
+
import type { TreeContext } from "./tree.ts";
|
|
5
|
+
|
|
6
|
+
/** One entry of the claims file the writer fills in: the source the words come from, and where in it (empty: anywhere). */
|
|
7
|
+
export type ScaffoldClaim = { readonly source: string; readonly address: string; readonly quote: string };
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The quotations quote-without-source finds in a document, as cite's claims with the source and address left for the
|
|
11
|
+
* writer. The rule's genre and level do not apply: asking for a scaffold is asking for every such quotation.
|
|
12
|
+
*/
|
|
13
|
+
export const scaffoldClaims = (doc: ProseDocument): ScaffoldClaim[] =>
|
|
14
|
+
documentQuotesWithoutSource(doc).map((found) => ({ source: "", address: "", quote: found.quote }));
|
|
15
|
+
|
|
16
|
+
/** Prints the claims file for one document. The writer fills in each source and runs `chaff cite <claims.json>`. */
|
|
17
|
+
export const runScaffold = async (targets: readonly string[], argv: readonly string[], context: TreeContext, usage: string): Promise<number> => {
|
|
18
|
+
const [path] = targets;
|
|
19
|
+
if (path === undefined || targets.length !== 1) {
|
|
20
|
+
console.error(usage);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
const read = await readDocument(path, argv, context, false);
|
|
24
|
+
if (read === undefined) return 1;
|
|
25
|
+
console.log(JSON.stringify(scaffoldClaims(read.doc), null, 2));
|
|
26
|
+
return 0;
|
|
27
|
+
};
|
package/src/commands/cite.ts
CHANGED
|
@@ -1,55 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
2
|
+
import { checkCitations, isAnywhere, type CitationResult } from "../structure/cite.ts";
|
|
3
|
+
import { bySource, parseCitations, sourceOf, sourceProblem, type Claim } from "./cite-claims.ts";
|
|
4
|
+
import { runScaffold } from "./cite-scaffold.ts";
|
|
5
|
+
import { isWebSource, readPageTree, type CiteContext } from "./cite-page.ts";
|
|
2
6
|
import { readSource, readTree, type TreeContext } from "./tree.ts";
|
|
3
|
-
import type { Texts
|
|
7
|
+
import type { Texts } from "../ui.ts";
|
|
4
8
|
|
|
5
9
|
const FORMATS: ReadonlySet<string> = new Set(["text", "json"]);
|
|
6
10
|
const QUOTE_WIDTH = 40;
|
|
7
|
-
const VALUED: ReadonlySet<string> = new Set(["--format", "--language", "--genre"]);
|
|
11
|
+
const VALUED: ReadonlySet<string> = new Set(["--format", "--language", "--genre", "--url"]);
|
|
8
12
|
|
|
9
13
|
export const citeTargets = (argv: readonly string[]): string[] =>
|
|
10
14
|
argv.slice(1).filter((arg, index, all) => !arg.startsWith("--") && !VALUED.has(all[index - 1] ?? ""));
|
|
11
15
|
|
|
12
|
-
const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13
|
-
|
|
14
|
-
const isCitation = (value: unknown): value is Citation => isRecord(value) && typeof value["address"] === "string" && typeof value["quote"] === "string";
|
|
15
|
-
|
|
16
|
-
export type ParsedCitations = { readonly citations: readonly Citation[] } | { readonly error: string };
|
|
17
|
-
|
|
18
|
-
const parseJson = (text: string, ui: UiLanguage): { readonly value: unknown } | { readonly error: string } => {
|
|
19
|
-
try {
|
|
20
|
-
return { value: JSON.parse(text) };
|
|
21
|
-
} catch (err) {
|
|
22
|
-
return { error: TEXT[ui].notJson(err instanceof Error ? err.message : String(err)) };
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/** 引用の一覧。[{ address, quote }] の配列だけを受け取る。形が違えば理由を返す。 */
|
|
27
|
-
export const parseCitations = (text: string, ui: UiLanguage = "ja"): ParsedCitations => {
|
|
28
|
-
const parsed = parseJson(text, ui);
|
|
29
|
-
if ("error" in parsed) return parsed;
|
|
30
|
-
if (!Array.isArray(parsed.value)) return { error: TEXT[ui].notArray };
|
|
31
|
-
const entries: readonly unknown[] = parsed.value;
|
|
32
|
-
const bad = entries.findIndex((entry) => !isCitation(entry));
|
|
33
|
-
if (bad !== -1) return { error: TEXT[ui].badEntry(bad + 1) };
|
|
34
|
-
return { citations: entries.filter(isCitation).map((entry) => ({ address: entry.address, quote: entry.quote })) };
|
|
35
|
-
};
|
|
36
|
-
|
|
37
16
|
type CiteText = {
|
|
38
17
|
readonly usage: string;
|
|
39
18
|
readonly quoted: (text: string) => string;
|
|
40
|
-
readonly
|
|
41
|
-
readonly
|
|
42
|
-
readonly
|
|
19
|
+
readonly anywhere: string;
|
|
20
|
+
readonly foundAt: (parts: readonly string[]) => string;
|
|
21
|
+
readonly line: (line: number) => string;
|
|
43
22
|
readonly results: Readonly<Record<CitationResult["status"], (result: CitationResult) => string>>;
|
|
44
23
|
};
|
|
45
24
|
|
|
46
25
|
const TEXT: Texts<CiteText> = {
|
|
47
26
|
ja: {
|
|
48
27
|
quoted: (text) => `「${text}」`,
|
|
49
|
-
usage:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
28
|
+
usage: [
|
|
29
|
+
"使い方: chaff cite <原文> <引用.json> [--format text|json] [--language ja|en|…]",
|
|
30
|
+
" chaff cite --url <URL> <引用.json> (原文が Web のページのとき)",
|
|
31
|
+
" chaff cite <引用.json> (引用ごとに source で原文のファイルか URL を書いたとき)",
|
|
32
|
+
" chaff cite --scaffold <文書> (出典の無い引用から引用.json のひな形を作る)",
|
|
33
|
+
].join("\n"),
|
|
34
|
+
anywhere: "(番地なし)",
|
|
35
|
+
foundAt: (parts) => `(${parts.join("、")})`,
|
|
36
|
+
line: (line) => `${String(line)} 行目`,
|
|
53
37
|
results: {
|
|
54
38
|
ok: () => "一致",
|
|
55
39
|
"missing-address": (result) => `番地 ${result.citation.address} は原文にありません`,
|
|
@@ -60,10 +44,15 @@ const TEXT: Texts<CiteText> = {
|
|
|
60
44
|
},
|
|
61
45
|
en: {
|
|
62
46
|
quoted: (text) => ` "${text}"`,
|
|
63
|
-
usage:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
usage: [
|
|
48
|
+
"usage: chaff cite <source> <quotes.json> [--format text|json] [--language ja|en|…]",
|
|
49
|
+
" chaff cite --url <URL> <quotes.json> (the source is a web page)",
|
|
50
|
+
" chaff cite <quotes.json> (each quotation names its source, a file or a URL)",
|
|
51
|
+
" chaff cite --scaffold <document> (a quotes.json to fill in, from the quotations with no source)",
|
|
52
|
+
].join("\n"),
|
|
53
|
+
anywhere: "(anywhere)",
|
|
54
|
+
foundAt: (parts) => ` (${parts.join(", ")})`,
|
|
55
|
+
line: (line) => `line ${String(line)}`,
|
|
67
56
|
results: {
|
|
68
57
|
ok: () => "matches",
|
|
69
58
|
"missing-address": (result) => `address ${result.citation.address} is not in the source`,
|
|
@@ -74,34 +63,114 @@ const TEXT: Texts<CiteText> = {
|
|
|
74
63
|
},
|
|
75
64
|
};
|
|
76
65
|
|
|
66
|
+
/** Where a quote given no address was found, so the reader can write the address in. */
|
|
67
|
+
const whereFound = (result: CitationResult, text: CiteText): string => {
|
|
68
|
+
if (result.status !== "ok" || !isAnywhere(result.citation) || result.line === undefined) return "";
|
|
69
|
+
return text.foundAt([...(result.foundAt === undefined ? [] : [result.foundAt]), text.line(result.line)]);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/** A claim that names its own source says which, before its address. */
|
|
73
|
+
const sourcePrefix = (result: CitationResult): string => {
|
|
74
|
+
const source = sourceOf(result.citation);
|
|
75
|
+
return source === undefined ? "" : `${source} `;
|
|
76
|
+
};
|
|
77
|
+
|
|
77
78
|
const describe = (result: CitationResult, text: CiteText): string => {
|
|
78
79
|
const mark = result.status === "ok" ? "✓" : "✗";
|
|
79
80
|
const oneLine = result.citation.quote.replace(/\s+/gu, " ").trim();
|
|
80
81
|
const quote = oneLine.length > QUOTE_WIDTH ? `${oneLine.slice(0, QUOTE_WIDTH)}…` : oneLine;
|
|
81
|
-
|
|
82
|
+
const address = isAnywhere(result.citation) ? text.anywhere : result.citation.address;
|
|
83
|
+
return `${mark} ${sourcePrefix(result)}${address}${text.quoted(quote)}: ${text.results[result.status](result)}${whereFound(result, text)}`;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** Each claim checked against one source, a file or a web page. undefined when it cannot be read as a tree (already said why). */
|
|
87
|
+
const checkAgainst = async (
|
|
88
|
+
location: string,
|
|
89
|
+
claims: readonly Claim[],
|
|
90
|
+
argv: readonly string[],
|
|
91
|
+
context: CiteContext,
|
|
92
|
+
): Promise<CitationResult[] | undefined> => {
|
|
93
|
+
const read = isWebSource(location) ? await readPageTree(location, argv, context) : await readTree(location, argv, context);
|
|
94
|
+
return read === undefined ? undefined : checkCitations(read.source, read.tree, claims);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/** A claim's source, read from where the claims file is: a scaffold sits next to the document that quotes. A URL is a URL. */
|
|
98
|
+
const sourcePath = (claimsPath: string, source: string): string => {
|
|
99
|
+
if (isWebSource(source)) return source;
|
|
100
|
+
// A claims file written on Windows says sources\talk.md; it names the same file everywhere.
|
|
101
|
+
const portable = source.replaceAll("\\", "/");
|
|
102
|
+
return isAbsolute(portable) ? portable : join(dirname(claimsPath), portable);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Each claim checked against the source it names, in the claims file's order. Sources are read one at a time, so what
|
|
107
|
+
* an unreadable one prints comes in the same order every run; any unreadable source fails the run.
|
|
108
|
+
*/
|
|
109
|
+
const checkEachSource = async (
|
|
110
|
+
claimsPath: string,
|
|
111
|
+
claims: readonly Claim[],
|
|
112
|
+
argv: readonly string[],
|
|
113
|
+
context: CiteContext,
|
|
114
|
+
): Promise<CitationResult[] | undefined> => {
|
|
115
|
+
const groups = bySource(claims);
|
|
116
|
+
const checked = await groups.reduce<Promise<(CitationResult[] | undefined)[]>>(async (previous, group) => {
|
|
117
|
+
const done = await previous;
|
|
118
|
+
return [...done, await checkAgainst(sourcePath(claimsPath, group.source), group.claims, argv, context)];
|
|
119
|
+
}, Promise.resolve([]));
|
|
120
|
+
const byClaim = new Map<Claim, CitationResult>();
|
|
121
|
+
const unread = groups.some((group, index) => {
|
|
122
|
+
const results = checked[index];
|
|
123
|
+
results?.forEach((result, at) => byClaim.set(group.claims[at] ?? result.citation, result));
|
|
124
|
+
return results === undefined;
|
|
125
|
+
});
|
|
126
|
+
return unread ? undefined : claims.flatMap((claim) => byClaim.get(claim) ?? []);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const readClaims = async (claimsPath: string, sourceGiven: boolean, context: TreeContext): Promise<readonly Claim[] | undefined> => {
|
|
130
|
+
const text = await readSource(claimsPath, context);
|
|
131
|
+
if (text === undefined) return undefined;
|
|
132
|
+
const ui = context.ui ?? "ja";
|
|
133
|
+
const parsed = parseCitations(text, ui);
|
|
134
|
+
const problem = "error" in parsed ? parsed.error : sourceProblem(parsed.citations, sourceGiven, ui);
|
|
135
|
+
if (problem === undefined && "citations" in parsed) return parsed.citations;
|
|
136
|
+
console.error(`${claimsPath}: ${problem ?? ""}`);
|
|
137
|
+
return undefined;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const usageError = (text: CiteText): number => {
|
|
141
|
+
console.error(text.usage);
|
|
142
|
+
return 1;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** The claims file, and the one source the command line gives (a file, or a page after --url), if any. */
|
|
146
|
+
type Run = { readonly claimsPath: string; readonly sourceGiven: string | undefined };
|
|
147
|
+
|
|
148
|
+
/** What the arguments ask to check, or undefined when they do not fit any usage. */
|
|
149
|
+
const runOf = (targets: readonly string[], argv: readonly string[], context: CiteContext): Run | undefined => {
|
|
150
|
+
const url = context.flag(argv, "--url");
|
|
151
|
+
if (argv.includes("--url") && (url === undefined || !isWebSource(url))) return undefined;
|
|
152
|
+
const claimsPath = targets.at(-1);
|
|
153
|
+
if (claimsPath === undefined || targets.length > (url === undefined ? 2 : 1)) return undefined;
|
|
154
|
+
return { claimsPath, sourceGiven: url ?? (targets.length === 2 ? targets[0] : undefined) };
|
|
82
155
|
};
|
|
83
156
|
|
|
84
157
|
/**
|
|
85
|
-
*
|
|
158
|
+
* 回答の引用が原文にあるかを確かめる。書き換えはしない。原文は引数で一つ渡すか、引用ごとに source で書く。
|
|
86
159
|
* 一つでも外れていれば 1 で終わるので、AI の回答を単体試験のように検査できる。
|
|
87
160
|
*/
|
|
88
|
-
export const runCite = async (targets: readonly string[], argv: readonly string[], context:
|
|
89
|
-
const [
|
|
161
|
+
export const runCite = async (targets: readonly string[], argv: readonly string[], context: CiteContext): Promise<number> => {
|
|
162
|
+
const text = TEXT[context.ui ?? "ja"];
|
|
90
163
|
const format = context.flag(argv, "--format") ?? "text";
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const read = await readTree(sourcePath, argv, context);
|
|
103
|
-
if (read === undefined) return 1;
|
|
104
|
-
const results = checkCitations(read.source, read.tree, parsed.citations);
|
|
105
|
-
console.log(format === "json" ? JSON.stringify(results, null, 2) : results.map((result) => describe(result, TEXT[context.ui ?? "ja"])).join("\n"));
|
|
164
|
+
if (!FORMATS.has(format)) return usageError(text);
|
|
165
|
+
// The scaffold is always JSON: it is a file to fill in.
|
|
166
|
+
if (argv.includes("--scaffold")) return argv.includes("--url") ? usageError(text) : runScaffold(targets, argv, context, text.usage);
|
|
167
|
+
const run = runOf(targets, argv, context);
|
|
168
|
+
if (run === undefined) return usageError(text);
|
|
169
|
+
const { claimsPath, sourceGiven } = run;
|
|
170
|
+
const claims = await readClaims(claimsPath, sourceGiven !== undefined, context);
|
|
171
|
+
if (claims === undefined) return 1;
|
|
172
|
+
const results = sourceGiven === undefined ? await checkEachSource(claimsPath, claims, argv, context) : await checkAgainst(sourceGiven, claims, argv, context);
|
|
173
|
+
if (results === undefined) return 1;
|
|
174
|
+
console.log(format === "json" ? JSON.stringify(results, null, 2) : results.map((result) => describe(result, text)).join("\n"));
|
|
106
175
|
return results.every((result) => result.status === "ok") ? 0 : 1;
|
|
107
176
|
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { nameKey } from "./name-variants.ts";
|
|
2
|
+
import { escapeRegExp } from "./orthography.ts";
|
|
3
|
+
|
|
4
|
+
// 会社の名前を、文書の中で二通りに書いた所(株式会社アオバシステム と アオバシステム株式会社、Aoba Systems Inc. と Aoba Systems Ltd.)。
|
|
5
|
+
// 会社の形の語(株式会社、Inc)は語彙表 company-form が言う。group が同じ語は同じ形(Inc と Incorporated、株式会社 と (株))、
|
|
6
|
+
// position は名前のどちら側に立つか(無ければどちらにも立つ)。名前の部分は、形の語のすぐ隣の、名前に使う字の連なり。
|
|
7
|
+
|
|
8
|
+
export type CompanyForm = { readonly pattern: string; readonly group: string; readonly position?: "before" | "after" | undefined };
|
|
9
|
+
|
|
10
|
+
/** surface は形の語も含めた書いたまま。base は名前の部分、form は形の組、position は形の語が名前のどちら側にあるか。 */
|
|
11
|
+
export type CompanyMention = {
|
|
12
|
+
readonly surface: string;
|
|
13
|
+
readonly offset: number;
|
|
14
|
+
readonly base: string;
|
|
15
|
+
readonly form: string;
|
|
16
|
+
readonly position: "before" | "after";
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** 二つの書き方の違い。spelling は記号・幅・大小だけ、form は会社の形、position は形の語の側、near は名前の一字違い。 */
|
|
20
|
+
type CompanyRelation = "spelling" | "form" | "position" | "near";
|
|
21
|
+
|
|
22
|
+
type CompanyVariant = { readonly mention: CompanyMention; readonly usual: string; readonly kind: CompanyRelation };
|
|
23
|
+
|
|
24
|
+
/** 名前の部分が、品詞解析が固有名詞と読んだ語に掛かるか。漢字だけの名前(清算、当該)は、ふつうの語と区別がつかない。 */
|
|
25
|
+
export type IsProper = (start: number, end: number) => boolean;
|
|
26
|
+
|
|
27
|
+
const LATIN = /\p{Script=Latin}/u;
|
|
28
|
+
const LETTER = /\p{L}/u;
|
|
29
|
+
/** 漢字・かなの名前に使う字。ひらがなは名前の外(の、は、まで)。 */
|
|
30
|
+
const CJK_NAME = /[\p{Script=Katakana}\p{Script=Han}\p{Script=Latin}\p{N}ー・&&]/u;
|
|
31
|
+
const NOT_HAN_LETTER = /(?!\p{Script=Han})\p{L}/u;
|
|
32
|
+
/** 英字の名前の一語。大文字か数字で始まる。 */
|
|
33
|
+
const LATIN_WORD = /^[\p{Lu}\p{N}][\p{L}\p{N}&'’.-]*$/u;
|
|
34
|
+
const AMPERSAND = "&";
|
|
35
|
+
/** 形の語のすぐあとに空白一つで大文字の語が続けば、形の語は長い名前の一部(Limited Partnership、Corporation Tax)。Inc. のあとの文や行は続きでない。 */
|
|
36
|
+
const CONTINUED = /^ \p{Lu}/u;
|
|
37
|
+
|
|
38
|
+
const occurrencesOf = (source: string, pattern: string): number[] => [...source.matchAll(new RegExp(escapeRegExp(pattern), "gu"))].map((match) => match.index);
|
|
39
|
+
|
|
40
|
+
/** 英字の語の続き。ハイフンでつないだ語(Limited-time)も一つの語。 */
|
|
41
|
+
const WORD_CONTINUES = /[\p{L}\p{N}-]/u;
|
|
42
|
+
|
|
43
|
+
/** 英字の形の語は、語の続き(Including の Inc、Limited-time の Limited)では形の語と読まない。 */
|
|
44
|
+
const standsAsWord = (source: string, pattern: string, at: number): boolean =>
|
|
45
|
+
!LATIN.test(pattern) || (!LETTER.test(source.charAt(at - 1)) && !WORD_CONTINUES.test(source.charAt(at + pattern.length)));
|
|
46
|
+
|
|
47
|
+
type Span = { readonly start: number; readonly end: number };
|
|
48
|
+
|
|
49
|
+
/** 英字の名前: 形の語の前の、大文字で始まる語の続き。頭の、固有名詞と読めない語(文頭の Contact)は外す。 */
|
|
50
|
+
const latinBaseBefore = (source: string, end: number, isProper: IsProper): Span | undefined => {
|
|
51
|
+
const before = source.slice(0, end).replace(/,?\s$/u, "");
|
|
52
|
+
const words = [...before.matchAll(/\S+/gu)].map((match): Span => ({ start: match.index, end: match.index + match[0].length }));
|
|
53
|
+
const isNameWord = (span: Span): boolean => {
|
|
54
|
+
const word = source.slice(span.start, span.end);
|
|
55
|
+
return LATIN_WORD.test(word) || word === AMPERSAND;
|
|
56
|
+
};
|
|
57
|
+
const run = words.slice(
|
|
58
|
+
words.findLastIndex((span, index) => !isNameWord(span) || before.slice(span.end, words[index + 1]?.start ?? before.length).includes("\n")) + 1,
|
|
59
|
+
);
|
|
60
|
+
const first = run.find((span) => isProper(span.start, span.end));
|
|
61
|
+
return first === undefined ? undefined : { start: first.start, end: before.length };
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const CJK_BEFORE = new RegExp(`${CJK_NAME.source}+$`, "u");
|
|
65
|
+
const CJK_AFTER = new RegExp(`^${CJK_NAME.source}+`, "u");
|
|
66
|
+
const SPACES: ReadonlySet<string> = new Set([" ", "\u3000"]);
|
|
67
|
+
|
|
68
|
+
/** 漢字・かなの名前: 形の語の隣の、名前に使う字の続き。形の語との間の空白一つは名前の外。 */
|
|
69
|
+
const cjkBaseBefore = (source: string, end: number): Span | undefined => {
|
|
70
|
+
const stop = SPACES.has(source.charAt(end - 1)) ? end - 1 : end;
|
|
71
|
+
const match = CJK_BEFORE.exec(source.slice(0, stop));
|
|
72
|
+
return match === null ? undefined : { start: match.index, end: stop };
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const cjkBaseAfter = (source: string, start: number): Span | undefined => {
|
|
76
|
+
const from = SPACES.has(source.charAt(start)) ? start + 1 : start;
|
|
77
|
+
const match = CJK_AFTER.exec(source.slice(from));
|
|
78
|
+
return match === null ? undefined : { start: from, end: from + match[0].length };
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** 名前の部分の字数。一字(法令の項目の印 イ、ロ)は名前と読まない。 */
|
|
82
|
+
const MIN_BASE_LENGTH = 2;
|
|
83
|
+
|
|
84
|
+
/** 名前と読めるか。二字以上で、記号で始まり終わらず、漢字だけなら固有名詞と読めるもの。 */
|
|
85
|
+
const isNameBase = (source: string, span: Span, isProper: IsProper): boolean => {
|
|
86
|
+
const base = source.slice(span.start, span.end);
|
|
87
|
+
if ([...base].length < MIN_BASE_LENGTH || /^[・&&]|[・&&]$/u.test(base)) return false;
|
|
88
|
+
return NOT_HAN_LETTER.test(base) || isProper(span.start, span.end);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const mentionOf = (source: string, base: Span, form: Span, group: string): CompanyMention => {
|
|
92
|
+
const position = form.start < base.start ? "before" : "after";
|
|
93
|
+
const [start, end] = [Math.min(base.start, form.start), Math.max(base.end, form.end)];
|
|
94
|
+
return { surface: source.slice(start, end), offset: start, base: source.slice(base.start, base.end), form: group, position };
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const baseBefore = (source: string, at: number, latin: boolean, isProper: IsProper): Span | undefined =>
|
|
98
|
+
latin ? latinBaseBefore(source, at, isProper) : cjkBaseBefore(source, at);
|
|
99
|
+
|
|
100
|
+
/** 形の語の一つの現れから、会社の名前の現れ。名前が前にあればそれを、無ければ後ろを取る。 */
|
|
101
|
+
const mentionAt = (source: string, form: CompanyForm, at: number, isProper: IsProper): CompanyMention | undefined => {
|
|
102
|
+
const formSpan = { start: at, end: at + form.pattern.length };
|
|
103
|
+
const latin = LATIN.test(form.pattern);
|
|
104
|
+
if (latin && CONTINUED.test(source.slice(formSpan.end))) return undefined;
|
|
105
|
+
const before = form.position === "before" ? undefined : baseBefore(source, at, latin, isProper);
|
|
106
|
+
if (before !== undefined && isNameBase(source, before, isProper)) return mentionOf(source, before, formSpan, form.group);
|
|
107
|
+
const after = form.position === "after" || latin ? undefined : cjkBaseAfter(source, formSpan.end);
|
|
108
|
+
return after !== undefined && isNameBase(source, after, isProper) ? mentionOf(source, after, formSpan, form.group) : undefined;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** 文書の中の会社の名前の現れ。長い形の語(Co., Ltd)を先に取り、その中の短い語(Ltd)は数えない。 */
|
|
112
|
+
export const companyMentionsIn = (source: string, forms: readonly CompanyForm[], isProper: IsProper): CompanyMention[] => {
|
|
113
|
+
const taken: Span[] = [];
|
|
114
|
+
return forms
|
|
115
|
+
.toSorted((left, right) => right.pattern.length - left.pattern.length)
|
|
116
|
+
.flatMap((form) =>
|
|
117
|
+
occurrencesOf(source, form.pattern).flatMap((at) => {
|
|
118
|
+
const end = at + form.pattern.length;
|
|
119
|
+
if (!standsAsWord(source, form.pattern, at) || taken.some((span) => span.start < end && at < span.end)) return [];
|
|
120
|
+
taken.push({ start: at, end });
|
|
121
|
+
const mention = mentionAt(source, form, at, isProper);
|
|
122
|
+
return mention === undefined ? [] : [mention];
|
|
123
|
+
}),
|
|
124
|
+
)
|
|
125
|
+
.toSorted((left, right) => left.offset - right.offset);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const MIN_SLIP_LENGTH = 7;
|
|
129
|
+
|
|
130
|
+
const spliced = (chars: readonly string[], at: number, count: number): string => chars.toSpliced(at, count).join("");
|
|
131
|
+
const firstDifference = (left: readonly string[], right: readonly string[]): number => left.findIndex((char, index) => char !== right[index]);
|
|
132
|
+
|
|
133
|
+
/** 一字の抜けなら、その字。 */
|
|
134
|
+
const droppedChars = (longer: readonly string[], shorter: readonly string[]): string[] | undefined => {
|
|
135
|
+
if (longer.length !== shorter.length + 1) return undefined;
|
|
136
|
+
const at = firstDifference(longer, shorter);
|
|
137
|
+
return spliced(longer, at, 1) === shorter.join("") ? [longer[at] ?? ""] : undefined;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/** 一字の置き換えか、隣どうしの入れ替えなら、その字。 */
|
|
141
|
+
const replacedChars = (left: readonly string[], right: readonly string[]): string[] | undefined => {
|
|
142
|
+
const at = firstDifference(left, right);
|
|
143
|
+
const changed = [left[at] ?? "", right[at] ?? ""];
|
|
144
|
+
if (left.length !== right.length || at < 0) return undefined;
|
|
145
|
+
if (spliced(left, at, 1) === spliced(right, at, 1)) return changed;
|
|
146
|
+
const swapped = left[at] === right[at + 1] && left[at + 1] === right[at] && spliced(left, at, 2) === spliced(right, at, 2);
|
|
147
|
+
return swapped ? changed : undefined;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* 名前の部分が一字違いか(置き換え・抜け・隣どうしの入れ替え)。違う字が漢字なら見ない。漢字の一字違い(日本電気 と 日本電機)
|
|
152
|
+
* は別の会社のことがある。短い名前(Alpha と Alpho)も別の会社のことが多い。
|
|
153
|
+
*/
|
|
154
|
+
const isSlip = (left: string, right: string): boolean => {
|
|
155
|
+
const [leftChars, rightChars] = [[...left], [...right]];
|
|
156
|
+
if (Math.min(leftChars.length, rightChars.length) < MIN_SLIP_LENGTH) return false;
|
|
157
|
+
const changed = replacedChars(leftChars, rightChars) ?? droppedChars(leftChars, rightChars) ?? droppedChars(rightChars, leftChars);
|
|
158
|
+
return changed !== undefined && changed.every((char) => NOT_HAN_LETTER.test(char));
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** 名前の部分が同じ二つ。同じ形の短い書き方と長い書き方(株式会社 と (株)、Inc と Incorporated)は書き分けと見ない。 */
|
|
162
|
+
const sameNameRelation = (left: CompanyMention, right: CompanyMention): CompanyRelation | undefined => {
|
|
163
|
+
if (left.form !== right.form) return "form";
|
|
164
|
+
if (left.position !== right.position) return "position";
|
|
165
|
+
return nameKey(left.surface) === nameKey(right.surface) ? "spelling" : undefined;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* 二つの書き方が、同じ会社を二通りに書いたものか。名前の部分が同じ(記号・幅・大小を除いて)なら、形の組か形の語の側の違い、
|
|
170
|
+
* どちらも同じなら記号・幅・大小だけの違い。名前の部分が違うのは、形も側も同じで、漢字でない字の一字違いのときだけ(Aoba Systems と
|
|
171
|
+
* Aoba System)。名前の違う会社(親会社と子会社、別の取引先)は、名前の部分が一字より多く違うので同じと見ない。
|
|
172
|
+
*/
|
|
173
|
+
export const companyRelation = (left: CompanyMention, right: CompanyMention): CompanyRelation | undefined => {
|
|
174
|
+
if (left.surface === right.surface) return undefined;
|
|
175
|
+
const [leftKey, rightKey] = [nameKey(left.base), nameKey(right.base)];
|
|
176
|
+
if (leftKey === rightKey) return sameNameRelation(left, right);
|
|
177
|
+
return left.form === right.form && left.position === right.position && isSlip(leftKey, rightKey) ? "near" : undefined;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
type Tally = { readonly first: CompanyMention; readonly count: number };
|
|
181
|
+
|
|
182
|
+
const talliesOf = (mentions: readonly CompanyMention[]): Tally[] => {
|
|
183
|
+
const tallies = new Map<string, Tally>();
|
|
184
|
+
mentions.forEach((mention) => {
|
|
185
|
+
const tally = tallies.get(mention.surface);
|
|
186
|
+
tallies.set(mention.surface, { first: tally?.first ?? mention, count: (tally?.count ?? 0) + 1 });
|
|
187
|
+
});
|
|
188
|
+
return [...tallies.values()];
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/** 多いほうが先。同数なら先に書いたほう。 */
|
|
192
|
+
const byUsage = (left: Tally, right: Tally): number => right.count - left.count || left.first.offset - right.first.offset;
|
|
193
|
+
|
|
194
|
+
/** 同じ会社の、少ないほうの書き方。同じ会社と言える相手のうち一番多いものと比べる。書き方ごとに最初の現れを一つ。 */
|
|
195
|
+
export const companyVariants = (mentions: readonly CompanyMention[]): CompanyVariant[] => {
|
|
196
|
+
const tallies = talliesOf(mentions);
|
|
197
|
+
return tallies.flatMap((tally) => {
|
|
198
|
+
const [usual] = tallies.filter((other) => other === tally || companyRelation(tally.first, other.first) !== undefined).toSorted(byUsage);
|
|
199
|
+
const kind = usual === undefined || usual === tally ? undefined : companyRelation(tally.first, usual.first);
|
|
200
|
+
return usual === undefined || kind === undefined ? [] : [{ mention: tally.first, usual: usual.first.surface, kind }];
|
|
201
|
+
});
|
|
202
|
+
};
|