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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { StructureNode } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
// 箇条書きで書いた項。規程は条の下の項を「1. 」「2.」の箇条書きで書くことがあり、木はそれを項として読まない。
|
|
4
|
+
|
|
5
|
+
/** 行頭の箇条書きの番号(「1. 」「2.」)。前の空白(全角も)を飛ばし、全角の数字と点も読む。 */
|
|
6
|
+
const LIST_MARK = /^[ \t\u3000]*(?<n>[0-90-9]{1,3})[..]/u;
|
|
7
|
+
|
|
8
|
+
/** 本文の行頭に箇条書きで書かれた番号。全角は半角の数にする(「2.」は 2)。Pure. */
|
|
9
|
+
export const listedNumbers = (body: string): ReadonlySet<number> =>
|
|
10
|
+
new Set(
|
|
11
|
+
body.split("\n").flatMap((line) => {
|
|
12
|
+
const written = LIST_MARK.exec(line)?.groups?.["n"];
|
|
13
|
+
return written === undefined ? [] : [Number(written.normalize("NFKC"))];
|
|
14
|
+
}),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
/** 「3.3」を条の番地「3」と項の番号 3 に分ける。項の先まで指す(3.3.1)か、項が数でなければ undefined。Pure. */
|
|
18
|
+
export const articleParagraph = (target: string): { readonly article: string; readonly paragraph: number } | undefined => {
|
|
19
|
+
const parts = target.split(".");
|
|
20
|
+
const [article, paragraph] = parts;
|
|
21
|
+
if (parts.length !== 2 || article === undefined || paragraph === undefined || !/^\d{1,3}$/u.test(paragraph)) return undefined;
|
|
22
|
+
return { article, paragraph: Number(paragraph) };
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 木が項を一つも読まなかった条ごとの、箇条書きの番号。条の本文は一度だけ読む。同じ番地の条が二つあれば、どちらかに書いてあればよい。
|
|
27
|
+
* nodes は木を平らにしたもの。Pure.
|
|
28
|
+
*/
|
|
29
|
+
export const listedParagraphsByArticle = (nodes: readonly StructureNode[], source: string): ReadonlyMap<string, ReadonlySet<number>> => {
|
|
30
|
+
const byArticle = new Map<string, Set<number>>();
|
|
31
|
+
nodes
|
|
32
|
+
.filter((node) => node.kind === "article" && !node.children.some((child) => child.kind === "item"))
|
|
33
|
+
.forEach((article) => {
|
|
34
|
+
const numbers = byArticle.get(article.address) ?? new Set<number>();
|
|
35
|
+
listedNumbers(source.slice(article.span.start, article.span.end)).forEach((number) => numbers.add(number));
|
|
36
|
+
byArticle.set(article.address, numbers);
|
|
37
|
+
});
|
|
38
|
+
return byArticle;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** 参照(第3条第3項)の項を、その条の箇条書きが書いているか。Pure. */
|
|
42
|
+
export const isListedParagraph = (target: string, listed: ReadonlyMap<string, ReadonlySet<number>>): boolean => {
|
|
43
|
+
const wanted = articleParagraph(target);
|
|
44
|
+
return wanted !== undefined && listed.get(wanted.article)?.has(wanted.paragraph) === true;
|
|
45
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { isMarkedNegation, negatedWords } from "./negated-act.ts";
|
|
1
2
|
import type { Sentence, Span, Token } from "../plugin.ts";
|
|
3
|
+
import { itemMarkerSpan } from "./list-lead-in.ts";
|
|
2
4
|
|
|
3
5
|
// 同じ主語と行為に、逆の様相(しなければならない と してはならない、may と must not)を書いた二つの文。
|
|
4
6
|
// 主語と行為は、文の中身の語(名詞・固有名詞・動詞・形容詞)の集まりで近似する。様相の語そのものは数えない。
|
|
@@ -24,13 +26,21 @@ const OPPOSITE: Readonly<Record<string, readonly string[]>> = {
|
|
|
24
26
|
|
|
25
27
|
const overlaps = (token: Token, spans: readonly Span[]): boolean => spans.some((span) => token.span.start < span.end && span.start < token.span.end);
|
|
26
28
|
|
|
27
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* 文の中身の語を、原形の小文字で、重ねずに並べたもの。様相の語の範囲にかかる語は外す。
|
|
31
|
+
* 打ち消しの印の付いた機能語(negationsMarked)は、近くの中身の語に印を付ける(negatedWords)。様相の語の中の打ち消し(must not)は数えない。
|
|
32
|
+
*/
|
|
28
33
|
export const contentKey = (tokens: readonly Token[], markers: readonly Span[]): string =>
|
|
29
34
|
[
|
|
30
35
|
...new Set(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
negatedWords(
|
|
37
|
+
tokens
|
|
38
|
+
.filter((token) => (CONTENT.has(token.pos) || isMarkedNegation(token)) && !overlaps(token, markers))
|
|
39
|
+
.map((token) => ({
|
|
40
|
+
word: (token.lemma !== undefined && token.lemma !== "" ? token.lemma : token.surface).toLowerCase(),
|
|
41
|
+
negation: !CONTENT.has(token.pos),
|
|
42
|
+
})),
|
|
43
|
+
),
|
|
34
44
|
),
|
|
35
45
|
]
|
|
36
46
|
.toSorted((left, right) => left.localeCompare(right, "en"))
|
|
@@ -51,11 +61,21 @@ const sentenceAt = (sentences: readonly Sentence[], offset: number): Sentence |
|
|
|
51
61
|
return undefined;
|
|
52
62
|
};
|
|
53
63
|
|
|
64
|
+
/** 中身の語の集まりを足し合わせたもの。並べ方は contentKey と同じ。 */
|
|
65
|
+
const joinedKey = (keys: readonly string[]): string =>
|
|
66
|
+
[...new Set(keys.flatMap((key) => (key === "" ? [] : key.split(" "))))].toSorted((left, right) => left.localeCompare(right, "en")).join(" ");
|
|
67
|
+
|
|
54
68
|
/**
|
|
55
69
|
* 様相の語を一つだけ持つ文の、様相と中身。二つ以上持つ文(shall do A and shall not do B)は、どの語がどの行為にかかるかが
|
|
56
70
|
* 中身の語の集まりからは分からないので外す。品詞の無い文も外す。
|
|
71
|
+
* leadIns は箇条書きの項目の文の導入の文(listLeadIns)。項目の中身には導入の中身の語を足す。導入の条件("If … is made—")は
|
|
72
|
+
* 項目の行為の条件なので、違う導入の下の項目どうしは、同じ行為を決めていない。
|
|
57
73
|
*/
|
|
58
|
-
export const modalStatements = (
|
|
74
|
+
export const modalStatements = (
|
|
75
|
+
obligations: readonly Obligation[],
|
|
76
|
+
sentences: readonly Sentence[],
|
|
77
|
+
leadIns: ReadonlyMap<Sentence, readonly Sentence[]> = new Map(),
|
|
78
|
+
): ModalStatement[] => {
|
|
59
79
|
const bySentence = new Map<Sentence, Obligation[]>();
|
|
60
80
|
obligations.forEach((obligation) => {
|
|
61
81
|
const sentence = sentenceAt(sentences, obligation.start);
|
|
@@ -64,11 +84,26 @@ export const modalStatements = (obligations: readonly Obligation[], sentences: r
|
|
|
64
84
|
if (found === undefined) bySentence.set(sentence, [obligation]);
|
|
65
85
|
else found.push(obligation);
|
|
66
86
|
});
|
|
87
|
+
/** 様相の語と項目の印を除いた中身。 */
|
|
88
|
+
const keyOf = (sentence: Sentence, tokens: readonly Token[], markers: readonly Span[]): string => {
|
|
89
|
+
const item = itemMarkerSpan(sentence);
|
|
90
|
+
return contentKey(tokens, item === undefined ? markers : [...markers, item]);
|
|
91
|
+
};
|
|
92
|
+
const leadInKeys = new Map<Sentence, string>();
|
|
93
|
+
const leadInKey = (sentence: Sentence): string => {
|
|
94
|
+
const known = leadInKeys.get(sentence);
|
|
95
|
+
if (known !== undefined) return known;
|
|
96
|
+
const key = sentence.tokens === undefined ? "" : keyOf(sentence, sentence.tokens, bySentence.get(sentence) ?? []);
|
|
97
|
+
leadInKeys.set(sentence, key);
|
|
98
|
+
return key;
|
|
99
|
+
};
|
|
67
100
|
return [...bySentence].flatMap(([sentence, found]) => {
|
|
68
101
|
const [only] = found;
|
|
69
102
|
if (found.length !== 1 || only === undefined || sentence.tokens === undefined) return [];
|
|
70
|
-
const
|
|
71
|
-
|
|
103
|
+
const own = keyOf(sentence, sentence.tokens, [only]);
|
|
104
|
+
if (own.split(" ").length < MIN_CONTENT_WORDS) return [];
|
|
105
|
+
const key = joinedKey([own, ...(leadIns.get(sentence) ?? []).map(leadInKey)]);
|
|
106
|
+
return [{ offset: sentence.span.start, type: only.type, marker: only.marker, key }];
|
|
72
107
|
});
|
|
73
108
|
};
|
|
74
109
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Lexicon, Sentence, Token } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
// 行為や条件の中の打ち消し("goods that do not conform"、「承認しなかった場合」)。打ち消しの語は中身の語ではないが、
|
|
4
|
+
// 打ち消しだけが違う二つの文は、違うことを決めている。
|
|
5
|
+
|
|
6
|
+
/** 打ち消しの語に付ける印(Token.features の名前)。 */
|
|
7
|
+
const NEGATION_FEATURE = "negation";
|
|
8
|
+
|
|
9
|
+
/** 打ち消しを受けた語の印。語の後ろに付ける。 */
|
|
10
|
+
export const NEGATED = "¬";
|
|
11
|
+
|
|
12
|
+
/** 語彙表の打ち消しの語(group の無いもの。接頭の「不」「未」は語の一部なので見ない)。英語は小文字で照らす。 */
|
|
13
|
+
export const negationWords = (lexicon: Lexicon | undefined): ReadonlySet<string> =>
|
|
14
|
+
new Set((lexicon ?? []).filter((entry) => entry.group === undefined).map((entry) => entry.pattern.toLowerCase()));
|
|
15
|
+
|
|
16
|
+
const isNegation = (token: Token, words: ReadonlySet<string>): boolean =>
|
|
17
|
+
words.has(token.surface.toLowerCase()) || (token.lemma !== undefined && words.has(token.lemma.toLowerCase()));
|
|
18
|
+
|
|
19
|
+
export const isMarkedNegation = (token: Token): boolean => token.features?.[NEGATION_FEATURE] !== undefined;
|
|
20
|
+
|
|
21
|
+
/** 打ち消しの語に印を付けた文。品詞の無い文はそのまま。 */
|
|
22
|
+
export const negationsMarked = (sentences: readonly Sentence[], words: ReadonlySet<string>): Sentence[] =>
|
|
23
|
+
sentences.map((sentence) =>
|
|
24
|
+
sentence.tokens === undefined
|
|
25
|
+
? sentence
|
|
26
|
+
: {
|
|
27
|
+
...sentence,
|
|
28
|
+
tokens: sentence.tokens.map((token) => (isNegation(token, words) ? { ...token, features: { ...token.features, [NEGATION_FEATURE]: "yes" } } : token)),
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
type Placed = { readonly out: readonly string[]; readonly pending: boolean };
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 語の並びの打ち消しを、すぐ前の語(文頭なら次の語)に NEGATED として付けたもの。どの語にかかるかは読まない。
|
|
36
|
+
* 打ち消しのある文と無い文を分けるための印で、二つ重なっても一つにする。
|
|
37
|
+
*/
|
|
38
|
+
export const negatedWords = (words: readonly { readonly word: string; readonly negation: boolean }[]): string[] =>
|
|
39
|
+
words
|
|
40
|
+
.reduce<Placed>(
|
|
41
|
+
({ out, pending }, { word, negation }) => {
|
|
42
|
+
if (!negation) return { out: [...out, pending ? `${word}${NEGATED}` : word], pending: false };
|
|
43
|
+
const last = out.at(-1);
|
|
44
|
+
if (last === undefined) return { out, pending: true };
|
|
45
|
+
return { out: last.endsWith(NEGATED) ? out : [...out.slice(0, -1), `${last}${NEGATED}`], pending: false };
|
|
46
|
+
},
|
|
47
|
+
{ out: [], pending: false },
|
|
48
|
+
)
|
|
49
|
+
.out.slice();
|
|
@@ -1,43 +1,80 @@
|
|
|
1
|
-
import type { StructureNode } from "../plugin.ts";
|
|
1
|
+
import type { Span, StructureNode } from "../plugin.ts";
|
|
2
2
|
import { inDocumentOrder, type StructureIssue } from "./issues.ts";
|
|
3
3
|
import { numbersQuotedInside } from "./quoted-number.ts";
|
|
4
4
|
import { isVersionHistory } from "./version-order.ts";
|
|
5
|
+
import { withRepeatsNamed } from "./repeated-number.ts";
|
|
5
6
|
|
|
6
7
|
const labelOf = (node: StructureNode): string => String(node.attrs["label"] ?? node.address);
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
/** sideSteps は、この番号の直前にある番号の無い手順(GOV.UK の「and」)の数。それぞれが番号を一つ使っていてよい。 */
|
|
10
|
+
type Ordered = { readonly node: StructureNode; readonly ordinal: number; readonly last: number; readonly sideSteps: number };
|
|
11
|
+
|
|
12
|
+
const OPENING_BRACKET = /^[([{〔【〈《]/u;
|
|
13
|
+
|
|
14
|
+
/** 括弧で囲んだ番号((1)、(a))か。全角と半角は同じに見る。 */
|
|
15
|
+
const isBracketed = (label: string): boolean => OPENING_BRACKET.test(label.normalize("NFKC"));
|
|
9
16
|
|
|
10
17
|
/**
|
|
11
|
-
*
|
|
18
|
+
* 同じ親の子のうち、番号の付いたものを種類と深さと書き方ごとに分ける。条と項は別の並び、項と号も別の並び。
|
|
12
19
|
* 法令の第 1 項は番号が無いので、その号(一、二)と第 2 項(2)は同じ条の直下に並ぶ。深さで分けないと「二の次が2」に見える。
|
|
20
|
+
* 社内規程は号の(1)(2)と第 2 項の「2」を同じ深さに読むことがあるので、括弧で囲んだ番号は囲まない番号と別の並びにする。
|
|
13
21
|
*/
|
|
14
|
-
const sequencesOf = (parent: StructureNode, quoting: ReadonlySet<StructureNode
|
|
22
|
+
const sequencesOf = (parent: StructureNode, quoting: ReadonlySet<StructureNode>, isSideStep: (node: StructureNode) => boolean): Ordered[][] => {
|
|
15
23
|
const groups = new Map<string, Ordered[]>();
|
|
24
|
+
let sideSteps = 0;
|
|
16
25
|
parent.children.forEach((node) => {
|
|
17
|
-
if (node.ordinal === undefined
|
|
18
|
-
|
|
26
|
+
if (node.ordinal === undefined) {
|
|
27
|
+
if (isSideStep(node)) sideSteps += 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (quoting.has(node)) return;
|
|
31
|
+
const key = `${node.kind}/${String(node.level ?? "")}/${isBracketed(labelOf(node)) ? "bracketed" : "bare"}`;
|
|
19
32
|
// 配列を作り直さずに足す。条が何千もある法令で二乗にしない。
|
|
20
33
|
const group = groups.get(key) ?? [];
|
|
21
|
-
group.push({ node, ordinal: node.ordinal, last: node.ordinalTo ?? node.ordinal });
|
|
34
|
+
group.push({ node, ordinal: node.ordinal, last: node.ordinalTo ?? node.ordinal, sideSteps });
|
|
22
35
|
groups.set(key, group);
|
|
36
|
+
sideSteps = 0;
|
|
23
37
|
});
|
|
24
38
|
return [...groups.values()];
|
|
25
39
|
};
|
|
26
40
|
|
|
27
|
-
/**
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
/** start が after より後ろの最初の範囲。unread は始まりの順に並ぶ。 */
|
|
42
|
+
const firstStartingAfter = (unread: readonly Span[], after: number): number => {
|
|
43
|
+
let low = 0;
|
|
44
|
+
let high = unread.length;
|
|
45
|
+
while (low < high) {
|
|
46
|
+
const middle = Math.floor((low + high) / 2);
|
|
47
|
+
if ((unread[middle]?.start ?? Infinity) > after) high = middle;
|
|
48
|
+
else low = middle + 1;
|
|
49
|
+
}
|
|
50
|
+
return low;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** 二つの番号のあいだに、読めなかった範囲が始まるか。 */
|
|
54
|
+
const unreadBetween = (unread: readonly Span[], previous: Ordered, current: Ordered): boolean =>
|
|
55
|
+
(unread[firstStartingAfter(unread, previous.node.span.start)]?.start ?? Infinity) < current.node.span.start;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 隣り合う二つの番号が、1 つ進んでいなければ指摘する。同じ番号なら重なり、飛べば抜け。
|
|
59
|
+
* あいだに読めなかった範囲(unread)があれば、抜けた番号はそこにあるかもしれないので言わない。重なりは言う。
|
|
60
|
+
*/
|
|
61
|
+
const breaksIn =
|
|
62
|
+
(unread: readonly Span[]) =>
|
|
63
|
+
(sequence: readonly Ordered[]): StructureIssue[] =>
|
|
64
|
+
sequence.flatMap((current, index) => {
|
|
65
|
+
const previous = sequence[index - 1];
|
|
66
|
+
// 1 に戻ったら新しい並び。一つの条に (a)(b) の箇条書きが二つある、附則が第1条から振り直す、のどちらも誤りではない。
|
|
67
|
+
// 範囲をまとめた行(第四十三条から第五十五条まで)の次は、範囲の最後から数える。
|
|
68
|
+
if (previous === undefined || current.ordinal === previous.last + 1 || current.ordinal === 1) return [];
|
|
69
|
+
if (current.ordinal > previous.last + 1 && unreadBetween(unread, previous, current)) return [];
|
|
70
|
+
if (current.ordinal > previous.last + 1 && current.ordinal <= previous.last + 1 + current.sideSteps) return [];
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
offset: current.node.span.start,
|
|
74
|
+
values: { previous: labelOf(previous.node), label: labelOf(current.node), expected: previous.last + 1, found: current.ordinal },
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
});
|
|
41
78
|
|
|
42
79
|
/**
|
|
43
80
|
* 番号の抜けと重なり。比べるのは同じ親の子どうしだけ。英米の法令は章ごとに Section 101、201 と百の位を変えるので、
|
|
@@ -45,12 +82,19 @@ const breaksIn = (sequence: readonly Ordered[]): StructureIssue[] =>
|
|
|
45
82
|
* 1 に戻った番号は新しい並びの始まりとして扱うので、「(a) の後の (a)」の重なりは見逃す。
|
|
46
83
|
* 同じ番号の節を中に持つ節(ほかの文書の条を引いた手本の見出し)は、並びに入れない。
|
|
47
84
|
* 変更履歴の版の見出し(## 3.1.0)は番号の並びではない。版の順番は version-order が見る。
|
|
85
|
+
* 同じ番号が二度続いて次が飛ぶ(4.1、4.1、4.3)ものは、重なりと抜けに分けず、二つ目で一度だけ言う(repeated-number.ts)。
|
|
86
|
+
* unread は、読み手には見えるが木に入らない範囲(Markdown の HTML ブロックの中の文字)を、始まりの順に並べたもの。
|
|
87
|
+
* isSideStep は、番号の代わりに「and」と書いた手順(前の手順と並べて行う)。その数だけ、次の番号は飛んでよい。
|
|
48
88
|
*/
|
|
49
|
-
export const numberingBreaks = (
|
|
89
|
+
export const numberingBreaks = (
|
|
90
|
+
tree: StructureNode,
|
|
91
|
+
unread: readonly Span[] = [],
|
|
92
|
+
isSideStep: (node: StructureNode) => boolean = () => false,
|
|
93
|
+
): StructureIssue[] => {
|
|
50
94
|
const quoting = numbersQuotedInside(tree);
|
|
51
|
-
|
|
52
|
-
.flatMap((parent) => sequencesOf(parent, quoting))
|
|
95
|
+
const breaks = inDocumentOrder(tree)
|
|
96
|
+
.flatMap((parent) => sequencesOf(parent, quoting, isSideStep))
|
|
53
97
|
.filter((sequence) => !isVersionHistory(sequence.map((ordered) => labelOf(ordered.node))))
|
|
54
|
-
.flatMap(breaksIn)
|
|
55
|
-
|
|
98
|
+
.flatMap(breaksIn(unread));
|
|
99
|
+
return withRepeatsNamed(tree, quoting, breaks, unread);
|
|
56
100
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StructureIssue } from "./issues.ts";
|
|
2
|
+
import { coarsestStep, roundingAllowance } from "./rounded-amount.ts";
|
|
2
3
|
import { shownTotal, type Amount } from "./total.ts";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -22,6 +23,10 @@ export type TotalWords = {
|
|
|
22
23
|
readonly leads: readonly string[];
|
|
23
24
|
/** 合計と内訳のあいだにあれば、後ろの金額は合計の内訳のすべてとは限らないと読む語(including、うち、or)。 */
|
|
24
25
|
readonly partials: readonly string[];
|
|
26
|
+
/** partials のうち、並べた金額が主なものだけだと言う語(主な、mainly)。合計の前に並べた内訳の前に書いても、内訳は合計のすべてではない。 */
|
|
27
|
+
readonly mainOnly: readonly string[];
|
|
28
|
+
/** 丸めた桁で書く金額の単位(百万円、千円、million)。どの金額もこの単位なら、丸めのずれ(内訳の数 − 1 桁まで)は合うとみなす。 */
|
|
29
|
+
readonly roundedUnits: readonly string[];
|
|
25
30
|
/** 次の文で内訳の語の前に書いて、前の文の合計を指す語(This、It、その)。何も書かなくてもよい。 */
|
|
26
31
|
readonly backReferences: readonly string[];
|
|
27
32
|
};
|
|
@@ -85,13 +90,15 @@ const signedValues = (source: string, parts: readonly Amount[], from: number, di
|
|
|
85
90
|
|
|
86
91
|
type Breakdown = { readonly total: Amount; readonly parts: readonly Amount[]; readonly from: number; readonly nearEnd: boolean };
|
|
87
92
|
|
|
88
|
-
const mismatch = (source: string, breakdown: Breakdown,
|
|
93
|
+
const mismatch = (source: string, breakdown: Breakdown, words: TotalWords): StructureIssue[] => {
|
|
89
94
|
const { total, from, nearEnd } = breakdown;
|
|
90
95
|
const parts = breakdown.parts.filter((part) => part.unit === total.unit);
|
|
91
96
|
if (parts.length < MIN_PARTS) return [];
|
|
92
|
-
const values = signedValues(source, parts, from, discounts);
|
|
97
|
+
const values = signedValues(source, parts, from, words.discounts);
|
|
93
98
|
const written = centsOf(total);
|
|
94
|
-
|
|
99
|
+
const step = coarsestStep(source, [total, ...parts], words.roundedUnits) * CENTS;
|
|
100
|
+
const matches = (run: readonly number[]): boolean => Math.abs(sumOf(run) - written) <= Math.round(roundingAllowance(step, run.length));
|
|
101
|
+
if (nearRuns(values, nearEnd).some(matches)) return [];
|
|
95
102
|
return [{ offset: total.offset, values: shownTotal(source, total, sumOf(values)) }];
|
|
96
103
|
};
|
|
97
104
|
|
|
@@ -106,6 +113,10 @@ const breakdownEnd = (source: string, total: Amount, marker: Span, sentence: Spa
|
|
|
106
113
|
|
|
107
114
|
const inside = (amounts: readonly Amount[], start: number, end: number): Amount[] => amounts.filter((amount) => amount.offset >= start && amount.end <= end);
|
|
108
115
|
|
|
116
|
+
/** 内訳の前(start から end まで)に、主なものだけを並べると言う語があるか(「主な設備投資は、…」「主な内訳は」)。 */
|
|
117
|
+
const saysMainOnly = (source: string, start: number, end: number, words: TotalWords): boolean =>
|
|
118
|
+
phraseSpans(source.slice(start, end), start, words.mainOnly).length > 0;
|
|
119
|
+
|
|
109
120
|
/** 合計の語のすぐ後ろの金額を、その前の内訳と比べる。内訳は、前の合計の語か内訳の語より後ろから。 */
|
|
110
121
|
const totalsAfterParts = (source: string, sentence: Span, amounts: readonly Amount[], words: TotalWords): StructureIssue[] => {
|
|
111
122
|
const text = source.slice(sentence.start, sentence.end);
|
|
@@ -115,7 +126,9 @@ const totalsAfterParts = (source: string, sentence: Span, amounts: readonly Amou
|
|
|
115
126
|
const total = amounts.find((amount) => amount.offset >= marker.end && isTotalGap(gapBefore(source, marker.end, amount)));
|
|
116
127
|
if (total === undefined) return [];
|
|
117
128
|
const from = Math.max(sentence.start, markers[index - 1]?.end ?? 0, ...breakdowns.filter((span) => span.end <= marker.start).map((span) => span.end));
|
|
118
|
-
|
|
129
|
+
const parts = inside(amounts, from, marker.start);
|
|
130
|
+
if (saysMainOnly(source, from, parts[0]?.offset ?? from, words)) return [];
|
|
131
|
+
return mismatch(source, { total, parts, from, nearEnd: true }, words);
|
|
119
132
|
});
|
|
120
133
|
};
|
|
121
134
|
|
|
@@ -126,9 +139,10 @@ const totalsBeforeParts = (source: string, sentence: Span, amounts: readonly Amo
|
|
|
126
139
|
return phraseSpans(text, sentence.start, words.breakdowns).flatMap((marker) => {
|
|
127
140
|
const total = amounts.findLast((amount) => amount.end <= marker.start);
|
|
128
141
|
if (total === undefined || phraseSpans(source.slice(total.end, marker.start), total.end, words.joiners).length > 0) return [];
|
|
142
|
+
if (saysMainOnly(source, total.end, marker.start, words)) return [];
|
|
129
143
|
const nextTotal = totalMarkers.find((span) => span.start >= marker.end)?.start ?? sentence.end;
|
|
130
144
|
const parts = inside(amounts, marker.end, Math.min(nextTotal, breakdownEnd(source, total, marker, sentence)));
|
|
131
|
-
return mismatch(source, { total, parts, from: marker.end, nearEnd: false }, words
|
|
145
|
+
return mismatch(source, { total, parts, from: marker.end, nearEnd: false }, words);
|
|
132
146
|
});
|
|
133
147
|
};
|
|
134
148
|
|
|
@@ -152,7 +166,7 @@ const fullBreakdown = (source: string, total: Amount, listed: readonly Amount[],
|
|
|
152
166
|
if (last === undefined || listed.some((part) => part.unit !== total.unit)) return [];
|
|
153
167
|
const between = source.slice(total.end, last.offset);
|
|
154
168
|
if (PERCENT.test(between) || phraseSpans(between, total.end, words.partials).length > 0) return [];
|
|
155
|
-
return mismatch(source, { total, parts: listed, from, nearEnd: false }, words
|
|
169
|
+
return mismatch(source, { total, parts: listed, from, nearEnd: false }, words);
|
|
156
170
|
};
|
|
157
171
|
|
|
158
172
|
/** 文の中で、合計の語の金額のすぐ後ろに内訳を始める記号や語(": ")があれば、その後ろから文の終わりか次の記号までが内訳。 */
|
|
@@ -16,6 +16,8 @@ export type ReferenceWords = {
|
|
|
16
16
|
readonly topicLinks: readonly string[];
|
|
17
17
|
/** 話題にならない語(詳細、内容、details)。どの節にも当てはまる。 */
|
|
18
18
|
readonly vagueTopics: readonly string[];
|
|
19
|
+
/** 二つの参照を一つの並びにする語(及び、から、and、to)。並びの後ろの括弧は並び全体の名前。 */
|
|
20
|
+
readonly listJoints: readonly string[];
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
export type ReferenceInput = {
|
|
@@ -70,17 +72,37 @@ export const holdsAside = (name: string, aside: string): boolean => {
|
|
|
70
72
|
return aside.trim() !== "" && words.includes(` ${aside.trim().toLowerCase()} `);
|
|
71
73
|
};
|
|
72
74
|
|
|
75
|
+
/** 句点で終わる括弧や引用符の中は名前でなく文(範囲の断り「…を除く。」、引いた条文)。見出しは句点で終わらない。 */
|
|
76
|
+
const SENTENCE_STOP = /[。.]$/u;
|
|
77
|
+
|
|
78
|
+
export const endsAsSentence = (name: string): boolean => SENTENCE_STOP.test(name);
|
|
79
|
+
|
|
73
80
|
const isName = (name: string, words: ReferenceWords): boolean =>
|
|
74
|
-
LETTER.test(name) &&
|
|
81
|
+
LETTER.test(name) &&
|
|
82
|
+
!DIGIT.test(name) &&
|
|
83
|
+
!ITEM_LABEL.test(name.normalize("NFKC")) &&
|
|
84
|
+
!endsAsSentence(name) &&
|
|
85
|
+
!words.asides.some((aside) => holdsAside(name, aside));
|
|
75
86
|
|
|
76
87
|
const agrees = (name: string, heading: string): boolean => {
|
|
77
88
|
const [a, b] = [normalized(name), normalized(heading)];
|
|
78
89
|
return a.includes(b) || b.includes(a);
|
|
79
90
|
};
|
|
80
91
|
|
|
81
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* The reference ends a list or range of references ("sections 162 and 164", "sections 9 to 11"): only a joint stands
|
|
94
|
+
* between it and the reference before it.
|
|
95
|
+
*/
|
|
96
|
+
export const endsList = (between: string, joints: readonly string[]): boolean => {
|
|
97
|
+
const joint = between.normalize("NFKC").trim().toLowerCase();
|
|
98
|
+
return joint !== "" && joints.some((candidate) => candidate.normalize("NFKC").trim().toLowerCase() === joint);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/** 名前を添えた参照で、名前が参照先の見出しと合わない。並びの後ろの括弧は並び全体の名前なので、どの見出しとも比べない。 */
|
|
82
102
|
export const titleMismatches = (input: ReferenceInput): StructureIssue[] =>
|
|
83
|
-
input.references.flatMap((reference) => {
|
|
103
|
+
input.references.flatMap((reference, index) => {
|
|
104
|
+
const previous = input.references[index - 1];
|
|
105
|
+
if (previous !== undefined && endsList(input.source.slice(previous.span.end, reference.span.start), input.words.listJoints)) return [];
|
|
84
106
|
const target = input.targetOf(reference);
|
|
85
107
|
const heading = target === undefined ? "" : headingOf(target);
|
|
86
108
|
const found = nameAfter(input.source, reference.span.end);
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Span, StructureNode } from "../plugin.ts";
|
|
2
|
+
import type { StructureIssue } from "./issues.ts";
|
|
3
|
+
import { isVersionHistory } from "./version-order.ts";
|
|
4
|
+
|
|
5
|
+
type Placed = { readonly node: StructureNode; readonly parent: StructureNode; readonly ordinal: number };
|
|
6
|
+
|
|
7
|
+
const labelOf = (node: StructureNode): string => String(node.attrs["label"] ?? node.address);
|
|
8
|
+
|
|
9
|
+
/** 「4.1」「4.1」の、最後の番号より前(「4」)。点で区切った番号でなければ無い。 */
|
|
10
|
+
const DOTTED = /^(.*\d)[..](\d+)$/u;
|
|
11
|
+
const dottedPrefixOf = (label: string): string | undefined => DOTTED.exec(label.normalize("NFKC").trim())?.[1];
|
|
12
|
+
|
|
13
|
+
const OPENING_BRACKET = /^[([{〔【〈《]/u;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 番号の並びの単位。点で区切った番号(4.1、4.3)は、前の番号(4)が同じものどうしを、親が違っても一つの並びに読む。
|
|
17
|
+
* 番号の無い見出し(## Approved Office Supplies List)が間に入ると、4.3 は 4.1 と別の親の下に入るが、読み手には 4 の続きに見える。
|
|
18
|
+
* それ以外の番号(第3条、(a))は、同じ親の子どうしだけを並べる。
|
|
19
|
+
*/
|
|
20
|
+
const familyOf = (placed: Placed, parentIds: ReadonlyMap<StructureNode, number>): string => {
|
|
21
|
+
const label = labelOf(placed.node);
|
|
22
|
+
const shape = `${placed.node.kind}/${String(placed.node.level ?? "")}/${OPENING_BRACKET.test(label.normalize("NFKC")) ? "bracketed" : "bare"}`;
|
|
23
|
+
const prefix = dottedPrefixOf(label);
|
|
24
|
+
return prefix === undefined ? `${shape}/parent:${String(parentIds.get(placed.parent))}` : `${shape}/dotted:${prefix}`;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const placedNodes = (tree: StructureNode, quoting: ReadonlySet<StructureNode>): Placed[] => {
|
|
28
|
+
const placed: Placed[] = [];
|
|
29
|
+
const pending: StructureNode[] = [tree];
|
|
30
|
+
for (let parent = pending.pop(); parent !== undefined; parent = pending.pop()) {
|
|
31
|
+
parent.children.forEach((node) => {
|
|
32
|
+
pending.push(node);
|
|
33
|
+
if (node.ordinal !== undefined && node.ordinalTo === undefined && !quoting.has(node)) placed.push({ node, parent, ordinal: node.ordinal });
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return placed.toSorted((left, right) => left.node.span.start - right.node.span.start);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const familiesOf = (placed: readonly Placed[]): Placed[][] => {
|
|
40
|
+
const parentIds = new Map<StructureNode, number>();
|
|
41
|
+
placed.forEach(({ parent }) => parentIds.set(parent, parentIds.get(parent) ?? parentIds.size));
|
|
42
|
+
const families = new Map<string, Placed[]>();
|
|
43
|
+
placed.forEach((entry) => {
|
|
44
|
+
const key = familyOf(entry, parentIds);
|
|
45
|
+
const family = families.get(key) ?? [];
|
|
46
|
+
family.push(entry);
|
|
47
|
+
families.set(key, family);
|
|
48
|
+
});
|
|
49
|
+
return [...families.values()];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** 番号の最後の数字を一つ進めた書き方(4.1 → 4.2、Section 2 → Section 3)。数字で書いていなければ、進めた番号だけ。 */
|
|
53
|
+
export const nextLabelOf = (label: string, ordinal: number): string => {
|
|
54
|
+
const normalized = label.normalize("NFKC");
|
|
55
|
+
const digits = [...normalized.matchAll(/\d+/gu)].at(-1);
|
|
56
|
+
if (digits === undefined || Number(digits[0]) !== ordinal) return String(ordinal + 1);
|
|
57
|
+
return `${normalized.slice(0, digits.index)}${String(ordinal + 1)}${normalized.slice(digits.index + digits[0].length)}`;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** explains は、この誤りで説明がつく、並びの指摘の位置(二つ目、同じ親の下なら次の番号)。 */
|
|
61
|
+
export type RepeatedNumber = { readonly explains: readonly number[]; readonly between: Span; readonly issue: StructureIssue };
|
|
62
|
+
|
|
63
|
+
const repeatsIn = (family: readonly Placed[]): RepeatedNumber[] =>
|
|
64
|
+
family.flatMap((first, index) => {
|
|
65
|
+
const second = family[index + 1];
|
|
66
|
+
const next = family[index + 2];
|
|
67
|
+
if (second === undefined || next === undefined || second.parent !== first.parent) return [];
|
|
68
|
+
if (second.ordinal !== first.ordinal || next.ordinal !== first.ordinal + 2) return [];
|
|
69
|
+
const label = labelOf(second.node);
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
between: { start: second.node.span.start, end: next.node.span.start },
|
|
73
|
+
explains: next.parent === second.parent ? [second.node.span.start, next.node.span.start] : [second.node.span.start],
|
|
74
|
+
issue: {
|
|
75
|
+
offset: second.node.span.start,
|
|
76
|
+
variant: "repeated",
|
|
77
|
+
values: { previous: labelOf(first.node), label, expected: first.ordinal + 1, found: second.ordinal, probably: nextLabelOf(label, second.ordinal) },
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 同じ番号が二度続き、その次が一つ飛ぶ(4.1、4.1、4.3)。二つ目は、振り間違えた 4.2 である見込みが高い。
|
|
85
|
+
* 重なりと抜けの二つに見えるが、誤りは一つなので、二つ目の番号で一度だけ言う。
|
|
86
|
+
* 同じ親の下で隣り合う二つが同じ番号のときだけ。変更履歴の版の見出し(## 3.1.0)は番号の並びではないので見ない。
|
|
87
|
+
* 別の部の 1.1 から振り直した並び(1.1、1.2 の後の 1.1、1.2)は、次が飛ばないので言わない。
|
|
88
|
+
*/
|
|
89
|
+
export const repeatedNumbers = (tree: StructureNode, quoting: ReadonlySet<StructureNode>): RepeatedNumber[] =>
|
|
90
|
+
familiesOf(placedNodes(tree, quoting))
|
|
91
|
+
.filter((family) => !isVersionHistory(family.map(({ node }) => labelOf(node))))
|
|
92
|
+
.flatMap(repeatsIn);
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 並びの抜けと重なり(issues)のうち、同じ番号が二度続いたもの(repeatedNumbers)で説明がつくものを、その一つにまとめる。
|
|
96
|
+
* 二つ目と次の番号のあいだに読めなかった範囲(unread)があれば、飛んだ番号はそこにあるかもしれないので、まとめずに元の指摘を残す。
|
|
97
|
+
* 二つ目の番号への指摘は置き換え、次の番号への抜けの指摘は、二つ目と同じ親の下にあるときだけ(二つ目の次として数えたもの)消す。
|
|
98
|
+
*/
|
|
99
|
+
export const withRepeatsNamed = (
|
|
100
|
+
tree: StructureNode,
|
|
101
|
+
quoting: ReadonlySet<StructureNode>,
|
|
102
|
+
issues: readonly StructureIssue[],
|
|
103
|
+
unread: readonly Span[] = [],
|
|
104
|
+
): StructureIssue[] => {
|
|
105
|
+
const repeats = repeatedNumbers(tree, quoting).filter(({ between }) => !unread.some((span) => span.start > between.start && span.start < between.end));
|
|
106
|
+
const explained = new Set(repeats.flatMap(({ explains }) => explains));
|
|
107
|
+
return [...issues.filter((issue) => !explained.has(issue.offset)), ...repeats.map(({ issue }) => issue)].toSorted(
|
|
108
|
+
(left, right) => left.offset - right.offset,
|
|
109
|
+
);
|
|
110
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Amount } from "./total.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 丸めた単位(百万円、千円、億円、$3.1 million)で書いた金額の、最後の桁一つ分。丸めて書いた内訳と合計は、
|
|
5
|
+
* 四捨五入でも切り捨てでも切り上げでも、内訳の数 − 1 桁までずれる(3,074百万円 + 2,434百万円 + 1,146百万円 と 総額6,655百万円)。
|
|
6
|
+
* 有効数字が 3 桁以上の金額だけを丸めたと読む。最後の桁一つ分がその金額の 1% 以下になり、1億円 + 2億円 = 4億円 のような
|
|
7
|
+
* 金額と同じ大きさのずれを丸めとは読まない。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** 書いた数(6,655、3.1)。漢数字だけの金額は読まない。 */
|
|
11
|
+
const NUMERAL = /\d[\d,,]*(?:[..]\d+)?/u;
|
|
12
|
+
/** 金額のすぐ後ろに書いた単位の語($3.1 million の million)までのあいだ。 */
|
|
13
|
+
const UNIT_AFTER = /^[ \t]?([A-Za-z]+)/u;
|
|
14
|
+
const DECIMAL_BASE = 10;
|
|
15
|
+
/** 金額の後ろで単位の語を探す長さ。 */
|
|
16
|
+
const UNIT_REACH = 16;
|
|
17
|
+
/** 丸めたと読む金額の、書いた数の有効数字の最小の桁数。 */
|
|
18
|
+
const MIN_SIGNIFICANT_DIGITS = 3;
|
|
19
|
+
|
|
20
|
+
/** 書いた数と、その小数の桁。 */
|
|
21
|
+
type Numeral = { readonly value: number; readonly decimals: number; readonly significant: number };
|
|
22
|
+
|
|
23
|
+
/** 書いた数と、その小数の桁と有効数字の桁数(頭の 0 を除いた数字の数。6,655 なら 4、3.1 なら 2、0.25 なら 2)。 */
|
|
24
|
+
const numeralOf = (written: string): Numeral | undefined => {
|
|
25
|
+
const match = NUMERAL.exec(written.normalize("NFKC"));
|
|
26
|
+
if (match === null) return undefined;
|
|
27
|
+
const [whole = "", fraction = ""] = match[0].replace(/,/gu, "").split(".");
|
|
28
|
+
const significant = `${whole}${fraction}`.replace(/^0+/u, "").length;
|
|
29
|
+
return { value: Number(`${whole}.${fraction || "0"}`), decimals: fraction.length, significant };
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/** 金額が丸めた単位で書いてあるか。和文の単位は金額の中に(6,655百万円)、英語の単位は金額のすぐ後ろに($5.6 million)ある。 */
|
|
33
|
+
const inRoundedUnit = (written: string, after: string, units: readonly string[]): boolean => {
|
|
34
|
+
const word = UNIT_AFTER.exec(after)?.[1]?.toLowerCase();
|
|
35
|
+
return units.some((unit) => written.includes(unit) || unit.toLowerCase() === word);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** 丸めた単位で書いた金額の最後の桁一つ分を、金額の値の単位で。丸めた単位でないか、有効数字が 3 桁未満なら undefined。 */
|
|
39
|
+
export const displayStep = (source: string, amount: Amount, units: readonly string[]): number | undefined => {
|
|
40
|
+
const written = source.slice(amount.offset, amount.end);
|
|
41
|
+
if (!inRoundedUnit(written, source.slice(amount.end, amount.end + UNIT_REACH), units)) return undefined;
|
|
42
|
+
const numeral = numeralOf(written);
|
|
43
|
+
if (numeral === undefined || numeral.value === 0 || numeral.significant < MIN_SIGNIFICANT_DIGITS) return undefined;
|
|
44
|
+
return (amount.value / numeral.value) * DECIMAL_BASE ** -numeral.decimals;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** 金額のどれもが丸めた単位で書いてあれば、その一番粗い桁一つ分。一つでも丸めた単位でなければ 0(ずれを許さない)。 */
|
|
48
|
+
export const coarsestStep = (source: string, amounts: readonly Amount[], units: readonly string[]): number => {
|
|
49
|
+
const steps = amounts.map((amount) => displayStep(source, amount, units));
|
|
50
|
+
const known = steps.filter((step) => step !== undefined);
|
|
51
|
+
return known.length === steps.length && known.length > 0 ? Math.max(...known) : 0;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** 丸めた桁 step で書いた parts 個の内訳の和が、合計からずれてよい幅。 */
|
|
55
|
+
export const roundingAllowance = (step: number, parts: number): number => step * Math.max(0, parts - 1);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { StructureNode } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
// 番号で呼ぶ他の法律の手続き。英国の「section 21 notice」は Housing Act 1988 の section 21 の通知で、この文書の section 21 ではない。
|
|
4
|
+
|
|
5
|
+
/** 参照のすぐ後ろの語。 */
|
|
6
|
+
const NEXT_WORD = /^[ \t]+(?<word>\p{L}+)/u;
|
|
7
|
+
const LOWER_START = /^\p{Ll}/u;
|
|
8
|
+
/** 後ろの語を読む長さ。名前を作る語は短い。 */
|
|
9
|
+
const NEXT_WORD_LENGTH = 24;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 名前の一部として書かれた番号(「section 21 notice」)の行き先。小文字で書いた参照の後ろに、名前を作る語(語彙表)が続くもの。
|
|
13
|
+
* 大文字の「Section 5 notice」は契約が自分の条を指す書き方なので当たらない。Pure.
|
|
14
|
+
*/
|
|
15
|
+
export const namedTargets = (references: readonly StructureNode[], source: string, nouns: readonly string[]): ReadonlySet<string> => {
|
|
16
|
+
if (nouns.length === 0) return new Set();
|
|
17
|
+
const names = new Set(nouns);
|
|
18
|
+
return new Set(
|
|
19
|
+
references.flatMap((reference) => {
|
|
20
|
+
const label = String(reference.attrs["label"] ?? "");
|
|
21
|
+
const word = NEXT_WORD.exec(source.slice(reference.span.end, reference.span.end + NEXT_WORD_LENGTH))?.groups?.["word"];
|
|
22
|
+
return LOWER_START.test(label) && word !== undefined && names.has(word) ? [String(reference.attrs["target"] ?? "")] : [];
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 名前として書かれた番号を指す参照か。小文字で書いた参照(「under section 21」)だけ。同じ文書の大文字の「Section 21」は、
|
|
29
|
+
* 文書が自分の section を指す書き方なので、名前があっても探す。Pure.
|
|
30
|
+
*/
|
|
31
|
+
export const pointsToNamedSection = (reference: StructureNode, named: ReadonlySet<string>): boolean =>
|
|
32
|
+
LOWER_START.test(String(reference.attrs["label"] ?? "")) && named.has(String(reference.attrs["target"] ?? ""));
|