chaffjs 0.35.0 → 0.37.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.ja.md +12 -0
- package/README.md +15 -0
- package/dist/announced-count.d.ts +2 -0
- package/dist/announced-count.d.ts.map +1 -1
- package/dist/announced-count.js +29 -7
- package/dist/announced-count.js.map +1 -1
- package/dist/chronology-rows.d.ts +9 -0
- package/dist/chronology-rows.d.ts.map +1 -0
- package/dist/chronology-rows.js +79 -0
- package/dist/chronology-rows.js.map +1 -0
- package/dist/company-name-run.d.ts +8 -0
- package/dist/company-name-run.d.ts.map +1 -0
- package/dist/company-name-run.js +30 -0
- package/dist/company-name-run.js.map +1 -0
- package/dist/compound-head.d.ts +7 -0
- package/dist/compound-head.d.ts.map +1 -0
- package/dist/compound-head.js +19 -0
- package/dist/compound-head.js.map +1 -0
- package/dist/date-format.d.ts +8 -3
- package/dist/date-format.d.ts.map +1 -1
- package/dist/date-format.js +36 -3
- package/dist/date-format.js.map +1 -1
- package/dist/derived/count-per-period.d.ts +23 -0
- package/dist/derived/count-per-period.d.ts.map +1 -0
- package/dist/derived/count-per-period.js +14 -0
- package/dist/derived/count-per-period.js.map +1 -0
- package/dist/detectors/acronym-context.d.ts +4 -0
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +29 -1
- package/dist/detectors/acronym-context.js.map +1 -1
- package/dist/detectors/acronym-expansion.d.ts +5 -1
- package/dist/detectors/acronym-expansion.d.ts.map +1 -1
- package/dist/detectors/acronym-expansion.js +42 -3
- package/dist/detectors/acronym-expansion.js.map +1 -1
- package/dist/detectors/acronym-known.d.ts +19 -0
- package/dist/detectors/acronym-known.d.ts.map +1 -0
- package/dist/detectors/acronym-known.js +32 -0
- package/dist/detectors/acronym-known.js.map +1 -0
- package/dist/detectors/acronym-link.d.ts +19 -0
- package/dist/detectors/acronym-link.d.ts.map +1 -0
- package/dist/detectors/acronym-link.js +65 -0
- package/dist/detectors/acronym-link.js.map +1 -0
- package/dist/detectors/acronym-mention.d.ts +5 -0
- package/dist/detectors/acronym-mention.d.ts.map +1 -0
- package/dist/detectors/acronym-mention.js +34 -0
- package/dist/detectors/acronym-mention.js.map +1 -0
- package/dist/detectors/acronym-name.d.ts +8 -1
- package/dist/detectors/acronym-name.d.ts.map +1 -1
- package/dist/detectors/acronym-name.js +25 -6
- package/dist/detectors/acronym-name.js.map +1 -1
- package/dist/detectors/addressee-edge.d.ts +13 -0
- package/dist/detectors/addressee-edge.d.ts.map +1 -0
- package/dist/detectors/addressee-edge.js +13 -0
- package/dist/detectors/addressee-edge.js.map +1 -0
- package/dist/detectors/addressee-title-edge.d.ts +21 -0
- package/dist/detectors/addressee-title-edge.d.ts.map +1 -0
- package/dist/detectors/addressee-title-edge.js +22 -0
- package/dist/detectors/addressee-title-edge.js.map +1 -0
- package/dist/detectors/announced-count.d.ts.map +1 -1
- package/dist/detectors/announced-count.js +1 -0
- package/dist/detectors/announced-count.js.map +1 -1
- package/dist/detectors/bare-comparative.d.ts +4 -0
- package/dist/detectors/bare-comparative.d.ts.map +1 -1
- package/dist/detectors/bare-comparative.js +28 -3
- package/dist/detectors/bare-comparative.js.map +1 -1
- package/dist/detectors/blank-structure.d.ts +7 -1
- package/dist/detectors/blank-structure.d.ts.map +1 -1
- package/dist/detectors/blank-structure.js +13 -8
- package/dist/detectors/blank-structure.js.map +1 -1
- package/dist/detectors/bracket-specified.d.ts +6 -0
- package/dist/detectors/bracket-specified.d.ts.map +1 -0
- package/dist/detectors/bracket-specified.js +23 -0
- package/dist/detectors/bracket-specified.js.map +1 -0
- package/dist/detectors/broken-link.d.ts +6 -0
- package/dist/detectors/broken-link.d.ts.map +1 -1
- package/dist/detectors/broken-link.js +23 -2
- package/dist/detectors/broken-link.js.map +1 -1
- package/dist/detectors/capitalised-term.d.ts +4 -0
- package/dist/detectors/capitalised-term.d.ts.map +1 -1
- package/dist/detectors/capitalised-term.js +18 -1
- package/dist/detectors/capitalised-term.js.map +1 -1
- package/dist/detectors/caps-caption.d.ts +17 -6
- package/dist/detectors/caps-caption.d.ts.map +1 -1
- package/dist/detectors/caps-caption.js +65 -0
- package/dist/detectors/caps-caption.js.map +1 -1
- package/dist/detectors/caps-phrase.d.ts +6 -0
- package/dist/detectors/caps-phrase.d.ts.map +1 -0
- package/dist/detectors/caps-phrase.js +16 -0
- package/dist/detectors/caps-phrase.js.map +1 -0
- package/dist/detectors/char-shape.d.ts +1 -0
- package/dist/detectors/char-shape.d.ts.map +1 -1
- package/dist/detectors/char-shape.js +56 -20
- package/dist/detectors/char-shape.js.map +1 -1
- package/dist/detectors/citation-sentence.d.ts +8 -0
- package/dist/detectors/citation-sentence.d.ts.map +1 -0
- package/dist/detectors/citation-sentence.js +40 -0
- package/dist/detectors/citation-sentence.js.map +1 -0
- package/dist/detectors/cited-title.d.ts +3 -2
- package/dist/detectors/cited-title.d.ts.map +1 -1
- package/dist/detectors/cited-title.js +14 -3
- package/dist/detectors/cited-title.js.map +1 -1
- package/dist/detectors/contraction-mention.d.ts +3 -0
- package/dist/detectors/contraction-mention.d.ts.map +1 -0
- package/dist/detectors/contraction-mention.js +22 -0
- package/dist/detectors/contraction-mention.js.map +1 -0
- package/dist/detectors/counter-edge.d.ts +2 -1
- package/dist/detectors/counter-edge.d.ts.map +1 -1
- package/dist/detectors/counter-edge.js +17 -2
- package/dist/detectors/counter-edge.js.map +1 -1
- package/dist/detectors/dash-break.d.ts +7 -0
- package/dist/detectors/dash-break.d.ts.map +1 -0
- package/dist/detectors/dash-break.js +30 -0
- package/dist/detectors/dash-break.js.map +1 -0
- package/dist/detectors/date-any-year.d.ts +7 -3
- package/dist/detectors/date-any-year.d.ts.map +1 -1
- package/dist/detectors/date-any-year.js +30 -8
- package/dist/detectors/date-any-year.js.map +1 -1
- package/dist/detectors/date-format.d.ts.map +1 -1
- package/dist/detectors/date-format.js +2 -1
- package/dist/detectors/date-format.js.map +1 -1
- package/dist/detectors/date-year.d.ts +9 -3
- package/dist/detectors/date-year.d.ts.map +1 -1
- package/dist/detectors/date-year.js +45 -9
- package/dist/detectors/date-year.js.map +1 -1
- package/dist/detectors/deadline-unit.d.ts +20 -0
- package/dist/detectors/deadline-unit.d.ts.map +1 -0
- package/dist/detectors/deadline-unit.js +19 -0
- package/dist/detectors/deadline-unit.js.map +1 -0
- package/dist/detectors/defined-term-form.d.ts.map +1 -1
- package/dist/detectors/defined-term-form.js +33 -7
- 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 +14 -6
- package/dist/detectors/definition-use.js.map +1 -1
- package/dist/detectors/derived-numbers.d.ts.map +1 -1
- package/dist/detectors/derived-numbers.js +17 -4
- package/dist/detectors/derived-numbers.js.map +1 -1
- package/dist/detectors/document-shape.d.ts +5 -0
- package/dist/detectors/document-shape.d.ts.map +1 -1
- package/dist/detectors/document-shape.js +15 -1
- package/dist/detectors/document-shape.js.map +1 -1
- package/dist/detectors/doubled-across-aside.d.ts +9 -0
- package/dist/detectors/doubled-across-aside.d.ts.map +1 -0
- package/dist/detectors/doubled-across-aside.js +27 -0
- package/dist/detectors/doubled-across-aside.js.map +1 -0
- package/dist/detectors/doubled-punctuation.d.ts +3 -3
- package/dist/detectors/doubled-punctuation.d.ts.map +1 -1
- package/dist/detectors/doubled-punctuation.js +23 -4
- package/dist/detectors/doubled-punctuation.js.map +1 -1
- package/dist/detectors/doubled-word.d.ts.map +1 -1
- package/dist/detectors/doubled-word.js +2 -1
- package/dist/detectors/doubled-word.js.map +1 -1
- package/dist/detectors/duplicate-heading.d.ts +1 -0
- package/dist/detectors/duplicate-heading.d.ts.map +1 -1
- package/dist/detectors/duplicate-heading.js +25 -3
- package/dist/detectors/duplicate-heading.js.map +1 -1
- package/dist/detectors/ellipsis.d.ts.map +1 -1
- package/dist/detectors/ellipsis.js +13 -1
- package/dist/detectors/ellipsis.js.map +1 -1
- package/dist/detectors/email-letter.d.ts +40 -3
- package/dist/detectors/email-letter.d.ts.map +1 -1
- package/dist/detectors/email-letter.js +110 -17
- package/dist/detectors/email-letter.js.map +1 -1
- package/dist/detectors/field-label.d.ts +7 -0
- package/dist/detectors/field-label.d.ts.map +1 -0
- package/dist/detectors/field-label.js +23 -0
- package/dist/detectors/field-label.js.map +1 -0
- package/dist/detectors/footnote-mismatch.d.ts +6 -1
- package/dist/detectors/footnote-mismatch.d.ts.map +1 -1
- package/dist/detectors/footnote-mismatch.js +28 -7
- package/dist/detectors/footnote-mismatch.js.map +1 -1
- package/dist/detectors/fullwidth-alnum.d.ts.map +1 -1
- package/dist/detectors/fullwidth-alnum.js +7 -1
- package/dist/detectors/fullwidth-alnum.js.map +1 -1
- package/dist/detectors/graded-step.d.ts +20 -0
- package/dist/detectors/graded-step.d.ts.map +1 -0
- package/dist/detectors/graded-step.js +33 -0
- package/dist/detectors/graded-step.js.map +1 -0
- package/dist/detectors/gram-openers.d.ts +9 -0
- package/dist/detectors/gram-openers.d.ts.map +1 -0
- package/dist/detectors/gram-openers.js +40 -0
- package/dist/detectors/gram-openers.js.map +1 -0
- package/dist/detectors/gram-place.d.ts +3 -1
- package/dist/detectors/gram-place.d.ts.map +1 -1
- package/dist/detectors/gram-place.js +8 -0
- package/dist/detectors/gram-place.js.map +1 -1
- package/dist/detectors/gram-predicate.d.ts.map +1 -1
- package/dist/detectors/gram-predicate.js +37 -3
- package/dist/detectors/gram-predicate.js.map +1 -1
- package/dist/detectors/heading-echo.d.ts.map +1 -1
- package/dist/detectors/heading-echo.js +28 -2
- package/dist/detectors/heading-echo.js.map +1 -1
- package/dist/detectors/heading-record-rhythm.d.ts +9 -0
- package/dist/detectors/heading-record-rhythm.d.ts.map +1 -0
- package/dist/detectors/heading-record-rhythm.js +57 -0
- package/dist/detectors/heading-record-rhythm.js.map +1 -0
- package/dist/detectors/ime-residue.d.ts +1 -1
- package/dist/detectors/ime-residue.d.ts.map +1 -1
- package/dist/detectors/ime-residue.js +4 -3
- package/dist/detectors/ime-residue.js.map +1 -1
- package/dist/detectors/kanji-compound-slip.d.ts +3 -0
- package/dist/detectors/kanji-compound-slip.d.ts.map +1 -0
- package/dist/detectors/kanji-compound-slip.js +50 -0
- package/dist/detectors/kanji-compound-slip.js.map +1 -0
- package/dist/detectors/kutoten-consistency.d.ts +10 -2
- package/dist/detectors/kutoten-consistency.d.ts.map +1 -1
- package/dist/detectors/kutoten-consistency.js +83 -12
- package/dist/detectors/kutoten-consistency.js.map +1 -1
- package/dist/detectors/lexicon.d.ts.map +1 -1
- package/dist/detectors/lexicon.js +13 -4
- package/dist/detectors/lexicon.js.map +1 -1
- package/dist/detectors/link-shape.d.ts.map +1 -1
- package/dist/detectors/link-shape.js +9 -3
- package/dist/detectors/link-shape.js.map +1 -1
- package/dist/detectors/list-item-ending.d.ts +18 -0
- package/dist/detectors/list-item-ending.d.ts.map +1 -0
- package/dist/detectors/list-item-ending.js +35 -0
- package/dist/detectors/list-item-ending.js.map +1 -0
- package/dist/detectors/list-parallel.d.ts +18 -5
- package/dist/detectors/list-parallel.d.ts.map +1 -1
- package/dist/detectors/list-parallel.js +116 -36
- package/dist/detectors/list-parallel.js.map +1 -1
- package/dist/detectors/list-sentence.d.ts +4 -0
- package/dist/detectors/list-sentence.d.ts.map +1 -1
- package/dist/detectors/list-sentence.js +1 -1
- package/dist/detectors/list-sentence.js.map +1 -1
- package/dist/detectors/mark-shape.d.ts +13 -4
- package/dist/detectors/mark-shape.d.ts.map +1 -1
- package/dist/detectors/mark-shape.js +73 -10
- package/dist/detectors/mark-shape.js.map +1 -1
- package/dist/detectors/mentioned-phrase.d.ts +9 -0
- package/dist/detectors/mentioned-phrase.d.ts.map +1 -0
- package/dist/detectors/mentioned-phrase.js +25 -0
- package/dist/detectors/mentioned-phrase.js.map +1 -0
- package/dist/detectors/middle-dot.d.ts +2 -2
- package/dist/detectors/middle-dot.d.ts.map +1 -1
- package/dist/detectors/middle-dot.js +4 -2
- package/dist/detectors/middle-dot.js.map +1 -1
- package/dist/detectors/modal-conflict.d.ts.map +1 -1
- package/dist/detectors/modal-conflict.js +5 -2
- package/dist/detectors/modal-conflict.js.map +1 -1
- package/dist/detectors/name-variant.d.ts.map +1 -1
- package/dist/detectors/name-variant.js +6 -0
- package/dist/detectors/name-variant.js.map +1 -1
- package/dist/detectors/notice-paragraph.d.ts +9 -0
- package/dist/detectors/notice-paragraph.d.ts.map +1 -0
- package/dist/detectors/notice-paragraph.js +21 -0
- package/dist/detectors/notice-paragraph.js.map +1 -0
- package/dist/detectors/number-style.d.ts.map +1 -1
- package/dist/detectors/number-style.js +15 -2
- package/dist/detectors/number-style.js.map +1 -1
- package/dist/detectors/number-unit.d.ts.map +1 -1
- package/dist/detectors/number-unit.js +24 -1
- package/dist/detectors/number-unit.js.map +1 -1
- package/dist/detectors/numeral-opener.d.ts +6 -0
- package/dist/detectors/numeral-opener.d.ts.map +1 -1
- package/dist/detectors/numeral-opener.js +24 -1
- package/dist/detectors/numeral-opener.js.map +1 -1
- package/dist/detectors/obligation-without-deadline.d.ts +5 -1
- package/dist/detectors/obligation-without-deadline.d.ts.map +1 -1
- package/dist/detectors/obligation-without-deadline.js +44 -23
- package/dist/detectors/obligation-without-deadline.js.map +1 -1
- package/dist/detectors/open-end-class.d.ts +16 -0
- package/dist/detectors/open-end-class.d.ts.map +1 -0
- package/dist/detectors/open-end-class.js +65 -0
- package/dist/detectors/open-end-class.js.map +1 -0
- package/dist/detectors/open-end-condition.d.ts +7 -0
- package/dist/detectors/open-end-condition.d.ts.map +1 -0
- package/dist/detectors/open-end-condition.js +35 -0
- package/dist/detectors/open-end-condition.js.map +1 -0
- package/dist/detectors/open-end-names.d.ts +9 -3
- package/dist/detectors/open-end-names.d.ts.map +1 -1
- package/dist/detectors/open-end-names.js +5 -2
- package/dist/detectors/open-end-names.js.map +1 -1
- package/dist/detectors/open-end-question.d.ts +15 -0
- package/dist/detectors/open-end-question.d.ts.map +1 -0
- package/dist/detectors/open-end-question.js +37 -0
- package/dist/detectors/open-end-question.js.map +1 -0
- package/dist/detectors/open-end-scope.d.ts +16 -0
- package/dist/detectors/open-end-scope.d.ts.map +1 -0
- package/dist/detectors/open-end-scope.js +47 -0
- package/dist/detectors/open-end-scope.js.map +1 -0
- package/dist/detectors/opening-date.d.ts +10 -0
- package/dist/detectors/opening-date.d.ts.map +1 -0
- package/dist/detectors/opening-date.js +33 -0
- package/dist/detectors/opening-date.js.map +1 -0
- package/dist/detectors/ordinary-phrase.d.ts +20 -0
- package/dist/detectors/ordinary-phrase.d.ts.map +1 -0
- package/dist/detectors/ordinary-phrase.js +54 -0
- package/dist/detectors/ordinary-phrase.js.map +1 -0
- package/dist/detectors/organisation-run.d.ts +5 -7
- package/dist/detectors/organisation-run.d.ts.map +1 -1
- package/dist/detectors/organisation-run.js +10 -0
- package/dist/detectors/organisation-run.js.map +1 -1
- package/dist/detectors/orthographic-variant.d.ts.map +1 -1
- package/dist/detectors/orthographic-variant.js +85 -20
- package/dist/detectors/orthographic-variant.js.map +1 -1
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +9 -2
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/oxford-comma.d.ts.map +1 -1
- package/dist/detectors/oxford-comma.js +70 -3
- package/dist/detectors/oxford-comma.js.map +1 -1
- package/dist/detectors/person-consistency.d.ts +2 -1
- package/dist/detectors/person-consistency.d.ts.map +1 -1
- package/dist/detectors/person-consistency.js +5 -3
- package/dist/detectors/person-consistency.js.map +1 -1
- package/dist/detectors/phrase-match.d.ts +2 -0
- package/dist/detectors/phrase-match.d.ts.map +1 -1
- package/dist/detectors/phrase-match.js +11 -4
- package/dist/detectors/phrase-match.js.map +1 -1
- package/dist/detectors/placeholder-text.d.ts.map +1 -1
- package/dist/detectors/placeholder-text.js +18 -3
- package/dist/detectors/placeholder-text.js.map +1 -1
- package/dist/detectors/placeholder.d.ts +3 -1
- package/dist/detectors/placeholder.d.ts.map +1 -1
- package/dist/detectors/placeholder.js +8 -3
- package/dist/detectors/placeholder.js.map +1 -1
- package/dist/detectors/postcode-end.d.ts +3 -0
- package/dist/detectors/postcode-end.d.ts.map +1 -0
- package/dist/detectors/postcode-end.js +15 -0
- package/dist/detectors/postcode-end.js.map +1 -0
- package/dist/detectors/prose-total-words.d.ts +5 -0
- package/dist/detectors/prose-total-words.d.ts.map +1 -0
- package/dist/detectors/prose-total-words.js +14 -0
- package/dist/detectors/prose-total-words.js.map +1 -0
- package/dist/detectors/range-notation.d.ts +2 -2
- package/dist/detectors/range-notation.d.ts.map +1 -1
- package/dist/detectors/range-notation.js +18 -7
- package/dist/detectors/range-notation.js.map +1 -1
- package/dist/detectors/registry/kanji-compound-slip.d.ts +3 -0
- package/dist/detectors/registry/kanji-compound-slip.d.ts.map +1 -0
- package/dist/detectors/registry/kanji-compound-slip.js +3 -0
- package/dist/detectors/registry/kanji-compound-slip.js.map +1 -0
- package/dist/detectors/registry/phrase-in-use.d.ts +3 -0
- package/dist/detectors/registry/phrase-in-use.d.ts.map +1 -0
- package/dist/detectors/registry/phrase-in-use.js +3 -0
- package/dist/detectors/registry/phrase-in-use.js.map +1 -0
- package/dist/detectors/requirement-smell.d.ts.map +1 -1
- package/dist/detectors/requirement-smell.js +35 -7
- package/dist/detectors/requirement-smell.js.map +1 -1
- package/dist/detectors/scaled-figure-unit.d.ts +28 -0
- package/dist/detectors/scaled-figure-unit.d.ts.map +1 -0
- package/dist/detectors/scaled-figure-unit.js +78 -0
- package/dist/detectors/scaled-figure-unit.js.map +1 -0
- package/dist/detectors/sentence-counts.d.ts +12 -2
- package/dist/detectors/sentence-counts.d.ts.map +1 -1
- package/dist/detectors/sentence-counts.js +52 -11
- package/dist/detectors/sentence-counts.js.map +1 -1
- package/dist/detectors/sentence-ending.d.ts +2 -0
- package/dist/detectors/sentence-ending.d.ts.map +1 -1
- package/dist/detectors/sentence-ending.js +10 -3
- package/dist/detectors/sentence-ending.js.map +1 -1
- package/dist/detectors/sentence-length.d.ts.map +1 -1
- package/dist/detectors/sentence-length.js +13 -4
- package/dist/detectors/sentence-length.js.map +1 -1
- package/dist/detectors/sentence-load.d.ts +4 -1
- package/dist/detectors/sentence-load.d.ts.map +1 -1
- package/dist/detectors/sentence-load.js +9 -2
- package/dist/detectors/sentence-load.js.map +1 -1
- package/dist/detectors/signals.d.ts.map +1 -1
- package/dist/detectors/signals.js +44 -52
- package/dist/detectors/signals.js.map +1 -1
- package/dist/detectors/structure-tree.d.ts.map +1 -1
- package/dist/detectors/structure-tree.js +14 -13
- package/dist/detectors/structure-tree.js.map +1 -1
- package/dist/detectors/structure.d.ts.map +1 -1
- package/dist/detectors/structure.js +2 -1
- package/dist/detectors/structure.js.map +1 -1
- package/dist/detectors/subject-name-line.d.ts +8 -0
- package/dist/detectors/subject-name-line.d.ts.map +1 -0
- package/dist/detectors/subject-name-line.js +53 -0
- package/dist/detectors/subject-name-line.js.map +1 -0
- package/dist/detectors/superlative-name.d.ts +5 -0
- package/dist/detectors/superlative-name.d.ts.map +1 -1
- package/dist/detectors/superlative-name.js +9 -0
- package/dist/detectors/superlative-name.js.map +1 -1
- package/dist/detectors/table-header.d.ts.map +1 -1
- package/dist/detectors/table-header.js +13 -1
- package/dist/detectors/table-header.js.map +1 -1
- package/dist/detectors/technical-docs.d.ts.map +1 -1
- package/dist/detectors/technical-docs.js +4 -1
- package/dist/detectors/technical-docs.js.map +1 -1
- package/dist/detectors/term-mention-sentence.d.ts +4 -0
- package/dist/detectors/term-mention-sentence.d.ts.map +1 -0
- package/dist/detectors/term-mention-sentence.js +28 -0
- package/dist/detectors/term-mention-sentence.js.map +1 -0
- package/dist/detectors/titled-run.d.ts +2 -1
- package/dist/detectors/titled-run.d.ts.map +1 -1
- package/dist/detectors/titled-run.js +9 -4
- package/dist/detectors/titled-run.js.map +1 -1
- package/dist/detectors/token-shape.d.ts.map +1 -1
- package/dist/detectors/token-shape.js +15 -5
- package/dist/detectors/token-shape.js.map +1 -1
- package/dist/detectors/undefined-term.d.ts.map +1 -1
- package/dist/detectors/undefined-term.js +5 -0
- package/dist/detectors/undefined-term.js.map +1 -1
- package/dist/detectors/unknown-word.d.ts +4 -1
- package/dist/detectors/unknown-word.d.ts.map +1 -1
- package/dist/detectors/unknown-word.js +1 -1
- package/dist/detectors/unknown-word.js.map +1 -1
- package/dist/detectors/vague-density.d.ts +5 -2
- package/dist/detectors/vague-density.d.ts.map +1 -1
- package/dist/detectors/vague-density.js +17 -4
- package/dist/detectors/vague-density.js.map +1 -1
- package/dist/document-paragraphs.d.ts +4 -0
- package/dist/document-paragraphs.d.ts.map +1 -0
- package/dist/document-paragraphs.js +24 -0
- package/dist/document-paragraphs.js.map +1 -0
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +2 -19
- package/dist/document.js.map +1 -1
- package/dist/figure-references.d.ts +3 -0
- package/dist/figure-references.d.ts.map +1 -1
- package/dist/figure-references.js +6 -2
- package/dist/figure-references.js.map +1 -1
- package/dist/format-template.d.ts +3 -0
- package/dist/format-template.d.ts.map +1 -0
- package/dist/format-template.js +13 -0
- package/dist/format-template.js.map +1 -0
- package/dist/formula-brackets.d.ts +7 -0
- package/dist/formula-brackets.d.ts.map +1 -0
- package/dist/formula-brackets.js +29 -0
- package/dist/formula-brackets.js.map +1 -0
- package/dist/html/html-markdown.d.ts.map +1 -1
- package/dist/html/html-markdown.js +2 -1
- package/dist/html/html-markdown.js.map +1 -1
- package/dist/html/html-site-chrome.d.ts +5 -0
- package/dist/html/html-site-chrome.d.ts.map +1 -0
- package/dist/html/html-site-chrome.js +56 -0
- package/dist/html/html-site-chrome.js.map +1 -0
- package/dist/joined-view.d.ts.map +1 -1
- package/dist/joined-view.js +1 -0
- package/dist/joined-view.js.map +1 -1
- package/dist/kanji-compound-slip.d.ts +32 -0
- package/dist/kanji-compound-slip.d.ts.map +1 -0
- package/dist/kanji-compound-slip.js +63 -0
- package/dist/kanji-compound-slip.js.map +1 -0
- package/dist/latin-company-form.d.ts +6 -0
- package/dist/latin-company-form.d.ts.map +1 -0
- package/dist/latin-company-form.js +32 -0
- package/dist/latin-company-form.js.map +1 -0
- package/dist/latin-word-boundary.d.ts +20 -0
- package/dist/latin-word-boundary.d.ts.map +1 -0
- package/dist/latin-word-boundary.js +57 -0
- package/dist/latin-word-boundary.js.map +1 -0
- package/dist/leading-label.d.ts +4 -0
- package/dist/leading-label.d.ts.map +1 -0
- package/dist/leading-label.js +14 -0
- package/dist/leading-label.js.map +1 -0
- package/dist/lexicon-genres.d.ts +2 -0
- package/dist/lexicon-genres.d.ts.map +1 -1
- package/dist/lexicon-genres.js +1 -1
- package/dist/lexicon-genres.js.map +1 -1
- package/dist/link-shape.d.ts +6 -0
- package/dist/link-shape.d.ts.map +1 -1
- package/dist/link-shape.js +27 -0
- package/dist/link-shape.js.map +1 -1
- package/dist/link-title.d.ts +4 -0
- package/dist/link-title.d.ts.map +1 -0
- package/dist/link-title.js +33 -0
- package/dist/link-title.js.map +1 -0
- package/dist/list-item-paragraphs.d.ts +15 -0
- package/dist/list-item-paragraphs.d.ts.map +1 -0
- package/dist/list-item-paragraphs.js +19 -0
- package/dist/list-item-paragraphs.js.map +1 -0
- package/dist/literal-quote.d.ts +12 -0
- package/dist/literal-quote.d.ts.map +1 -0
- package/dist/literal-quote.js +43 -0
- package/dist/literal-quote.js.map +1 -0
- package/dist/nado-closed-list.d.ts.map +1 -1
- package/dist/nado-closed-list.js +39 -5
- package/dist/nado-closed-list.js.map +1 -1
- package/dist/name-misspelt-usual.d.ts +5 -0
- package/dist/name-misspelt-usual.d.ts.map +1 -0
- package/dist/name-misspelt-usual.js +19 -0
- package/dist/name-misspelt-usual.js.map +1 -0
- package/dist/name-separator.d.ts.map +1 -1
- package/dist/name-separator.js +25 -2
- package/dist/name-separator.js.map +1 -1
- package/dist/nominal-stem.d.ts +14 -1
- package/dist/nominal-stem.d.ts.map +1 -1
- package/dist/nominal-stem.js +42 -4
- package/dist/nominal-stem.js.map +1 -1
- package/dist/notice-header.d.ts +19 -0
- package/dist/notice-header.d.ts.map +1 -0
- package/dist/notice-header.js +31 -0
- package/dist/notice-header.js.map +1 -0
- package/dist/person-forms.d.ts +8 -0
- package/dist/person-forms.d.ts.map +1 -1
- package/dist/person-forms.js +12 -0
- package/dist/person-forms.js.map +1 -1
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/preamble-paragraphs.d.ts +3 -2
- package/dist/preamble-paragraphs.d.ts.map +1 -1
- package/dist/preamble-paragraphs.js +8 -2
- package/dist/preamble-paragraphs.js.map +1 -1
- package/dist/sentence-load.d.ts +2 -1
- package/dist/sentence-load.d.ts.map +1 -1
- package/dist/sentence-load.js +11 -3
- package/dist/sentence-load.js.map +1 -1
- package/dist/spacing-code.d.ts +1 -0
- package/dist/spacing-code.d.ts.map +1 -1
- package/dist/spacing-code.js +4 -1
- package/dist/spacing-code.js.map +1 -1
- package/dist/split-noun.d.ts +10 -0
- package/dist/split-noun.d.ts.map +1 -0
- package/dist/split-noun.js +50 -0
- package/dist/split-noun.js.map +1 -0
- package/dist/structure/attached-parts.d.ts +12 -0
- package/dist/structure/attached-parts.d.ts.map +1 -0
- package/dist/structure/attached-parts.js +44 -0
- package/dist/structure/attached-parts.js.map +1 -0
- package/dist/structure/build.d.ts.map +1 -1
- package/dist/structure/build.js +7 -4
- package/dist/structure/build.js.map +1 -1
- package/dist/structure/contents-lines.d.ts +7 -0
- package/dist/structure/contents-lines.d.ts.map +1 -0
- package/dist/structure/contents-lines.js +51 -0
- package/dist/structure/contents-lines.js.map +1 -0
- package/dist/structure/defining-names.d.ts +37 -0
- package/dist/structure/defining-names.d.ts.map +1 -0
- package/dist/structure/defining-names.js +122 -0
- package/dist/structure/defining-names.js.map +1 -0
- package/dist/structure/definition-use.d.ts +8 -4
- package/dist/structure/definition-use.d.ts.map +1 -1
- package/dist/structure/definition-use.js +123 -38
- package/dist/structure/definition-use.js.map +1 -1
- package/dist/structure/gerund-phrase.d.ts +8 -0
- package/dist/structure/gerund-phrase.d.ts.map +1 -0
- package/dist/structure/gerund-phrase.js +30 -0
- package/dist/structure/gerund-phrase.js.map +1 -0
- package/dist/structure/issues.d.ts +4 -1
- package/dist/structure/issues.d.ts.map +1 -1
- package/dist/structure/issues.js +5 -2
- package/dist/structure/issues.js.map +1 -1
- package/dist/structure/list-lead-in.d.ts +19 -0
- package/dist/structure/list-lead-in.d.ts.map +1 -0
- package/dist/structure/list-lead-in.js +85 -0
- package/dist/structure/list-lead-in.js.map +1 -0
- package/dist/structure/modal-conflict.d.ts +7 -2
- package/dist/structure/modal-conflict.d.ts.map +1 -1
- package/dist/structure/modal-conflict.js +36 -7
- package/dist/structure/modal-conflict.js.map +1 -1
- package/dist/structure/negated-act.d.ts +17 -0
- package/dist/structure/negated-act.d.ts.map +1 -0
- package/dist/structure/negated-act.js +32 -0
- package/dist/structure/negated-act.js.map +1 -0
- package/dist/structure/numbering.d.ts +3 -1
- package/dist/structure/numbering.d.ts.map +1 -1
- package/dist/structure/numbering.js +20 -8
- package/dist/structure/numbering.js.map +1 -1
- package/dist/structure/prose-total.d.ts +4 -0
- package/dist/structure/prose-total.d.ts.map +1 -1
- package/dist/structure/prose-total.js +16 -6
- package/dist/structure/prose-total.js.map +1 -1
- package/dist/structure/repeated-number.d.ts +24 -0
- package/dist/structure/repeated-number.d.ts.map +1 -0
- package/dist/structure/repeated-number.js +89 -0
- package/dist/structure/repeated-number.js.map +1 -0
- package/dist/structure/rounded-amount.d.ts +8 -0
- package/dist/structure/rounded-amount.d.ts.map +1 -0
- package/dist/structure/rounded-amount.js +48 -0
- package/dist/structure/rounded-amount.js.map +1 -0
- package/dist/structure/side-step.d.ts +8 -0
- package/dist/structure/side-step.d.ts.map +1 -0
- package/dist/structure/side-step.js +21 -0
- package/dist/structure/side-step.js.map +1 -0
- package/dist/structure/spanned-label-blank.d.ts +8 -0
- package/dist/structure/spanned-label-blank.d.ts.map +1 -0
- package/dist/structure/spanned-label-blank.js +37 -0
- package/dist/structure/spanned-label-blank.js.map +1 -0
- package/dist/structure/universal.d.ts +10 -4
- package/dist/structure/universal.d.ts.map +1 -1
- package/dist/structure/universal.js +26 -7
- package/dist/structure/universal.js.map +1 -1
- package/dist/structure/unspaced-heading.d.ts +10 -0
- package/dist/structure/unspaced-heading.d.ts.map +1 -0
- package/dist/structure/unspaced-heading.js +24 -0
- package/dist/structure/unspaced-heading.js.map +1 -0
- package/dist/structure/written-list-path.d.ts +10 -0
- package/dist/structure/written-list-path.d.ts.map +1 -0
- package/dist/structure/written-list-path.js +37 -0
- package/dist/structure/written-list-path.js.map +1 -0
- package/dist/structure/written-resolve.d.ts +1 -1
- package/dist/structure/written-resolve.d.ts.map +1 -1
- package/dist/structure/written-resolve.js +15 -9
- package/dist/structure/written-resolve.js.map +1 -1
- package/dist/title-line.d.ts +23 -0
- package/dist/title-line.d.ts.map +1 -0
- package/dist/title-line.js +28 -0
- package/dist/title-line.js.map +1 -0
- package/dist/topic-clause.d.ts +7 -0
- package/dist/topic-clause.d.ts.map +1 -0
- package/dist/topic-clause.js +87 -0
- package/dist/topic-clause.js.map +1 -0
- package/dist/uncounted-particles.d.ts +18 -0
- package/dist/uncounted-particles.d.ts.map +1 -0
- package/dist/uncounted-particles.js +47 -0
- package/dist/uncounted-particles.js.map +1 -0
- package/package.json +3 -3
- package/rules/adversative-ga-repeat.yaml +1 -0
- package/rules/all-caps-shouting.yaml +2 -2
- package/rules/announced-count-mismatch.yaml +2 -2
- package/rules/bare-url-mix.yaml +2 -2
- package/rules/bracket-nesting.yaml +2 -2
- package/rules/bracket-width-consistency.yaml +2 -2
- package/rules/broken-link.yaml +2 -2
- package/rules/cliche.yaml +4 -3
- package/rules/code-fence-language-mix.yaml +2 -2
- package/rules/comparative-without-baseline.yaml +2 -2
- package/rules/concrete-evidence-density.yaml +1 -0
- package/rules/contraction-consistency.yaml +2 -2
- package/rules/dangling-figure-reference.yaml +2 -2
- package/rules/date-without-year.yaml +10 -2
- package/rules/defined-term-form.yaml +2 -2
- package/rules/doubled-punctuation.yaml +4 -4
- package/rules/doubled-word.yaml +2 -2
- package/rules/duplicate-definition.yaml +2 -2
- package/rules/duplicate-heading.yaml +2 -2
- package/rules/duration-mismatch.yaml +2 -2
- package/rules/email-greeting-closing.yaml +2 -2
- package/rules/email-subject-length.yaml +2 -2
- package/rules/empty-table-cell.yaml +2 -2
- package/rules/footnote-mismatch.yaml +2 -2
- package/rules/fullwidth-alnum-consistency.yaml +2 -2
- package/rules/heading-echo.yaml +2 -2
- package/rules/ime-residue.yaml +2 -2
- package/rules/kanji-compound-slip.yaml +67 -0
- package/rules/kutoten-consistency.yaml +4 -4
- package/rules/latin-spacing.yaml +2 -2
- package/rules/list-item-form-mix.yaml +2 -2
- package/rules/max-kanji-continuous.yaml +6 -4
- package/rules/max-sentence-length.yaml +2 -2
- package/rules/modal-conflict.yaml +1 -0
- package/rules/nado-closed-list.yaml +2 -2
- package/rules/ngram-repetition.yaml +2 -2
- package/rules/no-doubled-joshi.yaml +2 -2
- package/rules/no-mixed-desumasu.yaml +3 -3
- package/rules/no-nakaguro-parallel.yaml +2 -0
- package/rules/number-without-unit.yaml +9 -4
- package/rules/numbering-gap.yaml +7 -2
- package/rules/numeral-sentence-start.yaml +2 -2
- package/rules/obligation-without-deadline.yaml +2 -2
- package/rules/orthographic-variant.yaml +2 -2
- package/rules/oxford-comma-consistency.yaml +3 -3
- package/rules/preamble-length.yaml +3 -2
- package/rules/range-notation-consistency.yaml +2 -2
- package/rules/requirement-smell.yaml +3 -3
- package/rules/table-header-variant.yaml +2 -2
- package/rules/teki-overuse.yaml +3 -2
- package/rules/title-length.yaml +2 -2
- package/rules/topic-predicate-distance.yaml +2 -2
- package/rules/total-mismatch.yaml +2 -2
- package/rules/translationese-density.yaml +2 -2
- package/rules/undefined-acronym.yaml +5 -2
- package/rules/undefined-term.yaml +2 -2
- package/rules/unfilled-placeholder.yaml +4 -4
- package/rules/unqualified-superlative.yaml +1 -1
- package/rules/unused-definition.yaml +2 -2
- package/rules/use-before-definition.yaml +2 -2
- package/rules/vague-word-density.yaml +2 -2
- package/skills/chaff/SKILL.md +7 -1
- package/src/announced-count.ts +35 -8
- package/src/chronology-rows.ts +86 -0
- package/src/company-name-run.ts +37 -0
- package/src/compound-head.ts +25 -0
- package/src/date-format.ts +43 -4
- package/src/derived/count-per-period.ts +28 -0
- package/src/detectors/acronym-context.ts +30 -1
- package/src/detectors/acronym-expansion.ts +54 -6
- package/src/detectors/acronym-known.ts +40 -0
- package/src/detectors/acronym-link.ts +75 -0
- package/src/detectors/acronym-mention.ts +44 -0
- package/src/detectors/acronym-name.ts +29 -6
- package/src/detectors/addressee-edge.ts +16 -0
- package/src/detectors/addressee-title-edge.ts +39 -0
- package/src/detectors/announced-count.ts +1 -0
- package/src/detectors/bare-comparative.ts +44 -3
- package/src/detectors/blank-structure.ts +21 -10
- package/src/detectors/bracket-specified.ts +25 -0
- package/src/detectors/broken-link.ts +26 -2
- package/src/detectors/capitalised-term.ts +26 -2
- package/src/detectors/caps-caption.ts +76 -0
- package/src/detectors/caps-phrase.ts +17 -0
- package/src/detectors/char-shape.ts +73 -14
- package/src/detectors/citation-sentence.ts +44 -0
- package/src/detectors/cited-title.ts +15 -3
- package/src/detectors/contraction-mention.ts +24 -0
- package/src/detectors/counter-edge.ts +17 -2
- package/src/detectors/dash-break.ts +45 -0
- package/src/detectors/date-any-year.ts +34 -9
- package/src/detectors/date-format.ts +2 -1
- package/src/detectors/date-year.ts +64 -16
- package/src/detectors/deadline-unit.ts +40 -0
- package/src/detectors/defined-term-form.ts +32 -12
- package/src/detectors/definition-use.ts +17 -9
- package/src/detectors/derived-numbers.ts +19 -4
- package/src/detectors/document-shape.ts +20 -1
- package/src/detectors/doubled-across-aside.ts +36 -0
- package/src/detectors/doubled-punctuation.ts +28 -7
- package/src/detectors/doubled-word.ts +2 -1
- package/src/detectors/duplicate-heading.ts +26 -3
- package/src/detectors/ellipsis.ts +16 -1
- package/src/detectors/email-letter.ts +142 -23
- package/src/detectors/field-label.ts +25 -0
- package/src/detectors/footnote-mismatch.ts +39 -7
- package/src/detectors/fullwidth-alnum.ts +9 -1
- package/src/detectors/graded-step.ts +52 -0
- package/src/detectors/gram-openers.ts +50 -0
- package/src/detectors/gram-place.ts +10 -1
- package/src/detectors/gram-predicate.ts +43 -3
- package/src/detectors/heading-echo.ts +31 -3
- package/src/detectors/heading-record-rhythm.ts +57 -0
- package/src/detectors/ime-residue.ts +4 -3
- package/src/detectors/kanji-compound-slip.ts +61 -0
- package/src/detectors/kutoten-consistency.ts +102 -14
- package/src/detectors/lexicon.ts +18 -5
- package/src/detectors/link-shape.ts +10 -3
- package/src/detectors/list-item-ending.ts +51 -0
- package/src/detectors/list-parallel.ts +158 -33
- package/src/detectors/list-sentence.ts +5 -1
- package/src/detectors/mark-shape.ts +89 -10
- package/src/detectors/mentioned-phrase.ts +38 -0
- package/src/detectors/middle-dot.ts +7 -2
- package/src/detectors/modal-conflict.ts +5 -2
- package/src/detectors/name-variant.ts +6 -0
- package/src/detectors/notice-paragraph.ts +33 -0
- package/src/detectors/number-style.ts +14 -2
- package/src/detectors/number-unit.ts +28 -1
- package/src/detectors/numeral-opener.ts +27 -1
- package/src/detectors/obligation-without-deadline.ts +29 -4
- package/src/detectors/open-end-class.ts +78 -0
- package/src/detectors/open-end-condition.ts +40 -0
- package/src/detectors/open-end-names.ts +9 -3
- package/src/detectors/open-end-question.ts +50 -0
- package/src/detectors/open-end-scope.ts +62 -0
- package/src/detectors/opening-date.ts +47 -0
- package/src/detectors/ordinary-phrase.ts +62 -0
- package/src/detectors/organisation-run.ts +18 -2
- package/src/detectors/orthographic-variant.ts +124 -25
- package/src/detectors/orthography.ts +15 -2
- package/src/detectors/oxford-comma.ts +74 -3
- package/src/detectors/person-consistency.ts +5 -3
- package/src/detectors/phrase-match.ts +16 -5
- package/src/detectors/placeholder-text.ts +18 -3
- package/src/detectors/placeholder.ts +10 -3
- package/src/detectors/postcode-end.ts +16 -0
- package/src/detectors/prose-total-words.ts +18 -0
- package/src/detectors/range-notation.ts +26 -6
- package/src/detectors/registry/kanji-compound-slip.ts +4 -0
- package/src/detectors/registry/phrase-in-use.ts +4 -0
- package/src/detectors/requirement-smell.ts +45 -8
- package/src/detectors/scaled-figure-unit.ts +103 -0
- package/src/detectors/sentence-counts.ts +64 -12
- package/src/detectors/sentence-ending.ts +12 -3
- package/src/detectors/sentence-length.ts +17 -4
- package/src/detectors/sentence-load.ts +9 -2
- package/src/detectors/signals.ts +50 -53
- package/src/detectors/structure-tree.ts +14 -14
- package/src/detectors/structure.ts +2 -1
- package/src/detectors/subject-name-line.ts +66 -0
- package/src/detectors/superlative-name.ts +10 -0
- package/src/detectors/table-header.ts +15 -1
- package/src/detectors/technical-docs.ts +5 -1
- package/src/detectors/term-mention-sentence.ts +31 -0
- package/src/detectors/titled-run.ts +9 -4
- package/src/detectors/token-shape.ts +16 -5
- package/src/detectors/undefined-term.ts +8 -0
- package/src/detectors/unknown-word.ts +1 -1
- package/src/detectors/vague-density.ts +20 -4
- package/src/document-paragraphs.ts +27 -0
- package/src/document.ts +3 -23
- package/src/figure-references.ts +7 -2
- package/src/format-template.ts +15 -0
- package/src/formula-brackets.ts +36 -0
- package/src/html/html-markdown.ts +2 -1
- package/src/html/html-site-chrome.ts +104 -0
- package/src/joined-view.ts +1 -0
- package/src/kanji-compound-slip.ts +98 -0
- package/src/latin-company-form.ts +38 -0
- package/src/latin-word-boundary.ts +64 -0
- package/src/leading-label.ts +15 -0
- package/src/lexicon-genres.ts +1 -1
- package/src/link-shape.ts +31 -0
- package/src/link-title.ts +38 -0
- package/src/list-item-paragraphs.ts +22 -0
- package/src/literal-quote.ts +55 -0
- package/src/nado-closed-list.ts +48 -5
- package/src/name-misspelt-usual.ts +25 -0
- package/src/name-separator.ts +27 -2
- package/src/nominal-stem.ts +62 -5
- package/src/notice-header.ts +57 -0
- package/src/person-forms.ts +15 -0
- package/src/plugin.ts +5 -0
- package/src/preamble-paragraphs.ts +13 -3
- package/src/sentence-load.ts +14 -3
- package/src/spacing-code.ts +5 -1
- package/src/split-noun.ts +63 -0
- package/src/structure/attached-parts.ts +47 -0
- package/src/structure/build.ts +7 -4
- package/src/structure/contents-lines.ts +63 -0
- package/src/structure/defining-names.ts +155 -0
- package/src/structure/definition-use.ts +149 -32
- package/src/structure/gerund-phrase.ts +31 -0
- package/src/structure/issues.ts +7 -3
- package/src/structure/list-lead-in.ts +94 -0
- package/src/structure/modal-conflict.ts +42 -7
- package/src/structure/negated-act.ts +49 -0
- package/src/structure/numbering.ts +24 -9
- package/src/structure/prose-total.ts +20 -6
- package/src/structure/repeated-number.ts +110 -0
- package/src/structure/rounded-amount.ts +55 -0
- package/src/structure/side-step.ts +21 -0
- package/src/structure/spanned-label-blank.ts +39 -0
- package/src/structure/universal.ts +33 -9
- package/src/structure/unspaced-heading.ts +27 -0
- package/src/structure/written-list-path.ts +46 -0
- package/src/structure/written-resolve.ts +16 -9
- package/src/title-line.ts +53 -0
- package/src/topic-clause.ts +109 -0
- package/src/uncounted-particles.ts +72 -0
|
@@ -62,12 +62,36 @@ const CITATION_NUMBERS = /^[\d\s,,、–-]+$/u;
|
|
|
62
62
|
/** 画像の参照(`![alt][label]`)の頭の印。指摘の範囲に含める。 */
|
|
63
63
|
const IMAGE_MARK = "!";
|
|
64
64
|
|
|
65
|
+
/** 印の前の逃がし(\)を数えるのに見る字数。 */
|
|
66
|
+
const ESCAPE_REACH = 16;
|
|
67
|
+
const BACKSLASH = "\\";
|
|
68
|
+
|
|
69
|
+
/** 字の並びの終わりに続く \ の数。 */
|
|
70
|
+
const trailingBackslashes = (text: string): number => {
|
|
71
|
+
const reversed = [...text].reverse();
|
|
72
|
+
const other = reversed.findIndex((char) => char !== BACKSLASH);
|
|
73
|
+
return other === -1 ? reversed.length : other;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/** start の括弧の直前に、逃がしていない ! がある(「\![x][]」は画像ではなくリンク)。 */
|
|
77
|
+
const imageAt = (source: string, start: number): boolean => {
|
|
78
|
+
if (source.charAt(start - 1) !== IMAGE_MARK) return false;
|
|
79
|
+
return trailingBackslashes(source.slice(Math.max(0, start - 1 - ESCAPE_REACH), start - 1)) % 2 === 0;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 名前を省いた画像の参照(`![Complete][]`)は、サイトが全ページに定義を足す印や絵(mdBook の前処理、サイト共通の定義)。
|
|
84
|
+
* 画像の行き先をページの中で一度も書かずに名前だけで呼ぶのは、定義がページの外にあるとき。名前を書いた形(`![alt][logo]`)と
|
|
85
|
+
* リンク(`[text][]`)は指摘する。
|
|
86
|
+
*/
|
|
87
|
+
export const siteDefinedImage = (source: string, start: number, label: string): boolean => label === "" && imageAt(source, start);
|
|
88
|
+
|
|
65
89
|
export const unresolvedReferences = (source: string, markup: Markup): Span[] =>
|
|
66
90
|
markup.texts.flatMap((text) =>
|
|
67
91
|
[...source.slice(text.start, text.end).matchAll(REFERENCE_LIKE)]
|
|
68
|
-
.filter((match) => !CITATION_NUMBERS.test(match[1] ?? ""))
|
|
92
|
+
.filter((match) => !CITATION_NUMBERS.test(match[1] ?? "") && !siteDefinedImage(source, text.start + match.index, match[2] ?? ""))
|
|
69
93
|
.map((match) => ({ start: text.start + match.index, end: text.start + match.index + match[0].length }))
|
|
70
|
-
.map((span) => (source
|
|
94
|
+
.map((span) => (imageAt(source, span.start) ? { start: span.start - 1, end: span.end } : span)),
|
|
71
95
|
);
|
|
72
96
|
|
|
73
97
|
const emptyLinks = (doc: ProseDocument, markup: Markup): Finding[] =>
|
|
@@ -28,6 +28,10 @@ export type CapitalisedWords = {
|
|
|
28
28
|
readonly capacityMarkers: readonly string[];
|
|
29
29
|
/** Articles, which may stand between a capacity word and the capacity (as the Borrower). */
|
|
30
30
|
readonly articles: readonly string[];
|
|
31
|
+
/** Words right after a run that say it is attached (Termination Certificate attached hereto). */
|
|
32
|
+
readonly attachedCues: readonly string[];
|
|
33
|
+
/** Last words of a run that name a kind of document (Certificate, Form): with attachedCues after, the run is a title. */
|
|
34
|
+
readonly attachedTitleEnds: readonly string[];
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
/** A term the document defines; bare is a definition with no defining word (("GPC")), which names more than it defines. */
|
|
@@ -216,9 +220,26 @@ const capacityOfAName = (tokens: readonly Token[], start: number, words: Capital
|
|
|
216
220
|
return words.capacityMarkers.includes(marker.surface) && (continues(name) || name.surface === ".");
|
|
217
221
|
};
|
|
218
222
|
|
|
223
|
+
/** Words right after a run that say it is attached (the Certificate attached hereto), ending at a word's edge. */
|
|
224
|
+
const attachedAfterPattern = (cues: readonly string[]): RegExp | undefined => {
|
|
225
|
+
const words = cues.filter((cue) => cue !== "").map(escapeRegExp);
|
|
226
|
+
return words.length === 0 ? undefined : new RegExp(String.raw`^[ \t]+(?:${words.join("|")})(?![\p{L}\p{N}_])`, "u");
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* The run is the title of a document the agreement attaches: its last word names a kind of document (Certificate,
|
|
231
|
+
* Form) and words right after it say it is attached. Confidential Information attached hereto is no title.
|
|
232
|
+
*/
|
|
233
|
+
const titlesAttachment = (words: CapitalisedWords): ((last: Token, after: string) => boolean) => {
|
|
234
|
+
const attached = attachedAfterPattern(words.attachedCues);
|
|
235
|
+
const titleEnds = new Set(words.attachedTitleEnds);
|
|
236
|
+
return (last, after) => attached !== undefined && titleEnds.has(last.surface) && attached.test(after);
|
|
237
|
+
};
|
|
238
|
+
|
|
219
239
|
/**
|
|
220
240
|
* Whether a run is a name by what surrounds it: a number after it, a longer name it starts, brackets after it that
|
|
221
|
-
* define it, initials that spell a term the document defines (“IRS” means the Internal Revenue Service),
|
|
241
|
+
* define it, initials that spell a term the document defines (“IRS” means the Internal Revenue Service), a capacity, or
|
|
242
|
+
* words that make it the title of an attached form.
|
|
222
243
|
*/
|
|
223
244
|
type NameCue = (tokens: readonly Token[], start: number, end: number, term: string) => boolean;
|
|
224
245
|
|
|
@@ -226,14 +247,17 @@ const nameCues = (input: CapitalisedInput, joiners: ReadonlySet<string>): NameCu
|
|
|
226
247
|
const words = input.words;
|
|
227
248
|
const ends = { names: lastWordsOf(words.nameEnds), forms: lastWordsOf(words.formEnds), formEntries: new Set(words.formEnds) };
|
|
228
249
|
const definitionAfter = definitionAfterPattern(words);
|
|
250
|
+
const attachedTitle = titlesAttachment(words);
|
|
229
251
|
const abbreviations = new Set([...input.defined.map((definition) => definition.term), ...input.named].filter((term) => ACRONYM.test(term)));
|
|
230
252
|
return (tokens, start, end, term) => {
|
|
231
253
|
const last = tokens[end - 1];
|
|
232
254
|
if (last === undefined) return false;
|
|
255
|
+
const after = input.source.slice(last.span.end, last.span.end + DEFINITION_AFTER_CHARS);
|
|
233
256
|
return (
|
|
234
257
|
numberedName(last, tokens[end]) ||
|
|
235
258
|
startsLongerName(tokens, end, ends, joiners) ||
|
|
236
|
-
definitionAfter.test(
|
|
259
|
+
definitionAfter.test(after) ||
|
|
260
|
+
attachedTitle(last, after) ||
|
|
237
261
|
initialsOf(term, joiners).some((initials) => abbreviations.has(initials)) ||
|
|
238
262
|
capacityOfAName(tokens, start, words)
|
|
239
263
|
);
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* captions this way by convention, and prose that names one ("the FOR FURTHER INFORMATION CONTACT section") repeats it.
|
|
5
5
|
* A line of a hard-wrapped paragraph in capitals (a disclaimer) has text above it, so it is no caption.
|
|
6
6
|
*/
|
|
7
|
+
import { linesOf, type Line } from "../structure/lines.ts";
|
|
8
|
+
import type { Span } from "../plugin.ts";
|
|
7
9
|
|
|
8
10
|
/** Markdown heading or list marks and spaces that may stand before a caption on its line. */
|
|
9
11
|
const LINE_LEAD = /^[ \t]*(?:#{1,6}[ \t]+|[-*+][ \t]+)?$/u;
|
|
@@ -59,3 +61,77 @@ export const captionsOf = (source: string): ReadonlySet<string> => {
|
|
|
59
61
|
}),
|
|
60
62
|
);
|
|
61
63
|
};
|
|
64
|
+
|
|
65
|
+
/** A line ends a sentence when its last mark, past closing quotes and brackets, is a period, a question or an exclamation mark. */
|
|
66
|
+
const SENTENCE_END = /[.!?]["'”’)\]]*[ \t\r]*$/u;
|
|
67
|
+
const UPPER = /[A-Z]/u;
|
|
68
|
+
const LOWER = /[a-z]/u;
|
|
69
|
+
|
|
70
|
+
const isCapitalLine = (line: Line): boolean => {
|
|
71
|
+
const bare = line.text.replace(LEAD, "");
|
|
72
|
+
return UPPER.test(bare) && !LOWER.test(bare);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** The lines in paragraphs: runs of lines between blank lines. */
|
|
76
|
+
const paragraphsOf = (lines: readonly Line[]): Line[][] =>
|
|
77
|
+
lines.reduce<Line[][]>((paragraphs, line, index) => {
|
|
78
|
+
if (BLANK_LINE.test(line.text)) return paragraphs;
|
|
79
|
+
const above = lines[index - 1];
|
|
80
|
+
if (above !== undefined && !BLANK_LINE.test(above.text)) paragraphs.at(-1)?.push(line);
|
|
81
|
+
else paragraphs.push([line]);
|
|
82
|
+
return paragraphs;
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
const spanOf = (paragraph: readonly Line[]): Span[] => {
|
|
86
|
+
const first = paragraph[0];
|
|
87
|
+
const last = paragraph.at(-1);
|
|
88
|
+
return first === undefined || last === undefined ? [] : [{ start: first.start, end: last.start + last.text.length }];
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The paragraphs whose every line is in capitals and none ends a sentence: a letterhead or an address block at the head
|
|
93
|
+
* (BOARD OF GOVERNORS / WASHINGTON, D.C. 20551), and a heading a transcript sets in capitals on lines of its own
|
|
94
|
+
* (OPENING STATEMENT OF HON. JANE DOE, / U.S. SENATOR FROM OHIO). A warning in capitals is sentences, so it is not one. A
|
|
95
|
+
* document with no sentence has no prose to tell such a paragraph apart from.
|
|
96
|
+
*/
|
|
97
|
+
export const capitalParagraphSpans = (source: string): Span[] => {
|
|
98
|
+
const paragraphs = paragraphsOf(linesOf(source));
|
|
99
|
+
const endsSentence = (paragraph: readonly Line[]): boolean => paragraph.some((line) => SENTENCE_END.test(line.text));
|
|
100
|
+
if (!paragraphs.some(endsSentence)) return [];
|
|
101
|
+
return paragraphs.filter((paragraph) => paragraph.every(isCapitalLine) && !endsSentence(paragraph)).flatMap(spanOf);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/** The capital paragraphs and the roster names of a source, in order of where they start. */
|
|
105
|
+
export const capitalLineSpans = (source: string): Span[] =>
|
|
106
|
+
[...capitalParagraphSpans(source), ...rosterNameSpans(source)].sort((left, right) => left.start - right.start);
|
|
107
|
+
|
|
108
|
+
/** The index of the last span that starts at or before at, by halving: -1 when none does. */
|
|
109
|
+
const lastStartingBy = (spans: readonly Span[], at: number, low = 0, high = spans.length): number => {
|
|
110
|
+
if (low >= high) return low - 1;
|
|
111
|
+
const middle = Math.floor((low + high) / 2);
|
|
112
|
+
return (spans[middle]?.start ?? 0) <= at ? lastStartingBy(spans, at, middle + 1, high) : lastStartingBy(spans, at, low, middle);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/** Whether inner lies wholly in one of the spans, which do not overlap and are sorted by start (capitalLineSpans). */
|
|
116
|
+
export const isWithinSorted = (spans: readonly Span[], inner: Span): boolean => {
|
|
117
|
+
const span = spans[lastStartingBy(spans, inner.start)];
|
|
118
|
+
return span !== undefined && inner.end <= span.end;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/** Columns on a line: two spaces or more, or a tab, stand between them. */
|
|
122
|
+
const COLUMN_CELL = /[^\t ]+(?: [^\t ]+)*/gu;
|
|
123
|
+
/** A name in capitals, a comma, and a place or office in ordinary case: JANE Q. DOE, Ohio / JOHN DOE, JR., New Mexico. */
|
|
124
|
+
const ROSTER_CELL = /^([A-Z][A-Z.'’-]*(?: [A-Z][A-Z.'’-]*)*(?:, [JS]R\.)?), \p{Lu}\p{Ll}+(?: \p{Lu}\p{Ll}+)*$/u;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The names of a roster: a column that holds a name in capitals and the member's place in ordinary case (a committee's
|
|
128
|
+
* members, as a hearing sets them). A run in capitals followed by a comma and prose is no roster.
|
|
129
|
+
*/
|
|
130
|
+
export const rosterNameSpans = (source: string): Span[] =>
|
|
131
|
+
linesOf(source).flatMap((line) =>
|
|
132
|
+
[...line.text.matchAll(COLUMN_CELL)].flatMap((cell) => {
|
|
133
|
+
const name = ROSTER_CELL.exec(cell[0])?.[1];
|
|
134
|
+
const start = line.start + cell.index;
|
|
135
|
+
return name === undefined ? [] : [{ start, end: start + name.length }];
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Phrases set in capitals by convention ("NOW, THEREFORE, BE IT RESOLVED" in a resolution). Pure.
|
|
2
|
+
import { escapeRegExp } from "../orthography.ts";
|
|
3
|
+
|
|
4
|
+
const COMMA_OR_SPACE = /,?\s+/u;
|
|
5
|
+
|
|
6
|
+
const wordsOf = (text: string): string => text.trim().split(COMMA_OR_SPACE).join(" ");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Whether a run of capitals is made only of the listed phrases of several words, one after another ("NOW, THEREFORE" then
|
|
10
|
+
* "BE IT RESOLVED"). A comma after a word, as a run of capitals writes it, is ignored. One-word entries (MUST) match nothing here.
|
|
11
|
+
*/
|
|
12
|
+
export const isConventionalPhrase = (run: string, entries: Iterable<string>): boolean => {
|
|
13
|
+
const phrases = [...entries].map(wordsOf).filter((phrase) => phrase.includes(" "));
|
|
14
|
+
if (phrases.length === 0) return false;
|
|
15
|
+
const one = `(?:${phrases.map(escapeRegExp).join("|")})`;
|
|
16
|
+
return new RegExp(`^${one}(?: ${one})*$`, "u").test(wordsOf(run));
|
|
17
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Detector, DocumentProfile, Finding, ProseDocument, Sentence, Span, Token } from "../plugin.ts";
|
|
2
2
|
import { compacted } from "./gram-place.ts";
|
|
3
3
|
import { leadingCounter, trailingPrefix } from "./counter-edge.ts";
|
|
4
|
+
import { trailingAddressee, type AddresseeSuffix } from "./addressee-edge.ts";
|
|
5
|
+
import { leadingPrefix, trailingTitle, type AddresseeWords } from "./addressee-title-edge.ts";
|
|
4
6
|
import { maskAddresses } from "../address-chain.ts";
|
|
5
7
|
import { isAddressRun } from "./place-run.ts";
|
|
6
8
|
import { isOneName } from "./name-run.ts";
|
|
@@ -21,8 +23,15 @@ const KANJI_RUN = /[一-鿿]+/gu;
|
|
|
21
23
|
/**
|
|
22
24
|
* 漢字の連なりと、その文書全体の座標での範囲。quoted は括弧の中身がまるごとこの連なりであること。
|
|
23
25
|
* placed は、題の名前の置き方(括弧を閉じる、補いの括弧が続く、文がこれだけ)をしていること。
|
|
26
|
+
* after は、連なりが文の頭にあるときの、その後ろの文字(宛名の行の、空白と「殿」)。頭になければ undefined。
|
|
24
27
|
*/
|
|
25
|
-
type KanjiRun = {
|
|
28
|
+
type KanjiRun = {
|
|
29
|
+
readonly text: string;
|
|
30
|
+
readonly span: Span | undefined;
|
|
31
|
+
readonly quoted: boolean;
|
|
32
|
+
readonly placed: boolean;
|
|
33
|
+
readonly after: string | undefined;
|
|
34
|
+
};
|
|
26
35
|
|
|
27
36
|
const SPACE = /\s/gu;
|
|
28
37
|
|
|
@@ -47,14 +56,27 @@ const runsOf = (sentence: Sentence, profile: DocumentProfile | undefined, names:
|
|
|
47
56
|
return [...maskedProse(prose, profile, names).matchAll(KANJI_RUN)].map((match) => {
|
|
48
57
|
const before = prose.slice(0, match.index).replace(SPACE, "").length;
|
|
49
58
|
const [start, last] = [printed[before], printed[before + match[0].length - 1]];
|
|
50
|
-
if (start === undefined || last === undefined) return { text: match[0], span: undefined, quoted: false, placed: false };
|
|
59
|
+
if (start === undefined || last === undefined) return { text: match[0], span: undefined, quoted: false, placed: false, after: undefined };
|
|
51
60
|
const span = { start: sentence.span.start + start, end: sentence.span.start + last + 1 };
|
|
52
|
-
|
|
61
|
+
const after = sentence.text.slice(0, start).trim() === "" ? sentence.text.slice(last + 1) : undefined;
|
|
62
|
+
return { text: match[0], span, quoted: fillsQuote(sentence, start, last + 1), placed: isTitlePosition(sentence.text, start, last + 1), after };
|
|
53
63
|
});
|
|
54
64
|
};
|
|
55
65
|
|
|
56
66
|
/** 連なりを数えないと決める語彙: 住所の先頭にしか来ない単位(都道府県)と、組織の名前の形と単位と、題の名前を閉じる語。 */
|
|
57
|
-
type NameWords = {
|
|
67
|
+
type NameWords = {
|
|
68
|
+
readonly topUnits: ReadonlySet<string>;
|
|
69
|
+
readonly organisation: OrganisationWords;
|
|
70
|
+
readonly title: TitleWords;
|
|
71
|
+
/** 数の後ろで日付・時刻の位置を言う単位(月)。連なりの頭にあれば、数に付いた助数詞。 */
|
|
72
|
+
readonly positional: readonly string[];
|
|
73
|
+
/** 宛先の名前に付く語(宛、御中)。連なりの尻にあれば、名前の後ろに付いた語。 */
|
|
74
|
+
readonly addressee: readonly string[];
|
|
75
|
+
/** 宛名の並びの、組織の名前の前の「各」と後ろの役職(各…学校長、…協会会長)。 */
|
|
76
|
+
readonly addressees: AddresseeWords;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
type Tail = AddresseeSuffix;
|
|
58
80
|
|
|
59
81
|
/** 1 つの文書で連なりを読むのに要るもの。titled は、文書の中で題として置かれた名前(titledNames)。 */
|
|
60
82
|
type RunContext = {
|
|
@@ -84,18 +106,44 @@ const isTitle = (tokens: readonly Token[], span: Span, text: string, placed: boo
|
|
|
84
106
|
) &&
|
|
85
107
|
(placed || isTitledName(text, context.titled));
|
|
86
108
|
|
|
109
|
+
/** 宛名の行(各国公私立高等専門学校長、…協会会長 殿): 連なりが行の頭にあり、後ろは空白と宛先に付く語だけ。 */
|
|
110
|
+
const isAddresseeLine = (run: KanjiRun, words: NameWords): boolean => {
|
|
111
|
+
const after = run.after?.trim();
|
|
112
|
+
return after !== undefined && (after === "" || words.addressee.includes(after));
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/** 尻の外す語: 数に付く接頭の語か宛先に付く語と、宛名の行ならその前の役職(日本博物館協会会長殿の「会長殿」)。 */
|
|
116
|
+
const tailOf = (tokens: readonly Token[], run: KanjiRun, span: Span, words: NameWords): Tail | undefined => {
|
|
117
|
+
const prefix = trailingPrefix(tokens, span.end, run.text);
|
|
118
|
+
const suffix = prefix === undefined ? trailingAddressee(tokens, span.end, run.text, words.addressee) : { surface: prefix.surface, start: prefix.span.start };
|
|
119
|
+
const title = isAddresseeLine(run, words) ? trailingTitle(run.text.slice(0, run.text.length - (suffix?.surface.length ?? 0)), words.addressees) : undefined;
|
|
120
|
+
if (title === undefined) return suffix;
|
|
121
|
+
return { surface: title + (suffix?.surface ?? ""), start: (suffix?.start ?? span.end) - title.length };
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/** 外す語を外した残り。頭の「各」は、宛名の行でなければ、残りが名前と決まったときだけ外す(呼び出し側が戻す)。 */
|
|
125
|
+
type Measured = { readonly rest: Span; readonly text: string; readonly keptHead: string };
|
|
126
|
+
|
|
127
|
+
const measuredOf = (tokens: readonly Token[], run: KanjiRun, span: Span, words: NameWords): Measured => {
|
|
128
|
+
const tail = tailOf(tokens, run, span, words);
|
|
129
|
+
const name = run.text.slice(0, run.text.length - (tail?.surface.length ?? 0));
|
|
130
|
+
const counter = leadingCounter(tokens, span.start, run.text, words.positional);
|
|
131
|
+
const prefix = counter === undefined ? leadingPrefix(tokens, span.start, name, words.addressees) : undefined;
|
|
132
|
+
const head = counter ?? prefix;
|
|
133
|
+
const keptHead = prefix !== undefined && !isAddresseeLine(run, words) ? prefix.surface : "";
|
|
134
|
+
return { rest: { start: head?.span.end ?? span.start, end: tail?.start ?? span.end }, text: name.slice(head?.surface.length ?? 0), keptHead };
|
|
135
|
+
};
|
|
136
|
+
|
|
87
137
|
/**
|
|
88
|
-
* 数えない連なりは空。頭の、数に付いた助数詞(2日日本弁護士連合会の「日」)と、尻の、数に付く接頭の語(施行令第172
|
|
138
|
+
* 数えない連なりは空。頭の、数に付いた助数詞(2日日本弁護士連合会の「日」)と、尻の、数に付く接頭の語(施行令第172条の「第」)と
|
|
139
|
+
* 宛先に付く語(市政情報課宛ての「宛」)は数えない。宛名の「各」と、宛名の行の役職(各国公私立高等専門学校長の「各」と「長」)も数えない。
|
|
89
140
|
* 住所か名前かは、それを外した残りで決める(1日日本銀行の「日本銀行」)。品詞が無ければ判定しない。
|
|
90
141
|
*/
|
|
91
142
|
const measuredRun = (tokens: readonly Token[] | undefined, run: KanjiRun, context: RunContext): string => {
|
|
92
143
|
if (run.quoted) return "";
|
|
93
144
|
if (tokens === undefined || run.span === undefined) return run.text;
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const rest = { start: counter?.span.end ?? run.span.start, end: prefix?.span.start ?? run.span.end };
|
|
97
|
-
const text = run.text.slice(counter?.surface.length ?? 0, run.text.length - (prefix?.surface.length ?? 0));
|
|
98
|
-
return isPlaceName(tokens, rest, context.words) || isTitle(tokens, rest, text, run.placed, context) ? "" : text;
|
|
145
|
+
const { rest, text, keptHead } = measuredOf(tokens, run, run.span, context.words);
|
|
146
|
+
return isPlaceName(tokens, rest, context.words) || isTitle(tokens, rest, text, run.placed, context) ? "" : keptHead + text;
|
|
99
147
|
};
|
|
100
148
|
|
|
101
149
|
const longestKanji = (sentence: Sentence, context: RunContext): string =>
|
|
@@ -118,10 +166,18 @@ const titledNames = (doc: ProseDocument, profile: DocumentProfile | undefined, n
|
|
|
118
166
|
*/
|
|
119
167
|
export const kanjiRun: Detector = (doc, options): Finding[] => {
|
|
120
168
|
const patterns = (id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
|
|
169
|
+
const organisation: OrganisationWords = {
|
|
170
|
+
forms: patterns("organisation-form"),
|
|
171
|
+
closingForms: (doc.lexicons["organisation-form"] ?? []).filter((entry) => entry.position !== "before").map((entry) => entry.pattern),
|
|
172
|
+
units: patterns("organisation-unit"),
|
|
173
|
+
};
|
|
121
174
|
const words: NameWords = {
|
|
122
175
|
topUnits: new Set(patterns("prefecture-unit")),
|
|
123
|
-
organisation
|
|
176
|
+
organisation,
|
|
124
177
|
title: { endings: patterns("title-ending") },
|
|
178
|
+
positional: patterns("calendar-unit"),
|
|
179
|
+
addressee: patterns("addressee-suffix"),
|
|
180
|
+
addressees: { prefixes: patterns("addressee-prefix"), titles: patterns("addressee-title"), endings: organisation.units, forms: organisation.closingForms },
|
|
125
181
|
};
|
|
126
182
|
const names = doc.names ?? [];
|
|
127
183
|
const context: RunContext = { profile: doc.profile, names, words, titled: titledNames(doc, doc.profile, names) };
|
|
@@ -141,10 +197,12 @@ export const kanjiRun: Detector = (doc, options): Finding[] => {
|
|
|
141
197
|
/**
|
|
142
198
|
* 中黒で並べると、どこまでが 1 つの項目か分からなくなる。
|
|
143
199
|
* 「企画・開発・運用・保守体制」は、保守体制が 1 つなのか保守と体制なのか読めない。
|
|
200
|
+
* 語彙表(nakaguro-word)の、中黒を含めて 1 語の語(キャッシュ・フロー)の中黒は並べていないので数えない。
|
|
144
201
|
*/
|
|
145
|
-
export const middleDot: Detector = (doc, options): Finding[] =>
|
|
146
|
-
|
|
147
|
-
|
|
202
|
+
export const middleDot: Detector = (doc, options): Finding[] => {
|
|
203
|
+
const words = (options.lexicon ?? []).map((entry) => entry.pattern).toSorted((left, right) => right.length - left.length);
|
|
204
|
+
return doc.sentences
|
|
205
|
+
.map((sentence) => ({ sentence, count: parallelDotCount(sentence.text, words) }))
|
|
148
206
|
.filter(({ count }) => count > options.limit)
|
|
149
207
|
.map(({ sentence, count }) => ({
|
|
150
208
|
rule: "no-nakaguro-parallel",
|
|
@@ -154,3 +212,4 @@ export const middleDot: Detector = (doc, options): Finding[] =>
|
|
|
154
212
|
quote: sentence.text.trim(),
|
|
155
213
|
values: { count, limit: options.limit, offset: sentence.span.start },
|
|
156
214
|
}));
|
|
215
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// A bibliographic citation written out as a sentence, as in a footnote: authors and the year in parentheses, then a title
|
|
2
|
+
// or a publisher. Its length is the length of the reference, not of the writer's prose. Pure.
|
|
3
|
+
import { escapeRegExp } from "../orthography.ts";
|
|
4
|
+
|
|
5
|
+
/** "Keys and Reina (2025)," or "Federal Housing Finance Agency (n.d.),": the year in parentheses, a comma after it. */
|
|
6
|
+
const AUTHOR_YEAR = /\((?:\d{4}[a-z]?|n\.d\.)\),/gu;
|
|
7
|
+
|
|
8
|
+
/** What only a reference carries: a quoted title right after the year, a place and its publisher, or a page range. */
|
|
9
|
+
const PUBLICATION_MARKS: readonly RegExp[] = [
|
|
10
|
+
/\((?:\d{4}[a-z]?|n\.d\.)\),\s*["“]/u,
|
|
11
|
+
/\(\p{Lu}[\p{L}.'’-]*(?:,?\s\p{Lu}[\p{L}.'’-]*)*:\s\p{Lu}[^()]*\)/u,
|
|
12
|
+
/\bpp?\.\s*\d+\s*[-–−]\s*\d+/u,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
/** Where the citation's year stands: the last year before the first mark of a publication, or the first year when none is before it. */
|
|
16
|
+
const citationYearAt = (text: string): number | undefined => {
|
|
17
|
+
const years = [...text.matchAll(AUTHOR_YEAR)].map((match) => match.index);
|
|
18
|
+
const marks = PUBLICATION_MARKS.flatMap((mark) => {
|
|
19
|
+
const found = mark.exec(text);
|
|
20
|
+
return found === null ? [] : [found.index + found[0].length];
|
|
21
|
+
});
|
|
22
|
+
if (years.length === 0 || marks.length === 0) return undefined;
|
|
23
|
+
const firstMark = Math.min(...marks);
|
|
24
|
+
return years.filter((at) => at < firstMark).at(-1) ?? years[0];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const isCitationSentence = (text: string): boolean => citationYearAt(text) !== undefined;
|
|
28
|
+
|
|
29
|
+
const signalPattern = (signals: readonly string[]): RegExp | undefined =>
|
|
30
|
+
signals.length === 0 ? undefined : new RegExp(String.raw`(?<![\p{L}\p{N}])(?:${signals.map(escapeRegExp).join("|")})(?![\p{L}\p{N}])`, "giu");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The writer's own words in a citation sentence: what comes before the last citation signal ("see", from the language's
|
|
34
|
+
* word list) ahead of the citation's year, or everything before the year when no signal stands there (the authors' names
|
|
35
|
+
* are short). "For example, see Lisa Cook (2024), …" leads with "For example,". Undefined when the sentence is not a citation.
|
|
36
|
+
*/
|
|
37
|
+
export const citationLead = (text: string, signals: readonly string[]): string | undefined => {
|
|
38
|
+
const yearAt = citationYearAt(text);
|
|
39
|
+
if (yearAt === undefined) return undefined;
|
|
40
|
+
const beforeYear = text.slice(0, yearAt);
|
|
41
|
+
const pattern = signalPattern(signals);
|
|
42
|
+
const lastSignal = pattern === undefined ? undefined : [...beforeYear.matchAll(pattern)].at(-1);
|
|
43
|
+
return (lastSignal === undefined ? beforeYear : beforeYear.slice(0, lastSignal.index)).trim();
|
|
44
|
+
};
|
|
@@ -71,13 +71,24 @@ const VENUE_END = /^\s*(?:[,;.]|$)/u;
|
|
|
71
71
|
*/
|
|
72
72
|
const holdsPhrase = (runs: Runs, start: number, end: number): boolean => firstIn(runs.phrasePair, { start: start + 1, end: end + 1 }) !== -1;
|
|
73
73
|
|
|
74
|
+
const LETTER = /\p{L}/u;
|
|
75
|
+
|
|
76
|
+
/** 語の続きのすぐ前が、題名を導く語(whose full title is、entitled)で終わるか。語の途中(retitled)からは読まない。 */
|
|
77
|
+
const afterTitleCue = (source: string, first: Token, titleCues: readonly string[]): boolean => {
|
|
78
|
+
const before = source.slice(source.lastIndexOf("\n", first.span.start - 1) + 1, first.span.start);
|
|
79
|
+
if (before === before.trimEnd()) return false;
|
|
80
|
+
const lead = before.trimEnd().toLowerCase();
|
|
81
|
+
return titleCues.some((cue) => cue !== "" && lead.endsWith(cue.toLowerCase()) && !LETTER.test(lead.charAt(lead.length - cue.length - 1)));
|
|
82
|
+
};
|
|
83
|
+
|
|
74
84
|
/**
|
|
75
85
|
* 文の and / or が、引用した題名の中にあるか。and / or の両隣が Title Case の語の続きで、2 語以上の句を含み、その続きが
|
|
76
|
-
*
|
|
86
|
+
* 引用符か強調の印で囲まれているか、引用符で閉じた論文名のすぐ後ろにあって読点か文の終わりが続く(誌名)か、題名を導く語
|
|
87
|
+
* (titleCues: whose full title is、entitled)のすぐ後ろにあるとき。
|
|
77
88
|
* 本文の固有名詞の並び(Login.gov, TTS Engineering and USAi)や著者の並びは囲まれていないので、題名と読まない。
|
|
78
89
|
* 文を一度だけ読み、どの位置の問いにも続きを読み直さずに答える。
|
|
79
90
|
*/
|
|
80
|
-
export const citedTitles = (tokens: readonly Token[], source: string): ((at: number) => boolean) => {
|
|
91
|
+
export const citedTitles = (tokens: readonly Token[], source: string, titleCues: readonly string[] = []): ((at: number) => boolean) => {
|
|
81
92
|
const runs = runsOf(tokens, source);
|
|
82
93
|
return (at) => {
|
|
83
94
|
const start = leftStart(runs, at);
|
|
@@ -88,7 +99,8 @@ export const citedTitles = (tokens: readonly Token[], source: string): ((at: num
|
|
|
88
99
|
if (!holdsPhrase(runs, start, end)) return false;
|
|
89
100
|
const before = source.slice(Math.max(0, first.span.start - MARK_REACH), first.span.start);
|
|
90
101
|
const after = source.slice(last.span.end, last.span.end + MARK_REACH);
|
|
91
|
-
|
|
102
|
+
const quoted = (OPENING.test(before) && CLOSING.test(after)) || (AFTER_QUOTED_TITLE.test(before) && VENUE_END.test(after));
|
|
103
|
+
return quoted || afterTitleCue(source, first, titleCues);
|
|
92
104
|
};
|
|
93
105
|
};
|
|
94
106
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { quotedSpans } from "../quoted-span.ts";
|
|
2
|
+
|
|
3
|
+
// A short phrase in quotation marks ("Do Not Disturb", ‘we’re going to x’) is a name or an example: the form is mentioned,
|
|
4
|
+
// not used, so it says nothing about the document's register. Spoken words carry punctuation ("We don't know," she
|
|
5
|
+
// said) and stay. The text must already have straight apostrophes, so a ’ left in it closes a quotation.
|
|
6
|
+
|
|
7
|
+
const MENTION_MARKS: Readonly<Record<string, string>> = { "“": "”", '"': '"', "‘": "’" };
|
|
8
|
+
/** More words than this in quotation marks is a quoted sentence, not a phrase named as an example. */
|
|
9
|
+
const MAX_MENTION_WORDS = 4;
|
|
10
|
+
const PHRASE = /^[\p{L}' ]+$/u;
|
|
11
|
+
|
|
12
|
+
const isMention = (quoted: string): boolean => {
|
|
13
|
+
const phrase = quoted.trim();
|
|
14
|
+
return PHRASE.test(phrase) && phrase.split(/\s+/u).length <= MAX_MENTION_WORDS;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** The text with each quoted short phrase blanked out, every other character at its place. */
|
|
18
|
+
export const withoutMentions = (text: string): string => {
|
|
19
|
+
const mentions = quotedSpans(text, MENTION_MARKS).filter((span) => isMention(text.slice(span.start, span.end)));
|
|
20
|
+
if (mentions.length === 0) return text;
|
|
21
|
+
const units = text.split("");
|
|
22
|
+
mentions.forEach((span) => units.fill(" ", span.start, span.end));
|
|
23
|
+
return units.join("");
|
|
24
|
+
};
|
|
@@ -16,15 +16,30 @@ const wordBefore = (tokens: readonly Token[], at: number): Token | undefined =>
|
|
|
16
16
|
return beyond !== undefined && touches(beyond, previous) ? beyond : undefined;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
const DIGITS = /^[0-90-9]+$/u;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 数と一語に解析された日付の単位(全角の「4月」)。連なりは単位から始まるので、単位の分だけの語にして返す。
|
|
23
|
+
* positional は数の後ろに置くだけで暦や時計の位置を言う単位(月、時)。
|
|
24
|
+
*/
|
|
25
|
+
const gluedUnit = (tokens: readonly Token[], start: number, run: string, positional: readonly string[]): Token | undefined => {
|
|
26
|
+
const token = tokens.find((candidate) => candidate.span.start < start && start < candidate.span.end);
|
|
27
|
+
if (token === undefined) return undefined;
|
|
28
|
+
const unit = positional.find((word) => token.surface.endsWith(word) && DIGITS.test(token.surface.slice(0, -word.length)));
|
|
29
|
+
return unit !== undefined && run.startsWith(unit) ? { ...token, surface: unit, span: { start, end: token.span.end } } : undefined;
|
|
30
|
+
};
|
|
31
|
+
|
|
19
32
|
/**
|
|
20
33
|
* 漢字の連なり run(文書全体の座標で start から始まる)の頭が、直前の数に付いた助数詞(2日、第76回、24時間)なら、その助数詞の語。
|
|
21
34
|
* 数字が区切りを見せるので、助数詞は数と読まれ、後ろの複合語の一部ではない。そうでなければ undefined。
|
|
35
|
+
* 解析が助数詞と言わない日付の単位(4月の「月」)も、positional にあれば助数詞と読む。
|
|
22
36
|
* 折り返しをまたぐ語(年\n度)は span が surface より長いので、連なりの残りは span の終わりから始まる。
|
|
23
37
|
*/
|
|
24
|
-
export const leadingCounter = (tokens: readonly Token[], start: number, run: string): Token | undefined => {
|
|
38
|
+
export const leadingCounter = (tokens: readonly Token[], start: number, run: string, positional: readonly string[] = []): Token | undefined => {
|
|
25
39
|
const at = tokens.findIndex((token) => token.span.start === start);
|
|
26
40
|
const counter = tokens[at];
|
|
27
|
-
if (counter === undefined
|
|
41
|
+
if (counter === undefined) return gluedUnit(tokens, start, run, positional);
|
|
42
|
+
if (!(isCounter(counter) || positional.includes(counter.surface)) || !isNumber(wordBefore(tokens, at))) return undefined;
|
|
28
43
|
return run.startsWith(counter.surface) ? counter : undefined;
|
|
29
44
|
};
|
|
30
45
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// A dash with space on both sides after the last comma before an and / or ("Washington, DC – The Cybersecurity and
|
|
2
|
+
// Infrastructure Security Agency"). The dash closes off what came before it, a dateline here, so the commas before it
|
|
3
|
+
// do not separate the items of a list the and / or ends. Commas and dashes inside brackets or quotation marks are not
|
|
4
|
+
// the and / or's own. Pure, and one pass over the sentence.
|
|
5
|
+
import type { Token } from "../plugin.ts";
|
|
6
|
+
|
|
7
|
+
const DASHES = new Set(["–", "—", "―", "-", "--"]);
|
|
8
|
+
const OPENERS = new Set(["(", "[", "{", "“"]);
|
|
9
|
+
const CLOSERS = new Set([")", "]", "}", "”"]);
|
|
10
|
+
const SPACE = /\s/u;
|
|
11
|
+
|
|
12
|
+
const isSpacedDash = (token: Token, source: string): boolean =>
|
|
13
|
+
DASHES.has(token.surface) && SPACE.test(source.charAt(token.span.start - 1)) && SPACE.test(source.charAt(token.span.end));
|
|
14
|
+
|
|
15
|
+
/** The last comma and the last spaced dash seen at one depth of brackets. */
|
|
16
|
+
type Seen = { comma: number; dash: number };
|
|
17
|
+
|
|
18
|
+
type Scan = { depth: number; readonly seen: Seen[]; readonly breaks: boolean[] };
|
|
19
|
+
|
|
20
|
+
const seenAt = (scan: Scan): Seen => {
|
|
21
|
+
const seen = scan.seen[scan.depth] ?? { comma: -1, dash: -1 };
|
|
22
|
+
scan.seen[scan.depth] = seen;
|
|
23
|
+
return seen;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* For each token, whether a spaced dash comes between the last comma before it and it, at its depth, and not right
|
|
28
|
+
* before it: a dash right before the and / or sets off its last item (the plan, the budget – and the schedule).
|
|
29
|
+
*/
|
|
30
|
+
export const dashBreaks = (tokens: readonly Token[], source: string): boolean[] =>
|
|
31
|
+
tokens.reduce<Scan>(
|
|
32
|
+
(scan, token, at) => {
|
|
33
|
+
if (CLOSERS.has(token.surface)) {
|
|
34
|
+
scan.seen.length = scan.depth;
|
|
35
|
+
scan.depth = Math.max(0, scan.depth - 1);
|
|
36
|
+
}
|
|
37
|
+
const seen = seenAt(scan);
|
|
38
|
+
scan.breaks.push(seen.comma !== -1 && seen.dash > seen.comma && seen.dash < at - 1);
|
|
39
|
+
if (token.surface === ",") seen.comma = at;
|
|
40
|
+
if (isSpacedDash(token, source)) seen.dash = at;
|
|
41
|
+
if (OPENERS.has(token.surface)) scan.depth += 1;
|
|
42
|
+
return scan;
|
|
43
|
+
},
|
|
44
|
+
{ depth: 0, seen: [], breaks: [] },
|
|
45
|
+
).breaks;
|
|
@@ -13,17 +13,18 @@ export const YEAR_SPAN_JOINER_LEXICON = "year-span-joiner";
|
|
|
13
13
|
* `adjacent`: just before the date ("each December 31"). `near`: ending a few characters before it (決算日は、12月31日).
|
|
14
14
|
* `label`: before the bracket the date is in (年末年始閉庁日(12月29日~1月3日)). `continues`: opening a list item just
|
|
15
15
|
* after an example's item, it carries the example on ("- For example, … June 22." then "- If instead … June 25").
|
|
16
|
+
* `listed`: named in one list with the date, only list joiners between (祝休日及び12月29日, "public holidays and December 24").
|
|
16
17
|
*/
|
|
17
|
-
export type MarkerReach = "sentence" | "example" | "adjacent" | "near" | "label" | "continues";
|
|
18
|
+
export type MarkerReach = "sentence" | "example" | "adjacent" | "near" | "label" | "continues" | "listed";
|
|
18
19
|
|
|
19
|
-
export const MARKER_REACHES: readonly MarkerReach[] = ["sentence", "example", "adjacent", "near", "label", "continues"];
|
|
20
|
+
export const MARKER_REACHES: readonly MarkerReach[] = ["sentence", "example", "adjacent", "near", "label", "continues", "listed"];
|
|
20
21
|
|
|
21
22
|
export type AnyYearMarker = { readonly word: string; readonly reach: MarkerReach };
|
|
22
23
|
|
|
23
24
|
/** The span of a yearless date in the source. */
|
|
24
25
|
export type DateSpan = { readonly offset: number; readonly end: number };
|
|
25
26
|
|
|
26
|
-
/** How far apart the two ends of a period may stand
|
|
27
|
+
/** How far apart the two ends of a period may stand besides the joiner itself: a year word (「から翌年」, " to the next "). */
|
|
27
28
|
const SPAN_GAP_REACH = 12;
|
|
28
29
|
|
|
29
30
|
/** How many lines above a list item its introducing line is looked for: a longer list is read as no example. */
|
|
@@ -151,8 +152,24 @@ const continuesExample = (date: DateSpan, before: string, source: string, marker
|
|
|
151
152
|
return above !== undefined && exampleItem(source, above, lineStart(source, date.offset) - 1, markers, LIST_REACH);
|
|
152
153
|
};
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
/** What is left of `gap` once the list joiners at its head and the spaces around them are taken off. */
|
|
156
|
+
const afterJoiners = (gap: string, joiners: readonly string[]): string => {
|
|
157
|
+
const trimmed = gap.trimStart();
|
|
158
|
+
const joiner = joiners.find((candidate) => candidate !== "" && trimmed.startsWith(candidate) && !runsOn(trimmed, candidate));
|
|
159
|
+
return joiner === undefined ? trimmed : afterJoiners(trimmed.slice(joiner.length), joiners);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/** The word stands just before the date with only list joiners between: 「祝休日及び」, "holidays, and ". */
|
|
163
|
+
const listedBefore = (before: string, word: string, joiners: readonly string[]): boolean => {
|
|
164
|
+
const found = lastWordAt(before, word);
|
|
165
|
+
if (found === -1) return false;
|
|
166
|
+
const gap = before.slice(found + word.length);
|
|
167
|
+
return gap.trim() !== "" && afterJoiners(gap, joiners) === "";
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const coversDate = (before: string, dateStart: string, intro: string | undefined, word: string, reach: MarkerReach, joiners: readonly string[]): boolean => {
|
|
155
171
|
if (reach === "adjacent") return isAdjacent(latinLower(before), word);
|
|
172
|
+
if (reach === "listed") return listedBefore(latinLower(before), word, joiners);
|
|
156
173
|
if (reach === "near") return lastWordAt(latinLower(before.slice(-(word.length + NEAR_REACH))), word) !== -1;
|
|
157
174
|
if (reach === "label") return latinLower(labelOf(before) ?? "").includes(word);
|
|
158
175
|
if (reach === "continues") return false;
|
|
@@ -160,17 +177,25 @@ const coversDate = (before: string, dateStart: string, intro: string | undefined
|
|
|
160
177
|
return inItem || inSentence(before, dateStart, word) || (intro !== undefined && introEndsWith(latinLower(intro), word));
|
|
161
178
|
};
|
|
162
179
|
|
|
163
|
-
/**
|
|
164
|
-
|
|
180
|
+
/**
|
|
181
|
+
* The date is a recurring day or a worked example: a marker stands where its reach covers the date. `listJoiners` are the
|
|
182
|
+
* words a `listed` marker may stand before the date with (及び, "and").
|
|
183
|
+
*/
|
|
184
|
+
export const anyYearDate = (date: DateSpan, source: string, markers: readonly AnyYearMarker[], listJoiners: readonly string[] = []): boolean => {
|
|
165
185
|
const before = source.slice(lineStart(source, date.offset), date.offset);
|
|
166
186
|
const intro = introOf(source, before, date.offset);
|
|
167
|
-
const
|
|
187
|
+
const joiners = listJoiners.map(latinLower);
|
|
188
|
+
const covered = markers.some(({ word, reach }) => word !== "" && coversDate(before, source.charAt(date.offset), intro, latinLower(word), reach, joiners));
|
|
168
189
|
return covered || continuesExample(date, before, source, markers);
|
|
169
190
|
};
|
|
170
191
|
|
|
171
192
|
/** The date opens a period whose other end, just after it, follows a joiner (「4月1日から翌年3月31日」). */
|
|
172
193
|
export const opensSpan = (date: DateSpan, next: DateSpan | undefined, source: string, joiners: readonly string[]): boolean => {
|
|
173
|
-
|
|
194
|
+
const longest = Math.max(0, ...joiners.map((joiner) => joiner.length));
|
|
195
|
+
if (next === undefined || next.offset - date.end > SPAN_GAP_REACH + longest) return false;
|
|
174
196
|
const gap = source.slice(date.end, next.offset).trimStart();
|
|
175
|
-
return
|
|
197
|
+
return (
|
|
198
|
+
!SENTENCE_END.test(gap) &&
|
|
199
|
+
joiners.some((joiner) => joiner !== "" && gap.length - joiner.length <= SPAN_GAP_REACH && gap.startsWith(joiner) && !runsOn(gap, joiner))
|
|
200
|
+
);
|
|
176
201
|
};
|
|
@@ -22,7 +22,8 @@ export const dateFormat: Detector = (doc, options): Finding[] => {
|
|
|
22
22
|
eras: (doc.lexicons["calendar-era"] ?? []).map((entry) => entry.pattern),
|
|
23
23
|
};
|
|
24
24
|
const text = doc.prose ?? doc.source;
|
|
25
|
-
|
|
25
|
+
const stampLabels = (doc.lexicons["date-stamp-label"] ?? []).map((entry) => entry.pattern);
|
|
26
|
+
return dateGroups(text, datesIn(text, words), stampLabels).flatMap((group) => {
|
|
26
27
|
const minority = dateMinority(group, options.limit);
|
|
27
28
|
return minority === undefined ? [] : findingsOf(doc, minority);
|
|
28
29
|
});
|