chaffjs 0.34.0 → 0.36.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/capitals-passage.d.ts +3 -0
- package/dist/capitals-passage.d.ts.map +1 -0
- package/dist/capitals-passage.js +26 -0
- package/dist/capitals-passage.js.map +1 -0
- package/dist/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/coined-hyphen-name.d.ts +13 -0
- package/dist/coined-hyphen-name.d.ts.map +1 -0
- package/dist/coined-hyphen-name.js +21 -0
- package/dist/coined-hyphen-name.js.map +1 -0
- package/dist/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/company-names.d.ts +6 -1
- package/dist/company-names.d.ts.map +1 -1
- package/dist/company-names.js +22 -3
- package/dist/company-names.js.map +1 -1
- 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 +5 -1
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +32 -4
- package/dist/detectors/acronym-context.js.map +1 -1
- package/dist/detectors/acronym-definition.d.ts +13 -0
- package/dist/detectors/acronym-definition.d.ts.map +1 -0
- package/dist/detectors/acronym-definition.js +90 -0
- package/dist/detectors/acronym-definition.js.map +1 -0
- package/dist/detectors/acronym-expansion.d.ts +5 -1
- package/dist/detectors/acronym-expansion.d.ts.map +1 -1
- package/dist/detectors/acronym-expansion.js +35 -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 +14 -0
- package/dist/detectors/acronym-link.d.ts.map +1 -0
- package/dist/detectors/acronym-link.js +32 -0
- package/dist/detectors/acronym-link.js.map +1 -0
- package/dist/detectors/acronym-lone.d.ts +13 -0
- package/dist/detectors/acronym-lone.d.ts.map +1 -0
- package/dist/detectors/acronym-lone.js +22 -0
- package/dist/detectors/acronym-lone.js.map +1 -0
- package/dist/detectors/acronym-name.d.ts +62 -0
- package/dist/detectors/acronym-name.d.ts.map +1 -0
- package/dist/detectors/acronym-name.js +94 -0
- package/dist/detectors/acronym-name.js.map +1 -0
- 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/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 +14 -2
- package/dist/detectors/capitalised-term.d.ts.map +1 -1
- package/dist/detectors/capitalised-term.js +115 -4
- package/dist/detectors/capitalised-term.js.map +1 -1
- package/dist/detectors/caps-caption.d.ts +12 -0
- package/dist/detectors/caps-caption.d.ts.map +1 -0
- package/dist/detectors/caps-caption.js +89 -0
- package/dist/detectors/caps-caption.js.map +1 -0
- 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 +72 -30
- package/dist/detectors/char-shape.js.map +1 -1
- 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/clause-shape.d.ts +1 -1
- package/dist/detectors/clause-shape.d.ts.map +1 -1
- package/dist/detectors/clause-shape.js +9 -4
- package/dist/detectors/clause-shape.js.map +1 -1
- package/dist/detectors/concrete-evidence.d.ts +13 -1
- package/dist/detectors/concrete-evidence.d.ts.map +1 -1
- package/dist/detectors/concrete-evidence.js +59 -0
- package/dist/detectors/concrete-evidence.js.map +1 -1
- package/dist/detectors/contraction-minority.d.ts +11 -0
- package/dist/detectors/contraction-minority.d.ts.map +1 -0
- package/dist/detectors/contraction-minority.js +10 -0
- package/dist/detectors/contraction-minority.js.map +1 -0
- package/dist/detectors/counter-edge.d.ts +7 -1
- package/dist/detectors/counter-edge.d.ts.map +1 -1
- package/dist/detectors/counter-edge.js +40 -2
- package/dist/detectors/counter-edge.js.map +1 -1
- package/dist/detectors/date-any-year.d.ts +12 -5
- package/dist/detectors/date-any-year.d.ts.map +1 -1
- package/dist/detectors/date-any-year.js +69 -12
- 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-heading-year.d.ts +18 -0
- package/dist/detectors/date-heading-year.d.ts.map +1 -0
- package/dist/detectors/date-heading-year.js +38 -0
- package/dist/detectors/date-heading-year.js.map +1 -0
- package/dist/detectors/date-year.d.ts +19 -3
- package/dist/detectors/date-year.d.ts.map +1 -1
- package/dist/detectors/date-year.js +69 -8
- 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 +59 -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 +6 -3
- 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/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/due-date.d.ts.map +1 -1
- package/dist/detectors/due-date.js +6 -0
- package/dist/detectors/due-date.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 +31 -1
- package/dist/detectors/email-letter.d.ts.map +1 -1
- package/dist/detectors/email-letter.js +76 -14
- package/dist/detectors/email-letter.js.map +1 -1
- package/dist/detectors/en-shape.d.ts.map +1 -1
- package/dist/detectors/en-shape.js +5 -1
- package/dist/detectors/en-shape.js.map +1 -1
- package/dist/detectors/fact-consistency.d.ts.map +1 -1
- package/dist/detectors/fact-consistency.js +3 -2
- package/dist/detectors/fact-consistency.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/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 +8 -0
- package/dist/detectors/gram-openers.d.ts.map +1 -0
- package/dist/detectors/gram-openers.js +16 -0
- package/dist/detectors/gram-openers.js.map +1 -0
- package/dist/detectors/gram-passages.d.ts +11 -0
- package/dist/detectors/gram-passages.d.ts.map +1 -0
- package/dist/detectors/gram-passages.js +26 -0
- package/dist/detectors/gram-passages.js.map +1 -0
- package/dist/detectors/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-end-mark.d.ts +8 -3
- package/dist/detectors/heading-end-mark.d.ts.map +1 -1
- package/dist/detectors/heading-end-mark.js +18 -8
- package/dist/detectors/heading-end-mark.js.map +1 -1
- package/dist/detectors/heading-names.d.ts +7 -0
- package/dist/detectors/heading-names.d.ts.map +1 -0
- package/dist/detectors/heading-names.js +24 -0
- package/dist/detectors/heading-names.js.map +1 -0
- package/dist/detectors/heading-numbering.d.ts.map +1 -1
- package/dist/detectors/heading-numbering.js +7 -2
- package/dist/detectors/heading-numbering.js.map +1 -1
- package/dist/detectors/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/inch-mark.d.ts +10 -0
- package/dist/detectors/inch-mark.d.ts.map +1 -0
- package/dist/detectors/inch-mark.js +48 -0
- package/dist/detectors/inch-mark.js.map +1 -0
- package/dist/detectors/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 +76 -12
- package/dist/detectors/kutoten-consistency.js.map +1 -1
- package/dist/detectors/lexicon.d.ts +0 -1
- package/dist/detectors/lexicon.d.ts.map +1 -1
- package/dist/detectors/lexicon.js +37 -25
- 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 +15 -5
- package/dist/detectors/mark-shape.d.ts.map +1 -1
- package/dist/detectors/mark-shape.js +64 -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-apart.d.ts +27 -0
- package/dist/detectors/name-variant-apart.d.ts.map +1 -0
- package/dist/detectors/name-variant-apart.js +51 -0
- package/dist/detectors/name-variant-apart.js.map +1 -0
- package/dist/detectors/name-variant.d.ts.map +1 -1
- package/dist/detectors/name-variant.js +18 -11
- 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/numeral-word.d.ts +15 -0
- package/dist/detectors/numeral-word.d.ts.map +1 -0
- package/dist/detectors/numeral-word.js +26 -0
- package/dist/detectors/numeral-word.js.map +1 -0
- package/dist/detectors/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 +18 -0
- package/dist/detectors/organisation-run.d.ts.map +1 -0
- package/dist/detectors/organisation-run.js +80 -0
- package/dist/detectors/organisation-run.js.map +1 -0
- package/dist/detectors/orthographic-variant.d.ts.map +1 -1
- package/dist/detectors/orthographic-variant.js +65 -21
- package/dist/detectors/orthographic-variant.js.map +1 -1
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +6 -1
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/outline-label.d.ts +14 -0
- package/dist/detectors/outline-label.d.ts.map +1 -0
- package/dist/detectors/outline-label.js +32 -0
- package/dist/detectors/outline-label.js.map +1 -0
- package/dist/detectors/oxford-comma.d.ts.map +1 -1
- package/dist/detectors/oxford-comma.js +38 -1
- package/dist/detectors/oxford-comma.js.map +1 -1
- package/dist/detectors/page-marker.d.ts +6 -0
- package/dist/detectors/page-marker.d.ts.map +1 -0
- package/dist/detectors/page-marker.js +19 -0
- package/dist/detectors/page-marker.js.map +1 -0
- package/dist/detectors/parallel-definition.d.ts +16 -0
- package/dist/detectors/parallel-definition.d.ts.map +1 -0
- package/dist/detectors/parallel-definition.js +51 -0
- package/dist/detectors/parallel-definition.js.map +1 -0
- package/dist/detectors/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/reference-text.d.ts.map +1 -1
- package/dist/detectors/reference-text.js +1 -0
- package/dist/detectors/reference-text.js.map +1 -1
- package/dist/detectors/registry/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/registry/unfilled-placeholder.d.ts.map +1 -1
- package/dist/detectors/registry/unfilled-placeholder.js +2 -2
- package/dist/detectors/registry/unfilled-placeholder.js.map +1 -1
- package/dist/detectors/registry/vague-density.js +1 -1
- package/dist/detectors/registry/vague-density.js.map +1 -1
- package/dist/detectors/request-owner.d.ts +6 -2
- package/dist/detectors/request-owner.d.ts.map +1 -1
- package/dist/detectors/request-owner.js +57 -7
- package/dist/detectors/request-owner.js.map +1 -1
- package/dist/detectors/requirement-smell.d.ts.map +1 -1
- package/dist/detectors/requirement-smell.js +39 -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 +2 -0
- package/dist/detectors/sentence-counts.d.ts.map +1 -1
- package/dist/detectors/sentence-counts.js +18 -7
- 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 +24 -16
- 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/sentence-rhythm.d.ts.map +1 -1
- package/dist/detectors/sentence-rhythm.js +6 -3
- package/dist/detectors/sentence-rhythm.js.map +1 -1
- package/dist/detectors/series-label.d.ts +2 -1
- package/dist/detectors/series-label.d.ts.map +1 -1
- package/dist/detectors/series-label.js +10 -4
- package/dist/detectors/series-label.js.map +1 -1
- package/dist/detectors/signals.d.ts +4 -0
- package/dist/detectors/signals.d.ts.map +1 -1
- package/dist/detectors/signals.js +91 -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 +21 -19
- 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/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/template-sections.d.ts +14 -0
- package/dist/detectors/template-sections.d.ts.map +1 -0
- package/dist/detectors/template-sections.js +25 -0
- package/dist/detectors/template-sections.js.map +1 -0
- package/dist/detectors/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 +23 -0
- package/dist/detectors/titled-run.d.ts.map +1 -0
- package/dist/detectors/titled-run.js +39 -0
- package/dist/detectors/titled-run.js.map +1 -0
- package/dist/detectors/token-shape.d.ts.map +1 -1
- package/dist/detectors/token-shape.js +13 -5
- package/dist/detectors/token-shape.js.map +1 -1
- package/dist/detectors/unbalanced-bracket.d.ts.map +1 -1
- package/dist/detectors/unbalanced-bracket.js +4 -0
- package/dist/detectors/unbalanced-bracket.js.map +1 -1
- package/dist/detectors/undefined-term.d.ts.map +1 -1
- package/dist/detectors/undefined-term.js +8 -0
- package/dist/detectors/undefined-term.js.map +1 -1
- package/dist/detectors/unfilled-placeholder.d.ts +4 -0
- package/dist/detectors/unfilled-placeholder.d.ts.map +1 -0
- package/dist/detectors/unfilled-placeholder.js +9 -0
- package/dist/detectors/unfilled-placeholder.js.map +1 -0
- package/dist/detectors/vague-density.d.ts +8 -0
- package/dist/detectors/vague-density.d.ts.map +1 -0
- package/dist/detectors/vague-density.js +65 -0
- package/dist/detectors/vague-density.js.map +1 -0
- 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/facts/fact-scope.d.ts +10 -1
- package/dist/facts/fact-scope.d.ts.map +1 -1
- package/dist/facts/fact-scope.js +34 -3
- package/dist/facts/fact-scope.js.map +1 -1
- package/dist/facts/table-facts.d.ts +12 -2
- package/dist/facts/table-facts.d.ts.map +1 -1
- package/dist/facts/table-facts.js +22 -4
- package/dist/facts/table-facts.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/grade-api.d.ts +9 -2
- package/dist/grade-api.d.ts.map +1 -1
- package/dist/grade-api.js +31 -15
- package/dist/grade-api.js.map +1 -1
- package/dist/heading-numbering.d.ts +5 -2
- package/dist/heading-numbering.d.ts.map +1 -1
- package/dist/heading-numbering.js +27 -6
- package/dist/heading-numbering.js.map +1 -1
- package/dist/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 +33 -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 +15 -0
- package/dist/latin-word-boundary.d.ts.map +1 -0
- package/dist/latin-word-boundary.js +40 -0
- package/dist/latin-word-boundary.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 +5 -0
- package/dist/link-shape.d.ts.map +1 -1
- package/dist/link-shape.js +18 -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-end-letter.d.ts +5 -0
- package/dist/name-end-letter.d.ts.map +1 -1
- package/dist/name-end-letter.js +8 -0
- package/dist/name-end-letter.js.map +1 -1
- package/dist/name-given-before.d.ts +15 -0
- package/dist/name-given-before.d.ts.map +1 -0
- package/dist/name-given-before.js +30 -0
- package/dist/name-given-before.js.map +1 -0
- package/dist/name-separator.d.ts +2 -2
- package/dist/name-separator.d.ts.map +1 -1
- package/dist/name-separator.js +79 -5
- package/dist/name-separator.js.map +1 -1
- package/dist/name-variants.d.ts +3 -1
- package/dist/name-variants.d.ts.map +1 -1
- package/dist/name-variants.js +8 -7
- package/dist/name-variants.js.map +1 -1
- package/dist/name-word-order.d.ts +9 -5
- package/dist/name-word-order.d.ts.map +1 -1
- package/dist/name-word-order.js +47 -15
- package/dist/name-word-order.js.map +1 -1
- package/dist/nominal-stem.d.ts +26 -0
- package/dist/nominal-stem.d.ts.map +1 -0
- package/dist/nominal-stem.js +70 -0
- package/dist/nominal-stem.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 +6 -2
- 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 +11 -0
- package/dist/structure/attached-parts.d.ts.map +1 -0
- package/dist/structure/attached-parts.js +31 -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/cited-document-section.d.ts +7 -0
- package/dist/structure/cited-document-section.d.ts.map +1 -0
- package/dist/structure/cited-document-section.js +33 -0
- package/dist/structure/cited-document-section.js.map +1 -0
- package/dist/structure/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 +3 -2
- package/dist/structure/definition-use.d.ts.map +1 -1
- package/dist/structure/definition-use.js +99 -31
- package/dist/structure/definition-use.js.map +1 -1
- package/dist/structure/html-text-blocks.d.ts +8 -0
- package/dist/structure/html-text-blocks.d.ts.map +1 -0
- package/dist/structure/html-text-blocks.js +47 -0
- package/dist/structure/html-text-blocks.js.map +1 -0
- package/dist/structure/issues.d.ts +5 -2
- package/dist/structure/issues.d.ts.map +1 -1
- package/dist/structure/issues.js +24 -6
- package/dist/structure/issues.js.map +1 -1
- package/dist/structure/labelled-date-order.d.ts +4 -1
- package/dist/structure/labelled-date-order.d.ts.map +1 -1
- package/dist/structure/labelled-date-order.js +2 -2
- package/dist/structure/labelled-date-order.js.map +1 -1
- package/dist/structure/labelled-order.d.ts +3 -0
- package/dist/structure/labelled-order.d.ts.map +1 -1
- package/dist/structure/labelled-order.js +8 -3
- package/dist/structure/labelled-order.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/list-numbering.d.ts +20 -4
- package/dist/structure/list-numbering.d.ts.map +1 -1
- package/dist/structure/list-numbering.js +65 -9
- package/dist/structure/list-numbering.js.map +1 -1
- package/dist/structure/listed-paragraph.d.ts +16 -0
- package/dist/structure/listed-paragraph.d.ts.map +1 -0
- package/dist/structure/listed-paragraph.js +37 -0
- package/dist/structure/listed-paragraph.js.map +1 -0
- package/dist/structure/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 +5 -2
- package/dist/structure/numbering.d.ts.map +1 -1
- package/dist/structure/numbering.js +49 -12
- 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/reference-text.d.ts +9 -1
- package/dist/structure/reference-text.d.ts.map +1 -1
- package/dist/structure/reference-text.js +21 -3
- package/dist/structure/reference-text.js.map +1 -1
- package/dist/structure/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/section-names.d.ts +12 -0
- package/dist/structure/section-names.d.ts.map +1 -0
- package/dist/structure/section-names.js +26 -0
- package/dist/structure/section-names.js.map +1 -0
- package/dist/structure/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 +3 -1
- package/dist/structure/universal.d.ts.map +1 -1
- package/dist/structure/universal.js +9 -2
- 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/versioned-label.d.ts +16 -0
- package/dist/structure/versioned-label.d.ts.map +1 -0
- package/dist/structure/versioned-label.js +48 -0
- package/dist/structure/versioned-label.js.map +1 -0
- package/dist/structure/written-headings.d.ts +31 -0
- package/dist/structure/written-headings.d.ts.map +1 -0
- package/dist/structure/written-headings.js +119 -0
- package/dist/structure/written-headings.js.map +1 -0
- package/dist/structure/written-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 +12 -0
- package/dist/structure/written-resolve.d.ts.map +1 -0
- package/dist/structure/written-resolve.js +55 -0
- package/dist/structure/written-resolve.js.map +1 -0
- package/dist/title-line.d.ts +21 -0
- package/dist/title-line.d.ts.map +1 -0
- package/dist/title-line.js +27 -0
- package/dist/title-line.js.map +1 -0
- package/package.json +3 -3
- 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 +2 -2
- package/rules/contraction-consistency.yaml +13 -13
- package/rules/dangling-figure-reference.yaml +2 -2
- package/rules/dangling-reference.yaml +2 -2
- package/rules/date-without-year.yaml +10 -2
- package/rules/defined-name-repeated.yaml +2 -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/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/fact-conflict.yaml +2 -2
- package/rules/footnote-mismatch.yaml +2 -2
- package/rules/heading-echo.yaml +2 -2
- package/rules/heading-end-punctuation-mix.yaml +2 -2
- package/rules/heading-numbering-mix.yaml +2 -2
- package/rules/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 +4 -4
- package/rules/list-item-form-mix.yaml +2 -2
- package/rules/max-kanji-continuous.yaml +7 -3
- package/rules/max-sentence-length.yaml +3 -2
- package/rules/modal-conflict.yaml +1 -0
- package/rules/nado-closed-list.yaml +2 -2
- package/rules/name-variant.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 +2 -2
- package/rules/reference-title-mismatch.yaml +2 -2
- package/rules/repeated-sentence-ending.yaml +3 -2
- package/rules/request-without-deadline.yaml +2 -2
- package/rules/requirement-smell.yaml +3 -3
- package/rules/sentence-rhythm.yaml +2 -2
- package/rules/table-header-variant.yaml +2 -2
- package/rules/teki-overuse.yaml +3 -2
- package/rules/title-case-consistency.yaml +2 -2
- package/rules/total-mismatch.yaml +2 -2
- package/rules/translationese-density.yaml +2 -2
- package/rules/unbalanced-bracket.yaml +2 -2
- package/rules/undefined-acronym.yaml +15 -4
- package/rules/undefined-term.yaml +2 -2
- package/rules/unfilled-placeholder.yaml +4 -4
- 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/capitals-passage.ts +31 -0
- package/src/chronology-rows.ts +86 -0
- package/src/coined-hyphen-name.ts +27 -0
- package/src/company-name-run.ts +37 -0
- package/src/company-names.ts +24 -3
- 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 +34 -6
- package/src/detectors/acronym-definition.ts +123 -0
- package/src/detectors/acronym-expansion.ts +47 -6
- package/src/detectors/acronym-known.ts +40 -0
- package/src/detectors/acronym-link.ts +37 -0
- package/src/detectors/acronym-lone.ts +26 -0
- package/src/detectors/acronym-name.ts +140 -0
- package/src/detectors/addressee-edge.ts +16 -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 +154 -4
- package/src/detectors/caps-caption.ts +103 -0
- package/src/detectors/caps-phrase.ts +17 -0
- package/src/detectors/char-shape.ts +99 -26
- package/src/detectors/cited-title.ts +15 -3
- package/src/detectors/clause-shape.ts +14 -4
- package/src/detectors/concrete-evidence.ts +77 -1
- package/src/detectors/contraction-minority.ts +11 -0
- package/src/detectors/counter-edge.ts +40 -2
- package/src/detectors/date-any-year.ts +79 -12
- package/src/detectors/date-format.ts +2 -1
- package/src/detectors/date-heading-year.ts +55 -0
- package/src/detectors/date-year.ts +107 -14
- package/src/detectors/deadline-unit.ts +40 -0
- package/src/detectors/defined-term-form.ts +58 -17
- package/src/detectors/definition-use.ts +7 -3
- package/src/detectors/derived-numbers.ts +19 -4
- 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/due-date.ts +10 -1
- package/src/detectors/ellipsis.ts +16 -1
- package/src/detectors/email-letter.ts +97 -21
- package/src/detectors/en-shape.ts +5 -1
- package/src/detectors/fact-consistency.ts +3 -2
- package/src/detectors/field-label.ts +25 -0
- package/src/detectors/footnote-mismatch.ts +39 -7
- package/src/detectors/graded-step.ts +52 -0
- package/src/detectors/gram-openers.ts +21 -0
- package/src/detectors/gram-passages.ts +36 -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-end-mark.ts +23 -10
- package/src/detectors/heading-names.ts +31 -0
- package/src/detectors/heading-numbering.ts +7 -2
- package/src/detectors/ime-residue.ts +4 -3
- package/src/detectors/inch-mark.ts +49 -0
- package/src/detectors/kanji-compound-slip.ts +61 -0
- package/src/detectors/kutoten-consistency.ts +93 -14
- package/src/detectors/lexicon.ts +44 -24
- 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 +70 -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-apart.ts +63 -0
- package/src/detectors/name-variant.ts +30 -12
- 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/numeral-word.ts +33 -0
- 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 +97 -0
- package/src/detectors/orthographic-variant.ts +103 -27
- package/src/detectors/orthography.ts +10 -1
- package/src/detectors/outline-label.ts +48 -0
- package/src/detectors/oxford-comma.ts +40 -1
- package/src/detectors/page-marker.ts +26 -0
- package/src/detectors/parallel-definition.ts +64 -0
- 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/reference-text.ts +1 -0
- package/src/detectors/registry/kanji-compound-slip.ts +4 -0
- package/src/detectors/registry/phrase-in-use.ts +4 -0
- package/src/detectors/registry/unfilled-placeholder.ts +2 -2
- package/src/detectors/registry/vague-density.ts +1 -1
- package/src/detectors/request-owner.ts +71 -8
- package/src/detectors/requirement-smell.ts +53 -7
- package/src/detectors/scaled-figure-unit.ts +103 -0
- package/src/detectors/sentence-counts.ts +24 -8
- package/src/detectors/sentence-ending.ts +12 -3
- package/src/detectors/sentence-length.ts +14 -6
- package/src/detectors/sentence-load.ts +9 -2
- package/src/detectors/sentence-rhythm.ts +8 -4
- package/src/detectors/series-label.ts +13 -4
- package/src/detectors/signals.ts +105 -55
- package/src/detectors/structure-tree.ts +22 -20
- package/src/detectors/structure.ts +2 -1
- package/src/detectors/subject-name-line.ts +66 -0
- package/src/detectors/table-header.ts +15 -1
- package/src/detectors/technical-docs.ts +5 -1
- package/src/detectors/template-sections.ts +37 -0
- package/src/detectors/term-mention-sentence.ts +31 -0
- package/src/detectors/titled-run.ts +48 -0
- package/src/detectors/token-shape.ts +14 -5
- package/src/detectors/unbalanced-bracket.ts +3 -0
- package/src/detectors/undefined-term.ts +8 -0
- package/src/detectors/unfilled-placeholder.ts +10 -0
- package/src/detectors/vague-density.ts +84 -0
- package/src/document-paragraphs.ts +27 -0
- package/src/document.ts +3 -23
- package/src/facts/fact-scope.ts +53 -4
- package/src/facts/table-facts.ts +43 -6
- package/src/figure-references.ts +7 -2
- package/src/format-template.ts +15 -0
- package/src/formula-brackets.ts +36 -0
- package/src/grade-api.ts +38 -16
- package/src/heading-numbering.ts +35 -8
- package/src/html/html-markdown.ts +2 -1
- package/src/html/html-site-chrome.ts +47 -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 +46 -0
- package/src/lexicon-genres.ts +1 -1
- package/src/link-shape.ts +19 -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-end-letter.ts +9 -0
- package/src/name-given-before.ts +40 -0
- package/src/name-separator.ts +91 -5
- package/src/name-variants.ts +21 -11
- package/src/name-word-order.ts +62 -17
- package/src/nominal-stem.ts +93 -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 +7 -2
- package/src/spacing-code.ts +5 -1
- package/src/split-noun.ts +63 -0
- package/src/structure/attached-parts.ts +32 -0
- package/src/structure/build.ts +7 -4
- package/src/structure/cited-document-section.ts +42 -0
- package/src/structure/contents-lines.ts +63 -0
- package/src/structure/defining-names.ts +155 -0
- package/src/structure/definition-use.ts +116 -25
- package/src/structure/html-text-blocks.ts +45 -0
- package/src/structure/issues.ts +26 -7
- package/src/structure/labelled-date-order.ts +5 -2
- package/src/structure/labelled-order.ts +12 -3
- package/src/structure/list-lead-in.ts +94 -0
- package/src/structure/list-numbering.ts +100 -11
- package/src/structure/listed-paragraph.ts +45 -0
- package/src/structure/modal-conflict.ts +42 -7
- package/src/structure/negated-act.ts +49 -0
- package/src/structure/numbering.ts +70 -26
- package/src/structure/prose-total.ts +20 -6
- package/src/structure/reference-text.ts +25 -3
- package/src/structure/repeated-number.ts +110 -0
- package/src/structure/rounded-amount.ts +55 -0
- package/src/structure/section-names.ts +32 -0
- package/src/structure/side-step.ts +21 -0
- package/src/structure/spanned-label-blank.ts +39 -0
- package/src/structure/universal.ts +11 -2
- package/src/structure/unspaced-heading.ts +27 -0
- package/src/structure/versioned-label.ts +52 -0
- package/src/structure/written-headings.ts +137 -0
- package/src/structure/written-list-path.ts +46 -0
- package/src/structure/written-resolve.ts +64 -0
- package/src/title-line.ts +52 -0
|
@@ -7,7 +7,7 @@ import { lookalikeSlipsIn, type LookalikeChars } from "../name-lookalike-chars.t
|
|
|
7
7
|
import { givenNameReadingOf, readingOfWords, type CharReadings } from "../name-char-reading.ts";
|
|
8
8
|
import { nameCueAt, type NameCues } from "../name-cue.ts";
|
|
9
9
|
import { quoteAt } from "./structure-tree.ts";
|
|
10
|
-
import { companyMentionsIn, companyVariants, type CompanyForm, type IsProper, type PredicateEnds } from "../company-names.ts";
|
|
10
|
+
import { companyMentionsIn, companyVariants, type CompanyForm, type CompanyMention, type IsProper, type PredicateEnds } from "../company-names.ts";
|
|
11
11
|
import { kanaSpelledCompanies, type ReadWord } from "../company-kana-spelling.ts";
|
|
12
12
|
import { proseAndTablesOf } from "../table-text.ts";
|
|
13
13
|
import { tableBodyCells } from "../facts/table-facts.ts";
|
|
@@ -23,6 +23,7 @@ import { spacedPersonNamesIn } from "../spaced-person-name.ts";
|
|
|
23
23
|
import { isOrdinaryToken, withOrdinaryWords } from "../name-ordinary-word.ts";
|
|
24
24
|
import { isInPersonField } from "../person-field.ts";
|
|
25
25
|
import { labelledSpans, orderNamesOf, quotedSpans, stemOf, titleCaseSpans, wordOrderVariants, type OrderWord } from "../name-word-order.ts";
|
|
26
|
+
import { isGroupPairOf, notDefinedTerms, outsideCapitals, sentenceIndexOf, withGivenNames } from "./name-variant-apart.ts";
|
|
26
27
|
|
|
27
28
|
// 人の名前と読ませる敬称(様、さん)は語彙表 person-suffix、人を指す前置き(担当の)は person-lead、名前のすぐ後ろに来る語
|
|
28
29
|
// (です、まで)は name-particle、字体の違う同じ字(斎・斉・齋)は name-variant-char が組(group)ごとに言う。
|
|
@@ -145,20 +146,22 @@ const predicateEndsOf = (doc: ProseDocument): PredicateEnds =>
|
|
|
145
146
|
const readWordsOf = (doc: ProseDocument): ReadWord[] =>
|
|
146
147
|
tokensOf(doc).map((token) => ({ start: token.span.start, end: token.span.end, surface: token.surface, reading: token.reading }));
|
|
147
148
|
|
|
149
|
+
/** 会社の名前の現れ。大文字で書いた一節の中のものは除く。 */
|
|
150
|
+
const companyMentionsOf = (doc: ProseDocument, prose: string): CompanyMention[] =>
|
|
151
|
+
outsideCapitals(prose, companyMentionsIn(prose, [...companyFormsOf(doc), ...foreignFormsOf(doc)], properOf(doc), kanaStopsOf(doc), predicateEndsOf(doc)));
|
|
152
|
+
|
|
148
153
|
/**
|
|
149
154
|
* 会社の名前の書き分けと、名前の漢字一字をその読みのかなで書いた所(みどり野 と みどりの)。名前の見方がすでに指した所と重なる
|
|
150
155
|
* ものは除く。
|
|
151
156
|
*/
|
|
152
|
-
const companyFindings = (doc: ProseDocument, prose: string, reported: readonly Reported[]): Reported[] => {
|
|
153
|
-
const stops = kanaStopsOf(doc);
|
|
154
|
-
const mentions = companyMentionsIn(prose, [...companyFormsOf(doc), ...foreignFormsOf(doc)], properOf(doc), stops, predicateEndsOf(doc));
|
|
157
|
+
const companyFindings = (doc: ProseDocument, prose: string, mentions: readonly CompanyMention[], reported: readonly Reported[]): Reported[] => {
|
|
155
158
|
const variants = companyVariants(mentions).map(({ mention, usual, kind }) => ({
|
|
156
159
|
offset: mention.offset,
|
|
157
160
|
name: mention.surface,
|
|
158
161
|
usual,
|
|
159
162
|
kind: kind === "spelling" ? kind : `company-${kind}`,
|
|
160
163
|
}));
|
|
161
|
-
const kana = kanaSpelledCompanies(prose, mentions, readWordsOf(doc),
|
|
164
|
+
const kana = kanaSpelledCompanies(prose, mentions, readWordsOf(doc), kanaStopsOf(doc).particles)
|
|
162
165
|
.map(({ surface, offset, usual }) => ({ offset, name: surface, usual, kind: "company-kana" }))
|
|
163
166
|
.filter((found) => !overlapsAny(variants, found.offset, found.name.length));
|
|
164
167
|
return [...variants, ...kana].filter(({ offset, name }) => !overlapsAny(reported, offset, name.length));
|
|
@@ -207,6 +210,9 @@ const orderWordsOf = (doc: ProseDocument): OrderWord[] => {
|
|
|
207
210
|
.map((token) => ({ start: token.span.start, end: token.span.end, key: stemOf(token.surface, suffixes) }));
|
|
208
211
|
};
|
|
209
212
|
|
|
213
|
+
/** 語彙表 name-title-joiner の、前置詞の後ろにだけ立つ冠詞(the)の組。 */
|
|
214
|
+
const ARTICLE = "article";
|
|
215
|
+
|
|
210
216
|
/**
|
|
211
217
|
* 語の順を入れ替えて書いた同じ名前(統計学基礎 と 基礎統計学)。名前と読める所は、括弧の中(name-quote)、大文字で始まる語の並び
|
|
212
218
|
* (name-title-joiner を挟んでよい)、名前を書く欄の後ろ(name-label)。大文字の語の並びどうしは、片方が表の升まるごとに
|
|
@@ -214,13 +220,20 @@ const orderWordsOf = (doc: ProseDocument): OrderWord[] => {
|
|
|
214
220
|
*/
|
|
215
221
|
const orderFindings = (doc: ProseDocument, prose: string, reported: readonly Reported[]): Reported[] => {
|
|
216
222
|
const starts = sentenceStartsOf(doc);
|
|
223
|
+
const joiners = doc.lexicons["name-title-joiner"] ?? [];
|
|
217
224
|
const spans = [
|
|
218
225
|
...quotedSpans(prose, patternsOf(doc, "name-quote")),
|
|
219
|
-
...titleCaseSpans(
|
|
226
|
+
...titleCaseSpans(
|
|
227
|
+
prose,
|
|
228
|
+
joiners.filter((entry) => entry.group !== ARTICLE).map((entry) => entry.pattern),
|
|
229
|
+
(offset) => starts.has(offset),
|
|
230
|
+
joiners.filter((entry) => entry.group === ARTICLE).map((entry) => entry.pattern),
|
|
231
|
+
),
|
|
220
232
|
...labelledSpans(prose, patternsOf(doc, "name-label")),
|
|
221
233
|
];
|
|
222
234
|
const cells = new Set(tableBodyCells(proseAndTablesOf(doc)).map((cell) => cell.text.trim()));
|
|
223
|
-
|
|
235
|
+
const names = notDefinedTerms(doc, orderNamesOf(doc.source, spans, orderWordsOf(doc), orderStopsOf(doc)));
|
|
236
|
+
return wordOrderVariants(names, cells, sentenceIndexOf(doc))
|
|
224
237
|
.filter(({ name }) => !overlapsAny(reported, name.offset, name.surface.length))
|
|
225
238
|
.map(({ name, usual }) => ({ offset: name.offset, name: name.surface, usual, kind: "order" }));
|
|
226
239
|
};
|
|
@@ -270,7 +283,7 @@ const tokenRunsOf = (sentence: Sentence): readonly (readonly Token[])[] => {
|
|
|
270
283
|
const nameMentionsOf = (doc: ProseDocument, prose: string, chars: VariantChars): NameMention[] => {
|
|
271
284
|
const cues: NameCues = { leads: patternsOf(doc, "person-lead"), suffixes: patternsOf(doc, "person-suffix"), particles: patternsOf(doc, "name-particle") };
|
|
272
285
|
const charReadings = charReadingsOf(doc);
|
|
273
|
-
const tagged = doc.sentences.flatMap((sentence) => tokenRunsOf(sentence).flatMap((tokens) => mentionsIn(tokens,
|
|
286
|
+
const tagged = doc.sentences.flatMap((sentence) => tokenRunsOf(sentence).flatMap((tokens) => mentionsIn(tokens, prose, cues.suffixes, charReadings)));
|
|
274
287
|
const taggedOrSuffixed = [...tagged, ...suffixedNamesIn(prose, cues.suffixes, chars, tagged)];
|
|
275
288
|
const cued = [...taggedOrSuffixed, ...cuedNamesIn(prose, cues, chars, taggedOrSuffixed)].map((mention): NameMention => {
|
|
276
289
|
const cue = mention.cue ?? nameCueAt(prose, mention.offset, mention.surface, cues);
|
|
@@ -281,7 +294,7 @@ const nameMentionsOf = (doc: ProseDocument, prose: string, chars: VariantChars):
|
|
|
281
294
|
const outside = joined.filter(
|
|
282
295
|
(mention) => !spaced.some((name) => name.offset < mention.offset + mention.surface.length && mention.offset < name.offset + name.surface.length),
|
|
283
296
|
);
|
|
284
|
-
return withKnownNeighbours([...outside, ...spaced], prose).toSorted((left, right) => left.offset - right.offset);
|
|
297
|
+
return outsideCapitals(prose, withKnownNeighbours([...outside, ...spaced], prose)).toSorted((left, right) => left.offset - right.offset);
|
|
285
298
|
};
|
|
286
299
|
|
|
287
300
|
/** 人の名前で形の似た別の字(太 と 大)は語彙表 name-lookalike-char が組(group)ごとに言う。 */
|
|
@@ -352,10 +365,15 @@ const wordUseOf = (doc: ProseDocument): WordUse => {
|
|
|
352
365
|
export const nameVariant: Detector = (doc): Finding[] => {
|
|
353
366
|
const prose = doc.prose ?? doc.source;
|
|
354
367
|
const chars = variantCharsOf(doc);
|
|
355
|
-
const mentions = labelledNamesOf(doc, ordinaryNamesOf(doc, nameMentionsOf(doc, prose, chars)));
|
|
368
|
+
const mentions = labelledNamesOf(doc, ordinaryNamesOf(doc, withGivenNames(tokensOf(doc), doc.source, nameMentionsOf(doc, prose, chars))));
|
|
369
|
+
const companies = companyMentionsOf(doc, prose);
|
|
370
|
+
const inGroup = isGroupPairOf(
|
|
371
|
+
companies,
|
|
372
|
+
companyFormsOf(doc).map((form) => form.pattern),
|
|
373
|
+
);
|
|
356
374
|
const variants = nameVariants(mentions, chars, spellingInputOf(doc), wordUseOf(doc))
|
|
357
375
|
.map(({ mention, usual, kind }): Reported => ({ offset: mention.offset, name: mention.surface, usual, kind }))
|
|
358
|
-
.filter(notSpacingOnly);
|
|
376
|
+
.filter((found) => notSpacingOnly(found) && !inGroup(found));
|
|
359
377
|
const lookalikes = lookalikeSlipsIn(mentions, lookalikeCharsOf(doc)).map(({ mention, usual }) => ({
|
|
360
378
|
offset: mention.offset,
|
|
361
379
|
name: mention.surface,
|
|
@@ -363,7 +381,7 @@ export const nameVariant: Detector = (doc): Finding[] => {
|
|
|
363
381
|
kind: "lookalike",
|
|
364
382
|
}));
|
|
365
383
|
const names = [...variants, ...lookalikes.filter((found) => !overlapsAny(variants, found.offset, found.name.length))];
|
|
366
|
-
const namesAndCompanies = [...names, ...companyFindings(doc, prose, names)];
|
|
384
|
+
const namesAndCompanies = [...names, ...companyFindings(doc, prose, companies, names)];
|
|
367
385
|
const withTables = [...namesAndCompanies, ...tableFindings(doc, prose, mentions, namesAndCompanies).filter(notSpacingOnly)];
|
|
368
386
|
const withPlaces = [...withTables, ...placeFindings(doc, prose, withTables, chars)];
|
|
369
387
|
const withProducts = [...withPlaces, ...productFindings(doc, prose, withPlaces)];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { entryIn } from "./lexicon-match.ts";
|
|
2
|
+
import type { LexiconEntry, Paragraph, Sentence } from "../plugin.ts";
|
|
3
|
+
|
|
4
|
+
/** 一文だけの断りは本文の書き損じのことがある。段落ごと別の調子で揃えてあるときだけ、意図した別の声と読む。 */
|
|
5
|
+
const MIN_SENTENCES = 2;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 断り書きの段落(「…無償で提供します。…一切の責任を負いません。…ご了承ください。」)の文。
|
|
9
|
+
* 免責や変更の予告は、である調の文書でもですます調で書く決まり文句で、本文と文末の調子を比べるものではない。
|
|
10
|
+
* 断りの語(cues)を含み、調子を持つ文が MIN_SENTENCES 以上あって、それがみな同じ、文書の多いほう(majority)ではない調子の段落だけ。
|
|
11
|
+
* 調子が混ざった段落と、文書と同じ調子の段落は、本文と同じに数える。
|
|
12
|
+
*/
|
|
13
|
+
export const noticeSentences = <R>(
|
|
14
|
+
paragraphs: readonly Paragraph[],
|
|
15
|
+
cues: readonly LexiconEntry[],
|
|
16
|
+
registerOf: (sentence: Sentence) => R | undefined,
|
|
17
|
+
majority: R | undefined,
|
|
18
|
+
): Set<Sentence> =>
|
|
19
|
+
new Set(
|
|
20
|
+
paragraphs.flatMap((paragraph) => {
|
|
21
|
+
const registers = new Set(
|
|
22
|
+
paragraph.sentences.flatMap((sentence) => {
|
|
23
|
+
const register = registerOf(sentence);
|
|
24
|
+
return register === undefined ? [] : [register];
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
27
|
+
const counted = paragraph.sentences.filter((sentence) => registerOf(sentence) !== undefined).length;
|
|
28
|
+
const [only] = registers;
|
|
29
|
+
const ownVoice = counted >= MIN_SENTENCES && registers.size === 1 && only !== majority;
|
|
30
|
+
const notice = ownVoice && paragraph.sentences.some((sentence) => cues.some((cue) => entryIn(sentence, cue)));
|
|
31
|
+
return notice ? paragraph.sentences : [];
|
|
32
|
+
}),
|
|
33
|
+
);
|
|
@@ -51,12 +51,24 @@ const MAGNITUDES = /^[一百千万億]+$/u;
|
|
|
51
51
|
|
|
52
52
|
const isIdiomNumeral = (numeral: string): boolean => MAGNITUDES.test(numeral);
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
/**
|
|
55
|
+
* A number set off by a space from a word that only begins with a counter: 三, a space, 人事委員会 is the item number 三 of a list,
|
|
56
|
+
* not 三人. The tokenizer reads 人事 as one word there and 人 alone in 3 人が来た.
|
|
57
|
+
*/
|
|
58
|
+
const isBeforeLongerWord = (numeral: string, written: string, offset: number, tokens: readonly Token[]): boolean => {
|
|
59
|
+
const counter = written.slice(numeral.length).trimStart();
|
|
60
|
+
if (counter.length === written.length - numeral.length) return false;
|
|
61
|
+
const word = tokens.find((token) => token.span.start === offset + written.length - counter.length);
|
|
62
|
+
return word !== undefined && word.surface.length > counter.length;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const countMarks = (text: string, base: number, words: NumberWords, tokens: readonly Token[]): NumberMark[] => {
|
|
55
66
|
const pattern = countPattern(words);
|
|
56
67
|
if (pattern === undefined) return [];
|
|
57
68
|
return [...text.matchAll(pattern)].flatMap((match): NumberMark[] => {
|
|
58
69
|
const [written, digits, kanji] = match;
|
|
59
70
|
if (kanji !== undefined && isIdiomNumeral(kanji)) return [];
|
|
71
|
+
if (isBeforeLongerWord(digits ?? kanji ?? "", written, base + match.index, tokens)) return [];
|
|
60
72
|
return [{ kind: "count", style: digits === undefined ? "kanji" : "digits", written, offset: base + match.index }];
|
|
61
73
|
});
|
|
62
74
|
};
|
|
@@ -176,7 +188,7 @@ const englishCountMarks = (sentence: Sentence, words: NumberWords): NumberMark[]
|
|
|
176
188
|
export const numberMarksIn = (sentence: Sentence, words: NumberWords, language: string, source: string): NumberMark[] => {
|
|
177
189
|
const base = sentence.span.start;
|
|
178
190
|
const marks = [
|
|
179
|
-
...countMarks(sentence.text, base, words),
|
|
191
|
+
...countMarks(sentence.text, base, words, sentence.tokens ?? []),
|
|
180
192
|
...groupingMarks(sentence.text, base, words, source),
|
|
181
193
|
...percentMarks(sentence.text, base, words),
|
|
182
194
|
...(language === "ja" ? [] : englishCountMarks(sentence, words)),
|
|
@@ -6,6 +6,8 @@ import { readMarkdown } from "../markdown-read.ts";
|
|
|
6
6
|
import { spanOf, type MarkdownNode } from "../markdown-node.ts";
|
|
7
7
|
import { eachPreOrder } from "../tree-walk.ts";
|
|
8
8
|
import { quoteAt } from "./structure-tree.ts";
|
|
9
|
+
import { formsOf } from "./currency-notation.ts";
|
|
10
|
+
import { scaledFiguresIn, scaleGaps, type ScaleWords } from "./scaled-figure-unit.ts";
|
|
9
11
|
|
|
10
12
|
/** One value of a kind: where its number starts, as written, and its unit ("" when bare). */
|
|
11
13
|
export type Measured = { readonly kind: string; readonly name: string; readonly offset: number; readonly written: string; readonly unit: string };
|
|
@@ -157,7 +159,30 @@ const pieceCountOf = (doc: ProseDocument): PieceCount => {
|
|
|
157
159
|
return { columns: patterns("column"), periods: patterns("period") };
|
|
158
160
|
};
|
|
159
161
|
|
|
160
|
-
|
|
162
|
+
const patternsOf = (doc: ProseDocument, name: string): string[] => (doc.lexicons[name] ?? []).map((entry) => entry.pattern);
|
|
163
|
+
|
|
164
|
+
const scaleWordsOf = (doc: ProseDocument): ScaleWords => ({
|
|
165
|
+
scales: patternsOf(doc, "figure-scale-word"),
|
|
166
|
+
forms: formsOf(doc),
|
|
167
|
+
joiners: ["figure-scale-joiner", "range-connector", "enumeration-joiner"].flatMap((name) => patternsOf(doc, name)),
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/** The one number in prose with a word of scale and no unit, where that word otherwise always carries one (83,494百万). */
|
|
171
|
+
const scaleFindings = (doc: ProseDocument): Finding[] => {
|
|
172
|
+
const prose = doc.prose ?? doc.source;
|
|
173
|
+
const words = scaleWordsOf(doc);
|
|
174
|
+
return scaleGaps(prose, scaledFiguresIn(prose, words), words.joiners).map(({ figure, unit }) => ({
|
|
175
|
+
rule: "number-without-unit",
|
|
176
|
+
severity: "warning",
|
|
177
|
+
line: 0,
|
|
178
|
+
column: 0,
|
|
179
|
+
variant: "scale",
|
|
180
|
+
quote: quoteAt(doc.source, figure.offset),
|
|
181
|
+
values: { value: figure.written, name: figure.scale, unit, offset: figure.offset },
|
|
182
|
+
}));
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const columnFindings = (doc: ProseDocument): Finding[] => {
|
|
161
186
|
const count = pieceCountOf(doc);
|
|
162
187
|
return unitGaps(measuredValues(doc.source, doc.prose ?? doc.source, unitsOf(doc)))
|
|
163
188
|
.filter((gap) => !isPieceCount(gap, count))
|
|
@@ -170,3 +195,5 @@ export const numberWithoutUnit: Detector = (doc: ProseDocument): Finding[] => {
|
|
|
170
195
|
values: { value: gap.value.written, name: gap.value.name, unit: gap.unit, offset: gap.value.offset },
|
|
171
196
|
}));
|
|
172
197
|
};
|
|
198
|
+
|
|
199
|
+
export const numberWithoutUnit: Detector = (doc: ProseDocument): Finding[] => [...columnFindings(doc), ...scaleFindings(doc)];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { escapeRegExp } from "../orthography.ts";
|
|
1
2
|
import type { Detector, Finding, Sentence, Span } from "../plugin.ts";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -56,6 +57,31 @@ export const followsSentenceEnd = (source: string, offset: number, labels: Reado
|
|
|
56
57
|
return DIGITS.test(word) || (PLAIN_WORD.test(word) && !labels.has(word.toLowerCase()));
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
const CLAUSE_NUMBER = /^(?<parent>\d{1,3})\.(?<child>\d{1,3})$/u;
|
|
61
|
+
const BLANK = /^[ \t]*$/u;
|
|
62
|
+
|
|
63
|
+
/** Whether offset is the first thing on its line, after spaces only. */
|
|
64
|
+
const startsLine = (source: string, offset: number): boolean => BLANK.test(source.slice(source.lastIndexOf("\n", offset - 1) + 1, offset));
|
|
65
|
+
|
|
66
|
+
/** Whether a line opens with this clause number (2.2) and a space. */
|
|
67
|
+
const opensLine = (source: string, clause: string): boolean => new RegExp(String.raw`(?:^|\n)[ \t]*${escapeRegExp(clause)}[ \t]`, "u").test(source);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A clause number that opens a numbered paragraph (2.1 the term starts on signing.), not a figure: it opens a line, and a
|
|
71
|
+
* clause next to it in the same numbering (2.0 or 2.2) opens a line too. A figure at a line's start (2.5 million units
|
|
72
|
+
* were sold.) has no such neighbour.
|
|
73
|
+
*/
|
|
74
|
+
export const opensNumberedParagraph = (source: string, offset: number, numeral: string): boolean => {
|
|
75
|
+
const clause = CLAUSE_NUMBER.exec(numeral)?.groups;
|
|
76
|
+
if (clause === undefined || !startsLine(source, offset)) return false;
|
|
77
|
+
const child = clause["child"] ?? "";
|
|
78
|
+
// 3.10 sits next to 3.9 or, numbered with a zero, 3.09.
|
|
79
|
+
const neighbours = [Number(child) - 1, Number(child) + 1]
|
|
80
|
+
.filter((neighbour) => neighbour >= 0)
|
|
81
|
+
.flatMap((neighbour) => [String(neighbour), String(neighbour).padStart(child.length, "0")]);
|
|
82
|
+
return neighbours.some((neighbour) => opensLine(source, `${clause["parent"] ?? ""}.${neighbour}`));
|
|
83
|
+
};
|
|
84
|
+
|
|
59
85
|
const inside = (spans: readonly Span[], offset: number): boolean => spans.some((span) => span.start <= offset && offset < span.end);
|
|
60
86
|
|
|
61
87
|
const leadingSpace = (sentence: Sentence): number => sentence.text.length - sentence.text.trimStart().length;
|
|
@@ -66,7 +92,7 @@ export const numeralOpener: Detector = (doc): Finding[] => {
|
|
|
66
92
|
const offset = sentence.span.start + leadingSpace(sentence);
|
|
67
93
|
if (sentence.embeddedLanguage !== undefined || inside(doc.listSpans, offset)) return [];
|
|
68
94
|
const numeral = openingNumeral(sentence.text);
|
|
69
|
-
if (numeral === undefined || !followsSentenceEnd(doc.source, offset, labels)) return [];
|
|
95
|
+
if (numeral === undefined || !followsSentenceEnd(doc.source, offset, labels) || opensNumberedParagraph(doc.source, offset, numeral)) return [];
|
|
70
96
|
return [{ rule: "", severity: "warning", line: 0, column: 0, quote: sentence.text.trim(), values: { numeral, offset } }];
|
|
71
97
|
});
|
|
72
98
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大文字の並びでも略語として書かれないもの。どれも字の形だけで決まる。
|
|
3
|
+
* - I だけのローマ数字(II、III)。名前の後ろでなくても番号で(Doswell, III、1964: II Structure)、この形の略語は使われない。
|
|
4
|
+
* IV や VI のように V・X を含む数字は略語(静脈注射の IV)でもあるので、名前の番号(name-numeral.ts)の位置でだけ外す。
|
|
5
|
+
* - 大文字で始まる語に - で繋いだ I・V・X の数字(Association-IV)。名前の番号を空白でなく - で書いた形。
|
|
6
|
+
* - X を 3 つ以上並べた伏せ字(the Secretary of State for XXX)や X の数で書く染色体の型(XXX症候群)。KKK や WWW のような他の字の繰り返しは略語のまま数える。
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
type Span = { readonly start: number; readonly end: number };
|
|
10
|
+
|
|
11
|
+
// 略語の切り出しと同じ境目。日本語の文字(XXX症候群)は語の続きではない。
|
|
12
|
+
const NOT_BEFORE = String.raw`(?<![A-Za-z0-9_&])`;
|
|
13
|
+
const NOT_AFTER = String.raw`(?![A-Za-z0-9_&])`;
|
|
14
|
+
|
|
15
|
+
const ONES_NUMERAL = new RegExp(`${NOT_BEFORE}I{2,3}${NOT_AFTER}`, "gu");
|
|
16
|
+
const MASK = new RegExp(`${NOT_BEFORE}X{3,}${NOT_AFTER}`, "gu");
|
|
17
|
+
const SMALL_NUMERAL = "(?=[IVX])X{0,3}(?:IX|IV|V?I{0,3})";
|
|
18
|
+
const JOINED_NUMERAL = new RegExp(String.raw`(?<![A-Za-z0-9_-])\p{Lu}\p{Ll}+-(?<numeral>${SMALL_NUMERAL})${NOT_AFTER}`, "gu");
|
|
19
|
+
|
|
20
|
+
const spanOf = (match: RegExpExecArray): Span => ({ start: match.index, end: match.index + match[0].length });
|
|
21
|
+
|
|
22
|
+
const joinedSpans = (text: string): Span[] =>
|
|
23
|
+
[...text.matchAll(JOINED_NUMERAL)].map((match) => {
|
|
24
|
+
const end = match.index + match[0].length;
|
|
25
|
+
return { start: end - (match.groups?.["numeral"] ?? "").length, end };
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/** 文の中の、番号か伏せ字と読む大文字の範囲。 */
|
|
29
|
+
export const numeralWordSpans = (text: string): Span[] => [
|
|
30
|
+
...[...text.matchAll(ONES_NUMERAL)].map(spanOf),
|
|
31
|
+
...[...text.matchAll(MASK)].map(spanOf),
|
|
32
|
+
...joinedSpans(text),
|
|
33
|
+
];
|
|
@@ -6,14 +6,19 @@
|
|
|
6
6
|
// duty-marker (shall, will), duty-ending (う, するものとする: what may follow a Japanese act at the sentence end),
|
|
7
7
|
// stated-deadline (by the, までに) with concrete-deadline and vague-deadline, deadline-permission and currency-notation. Pure.
|
|
8
8
|
import { quoteAt } from "./structure-tree.ts";
|
|
9
|
+
import { actsTimedAt, type NamedDeadline, type Units } from "./deadline-unit.ts";
|
|
10
|
+
import { inDocumentOrder } from "../structure/issues.ts";
|
|
9
11
|
import { escapeRegExp } from "../orthography.ts";
|
|
10
12
|
import { grantsRight, statesConcrete, vagueIn } from "./vague-deadline.ts";
|
|
11
13
|
import type { Detector, Finding, LexiconEntry, ProseDocument } from "../plugin.ts";
|
|
12
14
|
|
|
13
15
|
export type UntimedDuty = { readonly offset: number; readonly act: string };
|
|
14
16
|
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
+
/**
|
|
18
|
+
* sameLine: the sentence goes on the line of the one before it (no line break between them). timedActs: the acts whose
|
|
19
|
+
* dated deadline (支払期日 for 支払) its article, else its list or paragraph, names; a duty to do one of them is timed.
|
|
20
|
+
*/
|
|
21
|
+
type Text = { readonly start: number; readonly text: string; readonly sameLine?: boolean; readonly timedActs?: readonly string[] };
|
|
17
22
|
|
|
18
23
|
/** What the word lists give the decision. */
|
|
19
24
|
export type DutyWords = {
|
|
@@ -155,6 +160,7 @@ export const untimedDuties = (texts: readonly Text[], words: DutyWords): Untimed
|
|
|
155
160
|
if (grantsRight(text, words.permissions) || statesAmount(text.text, words.currencies)) return [];
|
|
156
161
|
const act = actIn(text.text, words);
|
|
157
162
|
if (act === undefined || (LATIN.test(act.act) && !isWordStart(text.text, act.at))) return [];
|
|
163
|
+
if (text.timedActs?.some((timed) => timed.toLowerCase() === act.act.toLowerCase()) === true) return [];
|
|
158
164
|
return [{ offset: text.start + act.at, act: text.text.slice(act.at, act.at + act.act.length) }];
|
|
159
165
|
});
|
|
160
166
|
const limitedSentences = texts.filter((text) => statesLimit(text, words)).length;
|
|
@@ -163,12 +169,30 @@ export const untimedDuties = (texts: readonly Text[], words: DutyWords): Untimed
|
|
|
163
169
|
|
|
164
170
|
const patternsOf = (doc: ProseDocument, lexicon: string): string[] => (doc.lexicons[lexicon] ?? []).map((entry) => entry.pattern);
|
|
165
171
|
|
|
166
|
-
|
|
167
|
-
|
|
172
|
+
const unitsOf = (doc: ProseDocument): Units => ({
|
|
173
|
+
articles: doc.structure === undefined ? [] : inDocumentOrder(doc.structure).flatMap((node) => (node.kind === "article" ? [node.span] : [])),
|
|
174
|
+
lists: doc.lists.map((list) => list.span),
|
|
175
|
+
paragraphs: doc.paragraphs.map((paragraph) => paragraph.span),
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
/** The acts a sentence's unit names a dated deadline for (named-deadline: the name, and the act as its group). */
|
|
179
|
+
const timedActsReader = (doc: ProseDocument): ((offset: number) => string[]) => {
|
|
180
|
+
const deadlines: NamedDeadline[] = (doc.lexicons["named-deadline"] ?? []).flatMap((entry) =>
|
|
181
|
+
entry.group === undefined ? [] : [{ name: entry.pattern, act: entry.group }],
|
|
182
|
+
);
|
|
183
|
+
if (deadlines.length === 0) return () => [];
|
|
184
|
+
const units = unitsOf(doc);
|
|
185
|
+
return (offset) => actsTimedAt(doc.source, units, offset, deadlines, phraseIn);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export const obligationWithoutDeadline: Detector = (doc): Finding[] => {
|
|
189
|
+
const timedActs = timedActsReader(doc);
|
|
190
|
+
return untimedDuties(
|
|
168
191
|
doc.sentences.map((sentence, index) => ({
|
|
169
192
|
start: sentence.span.start,
|
|
170
193
|
text: sentence.text,
|
|
171
194
|
sameLine: index > 0 && !doc.source.slice(doc.sentences[index - 1]?.span.end ?? 0, sentence.span.start).includes("\n"),
|
|
195
|
+
timedActs: timedActs(sentence.span.start),
|
|
172
196
|
})),
|
|
173
197
|
{
|
|
174
198
|
acts: patternsOf(doc, "timed-duty"),
|
|
@@ -190,3 +214,4 @@ export const obligationWithoutDeadline: Detector = (doc): Finding[] =>
|
|
|
190
214
|
quote: quoteAt(doc.source, duty.offset),
|
|
191
215
|
values: { word: duty.act, offset: duty.offset },
|
|
192
216
|
}));
|
|
217
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { LexiconEntry, Token } from "../plugin.ts";
|
|
2
|
+
import type { TokenRange } from "./lexicon-match.ts";
|
|
3
|
+
|
|
4
|
+
// An open-end word on a list of acts that gives examples of a kind of act named right after it: 印刷等、二次的に利用される
|
|
5
|
+
// 場合 and 印刷等の二次的利用 say "secondary use, such as printing". The kind bounds the list, so it leaves nothing open.
|
|
6
|
+
// A list followed by the manner of the act the requirement asks for (ログ等、具体的に保存すること) names no kind and stays
|
|
7
|
+
// open. The link (、 の) and the suffix that makes a word name a kind (的) come from the language's requirement-open-end
|
|
8
|
+
// lexicon. Pure.
|
|
9
|
+
|
|
10
|
+
/** The lexicon groups: a link right after the open word, and a suffix that makes the noun after it name a kind. */
|
|
11
|
+
const LINK = "class-link";
|
|
12
|
+
const CLASS_SUFFIX = "class-suffix";
|
|
13
|
+
const NAME_POS: ReadonlySet<string> = new Set(["NOUN", "PROPN"]);
|
|
14
|
+
/** The tagger's mark of a noun that names an act (印刷, 利用: a verbal noun). */
|
|
15
|
+
const ACT_NOUN = "Vnoun";
|
|
16
|
+
const PUNCT = "PUNCT";
|
|
17
|
+
/** The parts of speech a phrase about the act ends in before its comma (場合、 には、). */
|
|
18
|
+
const PHRASE_END_POS: ReadonlySet<string> = new Set(["NOUN", "PROPN", "ADP"]);
|
|
19
|
+
/** How many tokens may stand between the suffix and the act it qualifies (二次的に利用: に). */
|
|
20
|
+
const SUFFIX_REACH = 2;
|
|
21
|
+
|
|
22
|
+
export type ClassWords = { readonly links: ReadonlySet<string>; readonly suffixes: ReadonlySet<string> };
|
|
23
|
+
|
|
24
|
+
const patternsIn = (entries: readonly LexiconEntry[], group: string): ReadonlySet<string> =>
|
|
25
|
+
new Set(entries.filter((entry) => entry.group === group).map((entry) => entry.pattern));
|
|
26
|
+
|
|
27
|
+
export const classWordsOf = (entries: readonly LexiconEntry[]): ClassWords => ({
|
|
28
|
+
links: patternsIn(entries, LINK),
|
|
29
|
+
suffixes: patternsIn(entries, CLASS_SUFFIX),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/** Whether an entry is one of the class cues rather than an open-end word. */
|
|
33
|
+
export const isClassCue = (entry: LexiconEntry): boolean => entry.group === LINK || entry.group === CLASS_SUFFIX;
|
|
34
|
+
|
|
35
|
+
const isActNoun = (token: Token | undefined): boolean => token !== undefined && token.features?.VerbForm === ACT_NOUN;
|
|
36
|
+
|
|
37
|
+
const attached = (left: Token | undefined, right: Token | undefined): boolean =>
|
|
38
|
+
left !== undefined && right !== undefined && left.span.end === right.span.start;
|
|
39
|
+
|
|
40
|
+
/** The index of the last noun written one after another from index on, or index - 1 when no noun stands there. */
|
|
41
|
+
const nounRunEnd = (tokens: readonly Token[], index: number): number => {
|
|
42
|
+
const token = tokens[index];
|
|
43
|
+
if (token === undefined || !NAME_POS.has(token.pos)) return index - 1;
|
|
44
|
+
return attached(token, tokens[index + 1]) ? nounRunEnd(tokens, index + 1) : index;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Whether the act at index heads a phrase the requirement is about (利用される場合、 二次的利用には、): its clause ends in
|
|
49
|
+
* a noun or a particle before a comma inside the sentence. An act whose clause runs to the end of the sentence, or ends
|
|
50
|
+
* in a verb (保存すること。 保存し、), is what the requirement asks for, and the list before it stays open.
|
|
51
|
+
*/
|
|
52
|
+
const headsPhrase = (tokens: readonly Token[], index: number): boolean => {
|
|
53
|
+
const comma = tokens.findIndex((token, at) => at > index && token.pos === PUNCT);
|
|
54
|
+
const last = tokens[comma - 1];
|
|
55
|
+
const goesOn = tokens.slice(comma + 1).some((token) => token.pos !== PUNCT && token.surface.trim() !== "");
|
|
56
|
+
return comma !== -1 && goesOn && last !== undefined && PHRASE_END_POS.has(last.pos);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Whether the noun run that starts at index holds a class suffix (二次的, 営利的) and an act that heads a phrase follows within reach. */
|
|
60
|
+
const kindOfActAt = (tokens: readonly Token[], index: number, words: ClassWords): boolean => {
|
|
61
|
+
const end = nounRunEnd(tokens, index);
|
|
62
|
+
const suffix = tokens.slice(index + 1, end + 1).findIndex((token) => words.suffixes.has(token.surface));
|
|
63
|
+
if (suffix === -1) return false;
|
|
64
|
+
const afterSuffix = index + 1 + suffix + 1;
|
|
65
|
+
const act = tokens.slice(afterSuffix, afterSuffix + SUFFIX_REACH).findIndex((token) => isActNoun(token));
|
|
66
|
+
return act !== -1 && headsPhrase(tokens, afterSuffix + act);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether the open word ends a list of acts that gives examples of a kind of act named right after it: the item before
|
|
71
|
+
* the word is an act (印刷), a link follows (、 の), then a noun built with a class suffix (二次的) and an act (利用).
|
|
72
|
+
* range: the tokens the open word covers.
|
|
73
|
+
*/
|
|
74
|
+
export const namesClassAfter = (tokens: readonly Token[], range: TokenRange, words: ClassWords): boolean => {
|
|
75
|
+
const link = tokens[range.end];
|
|
76
|
+
if (!isActNoun(tokens[range.start - 1]) || link === undefined || !words.links.has(link.surface)) return false;
|
|
77
|
+
return kindOfActAt(tokens, range.end + 1, words);
|
|
78
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Sentence } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
// An open list inside brackets that gloss a condition (必要ない場合(単一テーブルへの SELECT 等)も付与すること): the list
|
|
4
|
+
// gives examples of when the duty applies, not what the duty covers, so leaving it open is no smell. The condition words
|
|
5
|
+
// come from the language's requirement-open-condition lexicon. Pure.
|
|
6
|
+
|
|
7
|
+
/** Each closing bracket and the opening bracket it closes. */
|
|
8
|
+
const PAIRS: ReadonlyMap<string, string> = new Map([
|
|
9
|
+
[")", "("],
|
|
10
|
+
[")", "("],
|
|
11
|
+
]);
|
|
12
|
+
const OPENING: ReadonlySet<string> = new Set(PAIRS.values());
|
|
13
|
+
|
|
14
|
+
type Open = { readonly char: string; readonly index: number };
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The brackets still open before `end` of `text`, outermost first. A closing bracket closes only its own kind, so a
|
|
18
|
+
* stray half-width ")" leaves a full-width "(" open. One pass, no recursion: a statute's sentence is long.
|
|
19
|
+
*/
|
|
20
|
+
const openBracketsBefore = (text: string, end: number): Open[] => {
|
|
21
|
+
const open: Open[] = [];
|
|
22
|
+
text
|
|
23
|
+
.slice(0, Math.max(0, end))
|
|
24
|
+
.split("")
|
|
25
|
+
.forEach((char, index) => {
|
|
26
|
+
if (OPENING.has(char)) open.push({ char, index });
|
|
27
|
+
else if (PAIRS.has(char) && open.at(-1)?.char === PAIRS.get(char)) open.pop();
|
|
28
|
+
});
|
|
29
|
+
return open;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Whether the open word starting at document offset `start` stands inside brackets, at any depth, that open right after
|
|
34
|
+
* a condition word (場合(…等), とき(…など), 場合(A(B 等))).
|
|
35
|
+
*/
|
|
36
|
+
export const glossesCondition = (sentence: Sentence, start: number, conditions: readonly string[]): boolean =>
|
|
37
|
+
openBracketsBefore(sentence.text, start - sentence.span.start).some((bracket) => {
|
|
38
|
+
const before = sentence.text.slice(0, bracket.index).trimEnd();
|
|
39
|
+
return conditions.some((word) => word !== "" && before.endsWith(word));
|
|
40
|
+
});
|
|
@@ -135,6 +135,12 @@ const isNamed = (source: string, occurrence: Occurrence, names: OpenEndNames): b
|
|
|
135
135
|
inQuotedName(source, occurrence, names.quoted) ||
|
|
136
136
|
partsHoldingWord(source, occurrence).some((part) => names.defined.has(part) || names.heads.some((head) => head.startsWith(part)));
|
|
137
137
|
|
|
138
|
-
/**
|
|
139
|
-
export
|
|
140
|
-
|
|
138
|
+
/** Whether the words around an occurrence bound its list; range: the tokens the word covers. */
|
|
139
|
+
export type BoundedAfter = (tokens: readonly Token[], range: TokenRange) => boolean;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Where the word first stands outside a name the document gives and is not bounded by the words after it (its document
|
|
143
|
+
* offset), or undefined when it never does.
|
|
144
|
+
*/
|
|
145
|
+
export const openEndAt = (doc: ProseDocument, sentence: Sentence, word: LexiconEntry, names: OpenEndNames, boundedAfter: BoundedAfter): number | undefined =>
|
|
146
|
+
occurrencesIn(sentence, word).find((occurrence) => !isNamed(doc.source, occurrence, names) && !boundedAfter(occurrence.tokens, occurrence.range))?.start;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { LexiconEntry, Sentence } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
// An open list right before a question that asks the reader to choose (…措置など、どのような措置を求めるのかを記載する):
|
|
4
|
+
// the list gives example answers, and leaving it open is the point. The question's words come from the language's
|
|
5
|
+
// requirement-open-question lexicon. Pure.
|
|
6
|
+
|
|
7
|
+
const INTERROGATIVE = "interrogative";
|
|
8
|
+
const QUESTION_END = "question-end";
|
|
9
|
+
/** Words that start like an interrogative and ask how instead (どのように), which offers no list of answers. */
|
|
10
|
+
const NOT_INTERROGATIVE = "not-interrogative";
|
|
11
|
+
/** A particle that turns the interrogative into "any" (どの部署でも, 何をも): no question follows. */
|
|
12
|
+
const UNIVERSAL_MARK = "universal-mark";
|
|
13
|
+
/** The marks that may stand between the list's last word and the question (、). */
|
|
14
|
+
const LINK = /^[\s、,,]*/u;
|
|
15
|
+
const PARTICLE = "PART";
|
|
16
|
+
|
|
17
|
+
export type QuestionWords = {
|
|
18
|
+
readonly interrogatives: readonly string[];
|
|
19
|
+
readonly notInterrogatives: readonly string[];
|
|
20
|
+
readonly ends: ReadonlySet<string>;
|
|
21
|
+
readonly universalMarks: ReadonlySet<string>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const patternsIn = (entries: readonly LexiconEntry[], group: string): string[] =>
|
|
25
|
+
entries.filter((entry) => entry.group === group && entry.pattern !== "").map((entry) => entry.pattern);
|
|
26
|
+
|
|
27
|
+
export const questionWordsOf = (entries: readonly LexiconEntry[]): QuestionWords => ({
|
|
28
|
+
interrogatives: patternsIn(entries, INTERROGATIVE),
|
|
29
|
+
notInterrogatives: patternsIn(entries, NOT_INTERROGATIVE),
|
|
30
|
+
ends: new Set(patternsIn(entries, QUESTION_END)),
|
|
31
|
+
universalMarks: new Set(patternsIn(entries, UNIVERSAL_MARK)),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Whether a question starts right after the open word that ends at document offset end, and closes later in the
|
|
36
|
+
* sentence with a question particle, before any particle that makes the interrogative mean "any" (どの部署でも): the list
|
|
37
|
+
* before the word gives examples of what the question asks for.
|
|
38
|
+
*/
|
|
39
|
+
export const asksAfter = (sentence: Sentence, end: number, words: QuestionWords): boolean => {
|
|
40
|
+
const rest = sentence.text.slice(end - sentence.span.start);
|
|
41
|
+
const link = LINK.exec(rest)?.[0].length ?? 0;
|
|
42
|
+
const question = rest.slice(link);
|
|
43
|
+
const startsWithAny = (patterns: readonly string[]): boolean => patterns.some((word) => question.startsWith(word));
|
|
44
|
+
const asks = startsWithAny(words.interrogatives) && !startsWithAny(words.notInterrogatives);
|
|
45
|
+
const questionStart = end + link;
|
|
46
|
+
const after = (sentence.tokens ?? []).filter((token) => token.span.start >= questionStart);
|
|
47
|
+
const close = after.findIndex((token) => token.pos === PARTICLE && words.ends.has(token.surface));
|
|
48
|
+
const universal = after.slice(0, close).some((token) => words.universalMarks.has(token.surface));
|
|
49
|
+
return asks && close !== -1 && !universal;
|
|
50
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { LexiconEntry, Token } from "../plugin.ts";
|
|
2
|
+
import { entryEndsAt, type TokenRange } from "./lexicon-match.ts";
|
|
3
|
+
|
|
4
|
+
// An open-end word in a requirement is a smell only when its list is part of what the reader is asked to do (ログ等を保存
|
|
5
|
+
// すること): the reader cannot tell when the duty is met. A list in the condition the duty depends on (訂正等を行った際に、
|
|
6
|
+
// 通知する), in a right the writer grants (投稿データ等を消去できるものとします), or in what is forbidden or excluded
|
|
7
|
+
// (複製、転載等をしてはならない, 事情などにより責任を負わないものとします) is left open on purpose, and is the usual way a
|
|
8
|
+
// contract is drafted. The words that tell the four apart come from the language's requirement-open-end lexicon, in the
|
|
9
|
+
// groups below. Pure.
|
|
10
|
+
|
|
11
|
+
/** The lexicon groups, in the order a tie at one token is decided: a duty word wins over the words that open a list on purpose. */
|
|
12
|
+
const DUTY = "scope-duty";
|
|
13
|
+
const ON_PURPOSE = ["scope-permission", "scope-prohibition"] as const;
|
|
14
|
+
const CONDITION = "scope-condition";
|
|
15
|
+
const SCOPE_GROUPS: ReadonlySet<string> = new Set([DUTY, CONDITION, ...ON_PURPOSE]);
|
|
16
|
+
|
|
17
|
+
/** The parts of speech that end a clause with its own predicate before a comma (消去し、 行い、). */
|
|
18
|
+
const PREDICATE_POS: ReadonlySet<string> = new Set(["VERB", "AUX", "ADJ"]);
|
|
19
|
+
const PUNCT = "PUNCT";
|
|
20
|
+
|
|
21
|
+
export type ScopeWords = { readonly duty: readonly LexiconEntry[]; readonly onPurpose: readonly LexiconEntry[]; readonly condition: readonly LexiconEntry[] };
|
|
22
|
+
|
|
23
|
+
const inGroup = (entries: readonly LexiconEntry[], groups: readonly string[]): LexiconEntry[] => entries.filter((entry) => groups.includes(entry.group ?? ""));
|
|
24
|
+
|
|
25
|
+
export const scopeWordsOf = (entries: readonly LexiconEntry[]): ScopeWords => ({
|
|
26
|
+
duty: inGroup(entries, [DUTY]),
|
|
27
|
+
onPurpose: inGroup(entries, ON_PURPOSE),
|
|
28
|
+
condition: inGroup(entries, [CONDITION]),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/** Whether an entry is one of the scope cues rather than an open-end word. */
|
|
32
|
+
export const isScopeCue = (entry: LexiconEntry): boolean => SCOPE_GROUPS.has(entry.group ?? "");
|
|
33
|
+
|
|
34
|
+
const startsAt = (tokens: readonly Token[], entries: readonly LexiconEntry[], index: number): boolean =>
|
|
35
|
+
entries.some((entry) => entryEndsAt(tokens, entry, index + (entry.tokens?.length ?? 0)));
|
|
36
|
+
|
|
37
|
+
/** A comma right after a predicate closes the clause the list stands in (消去し、). */
|
|
38
|
+
const closesClause = (tokens: readonly Token[], index: number): boolean => tokens[index]?.pos === PUNCT && PREDICATE_POS.has(tokens[index - 1]?.pos ?? "");
|
|
39
|
+
|
|
40
|
+
/** A condition word that closes a clause about an act (行った際, 判断される場合): it follows a predicate. */
|
|
41
|
+
const conditionAt = (tokens: readonly Token[], index: number, words: ScopeWords): boolean =>
|
|
42
|
+
PREDICATE_POS.has(tokens[index - 1]?.pos ?? "") && startsAt(tokens, words.condition, index);
|
|
43
|
+
|
|
44
|
+
type Scope = "duty" | "on-purpose" | undefined;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* What the list belongs to: the first duty, permission or prohibition word after it, or a condition word before the
|
|
48
|
+
* clause the list stands in closes. undefined when none follows (the sentence's own ending decides: こと。).
|
|
49
|
+
*/
|
|
50
|
+
const scopeFrom = (tokens: readonly Token[], index: number, words: ScopeWords, inClause: boolean): Scope => {
|
|
51
|
+
if (index >= tokens.length) return undefined;
|
|
52
|
+
if (startsAt(tokens, words.duty, index)) return "duty";
|
|
53
|
+
if (startsAt(tokens, words.onPurpose, index) || (inClause && conditionAt(tokens, index, words))) return "on-purpose";
|
|
54
|
+
return scopeFrom(tokens, index + 1, words, inClause && !closesClause(tokens, index));
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether the open word at range ends a list that is open on purpose: a condition, a permission or a prohibition holds
|
|
59
|
+
* it, not the duty the requirement states. range: the tokens the open word covers.
|
|
60
|
+
*/
|
|
61
|
+
export const openOnPurpose = (tokens: readonly Token[], range: TokenRange, words: ScopeWords): boolean =>
|
|
62
|
+
scopeFrom(tokens, range.end, words, true) === "on-purpose";
|