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
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { MarkupHeading, StructureNode } from "../plugin.ts";
|
|
2
|
+
import { inDocumentOrder } from "./issues.ts";
|
|
3
|
+
import { lineNumberAt, type Line } from "./lines.ts";
|
|
4
|
+
|
|
5
|
+
// 題・見出しの行。見出しは節の中身に名前を付けるだけで、本文の文ではない。純関数: 木と行と Markdown の見出しを受け取る。
|
|
6
|
+
|
|
7
|
+
/** 見出しの行に、見出しの言葉のほかにあってよい字(括弧と空白)。法令の「(解雇の予告)」。 */
|
|
8
|
+
const CAPTION_MARKS = /[\s()()[][\]【】〔〕]/gu;
|
|
9
|
+
|
|
10
|
+
/** 条の前の行が、その条の見出しだけの行か。 */
|
|
11
|
+
const isCaptionLine = (line: Line | undefined, heading: string): boolean =>
|
|
12
|
+
line !== undefined && heading !== "" && line.text.replaceAll(CAPTION_MARKS, "") === heading.replaceAll(CAPTION_MARKS, "");
|
|
13
|
+
|
|
14
|
+
const lineNumbersOfTree = (tree: StructureNode, lines: readonly Line[]): number[] =>
|
|
15
|
+
inDocumentOrder(tree).flatMap((node) => {
|
|
16
|
+
if (node.kind === "chapter" || node.kind === "section") return [node.line];
|
|
17
|
+
if (node.kind !== "article") return [];
|
|
18
|
+
const caption = node.line - 1;
|
|
19
|
+
return isCaptionLine(lines[caption - 1], String(node.attrs["heading"] ?? "")) ? [caption] : [];
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 題・見出しの行の番号(1 始まり)。Markdown の見出しの行、木の章・節の行、条の前に置いた見出しだけの行。
|
|
24
|
+
* 条の行の中の見出し(第一条(目的))は条の本文と同じ行なので入れない。
|
|
25
|
+
*/
|
|
26
|
+
export const titleLineNumbers = (tree: StructureNode | undefined, lines: readonly Line[], headings: readonly MarkupHeading[]): ReadonlySet<number> =>
|
|
27
|
+
new Set([
|
|
28
|
+
...(tree === undefined ? [] : lineNumbersOfTree(tree, lines)),
|
|
29
|
+
...headings.flatMap((heading) => {
|
|
30
|
+
const line = lineNumberAt(lines, heading.start);
|
|
31
|
+
return line === undefined ? [] : [line];
|
|
32
|
+
}),
|
|
33
|
+
]);
|
package/src/structure/total.ts
CHANGED
|
@@ -142,6 +142,10 @@ const SIGN_REACH = 2;
|
|
|
142
142
|
const signBefore = (source: string, total: Placed, start: number): string =>
|
|
143
143
|
total.cents !== undefined && total.cents < 0 ? (SIGN_BEFORE.exec(source.slice(Math.max(0, start - SIGN_REACH), start))?.[0] ?? "") : "";
|
|
144
144
|
|
|
145
|
+
/** 数の後ろに書いた単位。単位の組の名前(credit)と書いた語(credits)が違えば、書いた語を見せる。 */
|
|
146
|
+
const unitAfterNumber = (written: string, unit: string): string =>
|
|
147
|
+
written.endsWith(unit) ? unit : written.slice(written.split("").findLastIndex((char) => char >= "0" && char <= "9") + 1);
|
|
148
|
+
|
|
145
149
|
/** 合計の行に書いた金額と、上の和を、同じ書き方で見せる。負の和には、合計に書いた印(無ければ -)を付ける。 */
|
|
146
150
|
const shownAmounts = (source: string, total: Placed, sumCents: number): Record<string, string> => {
|
|
147
151
|
const unitStart = unitStartBefore(source, total);
|
|
@@ -151,7 +155,7 @@ const shownAmounts = (source: string, total: Placed, sumCents: number): Record<s
|
|
|
151
155
|
const sumSign = sumCents < 0 ? sign || "-" : "";
|
|
152
156
|
const sum = formatCents(Math.abs(sumCents), written);
|
|
153
157
|
if (unitStart !== undefined) return { written, sum: `${sumSign}${source.slice(unitStart, total.offset)}${sum}` };
|
|
154
|
-
return { written, sum: `${sumSign}${sum}${written
|
|
158
|
+
return { written, sum: `${sumSign}${sum}${unitAfterNumber(written, total.unit)}` };
|
|
155
159
|
};
|
|
156
160
|
|
|
157
161
|
/** 文の中の合計の金額(符号の無い、単位付きの金額)と和を、合計の書き方で見せる。 */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// A version written in the lead-in to a code block ("Install version 2.3.0 from npm:") that the block itself does not
|
|
2
2
|
// show (npm install tidyq@2.4.0). Pure: reads the source, the code blocks, and the prose with code covered.
|
|
3
|
+
import { escapeRegExp } from "../orthography.ts";
|
|
3
4
|
import type { Span } from "../plugin.ts";
|
|
4
5
|
import type { StructureIssue } from "./issues.ts";
|
|
5
6
|
|
|
@@ -85,19 +86,72 @@ const leadInOf = (source: string, blockStart: number): Span | undefined => {
|
|
|
85
86
|
return text === "" || NOT_PROSE.test(text) || !LETTER.test(words) ? undefined : { start, end: lines.length };
|
|
86
87
|
};
|
|
87
88
|
|
|
89
|
+
/** A pin with the version it pins, of any number of parts: redis 7.4 in redis:7.4-alpine and in library/redis:7.4. */
|
|
90
|
+
const PIN_VERSION = /^([\w.-]+)(?:@|==|=|:)[v^~]?(\d+(?:\.\d+)*)/u;
|
|
91
|
+
const HAS_LETTER = /[A-Za-z]/u;
|
|
92
|
+
|
|
93
|
+
/** Each name the block pins, with the one version it pins it to; a name pinned to two versions is left out. */
|
|
94
|
+
const pinnedVersions = (code: string): Map<string, string> => {
|
|
95
|
+
const byName = new Map<string, Set<string>>();
|
|
96
|
+
codeWords(code).forEach((word) => {
|
|
97
|
+
const match = PIN_VERSION.exec(word.slice(word.lastIndexOf("/") + 1));
|
|
98
|
+
if (match?.[1] === undefined || match[2] === undefined || !HAS_LETTER.test(match[1])) return;
|
|
99
|
+
const name = match[1].toLowerCase();
|
|
100
|
+
byName.set(name, new Set([...(byName.get(name) ?? []), match[2]]));
|
|
101
|
+
});
|
|
102
|
+
const single = new Map<string, string>();
|
|
103
|
+
byName.forEach((versions, name) => {
|
|
104
|
+
const [only] = versions;
|
|
105
|
+
if (versions.size === 1 && only !== undefined) single.set(name, only);
|
|
106
|
+
});
|
|
107
|
+
return single;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/** 7 and 7.4, or 7.4 and 7.4.1: one names the other's series, so they agree. */
|
|
111
|
+
const sameSeries = (written: string, pinned: string): boolean => {
|
|
112
|
+
const [shorter, longer] = [written.split("."), pinned.split(".")].toSorted((left, right) => left.length - right.length);
|
|
113
|
+
return (shorter ?? []).every((part, index) => part === longer?.[index]);
|
|
114
|
+
};
|
|
115
|
+
|
|
88
116
|
/**
|
|
89
|
-
* Each version
|
|
90
|
-
*
|
|
91
|
-
*
|
|
117
|
+
* Each version written right after the name of a program the block pins ("We run Redis 7.2" over redis:7.4) that is not of
|
|
118
|
+
* the pinned version's series. The name says whose version it is, so a version of two parts is read here, where a bare 7.2
|
|
119
|
+
* is too often a decimal; one part (port 6379, Node 20) is too often another number.
|
|
92
120
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.map((found) => ({ offset: found.start, values: { written: found.version, code } }));
|
|
121
|
+
const namedMismatches = (prose: string, leadIn: Span, code: string, ranges: readonly RangeWord[]): StructureIssue[] =>
|
|
122
|
+
[...pinnedVersions(code)].flatMap(([name, pinned]) => {
|
|
123
|
+
const pattern = new RegExp(`(?<![\\w.-])${escapeRegExp(name)}\\s+v?(\\d+(?:\\.\\d+){1,2})(?![\\w.]|\\.\\d)`, "giu");
|
|
124
|
+
return [...prose.slice(leadIn.start, leadIn.end).matchAll(pattern)].flatMap((match) => {
|
|
125
|
+
const written = match[1] ?? "";
|
|
126
|
+
const span = { start: leadIn.start + match.index, end: leadIn.start + match.index + match[0].length };
|
|
127
|
+
if (sameSeries(written, pinned) || isBound(prose, span, ranges)) return [];
|
|
128
|
+
return [{ offset: span.end - written.length, values: { written, code: pinned } }];
|
|
129
|
+
});
|
|
103
130
|
});
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Each version in the lead-in that differs from the one version the block shows. A block with no version, or with two (an
|
|
134
|
+
* upgrade from one to the other), says nothing to compare; a version marked as a bound, or named after another program, is
|
|
135
|
+
* not the one installed.
|
|
136
|
+
*/
|
|
137
|
+
const shownMismatches = (prose: string, leadIn: Span, code: string, words: VersionWords): StructureIssue[] => {
|
|
138
|
+
const shown = [...new Set(versionsIn(code).map((found) => found.version))];
|
|
139
|
+
const [only] = shown;
|
|
140
|
+
if (shown.length !== 1 || only === undefined) return [];
|
|
141
|
+
const names = pinnedNames(code);
|
|
142
|
+
return versionsIn(prose.slice(leadIn.start, leadIn.end), leadIn.start)
|
|
143
|
+
.filter((found) => found.version !== only && !isBound(prose, found, words.ranges) && isAboutBlock(prose, found, names, words.versionWords))
|
|
144
|
+
.map((found) => ({ offset: found.start, values: { written: found.version, code: only } }));
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/** Both readings of one block; a version both report is reported once, against the pin of the program it names. */
|
|
148
|
+
const blockMismatches = (source: string, prose: string, block: CodeBlock, words: VersionWords): StructureIssue[] => {
|
|
149
|
+
const leadIn = leadInOf(source, block.start);
|
|
150
|
+
if (leadIn === undefined) return [];
|
|
151
|
+
const issues = [...namedMismatches(prose, leadIn, block.code, words.ranges), ...shownMismatches(prose, leadIn, block.code, words)];
|
|
152
|
+
return issues.filter((issue, index) => issues.findIndex((other) => other.offset === issue.offset) === index);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/** Each version in a code block's lead-in that differs from the version the block installs. */
|
|
156
|
+
export const versionMismatches = (source: string, prose: string, blocks: readonly CodeBlock[], words: VersionWords): StructureIssue[] =>
|
|
157
|
+
blocks.flatMap((block) => blockMismatches(source, prose, block, words));
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { StructureIssue } from "./issues.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Versions listed in order, a changelog's headings or a list of releases, with one out of place. The direction (newest or
|
|
5
|
+
* oldest first) is taken from most of the steps, and a version that fits in no longest run along it is pointed out.
|
|
6
|
+
*/
|
|
7
|
+
export type VersionPoint = { readonly offset: number; readonly label: string };
|
|
8
|
+
|
|
9
|
+
type Version = { readonly parts: readonly number[]; readonly prerelease: string };
|
|
10
|
+
|
|
11
|
+
/** A version at the start of a heading or an item: 3.2.0, v3.2.0, [3.2.0], 3.2.0-beta.1. */
|
|
12
|
+
const VERSION_START = /^\[?v?(\d{1,4})\.(\d{1,4})\.(\d{1,4})(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\]?(?![\w.])/u;
|
|
13
|
+
|
|
14
|
+
/** The version a heading or an item starts with, as written; undefined when it does not start with one. */
|
|
15
|
+
export const leadingVersion = (text: string): string | undefined => VERSION_START.exec(text.trim())?.[0];
|
|
16
|
+
|
|
17
|
+
const parse = (label: string): Version | undefined => {
|
|
18
|
+
const match = VERSION_START.exec(label);
|
|
19
|
+
if (match === null) return undefined;
|
|
20
|
+
return { parts: [match[1], match[2], match[3]].map(Number), prerelease: match[4] ?? "" };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** A prerelease (3.0.0-beta.1) comes before its release (3.0.0). */
|
|
24
|
+
const comparePrerelease = (left: string, right: string): number => {
|
|
25
|
+
if (left === right) return 0;
|
|
26
|
+
if (left === "") return 1;
|
|
27
|
+
return right === "" ? -1 : Math.sign(left.localeCompare(right, "en", { numeric: true }));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const compareVersions = (left: Version, right: Version): number => {
|
|
31
|
+
const differing = left.parts.findIndex((part, index) => part !== right.parts[index]);
|
|
32
|
+
return differing === -1 ? comparePrerelease(left.prerelease, right.prerelease) : Math.sign((left.parts[differing] ?? 0) - (right.parts[differing] ?? 0));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** The longest run along direction ending at each version (equal versions do not break it). */
|
|
36
|
+
const longestEndingAt = (versions: readonly Version[], direction: number): number[] =>
|
|
37
|
+
versions.reduce<number[]>((lengths, version, index) => {
|
|
38
|
+
const along = versions.slice(0, index).map((earlier, at) => (compareVersions(version, earlier) === -direction ? 0 : (lengths[at] ?? 0)));
|
|
39
|
+
return [...lengths, 1 + Math.max(0, ...along)];
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
42
|
+
const majorityOf = (versions: readonly Version[]): number =>
|
|
43
|
+
Math.sign(versions.slice(1).reduce((sum, version, index) => sum + compareVersions(version, versions[index] ?? version), 0));
|
|
44
|
+
|
|
45
|
+
/** The fewest versions an order is read from: with two, either one could be the one out of place. */
|
|
46
|
+
const MIN_VERSIONS = 3;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The versions that belong to no longest run along the majority direction. A run that holds no more than half of them is
|
|
50
|
+
* taken as sorted by something else, and nothing is said.
|
|
51
|
+
*/
|
|
52
|
+
export const versionOrderBreaks = (points: readonly VersionPoint[]): StructureIssue[] => {
|
|
53
|
+
const parsed = points.flatMap((point) => {
|
|
54
|
+
const version = parse(point.label);
|
|
55
|
+
return version === undefined ? [] : [{ point, version }];
|
|
56
|
+
});
|
|
57
|
+
const versions = parsed.map((entry) => entry.version);
|
|
58
|
+
const direction = majorityOf(versions);
|
|
59
|
+
if (versions.length < MIN_VERSIONS || direction === 0) return [];
|
|
60
|
+
const forward = longestEndingAt(versions, direction);
|
|
61
|
+
const backward = longestEndingAt(versions.toReversed(), -direction).toReversed();
|
|
62
|
+
const longest = Math.max(...forward);
|
|
63
|
+
if (longest * 2 <= versions.length) return [];
|
|
64
|
+
return parsed.flatMap((entry, index) =>
|
|
65
|
+
(forward[index] ?? 0) + (backward[index] ?? 0) - 1 === longest
|
|
66
|
+
? []
|
|
67
|
+
: [{ offset: entry.point.offset, values: { version: entry.point.label, previous: parsed[index - 1]?.point.label ?? "" } }],
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** A version whose last part is zero (3.1.0) is no section number: the sections under 3.1 count from 3.1.1. */
|
|
72
|
+
const endsInZero = (version: Version): boolean => version.parts.at(-1) === 0;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Whether dotted labels (1.2.1, 1.2.2) are a version history rather than section numbers: all of them versions, and
|
|
76
|
+
* either one ends in zero or most steps go down (newest first). Section numbers only go up. version-order checks the
|
|
77
|
+
* histories and numbering-gap the rest, so a sequence is never reported by both.
|
|
78
|
+
*/
|
|
79
|
+
export const isVersionHistory = (labels: readonly string[]): boolean => {
|
|
80
|
+
const versions = labels.map(parse);
|
|
81
|
+
const parsed = versions.filter((version) => version !== undefined);
|
|
82
|
+
if (labels.length < 2 || parsed.length !== labels.length) return false;
|
|
83
|
+
return parsed.some(endsInZero) || majorityOf(parsed) < 0;
|
|
84
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// The prose with its Markdown tables read back in. The prose masks tables, but a quote or an invoice keeps most of its
|
|
2
|
+
// amounts in one, and a rule comparing how amounts are written has to see them.
|
|
3
|
+
import type { ProseDocument, Span } from "./plugin.ts";
|
|
4
|
+
import { maskSpans } from "./mask.ts";
|
|
5
|
+
import { opaqueSpans, readMarkdown, spansOfType } from "./markdown-read.ts";
|
|
6
|
+
import { TABLE_RULE } from "./structure/runs.ts";
|
|
7
|
+
|
|
8
|
+
const within = (inner: Span, outer: Span): boolean => inner.start >= outer.start && inner.end <= outer.end;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The prose, with each table span as the source writes it, except what stays hidden inside it (code in a cell). Offsets
|
|
12
|
+
* are kept. Pure.
|
|
13
|
+
*/
|
|
14
|
+
export const proseWithTables = (prose: string, source: string, tables: readonly Span[], hidden: readonly Span[]): string => {
|
|
15
|
+
if (tables.length === 0) return prose;
|
|
16
|
+
const shown = maskSpans(source, hidden);
|
|
17
|
+
const pieces: string[] = [];
|
|
18
|
+
const end = tables
|
|
19
|
+
.toSorted((left, right) => left.start - right.start)
|
|
20
|
+
.reduce((from, table) => {
|
|
21
|
+
if (table.start < from) return from;
|
|
22
|
+
pieces.push(prose.slice(from, table.start), shown.slice(table.start, table.end));
|
|
23
|
+
return table.end;
|
|
24
|
+
}, 0);
|
|
25
|
+
pieces.push(prose.slice(end));
|
|
26
|
+
return pieces.join("");
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const hasTableRule = (source: string): boolean => source.split("\n").some((line) => TABLE_RULE.test(line) && line.includes("-"));
|
|
30
|
+
|
|
31
|
+
/** The document's prose with its tables, outside code and quoted replies. A document that is not Markdown keeps its prose. */
|
|
32
|
+
export const proseAndTablesOf = (doc: ProseDocument): string => {
|
|
33
|
+
const prose = doc.prose ?? doc.source;
|
|
34
|
+
if (doc.prose === undefined || doc.markup?.markdown !== true || !hasTableRule(doc.source)) return prose;
|
|
35
|
+
const { root } = readMarkdown(doc.source);
|
|
36
|
+
const quoted = [...spansOfType(root, "blockquote"), ...(doc.replyQuotes ?? [])];
|
|
37
|
+
const tables = spansOfType(root, "table").filter((table) => !quoted.some((quote) => within(table, quote)));
|
|
38
|
+
return proseWithTables(doc.prose, doc.source, tables, opaqueSpans(root));
|
|
39
|
+
};
|
package/src/ui-labels.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// The same label on the screen written two ways in one manual (**Start Restore** and **Start restore**, [復元を開始] and
|
|
2
|
+
// [復元開始]). Pure: reads the labels a manual marks as labels, bold or in [], and points at the form written less often.
|
|
3
|
+
|
|
4
|
+
import { escapeRegExp } from "./orthography.ts";
|
|
5
|
+
|
|
6
|
+
export type Label = { readonly surface: string; readonly offset: number };
|
|
7
|
+
export type LabelVariant = { readonly label: Label; readonly usual: string };
|
|
8
|
+
|
|
9
|
+
/** What a manual marks as a label on the screen: bold (** or __), or the full-width brackets Japanese manuals use. */
|
|
10
|
+
const MARKED = /\*\*([^*\n]{1,40})\*\*|__([^_\n]{1,40})__|[([^]\n]{1,40})]/gu;
|
|
11
|
+
const SPACES = /\s+/gu;
|
|
12
|
+
const LETTER = /\p{L}/u;
|
|
13
|
+
|
|
14
|
+
/** Each label marked in the source whose text is prose (not covered as code in prose) and holds a letter. */
|
|
15
|
+
export const labelsIn = (source: string, prose: string): Label[] =>
|
|
16
|
+
[...source.matchAll(MARKED)].flatMap((match) => {
|
|
17
|
+
const surface = (match[1] ?? match[2] ?? match[3] ?? "").trim();
|
|
18
|
+
const inner = match.index + match[0].indexOf(surface);
|
|
19
|
+
const covered = prose.slice(inner, inner + surface.length) !== surface;
|
|
20
|
+
return covered || !LETTER.test(surface) ? [] : [{ surface, offset: inner }];
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Two forms of one label differ only in case, spaces, or a word a label is written with or without (the label-particle
|
|
25
|
+
* lexicon: 復元を開始 and 復元開始).
|
|
26
|
+
*/
|
|
27
|
+
const keyOf = (surface: string, particles: readonly string[]): string =>
|
|
28
|
+
particles.reduce((text, particle) => text.replace(joining(particle), ""), surface.replace(SPACES, "")).toLowerCase();
|
|
29
|
+
|
|
30
|
+
/** A particle between two kanji or katakana (復元を開始), not one inside a word (その他). */
|
|
31
|
+
const joining = (particle: string): RegExp =>
|
|
32
|
+
new RegExp(`(?<=[\\p{Script=Han}\\p{Script=Katakana}ー])${escapeRegExp(particle)}(?=[\\p{Script=Han}\\p{Script=Katakana}])`, "gu");
|
|
33
|
+
|
|
34
|
+
/** Two forms that differ only in the case of their first letter (Note and note): emphasis at a sentence's start, not two labels. */
|
|
35
|
+
const onlyFirstLetterDiffers = (forms: readonly string[]): boolean =>
|
|
36
|
+
new Set(forms.map((form) => `${form.charAt(0).toLowerCase()}${form.slice(1)}`)).size === 1;
|
|
37
|
+
|
|
38
|
+
const groupBy = (labels: readonly Label[], keyFor: (label: Label) => string): Map<string, Label[]> =>
|
|
39
|
+
labels.reduce((groups, label) => groups.set(keyFor(label), [...(groups.get(keyFor(label)) ?? []), label]), new Map<string, Label[]>());
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Each label written in a form other than the one its key is written in most; on a tie, the later form. A label written
|
|
43
|
+
* one way only says nothing.
|
|
44
|
+
*/
|
|
45
|
+
export const labelVariants = (labels: readonly Label[], particles: readonly string[] = []): LabelVariant[] => {
|
|
46
|
+
const byKey = groupBy(labels, (label) => keyOf(label.surface, particles));
|
|
47
|
+
return [...byKey.values()].flatMap((group) => {
|
|
48
|
+
const counts = groupBy(group, (label) => label.surface);
|
|
49
|
+
if (counts.size < 2 || onlyFirstLetterDiffers([...counts.keys()])) return [];
|
|
50
|
+
const [first] = counts;
|
|
51
|
+
if (first === undefined) return [];
|
|
52
|
+
const usual = [...counts].reduce((best, entry) => (entry[1].length > best[1].length ? entry : best), first)[0];
|
|
53
|
+
return group.filter((label) => label.surface !== usual).map((label) => ({ label, usual }));
|
|
54
|
+
});
|
|
55
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// A function called in a code example that the page never defines, where the page documents one whose name it extends:
|
|
2
|
+
// wrapText( on a page about wrap, wrapLines( after import { wrap }. Pure; reads the Markdown source. The global functions
|
|
3
|
+
// of programming languages (parseInt, setTimeout) come from a lexicon, so a page about parse may call parseInt.
|
|
4
|
+
import { codeFences } from "./detectors/code-fences.ts";
|
|
5
|
+
|
|
6
|
+
/** A call to a name the page does not define, where it is written, and the documented name it is likely a slip of. */
|
|
7
|
+
export type UndefinedCall = { readonly name: string; readonly offset: number; readonly documented: string };
|
|
8
|
+
|
|
9
|
+
const CALL = /(?<![\w$.])([A-Za-z_$][\w$]*)[ \t]*\(/gu;
|
|
10
|
+
const WORD = /[A-Za-z_$][\w$]*/gu;
|
|
11
|
+
const LEADING_WORD = /^[A-Za-z_$][\w$]*/u;
|
|
12
|
+
/** import { wrap, type Options, measure as m } from "wrapkit" (JavaScript) and from wrapkit import wrap, measure (Python). */
|
|
13
|
+
const IMPORT_BRACES = /\bimport[ \t]*\{([^}]*)\}/gu;
|
|
14
|
+
const FROM_IMPORT = /\bfrom[ \t]+[\w.]+[ \t]+import[ \t]+([\w, \t]+)/gu;
|
|
15
|
+
const TYPE_MODIFIER = /^type[ \t]+/u;
|
|
16
|
+
/** A name right after one of these is being declared, not called: function wrapText(, def wrap_text(. */
|
|
17
|
+
const DECLARING = /\b(?:function\*?|def|fn|func|class|new)[ \t]+$/u;
|
|
18
|
+
/** Where a line comment starts: a call after it is commented out. */
|
|
19
|
+
const LINE_COMMENT = /\/\/|(?:^|[ \t])#/u;
|
|
20
|
+
/** The shortest documented name a call is compared with: shorter ones (id, get) are prefixes of too many names. */
|
|
21
|
+
const MIN_DOCUMENTED = 4;
|
|
22
|
+
|
|
23
|
+
/** Each specifier's own name: `type Options` is Options, `measure as m` is measure. */
|
|
24
|
+
const specifiers = (list: string): string[] =>
|
|
25
|
+
list.split(",").flatMap((specifier) => LEADING_WORD.exec(specifier.trim().replace(TYPE_MODIFIER, ""))?.[0] ?? []);
|
|
26
|
+
|
|
27
|
+
const importedNames = (source: string): string[] =>
|
|
28
|
+
[...source.matchAll(IMPORT_BRACES), ...source.matchAll(FROM_IMPORT)].flatMap((match) => specifiers(match[1] ?? ""));
|
|
29
|
+
|
|
30
|
+
/** Names the page documents: the first word of a heading (## wrap, ### `wrap()`) and the names it imports. */
|
|
31
|
+
const documentedNames = (source: string, headings: readonly string[]): Set<string> => {
|
|
32
|
+
const fromHeadings = headings.flatMap((heading) => LEADING_WORD.exec(heading.replace(/[`*]/gu, "").trim())?.[0] ?? []);
|
|
33
|
+
return new Set([...fromHeadings, ...importedNames(source)].filter((name) => name.length >= MIN_DOCUMENTED));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const countWords = (source: string): Map<string, number> =>
|
|
37
|
+
[...source.matchAll(WORD)].reduce((counts, match) => counts.set(match[0], (counts.get(match[0]) ?? 0) + 1), new Map<string, number>());
|
|
38
|
+
|
|
39
|
+
/** Whether the call at `at` in `code` is declared there or commented out. */
|
|
40
|
+
const isDeclaredOrCommented = (code: string, at: number): boolean => {
|
|
41
|
+
const lineStart = code.lastIndexOf("\n", at - 1) + 1;
|
|
42
|
+
const before = code.slice(lineStart, at);
|
|
43
|
+
return DECLARING.test(before) || LINE_COMMENT.test(before);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Every call in a code block to a name written nowhere else on the page, when a documented name is its stem
|
|
48
|
+
* (wrap → wrapText). A name used twice (defined and called, or called twice) is the example's own. headings are the page's
|
|
49
|
+
* Markdown headings; globals the language functions every page may call.
|
|
50
|
+
*/
|
|
51
|
+
export const undefinedCalls = (source: string, headings: readonly string[], globals: readonly string[] = []): UndefinedCall[] => {
|
|
52
|
+
const documented = documentedNames(source, headings);
|
|
53
|
+
if (documented.size === 0) return [];
|
|
54
|
+
const counts = countWords(source);
|
|
55
|
+
const known = new Set([...documented, ...globals]);
|
|
56
|
+
return codeFences(source).flatMap((fence) => {
|
|
57
|
+
const code = source.slice(fence.start, fence.end);
|
|
58
|
+
return [...code.matchAll(CALL)].flatMap((match) => {
|
|
59
|
+
const name = match[1] ?? "";
|
|
60
|
+
const stem = [...documented].find((candidate) => name !== candidate && name.startsWith(candidate));
|
|
61
|
+
if (stem === undefined || known.has(name) || (counts.get(name) ?? 0) > 1 || isDeclaredOrCommented(code, match.index)) return [];
|
|
62
|
+
return [{ name, offset: fence.start + match.index, documented: stem }];
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// A quotation whose speaker, in the words right beside it, is a role and not a name (業界のアナリストは「…」と述べた,
|
|
2
|
+
// "…," said an analyst). The words come from the language's word lists: unnamed-speaker (roles, what may follow a role,
|
|
3
|
+
// titles, words pointing back, the quoting particle) and quote-attribution (said, according to, と述べ). Pure.
|
|
4
|
+
import { QUOTATION_MARKS, quotedSpans } from "./quoted-span.ts";
|
|
5
|
+
import type { LexiconEntry, Span } from "./plugin.ts";
|
|
6
|
+
|
|
7
|
+
export type SpeakerSentence = { readonly start: number; readonly text: string };
|
|
8
|
+
|
|
9
|
+
export type UnnamedSpeakerQuote = { readonly offset: number; readonly quote: string; readonly speaker: string };
|
|
10
|
+
|
|
11
|
+
/** The word list unnamed-speaker, by group, and quote-attribution with the list's own cues (group cue), longest first. */
|
|
12
|
+
export type SpeakerWords = {
|
|
13
|
+
readonly roles: readonly string[];
|
|
14
|
+
readonly afterRole: readonly string[];
|
|
15
|
+
readonly honorifics: readonly string[];
|
|
16
|
+
readonly anaphors: readonly string[];
|
|
17
|
+
readonly afterQuote: readonly string[];
|
|
18
|
+
readonly cues: readonly LexiconEntry[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const speakerWords = (speaker: readonly LexiconEntry[], cues: readonly LexiconEntry[]): SpeakerWords => {
|
|
22
|
+
const group = (name: string): string[] => speaker.filter((entry) => entry.group === name && entry.pattern !== "").map((entry) => entry.pattern);
|
|
23
|
+
return {
|
|
24
|
+
roles: group("role"),
|
|
25
|
+
afterRole: group("after-role"),
|
|
26
|
+
honorifics: group("honorific"),
|
|
27
|
+
anaphors: group("anaphor"),
|
|
28
|
+
afterQuote: group("after-quote"),
|
|
29
|
+
cues: [...cues, ...speaker.filter((entry) => entry.group === "cue")]
|
|
30
|
+
.filter((cue) => cue.pattern !== "")
|
|
31
|
+
.toSorted((left, right) => right.pattern.length - left.pattern.length),
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Shorter than this, a quotation is a term or a label (「保存」, "Save"), not someone's words. */
|
|
36
|
+
const MIN_QUOTE_CHARS = 10;
|
|
37
|
+
|
|
38
|
+
const LATIN = /\p{Script=Latin}/u;
|
|
39
|
+
const LETTER = /\p{L}/u;
|
|
40
|
+
const UPPER_START = /^\p{Lu}/u;
|
|
41
|
+
const LOWER_START = /^\p{Ll}/u;
|
|
42
|
+
const WORD = /[\p{L}\p{N}'’-]+/gu;
|
|
43
|
+
/** Words, and the commas between them: a comma ends a run of capitalised words (an analyst at Acme, Hanako Mori). */
|
|
44
|
+
const WORD_OR_COMMA = /[\p{L}\p{N}'’-]+|[,,]/gu;
|
|
45
|
+
/** A Japanese title is not one when a kanji follows it (氏名, 様々). */
|
|
46
|
+
const JOINED_KANJI = /^[\p{Script=Han}々]/u;
|
|
47
|
+
/** How far from the quotation the speaker is looked for, on each side: keeps a long sentence of many quotations linear. */
|
|
48
|
+
const SPEAKER_REACH = 200;
|
|
49
|
+
/** Where the clause holding the speaker before a quotation starts: after these marks. */
|
|
50
|
+
const CLAUSE_MARKS_BEFORE = /[。.!?!?;;「」『』“”"、,]/u;
|
|
51
|
+
/** Where the speaker's phrase after a quotation ends. A comma does not end it in English (said Hanako Mori, an analyst). */
|
|
52
|
+
const CLAUSE_MARKS_AFTER = /[。.!?.!?;;「」『』“”"]/u;
|
|
53
|
+
/** Where a phrase after the quoting particle (「…」と業界関係者は話す) ends. */
|
|
54
|
+
const CLAUSE_MARKS_PARTICLE = /[。.!?.!?;;「」『』“”"、,]/u;
|
|
55
|
+
/** Where a speaker standing before its cue ("…," an analyst said) must not reach past. */
|
|
56
|
+
const CLAUSE_MARKS_INNER = /[,,、。.!?.!?;;::]/u;
|
|
57
|
+
/** Spaces and marks that join a speaker to a quotation or a cue, and are not part of either. */
|
|
58
|
+
const GLUE = /[\s,,、::—–-]/u;
|
|
59
|
+
const PHRASE_END = /^[,,、。..;;::))]/u;
|
|
60
|
+
|
|
61
|
+
/** A Latin word is matched whole and without case; a Japanese one as written, inside any text. */
|
|
62
|
+
const matchesAt = (text: string, at: number, word: string): boolean => {
|
|
63
|
+
if (!LATIN.test(word)) return text.startsWith(word, at);
|
|
64
|
+
return (
|
|
65
|
+
text.slice(at, at + word.length).toLowerCase() === word.toLowerCase() && !LETTER.test(text.charAt(at - 1)) && !LETTER.test(text.charAt(at + word.length))
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const positionsOf = (text: string, word: string): number[] =>
|
|
70
|
+
word === "" ? [] : [...Array(Math.max(0, text.length - word.length + 1)).keys()].filter((at) => matchesAt(text, at, word));
|
|
71
|
+
|
|
72
|
+
const startsWithWord = (text: string, word: string): boolean => matchesAt(text, 0, word);
|
|
73
|
+
|
|
74
|
+
const endsWithWord = (text: string, word: string): boolean => text.length >= word.length && matchesAt(text, text.length - word.length, word);
|
|
75
|
+
|
|
76
|
+
const afterLast = (text: string, marks: RegExp): string => {
|
|
77
|
+
const cut = [...text].reduce((last, char, index) => (marks.test(char) ? index : last), -1);
|
|
78
|
+
return [...text].slice(cut + 1).join("");
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const beforeFirst = (text: string, marks: RegExp): string => {
|
|
82
|
+
const at = [...text].findIndex((char) => marks.test(char));
|
|
83
|
+
return at < 0 ? text : [...text].slice(0, at).join("");
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** The text without glue at either end. */
|
|
87
|
+
const clean = (text: string): string => {
|
|
88
|
+
const chars = [...text];
|
|
89
|
+
const first = chars.findIndex((char) => !GLUE.test(char));
|
|
90
|
+
return first < 0 ? "" : chars.slice(first, chars.findLastIndex((char) => !GLUE.test(char)) + 1).join("");
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** leavesSpeakerBefore: after the quotation, whether the speaker may still be the one before it (「…」と述べた), not one after it (said X). */
|
|
94
|
+
type Side = { readonly speaker: string; readonly attributed: boolean; readonly leavesSpeakerBefore?: boolean };
|
|
95
|
+
|
|
96
|
+
/** The clause before the quotation: the speaker, with a cue at its end (An analyst said, 関係者によれば) or before it (according to). */
|
|
97
|
+
const speakerBefore = (before: string, words: SpeakerWords): Side => {
|
|
98
|
+
const clause = clean(afterLast(clean(before), CLAUSE_MARKS_BEFORE));
|
|
99
|
+
const cues = words.cues.filter((cue) => cue.position !== "after");
|
|
100
|
+
const ending = cues.find((cue) => endsWithWord(clause, cue.pattern));
|
|
101
|
+
if (ending !== undefined) return { speaker: clean(clause.slice(0, clause.length - ending.pattern.length)), attributed: true };
|
|
102
|
+
const leads = cues
|
|
103
|
+
.filter((cue) => cue.position === "before")
|
|
104
|
+
.flatMap((cue) => positionsOf(clause, cue.pattern).map((at) => at + cue.pattern.length))
|
|
105
|
+
.toSorted((left, right) => right - left);
|
|
106
|
+
const lead = leads[0];
|
|
107
|
+
if (lead !== undefined) return { speaker: clean(clause.slice(lead)), attributed: true };
|
|
108
|
+
return { speaker: clause, attributed: false };
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** The words after the quotation: a quoting particle (「…」と業界関係者は), a cue then the speaker (said an analyst), or the speaker then a cue. */
|
|
112
|
+
const speakerAfter = (after: string, words: SpeakerWords): Side => {
|
|
113
|
+
const rest = clean(after);
|
|
114
|
+
const particle = words.afterQuote.find((word) => startsWithWord(rest, word));
|
|
115
|
+
if (particle !== undefined)
|
|
116
|
+
return { speaker: clean(beforeFirst(clean(rest.slice(particle.length)), CLAUSE_MARKS_PARTICLE)), attributed: true, leavesSpeakerBefore: true };
|
|
117
|
+
const cues = words.cues.filter((cue) => cue.position !== "before");
|
|
118
|
+
const leading = cues.find((cue) => startsWithWord(rest, cue.pattern));
|
|
119
|
+
if (leading !== undefined) {
|
|
120
|
+
const speaker = clean(beforeFirst(rest.slice(leading.pattern.length), CLAUSE_MARKS_AFTER));
|
|
121
|
+
return { speaker, attributed: true, leavesSpeakerBefore: speaker === "" };
|
|
122
|
+
}
|
|
123
|
+
const clause = beforeFirst(rest, CLAUSE_MARKS_INNER);
|
|
124
|
+
const cueAt = cues.flatMap((cue) => positionsOf(clause, cue.pattern)).toSorted((left, right) => left - right)[0];
|
|
125
|
+
if (cueAt !== undefined) return { speaker: clean(clause.slice(0, cueAt)), attributed: true, leavesSpeakerBefore: cueAt === 0 };
|
|
126
|
+
return { speaker: "", attributed: false };
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const isCapitalised = (word: string | undefined): boolean => word !== undefined && UPPER_START.test(word);
|
|
130
|
+
|
|
131
|
+
const isRoleWord = (word: string | undefined, words: SpeakerWords): boolean =>
|
|
132
|
+
word !== undefined && words.roles.some((role) => LATIN.test(role) && role.toLowerCase() === word.toLowerCase());
|
|
133
|
+
|
|
134
|
+
const isAfterRoleWord = (word: string | undefined, words: SpeakerWords): boolean =>
|
|
135
|
+
word !== undefined && words.afterRole.some((entry) => entry.toLowerCase() === word.toLowerCase());
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* A run of capitalised words that is a person's name (Hanako Mori, analyst Hanako Mori). Not one: a run after a word like
|
|
139
|
+
* "at" (an analyst at Minato Research), a run right before a role (an Acme spokesperson), or, when the phrase opens the
|
|
140
|
+
* clause, its first word alone ("An analyst", "Experts"). After a cue it is a name: said Mori, an analyst.
|
|
141
|
+
*/
|
|
142
|
+
const holdsCapitalisedName = (phrase: string, words: SpeakerWords, opensSentence: boolean): boolean => {
|
|
143
|
+
const tokens = [...phrase.matchAll(WORD_OR_COMMA)].map((match) => match[0]);
|
|
144
|
+
return tokens.some((token, index) => {
|
|
145
|
+
if (!isCapitalised(token) || isCapitalised(tokens[index - 1])) return false;
|
|
146
|
+
const runEnd = tokens.findIndex((later, at) => at > index && !isCapitalised(later));
|
|
147
|
+
const end = runEnd < 0 ? tokens.length : runEnd;
|
|
148
|
+
if (isAfterRoleWord(tokens[index - 1], words) || isRoleWord(tokens[end], words)) return false;
|
|
149
|
+
const next = tokens[1];
|
|
150
|
+
return !(opensSentence && index === 0 && end === 1 && (next === undefined || LOWER_START.test(next)));
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const holdsTitle = (phrase: string, title: string): boolean =>
|
|
155
|
+
positionsOf(phrase, title).some((at) => LATIN.test(title) || !JOINED_KANJI.test(phrase.slice(at + title.length)));
|
|
156
|
+
|
|
157
|
+
const isNamed = (phrase: string, words: SpeakerWords, opensSentence: boolean): boolean =>
|
|
158
|
+
words.honorifics.some((title) => holdsTitle(phrase, title)) || holdsCapitalisedName(phrase, words, opensSentence);
|
|
159
|
+
|
|
160
|
+
const lastWord = (text: string): string => [...text.matchAll(WORD)].map((match) => match[0]).at(-1) ?? "";
|
|
161
|
+
|
|
162
|
+
/** Whether the role at this place is the head of the phrase: nothing after it, or only a word like は or "at". */
|
|
163
|
+
const headsPhrase = (phrase: string, at: number, role: string, words: SpeakerWords): boolean => {
|
|
164
|
+
const after = phrase.slice(at + role.length).trimStart();
|
|
165
|
+
return after === "" || PHRASE_END.test(after) || words.afterRole.some((word) => startsWithWord(after, word));
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const pointsBack = (phrase: string, at: number, words: SpeakerWords): boolean => {
|
|
169
|
+
const before = phrase.slice(0, at).trimEnd();
|
|
170
|
+
return words.anaphors.some((word) => (LATIN.test(word) ? lastWord(before).toLowerCase() === word.toLowerCase() : before.endsWith(word)));
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* The phrase as the message shows it, when a role heads it and does not point back at someone named before (同アナリスト,
|
|
175
|
+
* the analyst). A Japanese phrase is shown up to its role (業界関係者は話す as 業界関係者); an English one whole.
|
|
176
|
+
*/
|
|
177
|
+
const unnamedRoleIn = (phrase: string, words: SpeakerWords): string | undefined => {
|
|
178
|
+
const heads = words.roles.flatMap((role) =>
|
|
179
|
+
positionsOf(phrase, role)
|
|
180
|
+
.filter((at) => headsPhrase(phrase, at, role, words) && !pointsBack(phrase, at, words))
|
|
181
|
+
.map((at) => (LATIN.test(role) ? phrase : phrase.slice(0, at + role.length))),
|
|
182
|
+
);
|
|
183
|
+
return heads[0];
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
type Phrase = { readonly text: string; readonly opensSentence: boolean };
|
|
187
|
+
|
|
188
|
+
/** The phrases that may be the speaker: the attributed side's, and the one before when a cue after leaves the speaker there. */
|
|
189
|
+
const speakerPhrases = (before: Side, after: Side, beforeOpens: boolean): Phrase[] => {
|
|
190
|
+
const useBefore = before.attributed || (after.attributed && after.leavesSpeakerBefore === true);
|
|
191
|
+
return [
|
|
192
|
+
...(useBefore ? [{ text: before.speaker, opensSentence: beforeOpens }] : []),
|
|
193
|
+
...(after.attributed ? [{ text: after.speaker, opensSentence: false }] : []),
|
|
194
|
+
].filter((phrase) => phrase.text !== "");
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/** The phrase that gives this quotation to a role and to no name, if any. */
|
|
198
|
+
const unnamedSpeakerOf = (text: string, span: Span, words: SpeakerWords): string | undefined => {
|
|
199
|
+
const reach = Math.max(0, span.start - 1 - SPEAKER_REACH);
|
|
200
|
+
const before = speakerBefore(text.slice(reach, span.start - 1), words);
|
|
201
|
+
const after = speakerAfter(text.slice(span.end + 1, span.end + 1 + SPEAKER_REACH), words);
|
|
202
|
+
const phrases = speakerPhrases(
|
|
203
|
+
before,
|
|
204
|
+
after,
|
|
205
|
+
reach === 0 &&
|
|
206
|
+
text
|
|
207
|
+
.slice(0, span.start - 1)
|
|
208
|
+
.trim()
|
|
209
|
+
.startsWith(before.speaker),
|
|
210
|
+
);
|
|
211
|
+
if (phrases.some((phrase) => isNamed(phrase.text, words, phrase.opensSentence))) return undefined;
|
|
212
|
+
return phrases.map((phrase) => unnamedRoleIn(phrase.text, words)).find((speaker) => speaker !== undefined);
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/** Each quotation in the sentence given to a role with no name. */
|
|
216
|
+
export const unnamedSpeakerQuotes = (sentence: SpeakerSentence, words: SpeakerWords): UnnamedSpeakerQuote[] => {
|
|
217
|
+
if (words.roles.length === 0) return [];
|
|
218
|
+
return quotedSpans(sentence.text, QUOTATION_MARKS).flatMap((span) => {
|
|
219
|
+
const quote = clean(sentence.text.slice(span.start, span.end));
|
|
220
|
+
if ([...quote].length < MIN_QUOTE_CHARS) return [];
|
|
221
|
+
const speaker = unnamedSpeakerOf(sentence.text, span, words);
|
|
222
|
+
return speaker === undefined ? [] : [{ offset: sentence.start + span.start, quote, speaker }];
|
|
223
|
+
});
|
|
224
|
+
};
|