chaffjs 0.27.1 → 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/README.md +2 -1
- 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 +42 -18
- 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/number-word-counts.d.ts +10 -0
- package/dist/derived/number-word-counts.d.ts.map +1 -0
- package/dist/derived/number-word-counts.js +21 -0
- package/dist/derived/number-word-counts.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 +8 -0
- package/dist/detectors/amount-scale.d.ts.map +1 -0
- package/dist/detectors/amount-scale.js +74 -0
- package/dist/detectors/amount-scale.js.map +1 -0
- 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/change-rate.d.ts.map +1 -1
- package/dist/detectors/change-rate.js +12 -1
- package/dist/detectors/change-rate.js.map +1 -1
- 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 +3 -1
- package/dist/detectors/currency-notation.d.ts.map +1 -1
- package/dist/detectors/currency-notation.js +4 -3
- 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 +79 -16
- 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 +89 -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 +92 -10
- 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/amount-scale.d.ts +3 -0
- package/dist/detectors/registry/amount-scale.d.ts.map +1 -0
- package/dist/detectors/registry/amount-scale.js +3 -0
- package/dist/detectors/registry/amount-scale.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/counted-facts.d.ts +16 -0
- package/dist/facts/counted-facts.d.ts.map +1 -0
- package/dist/facts/counted-facts.js +45 -0
- package/dist/facts/counted-facts.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 +41 -5
- package/dist/name-variants.d.ts.map +1 -1
- package/dist/name-variants.js +93 -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 +35 -0
- package/dist/structure/amount-scale.d.ts.map +1 -0
- package/dist/structure/amount-scale.js +83 -0
- package/dist/structure/amount-scale.js.map +1 -0
- 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/subject-change.d.ts +8 -0
- package/dist/structure/subject-change.d.ts.map +1 -0
- package/dist/structure/subject-change.js +31 -0
- package/dist/structure/subject-change.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 +74 -0
- package/rules/announced-count-mismatch.yaml +9 -4
- package/rules/arrival-before-departure.yaml +48 -0
- package/rules/change-rate-mismatch.yaml +5 -4
- 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/elapsed-years-mismatch.yaml +2 -2
- 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 +17 -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 +42 -18
- 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/number-word-counts.ts +28 -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 +96 -0
- 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/change-rate.ts +15 -2
- 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 +4 -3
- 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 +115 -17
- 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 +110 -2
- 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 +114 -11
- 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/amount-scale.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/counted-facts.ts +59 -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 +152 -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 +115 -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/subject-change.ts +35 -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,82 @@
|
|
|
1
|
+
// Text a page writes for a screen reader alone, which a sighted reader never sees: an element whose class follows a
|
|
2
|
+
// visually-hidden convention, and the anchor a skip link moves focus to. Pure; a regular-expression reading.
|
|
3
|
+
import {
|
|
4
|
+
ATTRIBUTES,
|
|
5
|
+
HEADING_TAGS,
|
|
6
|
+
headingRanges,
|
|
7
|
+
isInside,
|
|
8
|
+
plainText,
|
|
9
|
+
withoutElementsOpening,
|
|
10
|
+
withoutElementsWhere,
|
|
11
|
+
type ElementRange,
|
|
12
|
+
} from "./html-elements.ts";
|
|
13
|
+
|
|
14
|
+
// The class names that frameworks and style guides give text written for a screen reader alone (sr-only,
|
|
15
|
+
// visually-hidden, govuk-visually-hidden, screen-reader-text), never negated (not-sr-only shows it); "hidden" only as
|
|
16
|
+
// a whole name (not hidden-xs).
|
|
17
|
+
const READER_ONLY_CLASS = /^(?:(?!not-)[a-z0-9]+-)*(?:sr-only|visually-?hidden|screen-reader-text|element-invisible)$/iu;
|
|
18
|
+
|
|
19
|
+
const CLASS_OPENING = /<([a-z][a-z0-9-]*)\b[^>]*\sclass\s*=/giu;
|
|
20
|
+
|
|
21
|
+
const CLASS_VALUE = new RegExp(String.raw`^<[a-z][a-z0-9-]*${ATTRIBUTES}\s+class\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))`, "iu");
|
|
22
|
+
|
|
23
|
+
/** A variant (md:block, md:not-sr-only) shows the element on some screens or states, so it is not hidden from sight. */
|
|
24
|
+
const isReaderOnlyClass = (range: ElementRange): boolean => {
|
|
25
|
+
const value = CLASS_VALUE.exec(range.openTag);
|
|
26
|
+
const names = (value?.[1] ?? value?.[2] ?? value?.[3] ?? "").split(/\s+/u);
|
|
27
|
+
if (names.some((name) => name.includes(":"))) return false;
|
|
28
|
+
return names.some((name) => READER_ONLY_CLASS.test(name)) || names.includes("hidden");
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** An anchor with no href that only a script can focus: where a skip link moves the reader ("ここから本文です。"). */
|
|
32
|
+
const isFocusTarget = (range: ElementRange): boolean =>
|
|
33
|
+
!/\shref\s*=/iu.test(range.openTag) && /\stabindex\s*=\s*(?:"\s*-1\s*"|'\s*-1\s*'|-1(?=[\s/>]))/iu.test(range.openTag);
|
|
34
|
+
|
|
35
|
+
const LINE_TAGS = [
|
|
36
|
+
"p",
|
|
37
|
+
"div",
|
|
38
|
+
"li",
|
|
39
|
+
"dt",
|
|
40
|
+
"dd",
|
|
41
|
+
"td",
|
|
42
|
+
"th",
|
|
43
|
+
...HEADING_TAGS,
|
|
44
|
+
"section",
|
|
45
|
+
"article",
|
|
46
|
+
"header",
|
|
47
|
+
"footer",
|
|
48
|
+
"main",
|
|
49
|
+
"body",
|
|
50
|
+
"blockquote",
|
|
51
|
+
"ul",
|
|
52
|
+
"ol",
|
|
53
|
+
"dl",
|
|
54
|
+
"table",
|
|
55
|
+
"tr",
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const LINE_BOUNDARY = new RegExp(String.raw`<\/?(?:${LINE_TAGS.join("|")})\b[^<>]*>|<br\b[^<>]*>`, "giu");
|
|
59
|
+
|
|
60
|
+
/** Text between the anchor and the block's edge on each side: what shares a line with it. */
|
|
61
|
+
const lineAround = (html: string, range: ElementRange): readonly [string, string] => {
|
|
62
|
+
const before = html.slice(0, range.start);
|
|
63
|
+
const lineStart = [...before.matchAll(LINE_BOUNDARY)].at(-1);
|
|
64
|
+
const after = html.slice(range.end);
|
|
65
|
+
const lineEnd = new RegExp(LINE_BOUNDARY.source, "iu").exec(after)?.index ?? after.length;
|
|
66
|
+
return [lineStart === undefined ? before : before.slice(lineStart.index + lineStart[0].length), after.slice(0, lineEnd)];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** No other text on its line: the anchor is a block of its own, not a word in a sentence. */
|
|
70
|
+
const standsAlone = (html: string, range: ElementRange): boolean => lineAround(html, range).every((beside) => plainText(beside) === "");
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Text the page writes for a screen reader and does not show. A focus target counts only standing alone outside a
|
|
74
|
+
* heading: inside a heading it is the heading's title, inside a sentence a word of it.
|
|
75
|
+
*/
|
|
76
|
+
export const withoutReaderOnlyText = (html: string): string => {
|
|
77
|
+
const shown = withoutElementsOpening(html, CLASS_OPENING, isReaderOnlyClass);
|
|
78
|
+
const headings = headingRanges(shown);
|
|
79
|
+
const isReaderTarget = (anchor: ElementRange): boolean =>
|
|
80
|
+
isFocusTarget(anchor) && standsAlone(shown, anchor) && !headings.some((heading) => isInside(heading, anchor));
|
|
81
|
+
return withoutElementsWhere(shown, "a", isReaderTarget);
|
|
82
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// A section title drawn as a bold first line of its paragraph: <p><strong>Conclusion</strong><br />In closing, …</p>.
|
|
2
|
+
// Read as text the title runs into the paragraph as one line. The bold run becomes a heading one level below the
|
|
3
|
+
// heading before it (h2 when none), and the rest stays the paragraph. Only a bold run that opens the paragraph, holds
|
|
4
|
+
// plain text, is short, does not end as a sentence or a label (".", ":") and has a sentence (or a lead-in ending in a
|
|
5
|
+
// colon) after its line break is taken for a title; a name over its role ("Jane Roe<br>Secretary") is a signature. Pure.
|
|
6
|
+
import { hasSentence, plainText } from "./html-elements.ts";
|
|
7
|
+
|
|
8
|
+
const MAX_TITLE_LENGTH = 100;
|
|
9
|
+
const DEEPEST_LEVEL = 6;
|
|
10
|
+
const TOP_LEVEL = 1;
|
|
11
|
+
|
|
12
|
+
// A paragraph's start, a bold run and a line break: the paragraph's text follows up to its end tag.
|
|
13
|
+
const OPENING = /<p\b([^>]*)>\s*<(strong|b)\b[^>]*>([^<]*)<\/\2\s*>\s*<br\b[^>]*>/giu;
|
|
14
|
+
|
|
15
|
+
/** The paragraph's text after from, up to its end tag; undefined when another paragraph opens first or none closes. */
|
|
16
|
+
const restOfParagraph = (html: string, from: number): string | undefined => {
|
|
17
|
+
const next = /<(\/?)p\b/iu.exec(html.slice(from));
|
|
18
|
+
return next?.[1] === "/" ? html.slice(from, from + next.index) : undefined;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// A sentence's end, a label's colon, or a clause's comma or semicolon: the bold run is part of the text, not a title.
|
|
22
|
+
const ENDS_AS_TEXT = /[.!?:;,。!?:;、]$/u;
|
|
23
|
+
|
|
24
|
+
/** A sentence, or a lead-in to a list ("… with the same:"): what a section holds, unlike a role under a name. */
|
|
25
|
+
const isProse = (html: string): boolean => hasSentence(html) || /[::]$/u.test(plainText(html));
|
|
26
|
+
|
|
27
|
+
const isTitle = (bold: string, rest: string | undefined): boolean => {
|
|
28
|
+
const title = bold.trim();
|
|
29
|
+
return title !== "" && title.length <= MAX_TITLE_LENGTH && !ENDS_AS_TEXT.test(title) && rest !== undefined && isProse(rest);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/** The level of the last heading opening before at; 1 when there is none, as if under the page's title. */
|
|
33
|
+
const levelBefore = (html: string, at: number): number => {
|
|
34
|
+
const headings = [...html.slice(0, at).matchAll(/<h([1-6])\b/giu)];
|
|
35
|
+
return Number(headings.at(-1)?.[1] ?? TOP_LEVEL);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const withRunInHeadingsRead = (html: string): string =>
|
|
39
|
+
html.replace(OPENING, (opening: string, attributes: string, _tag: string, bold: string, at: number) => {
|
|
40
|
+
if (!isTitle(bold, restOfParagraph(html, at + opening.length))) return opening;
|
|
41
|
+
const level = String(Math.min(levelBefore(html, at) + 1, DEEPEST_LEVEL));
|
|
42
|
+
return `<h${level}>${bold.trim()}</h${level}><p${attributes}>`;
|
|
43
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Tables as the HTML converter reads them. A table whose rows are sentences (a glossary of terms and what they mean,
|
|
2
|
+
// a list of routes and how each one works) keeps each cell as a block of its own, so its sentences are read as prose;
|
|
3
|
+
// its header rows go. Any other table (figures, a grid of links) goes whole, as before. Nested tables are read from
|
|
4
|
+
// the inside out. Pure; a regular-expression reading, not a parser.
|
|
5
|
+
import { plainText, untilStable } from "./html-elements.ts";
|
|
6
|
+
|
|
7
|
+
type Cell = { readonly header: boolean; readonly html: string };
|
|
8
|
+
type Row = readonly Cell[];
|
|
9
|
+
|
|
10
|
+
const INNERMOST_TABLE = /<table\b[^>]*>((?:(?!<table\b)[\s\S])*?)<\/table\s*>/giu;
|
|
11
|
+
|
|
12
|
+
// A row and a cell may leave out their closing tags: each ends where the next one opens.
|
|
13
|
+
const ROW_OPENING = /<tr\b[^>]*>/iu;
|
|
14
|
+
const ROW_END = /<\/(?:tr|thead|tbody|tfoot)\s*>[\s\S]*$/iu;
|
|
15
|
+
const CELL_OPENING = /<(t[dh])\b[^>]*>/giu;
|
|
16
|
+
const CELL_END = /<\/t[dh]\s*>[\s\S]*$/iu;
|
|
17
|
+
|
|
18
|
+
const cellsOf = (row: string): Row => {
|
|
19
|
+
const openings = [...row.matchAll(CELL_OPENING)];
|
|
20
|
+
return openings.map((opening, index) => {
|
|
21
|
+
const end = openings[index + 1]?.index ?? row.length;
|
|
22
|
+
const html = row.slice(opening.index + opening[0].length, end).replace(CELL_END, "");
|
|
23
|
+
return { header: opening[1]?.toLowerCase() === "th", html };
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const rowsOf = (table: string): Row[] =>
|
|
28
|
+
table
|
|
29
|
+
.split(ROW_OPENING)
|
|
30
|
+
.slice(1)
|
|
31
|
+
.map((row) => cellsOf(row.replace(ROW_END, "")));
|
|
32
|
+
|
|
33
|
+
const hasText = (cell: Cell): boolean => plainText(cell.html) !== "";
|
|
34
|
+
|
|
35
|
+
// A cell ends a sentence with its last mark. A point inside it ("H.Con.Res. 218") or after a short capitalised word
|
|
36
|
+
// or a letter after a point ("Inc.", "U.S.") is an abbreviation.
|
|
37
|
+
const ENDS_SENTENCE = /(?:[。.!?!?]|(?<!\b[A-Z][A-Za-z]{0,3}|\.[A-Za-z])\.)[)\]"'”’」』)]*$/u;
|
|
38
|
+
|
|
39
|
+
const holdsSentence = (cell: Cell): boolean => ENDS_SENTENCE.test(plainText(cell.html));
|
|
40
|
+
|
|
41
|
+
// A cell that opens with a number and holds no word of the Latin alphabet: a row number ("1", "2."), a figure or a
|
|
42
|
+
// range ("0.3 以上 1.6未満", "1未満"), a section ("302(c)"). "401(k) plan" and "24/7 desk" are names.
|
|
43
|
+
const isNumberLabel = (text: string): boolean => /^\p{Nd}/u.test(text) && !/[A-Za-z]{2,}/u.test(text);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A cell kept as a block: one with a sentence, or a label in words. A number label is read by no prose rule, and alone
|
|
47
|
+
* on a line it would read as a section number.
|
|
48
|
+
*/
|
|
49
|
+
const isKept = (cell: Cell): boolean => holdsSentence(cell) || (hasText(cell) && !isNumberLabel(plainText(cell.html)));
|
|
50
|
+
|
|
51
|
+
/** A row of nothing but header cells labels the columns. */
|
|
52
|
+
const isHeaderRow = (row: Row): boolean => row.length > 0 && row.every((cell) => cell.header);
|
|
53
|
+
|
|
54
|
+
/** At least half of the rows with text in them, header rows aside, hold a sentence. */
|
|
55
|
+
const isProse = (rows: readonly Row[]): boolean => {
|
|
56
|
+
const written = rows.filter((row) => !isHeaderRow(row) && row.some(hasText));
|
|
57
|
+
const sentences = written.filter((row) => row.some(holdsSentence)).length;
|
|
58
|
+
return sentences > 0 && sentences * 2 >= written.length;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const CAPTION = /<caption\b[^>]*>([\s\S]*?)<\/caption\s*>/iu;
|
|
62
|
+
|
|
63
|
+
/** Each cell with text as a block, the caption first. */
|
|
64
|
+
const asBlocks = (table: string, rows: readonly Row[]): string => {
|
|
65
|
+
const caption = CAPTION.exec(table)?.[1];
|
|
66
|
+
const cells = rows.filter((row) => !isHeaderRow(row)).flatMap((row) => row.filter(isKept).map((cell) => cell.html));
|
|
67
|
+
return ["<div>", ...[caption ?? "", ...cells].filter((html) => html !== "").map((html) => `<div>${html}</div>`), "</div>"].join("");
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const readTable = (_whole: string, inside: string): string => {
|
|
71
|
+
const rows = rowsOf(inside);
|
|
72
|
+
return isProse(rows) ? asBlocks(inside, rows) : " ";
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Every table read from the inside out: a table of sentences as blocks, any other table replaced by a space. */
|
|
76
|
+
export const withTablesRead = (html: string): string => untilStable(html, (text) => text.replace(INNERMOST_TABLE, readTable));
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Parts of a page that are controls rather than the document: a tooltip, a media player with its buttons, a block a
|
|
2
|
+
// script runs when clicked, a bar of previous and next links between arrows, and text marked never to be spoken.
|
|
3
|
+
// Each is told by its structure (a role, an <audio> or <video>, an event handler, the arrows), never by a site's class
|
|
4
|
+
// names. Pure; a regular-expression reading.
|
|
5
|
+
import {
|
|
6
|
+
ANY_LINK,
|
|
7
|
+
ATTRIBUTES,
|
|
8
|
+
elementRanges,
|
|
9
|
+
fileExtension,
|
|
10
|
+
hasNoWords,
|
|
11
|
+
hasSentence,
|
|
12
|
+
isFileLink,
|
|
13
|
+
plainText,
|
|
14
|
+
withoutElementsOpening,
|
|
15
|
+
withoutRanges,
|
|
16
|
+
type ElementRange,
|
|
17
|
+
} from "./html-elements.ts";
|
|
18
|
+
|
|
19
|
+
/** Every element whose opening tag carries attribute (name and value as a pattern), matched to its own closing tag. */
|
|
20
|
+
const withoutElementsWithAttribute = (html: string, attribute: string): string => {
|
|
21
|
+
const opening = new RegExp(String.raw`<([a-z][a-z0-9-]*)${ATTRIBUTES}\s+${attribute}`, "giu");
|
|
22
|
+
const marked = new RegExp(String.raw`^<[a-z][a-z0-9-]*${ATTRIBUTES}\s+${attribute}`, "iu");
|
|
23
|
+
return withoutElementsOpening(html, opening, (range) => marked.test(range.openTag));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// A role is a list of tokens and the first one counts, as for role="main".
|
|
27
|
+
const TOOLTIP_ROLE = String.raw`role\s*=\s*(?:"\s*tooltip(?:\s[^"]*)?"|'\s*tooltip(?:\s[^']*)?'|tooltip(?=[\s/>]))`;
|
|
28
|
+
|
|
29
|
+
// speak: none in a style says the text is not to be read out: data for scripts, such as an id beside a title.
|
|
30
|
+
const UNSPOKEN_STYLE = String.raw`style\s*=\s*(?:"[^"]*\bspeak\s*:\s*none\b[^"]*"|'[^']*\bspeak\s*:\s*none\b[^']*')`;
|
|
31
|
+
|
|
32
|
+
/** A tooltip ("The code has been copied to your clipboard.") shows beside a control, and unspoken text is not read. */
|
|
33
|
+
const withoutTooltipsAndUnspoken = (html: string): string => withoutElementsWithAttribute(withoutElementsWithAttribute(html, TOOLTIP_ROLE), UNSPOKEN_STYLE);
|
|
34
|
+
|
|
35
|
+
const MEDIA_ELEMENT = /<(audio|video)\b[^>]*>[\s\S]*?<\/\1\s*>/giu;
|
|
36
|
+
|
|
37
|
+
const PLAYER_BLOCKS = ["div", "section", "figure"];
|
|
38
|
+
|
|
39
|
+
// A caption is the document's even when it is not a sentence ("Interview with the mayor"), so its block is no player.
|
|
40
|
+
const holdsMedia = (range: ElementRange): boolean => /<(?:audio|video)\b/iu.test(range.inner) && !/<figcaption\b/iu.test(range.inner);
|
|
41
|
+
|
|
42
|
+
/** The text around the media, without the words a browser shows only when it cannot play it. */
|
|
43
|
+
const hasSentenceBesideMedia = (range: ElementRange): boolean => hasSentence(range.inner.replace(MEDIA_ELEMENT, " "));
|
|
44
|
+
|
|
45
|
+
const MEDIA_EXTENSION = /^(?:mp3|m4a|aac|wav|ogg|oga|opus|mp4|m4v|webm|mov)$/iu;
|
|
46
|
+
|
|
47
|
+
/** A link to a file other than the media itself (a transcript in PDF, an address) is the document's. */
|
|
48
|
+
const isDocumentFile = (link: string): boolean => isFileLink(link) && !MEDIA_EXTENSION.test(fileExtension(link) ?? "");
|
|
49
|
+
|
|
50
|
+
const isPlayer = (range: ElementRange): boolean =>
|
|
51
|
+
holdsMedia(range) && !hasSentenceBesideMedia(range) && ![...range.inner.matchAll(ANY_LINK)].some((link) => isDocumentFile(link[0]));
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A block holding an <audio> or <video> and not a sentence is its player: the controls, the timer, "Embed", "share",
|
|
55
|
+
* "Direct link" to the media's own file. The outermost such block goes; a block with a sentence, a caption or a link
|
|
56
|
+
* to another file stays.
|
|
57
|
+
*/
|
|
58
|
+
const withoutMediaPlayers = (html: string): string => {
|
|
59
|
+
const players = PLAYER_BLOCKS.flatMap((tag) => elementRanges(html, tag)).filter(isPlayer);
|
|
60
|
+
return withoutRanges(
|
|
61
|
+
html,
|
|
62
|
+
players.toSorted((left, right) => left.start - right.start || right.end - left.end),
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const EVENT_HANDLER = String.raw`on[a-z]+\s*=`;
|
|
67
|
+
|
|
68
|
+
const CONTROL_OPENING = new RegExp(String.raw`<(div|p|span|li)${ATTRIBUTES}\s+${EVENT_HANDLER}`, "giu");
|
|
69
|
+
|
|
70
|
+
/** Links and nothing else, but no link that wraps blocks. */
|
|
71
|
+
const isOnlyPlainLinks = (inner: string): boolean => {
|
|
72
|
+
const links = [...inner.matchAll(ANY_LINK)].map((link) => link[0]);
|
|
73
|
+
return links.length > 0 && !links.some((link) => /<(?:div|p|h[1-6]|ul|ol)\b/iu.test(link)) && hasNoWords(plainText(inner.replace(ANY_LINK, " ")));
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A block that runs a script when clicked (onclick) and holds only a link ("Start Quiz") is a button drawn as a link.
|
|
78
|
+
* A link with a handler of its own, inside a sentence, stays: it is only counted when followed.
|
|
79
|
+
*/
|
|
80
|
+
const isScriptedControl = (range: ElementRange): boolean =>
|
|
81
|
+
new RegExp(String.raw`^<[a-z]+${ATTRIBUTES}\s+${EVENT_HANDLER}`, "iu").test(range.openTag) && isOnlyPlainLinks(range.inner);
|
|
82
|
+
|
|
83
|
+
const withoutScriptedControls = (html: string): string => withoutElementsOpening(html, CONTROL_OPENING, isScriptedControl);
|
|
84
|
+
|
|
85
|
+
const BACK_ARROW = "[←‹«◀◁]";
|
|
86
|
+
const FORWARD_ARROW = "[→›»▶▷]";
|
|
87
|
+
const PAGING_TEXT = new RegExp(`^${BACK_ARROW}.*${FORWARD_ARROW}$`, "u");
|
|
88
|
+
const MIN_PAGING_LINKS = 2;
|
|
89
|
+
|
|
90
|
+
const PAGING_BLOCKS = ["div", "section", "p", "td"];
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Opens with a back arrow and closes with a forward one around two or more links to pages (never a file), with no sentence beside them: "←
|
|
94
|
+
* Previous | Title | Next →". Link text is not looked at, since a name's initial ("John P.") is not a sentence.
|
|
95
|
+
*/
|
|
96
|
+
const isPagingBar = (range: ElementRange): boolean => {
|
|
97
|
+
const links = [...range.inner.matchAll(ANY_LINK)].map((link) => link[0]);
|
|
98
|
+
return (
|
|
99
|
+
PAGING_TEXT.test(plainText(range.inner)) && links.length >= MIN_PAGING_LINKS && !links.some(isFileLink) && !hasSentence(range.inner.replace(ANY_LINK, " "))
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/** The innermost blocks that are a bar of previous and next links, as a work's header draws them over each chapter. */
|
|
104
|
+
const withoutPagingBars = (html: string): string => {
|
|
105
|
+
const bars = PAGING_BLOCKS.flatMap((tag) => elementRanges(html, tag)).filter(isPagingBar);
|
|
106
|
+
const innermost = bars.filter((outer) => !bars.some((inner) => inner !== outer && outer.start <= inner.start && inner.end <= outer.end));
|
|
107
|
+
return withoutRanges(
|
|
108
|
+
html,
|
|
109
|
+
innermost.toSorted((left, right) => left.start - right.start),
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/** Controls and their text: tooltips, unspoken data, media players, scripted link buttons and paging bars. */
|
|
114
|
+
export const withoutWidgets = (html: string): string => withoutPagingBars(withoutScriptedControls(withoutMediaPlayers(withoutTooltipsAndUnspoken(html))));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// What the wikitext and HTML converters share: character references turned back into characters, and the blank
|
|
2
|
+
// lines and trailing spaces a converter leaves behind tidied away. Pure.
|
|
3
|
+
import { characterEntities } from "character-entities";
|
|
4
|
+
|
|
5
|
+
// A named space ( ,  ) is read as a plain space, like the spacing between the page's other words.
|
|
6
|
+
const isSpace = (value: string): boolean => /^\p{Zs}+$/u.test(value);
|
|
7
|
+
|
|
8
|
+
/** A name of the HTML standard, matched as written: "Ø" is Ø and "ø" is ø. */
|
|
9
|
+
const decodeName = (name: string, whole: string): string => {
|
|
10
|
+
const value = Object.hasOwn(characterEntities, name) ? characterEntities[name] : undefined;
|
|
11
|
+
if (value === undefined) return whole;
|
|
12
|
+
return isSpace(value) ? " " : value;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const fromCodePoint = (code: number, whole: string): string => (Number.isInteger(code) && code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : whole);
|
|
16
|
+
|
|
17
|
+
const decodeOne = (whole: string, name: string): string => {
|
|
18
|
+
if (name.startsWith("#x") || name.startsWith("#X")) return fromCodePoint(Number.parseInt(name.slice(2), 16), whole);
|
|
19
|
+
if (name.startsWith("#")) return fromCodePoint(Number.parseInt(name.slice(1), 10), whole);
|
|
20
|
+
return decodeName(name, whole);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** In one pass, so "&lt;" is "<" and not "<". An unknown name is left as written. */
|
|
24
|
+
export const decodeEntities = (text: string): string =>
|
|
25
|
+
text.replace(/&(#x[0-9a-f]+|#\d+|[a-z][a-z0-9]*);/giu, (whole: string, name: string) => decodeOne(whole, name));
|
|
26
|
+
|
|
27
|
+
/** Trailing spaces removed, runs of blank lines made one, and a single newline at the end. */
|
|
28
|
+
export const tidyLines = (lines: readonly string[]): string => {
|
|
29
|
+
const text = lines
|
|
30
|
+
.map((line) => line.trimEnd())
|
|
31
|
+
.join("\n")
|
|
32
|
+
.replace(/\n{3,}/gu, "\n\n")
|
|
33
|
+
.trim();
|
|
34
|
+
return text === "" ? "" : `${text}\n`;
|
|
35
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// A fetched page as a document chaff reads: HTML turned into Markdown (headings become addresses), Markdown and plain
|
|
2
|
+
// text as they are. Anything else (a PDF, JSON, an image) is not text a quotation can be found in. Pure.
|
|
3
|
+
import { htmlToMarkdown } from "./html-markdown.ts";
|
|
4
|
+
|
|
5
|
+
/** The document a page reads as: the name that says how to read it (.md or .txt), and its text. */
|
|
6
|
+
export type PageDocument = { readonly path: string; readonly text: string } | { readonly unsupported: string };
|
|
7
|
+
|
|
8
|
+
const mediaTypeOf = (contentType: string | null): string => (contentType ?? "").split(";")[0]?.trim().toLowerCase() ?? "";
|
|
9
|
+
|
|
10
|
+
/** A body sent with no Content-Type is HTML when it opens like markup. */
|
|
11
|
+
const LOOKS_LIKE_HTML = /^\s*(?:<!doctype html|<html[\s>]|<head[\s>]|<body[\s>])/iu;
|
|
12
|
+
|
|
13
|
+
const HTML_TYPES: ReadonlySet<string> = new Set(["text/html", "application/xhtml+xml"]);
|
|
14
|
+
const MARKDOWN_TYPES: ReadonlySet<string> = new Set(["text/markdown", "text/x-markdown"]);
|
|
15
|
+
|
|
16
|
+
export const pageDocument = (contentType: string | null, body: string): PageDocument => {
|
|
17
|
+
const type = mediaTypeOf(contentType);
|
|
18
|
+
if (HTML_TYPES.has(type) || (type === "" && LOOKS_LIKE_HTML.test(body))) return { path: "page.md", text: htmlToMarkdown(body) };
|
|
19
|
+
if (MARKDOWN_TYPES.has(type)) return { path: "page.md", text: body };
|
|
20
|
+
if (type === "" || type.startsWith("text/")) return { path: "page.txt", text: body };
|
|
21
|
+
return { unsupported: type };
|
|
22
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { escapeRegExp } from "./orthography.ts";
|
|
2
|
+
import { alternation, valueOf, type CountMismatch, type CountWords } from "./announced-count.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 一行に並べた名前の予告(出席者(6名):田中、鈴木、佐藤 / Attendees (6): Tanaka, Suzuki)。ラベルの後ろの括弧の数と、
|
|
6
|
+
* コロンの後ろに区切って並べた名前の数を比べる。区切りが決まらない並び(名前をつなぐ語がある、括弧が閉じていない、文が続く)と、
|
|
7
|
+
* 閉じていない並び(ほか、etc.)は数えない。言語の知識(区切り、つなぐ語、閉じていないことを言う語)は語彙表から受け取る。
|
|
8
|
+
*/
|
|
9
|
+
export type MemberWords = {
|
|
10
|
+
/** 名前の区切り。、 , */
|
|
11
|
+
readonly separators: readonly string[];
|
|
12
|
+
/** 名前をつなぐ語。と、and。 */
|
|
13
|
+
readonly joiners: readonly string[];
|
|
14
|
+
/** 並びが閉じていないことを言う語。ほか、etc。 */
|
|
15
|
+
readonly open: readonly string[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const MAX_LABEL_CHARS = 30;
|
|
19
|
+
const MAX_MEMBER_CHARS = 40;
|
|
20
|
+
const MIN_MEMBERS = 2;
|
|
21
|
+
/** 一行に並べる名前の数として読む上限。括弧の年(Holland (1993): ...)を数に読まない。 */
|
|
22
|
+
const MAX_ANNOUNCED = 99;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 行頭(箇条書きの印の後ろでもよい)のラベル、括弧の中の数(数える語は付いても付かなくてもよい)、コロン。
|
|
26
|
+
* 括弧の中に数以外の語があるもの(約6名、6名以上、5名ほか)は形が合わず、ここで外れる。
|
|
27
|
+
*/
|
|
28
|
+
const headPattern = (words: CountWords): RegExp => {
|
|
29
|
+
const numbers = words.numbers.length === 0 ? "\\p{Nd}+" : `\\p{Nd}+|${alternation(words.numbers)}`;
|
|
30
|
+
const counter = words.counters.length === 0 ? "" : `(?:[ \\t]?(?<counter>${alternation(words.counters)})(?![A-Za-z]))?`;
|
|
31
|
+
const label = `(?<label>[^\\s\\p{Nd}((::|>#*+-][^((::\\n]{0,${MAX_LABEL_CHARS}})`;
|
|
32
|
+
const listMark = String.raw`(?:(?:[-*+]|\d{1,9}[.)])[ \t]+)?`;
|
|
33
|
+
return new RegExp(`^[ \\t]*${listMark}${label}[((][ \\t]*(?<phrase>(?<number>${numbers})${counter})[ \\t]*[))][ \\t]*[::][ \\t]*`, "diu");
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const LATIN_LETTER = /[A-Za-z]/u;
|
|
37
|
+
|
|
38
|
+
/** 英語の語は語の切れ目で照らす(and が Anderson に当たらない)。日本語の語は字面どおり。atEnd なら末尾の語だけ。 */
|
|
39
|
+
const wordPattern = (word: string, atEnd = false): RegExp => {
|
|
40
|
+
const before = LATIN_LETTER.test(word[0] ?? "") ? "(?<![A-Za-z])" : "";
|
|
41
|
+
const after = LATIN_LETTER.test(word.at(-1) ?? "") ? "(?![A-Za-z])" : "";
|
|
42
|
+
return new RegExp(`${before}${escapeRegExp(word)}${after}${atEnd ? "\\s*$" : ""}`, "iu");
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const BRACKETED = /\([^()()]*\)|([^()()]*)|「[^「」]*」|\[[^[\]]*\]/gu;
|
|
46
|
+
const BRACKET = /[()()「」[\]]/u;
|
|
47
|
+
/** 並びの途中で文が切れる、別のラベルが始まる。名前の並びでなく文なので数えない。 */
|
|
48
|
+
const NOT_A_NAME_LIST = /[。..::;;]/u;
|
|
49
|
+
const TRAILING_END = /[。..]\s*$/u;
|
|
50
|
+
|
|
51
|
+
/** 括弧の中の注記(議長)を除いた並び。括弧が閉じていなければ undefined。 */
|
|
52
|
+
const withoutNotes = (members: string): string | undefined => {
|
|
53
|
+
const stripped = members.replace(BRACKETED, "");
|
|
54
|
+
return BRACKET.test(stripped) ? undefined : stripped;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const hasAny = (text: string, words: readonly string[]): boolean => words.some((word) => wordPattern(word).test(text));
|
|
58
|
+
|
|
59
|
+
/** 閉じていないことを言う語は名前の後ろに付く(田中ほか、etc)。名前の中の字(等々力)は数える。 */
|
|
60
|
+
const endsOpen = (member: string, open: readonly string[]): boolean => open.some((word) => wordPattern(word, true).test(member));
|
|
61
|
+
|
|
62
|
+
/** 最後の名前の前のつなぐ語(, and Ito)は並びの終わりの印で、名前の一部ではない。 */
|
|
63
|
+
const withoutLeadingJoiner = (member: string, joiners: readonly string[]): string => {
|
|
64
|
+
const leading = joiners.find((joiner) => new RegExp(`^${escapeRegExp(joiner)}\\s+`, "iu").test(member));
|
|
65
|
+
return leading === undefined ? member : member.slice(leading.length).trimStart();
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const splitMembers = (text: string, separators: readonly string[]): string[] =>
|
|
69
|
+
text.split(new RegExp(separators.map(escapeRegExp).join("|"), "u")).map((part) => part.trim());
|
|
70
|
+
|
|
71
|
+
const withLastJoinerOff = (parts: readonly string[], joiners: readonly string[]): string[] => {
|
|
72
|
+
const last = parts.at(-1);
|
|
73
|
+
return last === undefined ? [...parts] : [...parts.slice(0, -1), withoutLeadingJoiner(last, joiners)];
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const isNameLike = (member: string, words: MemberWords): boolean => member !== "" && member.length <= MAX_MEMBER_CHARS && !hasAny(member, words.joiners);
|
|
77
|
+
|
|
78
|
+
/** 区切って並べた名前の数。並びとして読めないときは undefined。 */
|
|
79
|
+
export const memberCount = (members: string, words: MemberWords): number | undefined => {
|
|
80
|
+
if (words.separators.length === 0) return undefined;
|
|
81
|
+
const notes = withoutNotes(members.trim().replace(TRAILING_END, ""));
|
|
82
|
+
if (notes === undefined || NOT_A_NAME_LIST.test(notes)) return undefined;
|
|
83
|
+
const parts = splitMembers(notes, words.separators);
|
|
84
|
+
if (parts.some((part) => endsOpen(part, words.open))) return undefined;
|
|
85
|
+
const names = withLastJoinerOff(parts, words.joiners);
|
|
86
|
+
return names.length >= MIN_MEMBERS && names.every((name) => isNameLike(name, words)) ? names.length : undefined;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** 次の行に並びが続いてよい行。空行、箇条書き、見出し、引用、表の行は別のもの。 */
|
|
90
|
+
const CONTINUATION = /^[ \t]*[^\s\-*+#>|]/u;
|
|
91
|
+
|
|
92
|
+
const endsWithSeparator = (text: string, words: MemberWords): boolean => words.separators.some((separator) => text.trimEnd().endsWith(separator));
|
|
93
|
+
|
|
94
|
+
/** 区切りで終わる行は、次の行に並びが続く。 */
|
|
95
|
+
const membersFrom = (lines: readonly string[], next: number, soFar: string, words: MemberWords): string => {
|
|
96
|
+
const line = lines[next] ?? "";
|
|
97
|
+
return endsWithSeparator(soFar, words) && CONTINUATION.test(line) ? membersFrom(lines, next + 1, soFar + line, words) : soFar;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* ラベルは短い名前(出席者、Attendees)。区切りを含むもの(Dunn, G.E. (1960):)は文献の著者で、番号で終わるもの(Step 2 (3):)は
|
|
102
|
+
* 番号の付いた項目。どちらも括弧の数は並べた名前の数ではない。
|
|
103
|
+
*/
|
|
104
|
+
const isLabel = (label: string, members: MemberWords): boolean =>
|
|
105
|
+
!/\p{Nd}\s*$/u.test(label) && !members.separators.some((separator) => label.includes(separator));
|
|
106
|
+
|
|
107
|
+
/** 数える語の無い数(Attendees (6))は、ラベル自身が数えるもの(attendees、items)を言うときだけ数。Appendix (3) は番号。 */
|
|
108
|
+
const labelCounts = (label: string, counters: readonly string[]): boolean => counters.some((counter) => wordPattern(counter, true).test(label));
|
|
109
|
+
|
|
110
|
+
type Line = { readonly text: string; readonly start: number };
|
|
111
|
+
|
|
112
|
+
const linesOf = (text: string): Line[] => {
|
|
113
|
+
const starts = [0, ...[...text.matchAll(/\n/gu)].map((match) => match.index + 1)];
|
|
114
|
+
return text.split("\n").map((line, index) => ({ text: line, start: starts[index] ?? 0 }));
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** ラベルと括弧の数。phraseAt は行の中の数の位置、rest はコロンの後ろ。 */
|
|
118
|
+
type Head = { readonly phrase: string; readonly phraseAt: number; readonly announced: number; readonly rest: string };
|
|
119
|
+
|
|
120
|
+
/** 数える語が数に付いているか、ラベルが数えるものを言っている(Attendees (6))ときだけ、括弧の数を名前の数に読む。 */
|
|
121
|
+
const isCount = (announced: number, counter: string | undefined, label: string, words: CountWords): boolean =>
|
|
122
|
+
(counter !== undefined || labelCounts(label, words.counters)) && announced >= 1 && announced <= MAX_ANNOUNCED;
|
|
123
|
+
|
|
124
|
+
const headOf = (text: string, head: RegExp, words: CountWords, members: MemberWords): Head | undefined => {
|
|
125
|
+
const match = head.exec(text);
|
|
126
|
+
const groups = match?.groups;
|
|
127
|
+
const phraseAt = match?.indices?.groups?.["phrase"]?.[0];
|
|
128
|
+
const label = groups?.["label"] ?? "";
|
|
129
|
+
if (match === null || groups === undefined || phraseAt === undefined || !isLabel(label, members)) return undefined;
|
|
130
|
+
const announced = valueOf(groups["number"] ?? "", words.numbers);
|
|
131
|
+
if (!isCount(announced, groups["counter"], label, words)) return undefined;
|
|
132
|
+
return { phrase: (groups["phrase"] ?? "").trim(), phraseAt, announced, rest: text.slice(match[0].length) };
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** 本文(コードや強調の印を空白で覆ったもの)の、一行に並べた名前の予告で、数が合わないもの。 */
|
|
136
|
+
export const inlineCountMismatches = (text: string, words: CountWords, members: MemberWords): CountMismatch[] => {
|
|
137
|
+
const head = headPattern(words);
|
|
138
|
+
const lines = linesOf(text);
|
|
139
|
+
const texts = lines.map((line) => line.text);
|
|
140
|
+
return lines.flatMap((line, index) => {
|
|
141
|
+
const found = headOf(line.text, head, words, members);
|
|
142
|
+
const listed = found === undefined ? undefined : memberCount(membersFrom(texts, index + 1, found.rest, members), members);
|
|
143
|
+
if (found === undefined || listed === undefined || listed === found.announced) return [];
|
|
144
|
+
return [{ offset: line.start + found.phraseAt, phrase: found.phrase, announced: found.announced, listed }];
|
|
145
|
+
});
|
|
146
|
+
};
|
package/src/kana-spelling.ts
CHANGED
|
@@ -15,6 +15,13 @@ export const isKanaOnly = (text: string): boolean => KANA_ONLY.test(text);
|
|
|
15
15
|
/** The kanji of a spelling, in order: 引越 for both 引っ越し and 引越し, nothing for できる. */
|
|
16
16
|
export const kanjiSkeleton = (text: string): string => [...text.matchAll(KANJI)].map((match) => match[0]).join("");
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Whether a spelling is the kanji alone of a word the others spell with okurigana: 取扱 beside 取扱い, 締切 beside 締切り. Official
|
|
20
|
+
* Japanese drops okurigana at the head of a compound (取扱事業者) and keeps it on the word alone, so the two are one convention.
|
|
21
|
+
*/
|
|
22
|
+
export const dropsOkurigana = (spelling: string, spellings: readonly string[]): boolean =>
|
|
23
|
+
spelling !== "" && kanjiSkeleton(spelling) === spelling && spellings.some((other) => other !== spelling && kanjiSkeleton(other) === spelling);
|
|
24
|
+
|
|
18
25
|
/** The length, in UTF-16 units, of the start both strings share, compared character by character (𠮟 is one character, two units). */
|
|
19
26
|
const sharedPrefixLength = (left: string, right: string): number => {
|
|
20
27
|
const [leftChars, rightChars] = [[...left], [...right]];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Span, Token } from "./plugin.ts";
|
|
2
|
+
|
|
3
|
+
/** 空白の前の、建物や場所の名前になる語の品詞。助詞の後ろ(「会場は 5階」)は名前の区切りではない。 */
|
|
4
|
+
const NAME_POS = new Set(["NOUN", "PROPN"]);
|
|
5
|
+
|
|
6
|
+
/** 階・部屋の番号の後ろに続けば、番号が語の一部(5階建て、5階です)で、所在の組を閉じていない字。 */
|
|
7
|
+
const WORD_CHAR = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u;
|
|
8
|
+
|
|
9
|
+
const SPACES = new Set([" ", " "]);
|
|
10
|
+
|
|
11
|
+
/** units は階・部屋の番号の単位(語彙表 floor-unit)、levels は番号の前に書いて階の名前の一部になる語(語彙表 floor-level)。 */
|
|
12
|
+
export type FloorWords = { readonly units: ReadonlySet<string>; readonly levels: ReadonlySet<string> };
|
|
13
|
+
|
|
14
|
+
/** run のすぐ後ろに書いた、units のうち最も長い語。無ければ undefined。 */
|
|
15
|
+
const unitAfter = (text: string, run: Span, units: ReadonlySet<string>): string | undefined =>
|
|
16
|
+
[...units].filter((unit) => text.startsWith(unit, run.end)).toSorted((left, right) => right.length - left.length)[0];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 「本社 5階 第2会議室」「研究所 3階 セミナー室」のように、名前の語の後ろに空白で区切って書いた階・部屋の番号。
|
|
20
|
+
* その前の空白は所在の組を分ける区切りで、日本語と数字のあいだの空け方の好みではない。「地下 1階」「地上 5階」の空白は階の名前の中の空け方なので、区切りと読まない。
|
|
21
|
+
* 番号は数字だけで、単位の後ろで組が閉じる(空白・読点・文末・英字が続く)ものだけ。tokens は文書全体の座標で、base は text の先頭の位置。
|
|
22
|
+
*/
|
|
23
|
+
export const isSpacedLocationPart = (text: string, run: Span, tokens: readonly Token[] | undefined, base: number, words: FloorWords): boolean => {
|
|
24
|
+
if (tokens === undefined || !SPACES.has(text[run.start - 1] ?? "")) return false;
|
|
25
|
+
if (!/^\d+$/u.test(text.slice(run.start, run.end))) return false;
|
|
26
|
+
const unit = unitAfter(text, run, words.units);
|
|
27
|
+
if (unit === undefined || WORD_CHAR.test(text[run.end + unit.length] ?? "")) return false;
|
|
28
|
+
const named = tokens.find((token) => token.span.end === base + run.start - 1);
|
|
29
|
+
return named !== undefined && NAME_POS.has(named.pos) && !words.levels.has(named.surface);
|
|
30
|
+
};
|