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
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import type { Span, StructureNode } from "../plugin.ts";
|
|
2
2
|
import { escapeRegExp } from "../orthography.ts";
|
|
3
3
|
import { inDocumentOrder } from "./issues.ts";
|
|
4
|
+
import { isTitleWords } from "./contents-lines.ts";
|
|
5
|
+
import {
|
|
6
|
+
definingNameOf,
|
|
7
|
+
echoesName,
|
|
8
|
+
endsLatinName,
|
|
9
|
+
followsSelfPrefix,
|
|
10
|
+
glossedWithName,
|
|
11
|
+
MIN_ECHO,
|
|
12
|
+
nameBefore,
|
|
13
|
+
namesItself,
|
|
14
|
+
sharedTail,
|
|
15
|
+
type DefiningName,
|
|
16
|
+
} from "./defining-names.ts";
|
|
4
17
|
|
|
5
18
|
// 定義した語が本文で使われているか、定義より前に使われていないか。どちらも木の定義と、本文の文の字面だけで決まる。
|
|
6
19
|
|
|
@@ -135,6 +148,24 @@ const LABEL_SLACK = 3;
|
|
|
135
148
|
const isLabel = (body: BodyText | undefined, term: string): boolean =>
|
|
136
149
|
body !== undefined && (body.text.replaceAll(term, "").match(LETTER) ?? []).length <= LABEL_SLACK;
|
|
137
150
|
|
|
151
|
+
/** 番地の後ろの、条の題の始まり(Section 1.1 Closing. の Closing)。 */
|
|
152
|
+
const AFTER_ADDRESS = /\d\.?\s+(?=\p{Lu})/gu;
|
|
153
|
+
/** 文の終わりまでが、文の終わりの印を一つしか持たない(題の終わりの点)。 */
|
|
154
|
+
const CAPTION_TO_END = /^[^.!?。]*[.。]?$/u;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 条の題の中か。番地の後ろに題を置いて文がその題で終わる所(Section 1.1 Closing.)か、文が題だけのもの(Section 6.06. の後ろの
|
|
158
|
+
* Financing Covenant.、Company Stockholder Meeting; Company Proxy Statement.)。
|
|
159
|
+
*/
|
|
160
|
+
const insideCaption = (body: BodyText | undefined, offset: number): boolean => {
|
|
161
|
+
if (body === undefined) return false;
|
|
162
|
+
const at = offset - body.start;
|
|
163
|
+
const starts = [...body.text.matchAll(AFTER_ADDRESS)].filter((start) => start.index + start[0].length <= at);
|
|
164
|
+
const last = starts.at(-1);
|
|
165
|
+
const caption = last === undefined ? body.text : body.text.slice(last.index + last[0].length);
|
|
166
|
+
return CAPTION_TO_END.test(caption.trimEnd()) && isTitleWords(caption);
|
|
167
|
+
};
|
|
168
|
+
|
|
138
169
|
/** 文書の位置が、題・見出し・条の見出しの行にあるか。見出しは節の中身に名前を付けるだけで、語を使った所ではない。 */
|
|
139
170
|
export type IsTitle = (offset: number) => boolean;
|
|
140
171
|
|
|
@@ -169,24 +200,6 @@ const insideKatakanaName = (texts: readonly BodyText[], term: string, offset: nu
|
|
|
169
200
|
return (KATAKANA.test(term.charAt(0)) && joinedBefore) || (KATAKANA.test(term.at(-1) ?? "") && joinedAfter);
|
|
170
201
|
};
|
|
171
202
|
|
|
172
|
-
/** 長い名前の写しと読むのに、語の前で定義の名前と重ならなければならない字の数(手引き の前の「の」と「成」)。 */
|
|
173
|
-
const MIN_ECHO = 2;
|
|
174
|
-
const OPENING_BRACKET = /[\s((]/u;
|
|
175
|
-
|
|
176
|
-
/** 定義の括弧を開けた字((、空白)を後ろから外した、括弧の前の名前。 */
|
|
177
|
-
const nameBefore = (text: string): string => {
|
|
178
|
-
let end = text.length;
|
|
179
|
-
while (end > 0 && OPENING_BRACKET.test(text.charAt(end - 1))) end -= 1;
|
|
180
|
-
return text.slice(0, end);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
/** 二つの文字列が後ろから何字重なるか。 */
|
|
184
|
-
const sharedTail = (left: string, right: string): number => {
|
|
185
|
-
let shared = 0;
|
|
186
|
-
while (shared < left.length && shared < right.length && left.at(-1 - shared) === right.at(-1 - shared)) shared += 1;
|
|
187
|
-
return shared;
|
|
188
|
-
};
|
|
189
|
-
|
|
190
203
|
/**
|
|
191
204
|
* 定義の括弧の前に書いた長い名前(…ガイドライン作成の手引き(以下、「手引き」という。))を、定義より前でそのまま書いた所。
|
|
192
205
|
* 名前が語で終わり、語の前の字も名前と同じなら、それは長い名前で、定義した短い名前の使用ではない。
|
|
@@ -229,10 +242,81 @@ const CAPITAL_OR_NON_LATIN = /\p{Lu}|[^\p{Script=Latin}\p{N}\s\p{P}]/u;
|
|
|
229
242
|
*/
|
|
230
243
|
const isDistinctive = (term: string): boolean => CAPITAL_OR_NON_LATIN.test(term) && !SINGLE_KANJI.test(term);
|
|
231
244
|
|
|
245
|
+
/** 文の途中の定義ごとの、括弧の前の名前。 */
|
|
246
|
+
const definingNames = (terms: readonly DefinedTerm[], texts: readonly BodyText[]): Map<DefinedTerm, DefiningName> =>
|
|
247
|
+
new Map(
|
|
248
|
+
terms.flatMap((term): [DefinedTerm, DefiningName][] => {
|
|
249
|
+
const sentence = term.inline ? sentenceAt(texts, term.span.start) : undefined;
|
|
250
|
+
return sentence === undefined ? [] : [[term, definingNameOf(sentence, term.span.start, term.span.end, term.term)]];
|
|
251
|
+
}),
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* 語を含む、もっと長い名前の中の現れか。別の語の定義の中((the "Certificate of Merger") の Certificate)、もっと長い定義した語
|
|
256
|
+
* (NFLN Agreement の NFLN)、定義の括弧の前の名前の写し(Board of Directors)、大文字の語に続く英語の名前の終わり。
|
|
257
|
+
*/
|
|
258
|
+
type InsideLongerName = (term: string, offset: number) => boolean;
|
|
259
|
+
|
|
260
|
+
/** 位置がどれかの範囲の中か。範囲を頭の順に並べ、二分探索で引く(定義が何千あっても、現れ一つに対数)。 */
|
|
261
|
+
const insideAnyOf = (spans: readonly Span[]): ((offset: number) => boolean) => {
|
|
262
|
+
const sorted = spans.toSorted((left, right) => left.start - right.start);
|
|
263
|
+
const furthestEnd: number[] = [];
|
|
264
|
+
sorted.forEach((span, index) => furthestEnd.push(Math.max(furthestEnd[index - 1] ?? 0, span.end)));
|
|
265
|
+
return (offset) => {
|
|
266
|
+
let low = 0;
|
|
267
|
+
let high = sorted.length - 1;
|
|
268
|
+
while (low <= high) {
|
|
269
|
+
const middle = (low + high) >> 1;
|
|
270
|
+
if ((sorted[middle]?.start ?? 0) <= offset) low = middle + 1;
|
|
271
|
+
else high = middle - 1;
|
|
272
|
+
}
|
|
273
|
+
if (high < 0 || (furthestEnd[high] ?? 0) <= offset) return false;
|
|
274
|
+
return offset < (sorted[high]?.end ?? 0) || inside(offset, sorted.slice(0, high));
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const insideLongerNameIn = (texts: readonly BodyText[], terms: readonly DefinedTerm[], names: ReadonlyMap<DefinedTerm, DefiningName>): InsideLongerName => {
|
|
279
|
+
const insideDefinition = insideAnyOf(terms.map((term) => term.span));
|
|
280
|
+
const longNames = [...new Set([...[...names.values()].map((defining) => defining.name), ...terms.map((term) => term.term)])];
|
|
281
|
+
const holding = new Map<string, readonly string[]>();
|
|
282
|
+
const namesHolding = (term: string): readonly string[] => {
|
|
283
|
+
const known = holding.get(term);
|
|
284
|
+
if (known !== undefined) return known;
|
|
285
|
+
const found = longNames.filter((name) => name !== term && name.includes(term));
|
|
286
|
+
holding.set(term, found);
|
|
287
|
+
return found;
|
|
288
|
+
};
|
|
289
|
+
return (term, offset) => {
|
|
290
|
+
if (insideDefinition(offset)) return true;
|
|
291
|
+
const sentence = sentenceAt(texts, offset);
|
|
292
|
+
if (sentence === undefined) return false;
|
|
293
|
+
const at = offset - sentence.start;
|
|
294
|
+
return endsLatinName(sentence, at, term) || namesHolding(term).some((name) => echoesName(sentence, at, term, name));
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* 前で書いても読み手が分かる所。文書自身の名前と定義した語(この就業規則(以下「規則」))を同じ頭を付けて書いた所(この規則は、…)と、
|
|
300
|
+
* すぐ後ろの括弧に定義の長い名前を書き添えた所(こども性暴力防止法(…に関する法律))。
|
|
301
|
+
*/
|
|
302
|
+
const explainedInPlace = (
|
|
303
|
+
texts: readonly BodyText[],
|
|
304
|
+
term: string,
|
|
305
|
+
defining: DefiningName | undefined,
|
|
306
|
+
prefixes: readonly string[],
|
|
307
|
+
offset: number,
|
|
308
|
+
): boolean => {
|
|
309
|
+
const sentence = sentenceAt(texts, offset);
|
|
310
|
+
if (defining === undefined || sentence === undefined) return false;
|
|
311
|
+
const at = offset - sentence.start;
|
|
312
|
+
return (namesItself(defining, prefixes) && followsSelfPrefix(sentence, at, prefixes)) || glossedWithName(sentence, at, term, defining.name);
|
|
313
|
+
};
|
|
314
|
+
|
|
232
315
|
/**
|
|
233
316
|
* 文の途中で括弧に入れて定義した語((the "Seller")、以下「甲」という)を、その定義の文より前で使っている所。最初の一つだけ。
|
|
234
317
|
* 定義の文の中の現れ(株式会社GovTech東京(以下「GovTech東京」という。))は、定義する名前そのものなので数えない。札の文も、
|
|
235
|
-
* isTitle
|
|
318
|
+
* isTitle が言う題・見出し・目次の行も、漢字で終わる語にさらに漢字が続く長い語の一部も、定義の括弧の前の長い名前を写した所も、
|
|
319
|
+
* 語を含むもっと長い名前の中も数えない。文書自身の名前を定義した語は、selfPrefixes(この、本、this)を付けて前で書いても数えない。
|
|
236
320
|
* 定義の条("Seller" means、「甲」とは)は条の並びの頭にも終わりにも置く書き方があるので、前で使っても言わない。
|
|
237
321
|
* 定義の語の無い括弧の引用(("The key point is"))は例の引用と同じ形なので、その語を引用符で挙げただけの現れ
|
|
238
322
|
* (Its sentences open with "The key point is")は使用ではない。定義の語のある定義((the "Seller")、以下「買主」という)は、
|
|
@@ -243,21 +327,28 @@ export const usesBeforeDefinition = (
|
|
|
243
327
|
texts: readonly BodyText[],
|
|
244
328
|
mentioned: Mentioned = NEVER_MENTIONED,
|
|
245
329
|
isTitle: IsTitle = NEVER_TITLE,
|
|
246
|
-
|
|
247
|
-
|
|
330
|
+
selfPrefixes: readonly string[] = [],
|
|
331
|
+
): TermUse[] => {
|
|
332
|
+
const inline = terms.filter((term) => term.inline);
|
|
333
|
+
const names = definingNames(terms, texts);
|
|
334
|
+
const insideLongerName = insideLongerNameIn(texts, terms, names);
|
|
335
|
+
return groupsOf(terms)
|
|
248
336
|
.filter((group) => group.first.inline && isDistinctive(group.first.term))
|
|
249
337
|
.flatMap(({ first: defined, spans }) => {
|
|
250
|
-
const inline = terms.filter((term) => term.inline);
|
|
251
338
|
const defining = sentenceAt(texts, defined.span.start)?.start ?? defined.span.start;
|
|
252
|
-
const uses = usesOf(defined.term, texts, spans, "exact", defined.bare === true ? mentioned : NEVER_MENTIONED);
|
|
339
|
+
const uses = usesOf(defined.term, texts, spans, "exact", defined.bare === true ? mentioned : NEVER_MENTIONED).filter((offset) => offset < defining);
|
|
253
340
|
const first = uses.find(
|
|
254
341
|
(offset) =>
|
|
255
342
|
!isLabel(sentenceAt(texts, offset), defined.term) &&
|
|
343
|
+
!insideCaption(sentenceAt(texts, offset), offset) &&
|
|
256
344
|
!isTitle(offset) &&
|
|
257
345
|
!continuesInHan(texts, defined.term, offset) &&
|
|
258
346
|
!insideKatakanaName(texts, defined.term, offset) &&
|
|
259
347
|
!echoesLongName(texts, defined, offset) &&
|
|
260
|
-
!insideDefiningName(texts, inline, defined, offset)
|
|
348
|
+
!insideDefiningName(texts, inline, defined, offset) &&
|
|
349
|
+
!insideLongerName(defined.term, offset) &&
|
|
350
|
+
!explainedInPlace(texts, defined.term, names.get(defined), selfPrefixes, offset),
|
|
261
351
|
);
|
|
262
|
-
return first
|
|
352
|
+
return first === undefined ? [] : [{ term: defined, offset: first }];
|
|
263
353
|
});
|
|
354
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readMarkdown } from "../markdown-read.ts";
|
|
2
|
+
import { spanOf, type MarkdownNode } from "../markdown-node.ts";
|
|
3
|
+
import type { Span } from "../plugin.ts";
|
|
4
|
+
|
|
5
|
+
const COMMENT = /<!--[\s\S]*?(?:-->|$)/gu;
|
|
6
|
+
const INLINE_CONTAINERS = new Set(["paragraph", "heading", "tableCell"]);
|
|
7
|
+
const ENTITY = /&(?:#\d+|#x[\da-f]+|[a-z]+\d*);/giu;
|
|
8
|
+
|
|
9
|
+
type TagScan = { readonly kept: string[]; inTag: boolean; quote: string | undefined };
|
|
10
|
+
|
|
11
|
+
/** Reads one character of HTML: text outside a tag is kept. A quoted attribute may hold `>` (`<div title=">">`). */
|
|
12
|
+
const scanned = (scan: TagScan, char: string): TagScan => {
|
|
13
|
+
if (!scan.inTag) {
|
|
14
|
+
if (char === "<") scan.inTag = true;
|
|
15
|
+
else scan.kept.push(char);
|
|
16
|
+
} else if (scan.quote !== undefined) {
|
|
17
|
+
if (char === scan.quote) scan.quote = undefined;
|
|
18
|
+
} else if (char === '"' || char === "'") scan.quote = char;
|
|
19
|
+
else if (char === ">") scan.inTag = false;
|
|
20
|
+
return scan;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const withoutTags = (html: string): string => [...html].reduce<TagScan>(scanned, { kept: [], inTag: false, quote: undefined }).kept.join("");
|
|
24
|
+
|
|
25
|
+
/** What an HTML block shows the reader: its text without tags, comments and character references such as ` `. */
|
|
26
|
+
const showsText = (html: string): boolean => withoutTags(html.replace(COMMENT, "")).replace(ENTITY, "").trim() !== "";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Markdown's HTML blocks that show text. CommonMark runs a block that starts with a tag alone on its line (`<br/>`) to
|
|
30
|
+
* the next blank line, so a `第11条` written right under it is raw HTML: the reader sees it, chaff's structure does not.
|
|
31
|
+
* Only blocks are returned; an inline tag inside a paragraph (`text<br/>`) leaves the text beside it readable.
|
|
32
|
+
*/
|
|
33
|
+
export const htmlTextBlocks = (source: string): Span[] => {
|
|
34
|
+
if (!source.includes("<")) return [];
|
|
35
|
+
const blocks: Span[] = [];
|
|
36
|
+
const visit = (node: MarkdownNode, inParagraph: boolean): void => {
|
|
37
|
+
if (node.type === "html" && !inParagraph && showsText(node.value ?? "")) {
|
|
38
|
+
const span = spanOf(node);
|
|
39
|
+
if (span !== undefined) blocks.push(span);
|
|
40
|
+
}
|
|
41
|
+
(node.children ?? []).forEach((child) => visit(child, inParagraph || INLINE_CONTAINERS.has(node.type)));
|
|
42
|
+
};
|
|
43
|
+
visit(readMarkdown(source).root, false);
|
|
44
|
+
return blocks.toSorted((left, right) => left.start - right.start);
|
|
45
|
+
};
|
package/src/structure/issues.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { StructureNode } from "../plugin.ts";
|
|
2
|
+
import { writtenReading } from "./written-resolve.ts";
|
|
3
|
+
import { partAt } from "./attached-parts.ts";
|
|
4
|
+
import { namedTargets, pointsToNamedSection } from "./section-names.ts";
|
|
2
5
|
import { listedTags } from "./listed-tags.ts";
|
|
3
6
|
import { namesAbsentUnit } from "./unit-word.ts";
|
|
7
|
+
import { isListedParagraph, listedParagraphsByArticle } from "./listed-paragraph.ts";
|
|
8
|
+
import { referencesInCitedDocuments } from "./cited-document-section.ts";
|
|
4
9
|
|
|
5
10
|
// 木だけで決まる誤り。参照先が無い、番号が飛ぶ・重なる、同じ語を二度定義する。
|
|
6
11
|
// 意味の食い違いは判定しない。書いてあることから機械で決まるものだけを出す。
|
|
7
12
|
|
|
8
|
-
|
|
13
|
+
/** variant は、rule の messages から文を選ぶ鍵。無ければ message。 */
|
|
14
|
+
export type StructureIssue = { readonly offset: number; readonly values: Readonly<Record<string, string | number>>; readonly variant?: string };
|
|
9
15
|
|
|
10
16
|
const NUMBERED: ReadonlySet<string> = new Set(["chapter", "article", "item"]);
|
|
11
17
|
|
|
@@ -111,7 +117,7 @@ const numbering = (node: StructureNode): unknown => node.attrs["numbering"];
|
|
|
111
117
|
* 参照の番地が木に無い。他の文書の名前が付いた参照(民法第709条、Section 9 of the Master Agreement)は引かない。
|
|
112
118
|
* 条を 1 つも持たない文書も見ない。他の文書を指しているだけかもしれない。
|
|
113
119
|
*/
|
|
114
|
-
export const danglingReferences = (tree: StructureNode, source: string): StructureIssue[] => {
|
|
120
|
+
export const danglingReferences = (tree: StructureNode, source: string, nameNouns: readonly string[] = []): StructureIssue[] => {
|
|
115
121
|
const nodes = inDocumentOrder(tree);
|
|
116
122
|
// 参照は条を指す。条を一つも持たない文書(契約書に付ける承諾書のひな形など)の「契約書第6条」は、別の文書の条。
|
|
117
123
|
if (!nodes.some((node) => node.kind === "article")) return [];
|
|
@@ -127,10 +133,21 @@ export const danglingReferences = (tree: StructureNode, source: string): Structu
|
|
|
127
133
|
const articleLabels = nodes.filter((node) => node.kind === "article").map((node) => textOf(node, "label"));
|
|
128
134
|
const chapters = chaptersOf(nodes);
|
|
129
135
|
const elsewhere = elsewhereReferences(nodes, source);
|
|
130
|
-
|
|
131
|
-
|
|
136
|
+
const quoted = referencesInCitedDocuments(tree);
|
|
137
|
+
const references = nodes.filter((node) => node.kind === "reference");
|
|
138
|
+
const named = namedTargets(references, source, nameNouns);
|
|
139
|
+
const unresolved = references
|
|
140
|
+
.filter((node) => !citesOther(node) && !otherNumbering(node) && !pointsToNamedSection(node, named))
|
|
132
141
|
.filter((node) => !namesAbsentUnit(node, articleLabels) && !elsewhere.has(node))
|
|
133
|
-
.filter((node) => !resolves(node, addresses, chapters))
|
|
142
|
+
.filter((node) => !quoted.has(node) && !resolves(node, addresses, chapters));
|
|
143
|
+
// 規程は条の下の項を箇条書き(「1. 」「2.」)で書くことがあり、木はそれを項として読まない。条の本文は、要るときに一度だけ読む。
|
|
144
|
+
const listed = unresolved.length === 0 ? new Map() : listedParagraphsByArticle(nodes, source);
|
|
145
|
+
// 平文の契約は見出しを「9. Indemnification.」と本文の形で書き、木はそれを番地にしない。残った参照があるときだけ読む。
|
|
146
|
+
const written = unresolved.length === 0 ? undefined : writtenReading(nodes, source);
|
|
147
|
+
const writtenAddresses = new Set(written?.addresses);
|
|
148
|
+
return unresolved
|
|
149
|
+
.filter((node) => !isListedParagraph(textOf(node, "target"), listed))
|
|
150
|
+
.filter((node) => !writtenAddresses.has(textOf(node, "target")) && written?.subdivision(node) !== true)
|
|
134
151
|
.map((node) => ({ offset: node.span.start, values: { label: textOf(node, "label"), target: textOf(node, "target") } }));
|
|
135
152
|
};
|
|
136
153
|
|
|
@@ -180,13 +197,15 @@ const definitionsInOrder = (tree: StructureNode): Definition[] => {
|
|
|
180
197
|
/**
|
|
181
198
|
* 同じ語の二度目以降の定義。どちらが正しいかは決めず、両方の場所を示す。
|
|
182
199
|
* 範囲を限った定義(この条において「X」とは)は、同じ条の中でだけ比べる。別の条で定義し直すのは正しい書き方。
|
|
200
|
+
* 添付した文書(partStarts から始まる Exhibit A など)は別の文書なので、その中の定義はその中でだけ比べる。
|
|
183
201
|
*/
|
|
184
|
-
export const duplicateDefinitions = (tree: StructureNode): StructureIssue[] => {
|
|
202
|
+
export const duplicateDefinitions = (tree: StructureNode, partStarts: readonly number[] = []): StructureIssue[] => {
|
|
185
203
|
const first = new Map<string, StructureNode>();
|
|
186
204
|
return definitionsInOrder(tree).flatMap(({ node, article }) => {
|
|
187
205
|
const term = textOf(node, "term");
|
|
188
206
|
const within = node.attrs["within"] === undefined ? article : textOf(node, "within");
|
|
189
|
-
const
|
|
207
|
+
const scoped = node.attrs["scope"] === "local" ? `${within}\u0000${term}` : term;
|
|
208
|
+
const key = `${partAt(partStarts, node.span.start)}\u0000${scoped}`;
|
|
190
209
|
const earlier = first.get(key);
|
|
191
210
|
if (earlier === undefined) {
|
|
192
211
|
first.set(key, node);
|
|
@@ -4,6 +4,7 @@ import type { StructureIssue } from "./issues.ts";
|
|
|
4
4
|
import type { Line } from "./lines.ts";
|
|
5
5
|
import { labelPairsOf, pointsOutOfOrder, type OrderLabel, type PairWords, type PointOf } from "./labelled-order.ts";
|
|
6
6
|
import { TABLE_ROW } from "./runs.ts";
|
|
7
|
+
import type { VersionWords } from "./versioned-label.ts";
|
|
7
8
|
import { isSignedDateLine } from "./signed-date-line.ts";
|
|
8
9
|
import { statedPeriod, type DateMention, type PeriodWords } from "./stated-period.ts";
|
|
9
10
|
|
|
@@ -132,6 +133,8 @@ export type PairedReading = {
|
|
|
132
133
|
readonly spans?: PairSpans | undefined;
|
|
133
134
|
readonly whole?: string | undefined;
|
|
134
135
|
readonly signers?: readonly OrderLabel[] | undefined;
|
|
136
|
+
/** The words that join a version to a label (End of support for 5.0.0, 3.0.0 のサポート終了日). */
|
|
137
|
+
readonly versions?: VersionWords | undefined;
|
|
135
138
|
};
|
|
136
139
|
|
|
137
140
|
const signersOf = (signers: readonly OrderLabel[], group: string): string[] =>
|
|
@@ -166,14 +169,14 @@ export const pairedDatesOutOfOrder = (
|
|
|
166
169
|
labels: readonly OrderLabel[],
|
|
167
170
|
passed: readonly string[],
|
|
168
171
|
maxLineGap: number,
|
|
169
|
-
{ spans, whole = source, signers = [] }: PairedReading = {},
|
|
172
|
+
{ spans, whole = source, signers = [], versions }: PairedReading = {},
|
|
170
173
|
): PairedIssue[] =>
|
|
171
174
|
withoutRepeats(
|
|
172
175
|
labelPairsOf(labels).flatMap((pair) => {
|
|
173
176
|
const context = contextOf(labels, pair.group);
|
|
174
177
|
if (context.length > 0 && !namesDocumentKind(whole, context)) return [];
|
|
175
178
|
const fromStart = spanStartsOf(spans?.entries ?? [], pair.group);
|
|
176
|
-
const words = { ...pair, passed, maxLineGap, spans, fromStart, signers: signersOf(signers, pair.group) };
|
|
179
|
+
const words = { ...pair, passed, maxLineGap, spans, fromStart, signers: signersOf(signers, pair.group), versions };
|
|
177
180
|
return datesOutOfOrder(source, dates, words).map(({ earlier, later }) => ({
|
|
178
181
|
offset: Math.max(later.date.offset, earlier.date.offset),
|
|
179
182
|
values: { later: later.date.value, earlier: earlier.date.value, later_label: later.label, earlier_label: earlier.label },
|
|
@@ -2,6 +2,7 @@ import { linesOf, type Line } from "./lines.ts";
|
|
|
2
2
|
import { tableAround } from "./key-value-row.ts";
|
|
3
3
|
import { signerRoleOf } from "./signed-date-line.ts";
|
|
4
4
|
import { isTotalLabel } from "./total.ts";
|
|
5
|
+
import { withoutLabelVersion, type VersionWords } from "./versioned-label.ts";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Two labelled points that must come in order: a line (or a list item, or a table's first column) starting with an
|
|
@@ -24,6 +25,8 @@ export type PairWords = {
|
|
|
24
25
|
* pointOf decides whether the line is one. A signature closes the whole document, so it is read at any distance.
|
|
25
26
|
*/
|
|
26
27
|
readonly signers?: readonly string[] | undefined;
|
|
28
|
+
/** The words that join a version to a label (End of support for 5.0.0, 3.0.0 のサポート終了日). */
|
|
29
|
+
readonly versions?: VersionWords | undefined;
|
|
27
30
|
};
|
|
28
31
|
|
|
29
32
|
/** A labelled point: the word that labels it, as the lexicon writes it. span is set when the point ends a stated period. */
|
|
@@ -36,7 +39,13 @@ export type PointOf = (line: Line, label: string, tableOf: () => readonly string
|
|
|
36
39
|
|
|
37
40
|
type Read = LabelledPoint & { readonly kind: "earlier" | "later"; readonly signed?: boolean | undefined };
|
|
38
41
|
|
|
39
|
-
const
|
|
42
|
+
const isVersionedLabel = (text: string, word: string, versions: VersionWords | undefined): boolean => {
|
|
43
|
+
const bare = versions === undefined ? undefined : withoutLabelVersion(text, word, versions);
|
|
44
|
+
return bare !== undefined && isTotalLabel(bare, [word]);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const labelOf = (text: string, words: readonly string[], versions?: VersionWords): string | undefined =>
|
|
48
|
+
words.find((word) => isTotalLabel(text, [word]) || isVersionedLabel(text, word, versions));
|
|
40
49
|
|
|
41
50
|
const signerOf = (text: string, words: PairWords): Pick<Read, "kind" | "label" | "signed"> | undefined => {
|
|
42
51
|
const role = signerRoleOf(text, words.signers ?? []);
|
|
@@ -44,9 +53,9 @@ const signerOf = (text: string, words: PairWords): Pick<Read, "kind" | "label" |
|
|
|
44
53
|
};
|
|
45
54
|
|
|
46
55
|
const kindOf = (text: string, words: PairWords): Pick<Read, "kind" | "label" | "signed"> | undefined => {
|
|
47
|
-
const earlier = labelOf(text, words.earlier);
|
|
56
|
+
const earlier = labelOf(text, words.earlier, words.versions);
|
|
48
57
|
if (earlier !== undefined) return { kind: "earlier", label: earlier };
|
|
49
|
-
const later = labelOf(text, words.later);
|
|
58
|
+
const later = labelOf(text, words.later, words.versions);
|
|
50
59
|
return later === undefined ? signerOf(text, words) : { kind: "later", label: later };
|
|
51
60
|
};
|
|
52
61
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Sentence, Span } from "../plugin.ts";
|
|
2
|
+
|
|
3
|
+
// 箇条書きの項目の文が、どの導入の文の下にあるか。「(3) If … no such resolution is made—\n(a) the Commissioner must issue …」の
|
|
4
|
+
// (a) は (3) の条件の下にあり、(a) だけを読むと条件が落ちる。
|
|
5
|
+
|
|
6
|
+
/** 導入の文の終わり。この後に項目が並ぶ("must include—"、"is made:"、「承認した場合:」)。 */
|
|
7
|
+
const LEAD_IN_END = /[::—–]\s*$/u;
|
|
8
|
+
|
|
9
|
+
/** 空行。そこで段落が改まり、導入はそこを越えて探さない。 */
|
|
10
|
+
const BLANK_LINE = /\n[^\S\n]*\n/u;
|
|
11
|
+
|
|
12
|
+
/** 項目の頭の印: 開き括弧、番号か記号(囲み数字や仮名は 1 字)、閉じ括弧か点。 */
|
|
13
|
+
const MARKER = /^\s*([(([[]?)([0-90-9]+|[a-zA-Za-zA-Z]+|[一二三四五六七八九十]+|\S)([))]\]..]?)/u;
|
|
14
|
+
|
|
15
|
+
/** 1 字のローマ数字。英字の並び((h) の次の (i))でもありうる。 */
|
|
16
|
+
const SINGLE_ROMAN = /^[ivxIVX]$/u;
|
|
17
|
+
const ROMAN = /^(?:[ivxlc]{2,}|[IVXLC]{2,})$/u;
|
|
18
|
+
|
|
19
|
+
const labelClass = (label: string): string => {
|
|
20
|
+
if (/^[0-90-9]+$/u.test(label)) return "1";
|
|
21
|
+
if (ROMAN.test(label) || SINGLE_ROMAN.test(label)) return /[a-z]/u.test(label) ? "i" : "I";
|
|
22
|
+
if (/^[a-za-z]+$/u.test(label)) return "a";
|
|
23
|
+
if (/^[A-ZA-Z]+$/u.test(label)) return "A";
|
|
24
|
+
if (/^[一二三四五六七八九十]+$/u.test(label)) return "一";
|
|
25
|
+
if (/^[\p{Script=Katakana}\p{Script=Hiragana}]$/u.test(label)) return "イ";
|
|
26
|
+
if (/^[①-⑳㉑-㉟㊱-㊿]$/u.test(label)) return "①";
|
|
27
|
+
if (/^[⑴-⒇]$/u.test(label)) return "⑴";
|
|
28
|
+
return label;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** 項目の文の頭の印の範囲("(a)"、"①")。番号は文の中身ではない。項目の文でなければ undefined。 */
|
|
32
|
+
export const itemMarkerSpan = (sentence: Sentence): Span | undefined => {
|
|
33
|
+
const match = sentence.listItem === true ? MARKER.exec(sentence.text) : null;
|
|
34
|
+
return match === null ? undefined : { start: sentence.span.start, end: sentence.span.start + match[0].length };
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const previousLetter = (label: string): string => String.fromCharCode(label.charCodeAt(0) - 1);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 項目の印の形("(1)"、"(a)"、"(i)"、"①"、"・")。番号そのものは数えない。
|
|
41
|
+
* 1 字の i・v・x は、同じ括弧の英字の項目がその前の字(h・u・w)で終わっていれば英字、でなければローマ数字。
|
|
42
|
+
*/
|
|
43
|
+
export const markerShape = (text: string, lastLetters: ReadonlyMap<string, string>): { readonly shape: string; readonly letter?: string } | undefined => {
|
|
44
|
+
const match = MARKER.exec(text);
|
|
45
|
+
const [, open = "", label, close = ""] = match ?? [];
|
|
46
|
+
if (label === undefined) return undefined;
|
|
47
|
+
const letterShape = `${open}${/[a-z]/u.test(label) ? "a" : "A"}${close}`;
|
|
48
|
+
const continuesLetters = SINGLE_ROMAN.test(label) && lastLetters.get(letterShape) === previousLetter(label);
|
|
49
|
+
const shape = continuesLetters ? letterShape : `${open}${labelClass(label)}${close}`;
|
|
50
|
+
return shape === letterShape ? { shape, letter: label } : { shape };
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
type Entry = { readonly sentence: Sentence; readonly leadIns: readonly Sentence[] };
|
|
54
|
+
|
|
55
|
+
/** 段落の中で、項目の形ごとの最後の項目と、すぐ前の文が導入ならその文。 */
|
|
56
|
+
type Block = {
|
|
57
|
+
readonly lastByShape: Map<string, { readonly at: number; readonly entry: Entry }>;
|
|
58
|
+
readonly lastLetters: Map<string, string>;
|
|
59
|
+
leadIn: { readonly at: number; readonly entry: Entry } | undefined;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const newBlock = (): Block => ({ lastByShape: new Map(), lastLetters: new Map(), leadIn: undefined });
|
|
63
|
+
|
|
64
|
+
/** 項目の導入の文: すぐ前の文が導入で、それより後に同じ形の項目(兄弟)が無ければその文とその導入、でなければ兄弟の導入。 */
|
|
65
|
+
const leadInsOf = (block: Block, shape: string): readonly Sentence[] => {
|
|
66
|
+
const sibling = block.lastByShape.get(shape);
|
|
67
|
+
const leadIn = block.leadIn;
|
|
68
|
+
if (sibling !== undefined && (leadIn === undefined || sibling.at >= leadIn.at)) return sibling.entry.leadIns;
|
|
69
|
+
return leadIn === undefined ? [] : [leadIn.entry.sentence, ...leadIn.entry.leadIns];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 箇条書きの項目の文(listItem)ごとの、導入の文。近い順で、導入が項目なら、その導入も続ける。
|
|
74
|
+
* 導入は、並びの最初の項目のすぐ前の文で、「—」「:」「:」で終わるもの。同じ段落(空行を挟まない)の中で、同じ形の項目どうしは
|
|
75
|
+
* 同じ導入の下にある。
|
|
76
|
+
* sentences は文書の順。source は sentences の span の座標の文字列。
|
|
77
|
+
*/
|
|
78
|
+
export const listLeadIns = (source: string, sentences: readonly Sentence[]): Map<Sentence, readonly Sentence[]> => {
|
|
79
|
+
const found = new Map<Sentence, readonly Sentence[]>();
|
|
80
|
+
let block = newBlock();
|
|
81
|
+
sentences.forEach((sentence, at) => {
|
|
82
|
+
const previous = sentences[at - 1];
|
|
83
|
+
if (previous !== undefined && BLANK_LINE.test(source.slice(previous.span.end, sentence.span.start))) block = newBlock();
|
|
84
|
+
const marker = sentence.listItem === true ? markerShape(sentence.text, block.lastLetters) : undefined;
|
|
85
|
+
const entry: Entry = { sentence, leadIns: marker === undefined ? [] : leadInsOf(block, marker.shape) };
|
|
86
|
+
if (marker !== undefined) {
|
|
87
|
+
found.set(sentence, entry.leadIns);
|
|
88
|
+
block.lastByShape.set(marker.shape, { at, entry });
|
|
89
|
+
if (marker.letter !== undefined) block.lastLetters.set(marker.shape, marker.letter.at(-1) ?? "");
|
|
90
|
+
}
|
|
91
|
+
block.leadIn = LEAD_IN_END.test(sentence.text) ? { at, entry } : undefined;
|
|
92
|
+
});
|
|
93
|
+
return found;
|
|
94
|
+
};
|
|
@@ -4,31 +4,120 @@ import type { Span } from "../plugin.ts";
|
|
|
4
4
|
import type { StructureIssue } from "./issues.ts";
|
|
5
5
|
|
|
6
6
|
const ITEM_NUMBER = /^(?<number>\d{1,9})(?<delimiter>[.)])[ \t]/u;
|
|
7
|
+
const TAB_WIDTH = 4;
|
|
7
8
|
|
|
8
|
-
/** One item's written number: where the item starts, the number and the number as written (「4.」). */
|
|
9
|
-
export type WrittenNumber = {
|
|
9
|
+
/** One item's written number: where the item starts and ends, its column, the number and the number as written (「4.」). */
|
|
10
|
+
export type WrittenNumber = {
|
|
11
|
+
readonly offset: number;
|
|
12
|
+
readonly number: number;
|
|
13
|
+
readonly label: string;
|
|
14
|
+
readonly indent?: number;
|
|
15
|
+
readonly end?: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** The column an offset sits at, a tab counted to the next stop of four as CommonMark counts it. */
|
|
19
|
+
const columnAt = (source: string, offset: number): number =>
|
|
20
|
+
Array.from(source.slice(source.lastIndexOf("\n", offset - 1) + 1, offset)).reduce(
|
|
21
|
+
(column, char) => (char === "\t" ? column + TAB_WIDTH - (column % TAB_WIDTH) : column + 1),
|
|
22
|
+
0,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const numberAt = (source: string, span: Span): { number: number; label: string } | undefined => {
|
|
26
|
+
const found = ITEM_NUMBER.exec(source.slice(span.start, span.end))?.groups;
|
|
27
|
+
return found === undefined ? undefined : { number: Number(found["number"]), label: `${found["number"] ?? ""}${found["delimiter"] ?? ""}` };
|
|
28
|
+
};
|
|
10
29
|
|
|
11
30
|
/** The number written at the start of each item, or undefined when an item has none (a bulleted list). */
|
|
12
31
|
export const writtenNumbers = (source: string, itemSpans: readonly Span[]): WrittenNumber[] | undefined => {
|
|
13
32
|
const numbers = itemSpans.map((span) => {
|
|
14
|
-
const found =
|
|
15
|
-
return found === undefined
|
|
16
|
-
? undefined
|
|
17
|
-
: { offset: span.start, number: Number(found["number"]), label: `${found["number"] ?? ""}${found["delimiter"] ?? ""}` };
|
|
33
|
+
const found = numberAt(source, span);
|
|
34
|
+
return found === undefined ? undefined : { offset: span.start, end: span.end, ...found, indent: columnAt(source, span.start) };
|
|
18
35
|
});
|
|
19
36
|
return numbers.every((entry) => entry !== undefined) ? numbers : undefined;
|
|
20
37
|
};
|
|
21
38
|
|
|
39
|
+
/** The last number of an ordered list nested in an item, if there is one. */
|
|
40
|
+
export type NestedLast = (item: WrittenNumber) => number | undefined;
|
|
41
|
+
|
|
42
|
+
type OrderedList = { readonly start: number; readonly end: number; readonly last: number };
|
|
43
|
+
|
|
44
|
+
const orderedListOf = (source: string, spans: readonly Span[]): OrderedList[] => {
|
|
45
|
+
const first = spans[0];
|
|
46
|
+
const last = writtenNumbers(source, spans)?.at(-1);
|
|
47
|
+
return first === undefined || last === undefined ? [] : [{ start: first.start, end: last.end ?? last.offset, last: last.number }];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* For an item, the last number of the ordered list inside it that ends last (the outermost one, when lists nested in
|
|
52
|
+
* each other end together). lists are the item spans of every list in the document; bulleted lists are left out.
|
|
53
|
+
*/
|
|
54
|
+
export const nestedLastFinder = (source: string, lists: readonly (readonly Span[])[]): NestedLast => {
|
|
55
|
+
const ordered = lists.flatMap((spans) => orderedListOf(source, spans));
|
|
56
|
+
return (item) =>
|
|
57
|
+
ordered
|
|
58
|
+
.filter((list) => list.start > item.offset && list.end <= (item.end ?? item.offset))
|
|
59
|
+
.reduce<OrderedList | undefined>(
|
|
60
|
+
(best, list) => (best === undefined || list.end > best.end || (list.end === best.end && list.start < best.start) ? list : best),
|
|
61
|
+
undefined,
|
|
62
|
+
)?.last;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
type Compared = { readonly item: WrittenNumber; readonly previous: WrittenNumber | undefined };
|
|
66
|
+
|
|
67
|
+
const indentOf = (item: WrittenNumber): number => item.indent ?? 0;
|
|
68
|
+
|
|
22
69
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
70
|
+
* Which item each item's number follows. An item at the same indentation follows the last one there. An item indented
|
|
71
|
+
* deeper starts a nested count (CommonMark can still put it in the same list, when the indentation falls short of the
|
|
72
|
+
* parent's text), unless it carries on the count above it: the parent's number plus one (a slip of indentation), or
|
|
73
|
+
* one past the last number of the list nested in the parent (that list, carried on at a different indentation).
|
|
74
|
+
*/
|
|
75
|
+
const comparedPairs = (items: readonly WrittenNumber[], nestedLast: NestedLast): Compared[] => {
|
|
76
|
+
const open: WrittenNumber[] = [];
|
|
77
|
+
return items.map((item) => {
|
|
78
|
+
const popped: WrittenNumber[] = [];
|
|
79
|
+
for (let top = open.at(-1); top !== undefined && indentOf(top) > indentOf(item); top = open.at(-1)) {
|
|
80
|
+
popped.push(top);
|
|
81
|
+
open.pop();
|
|
82
|
+
}
|
|
83
|
+
const parent = open.at(-1);
|
|
84
|
+
if (parent !== undefined && indentOf(parent) === indentOf(item)) {
|
|
85
|
+
open[open.length - 1] = item;
|
|
86
|
+
return { item, previous: parent };
|
|
87
|
+
}
|
|
88
|
+
if (parent === undefined) {
|
|
89
|
+
open.push(item);
|
|
90
|
+
return { item, previous: popped.at(-1) };
|
|
91
|
+
}
|
|
92
|
+
if (item.number === parent.number + 1) {
|
|
93
|
+
open[open.length - 1] = { ...item, indent: indentOf(parent) };
|
|
94
|
+
return { item, previous: parent };
|
|
95
|
+
}
|
|
96
|
+
open.push(item);
|
|
97
|
+
return { item, previous: item.number === 1 || item.number === (nestedLast(parent) ?? 0) + 1 ? undefined : parent };
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Each item whose number is not one more than the item it follows. A list that writes one number on every item (「1.」
|
|
103
|
+
* on each, which Markdown counts up) is numbered by the renderer, not by the writer, and is not read. An item numbered 1
|
|
25
104
|
* starts a new count, as the structure rule reads a 1 that follows other items.
|
|
26
105
|
*/
|
|
27
|
-
export const listNumberBreaks = (items: readonly WrittenNumber[]): StructureIssue[] => {
|
|
106
|
+
export const listNumberBreaks = (items: readonly WrittenNumber[], nestedLast: NestedLast = () => undefined): StructureIssue[] => {
|
|
28
107
|
if (new Set(items.map((item) => item.number)).size < 2) return [];
|
|
29
|
-
return items.flatMap((item,
|
|
30
|
-
const previous = items[index - 1];
|
|
108
|
+
return comparedPairs(items, nestedLast).flatMap(({ item, previous }) => {
|
|
31
109
|
if (previous === undefined || item.number === previous.number + 1 || item.number === 1) return [];
|
|
32
110
|
return [{ offset: item.offset, values: { previous: previous.label, label: item.label, expected: previous.number + 1, found: item.number } }];
|
|
33
111
|
});
|
|
34
112
|
};
|
|
113
|
+
|
|
114
|
+
type ListSpans = { readonly span: Span; readonly itemSpans: readonly Span[] };
|
|
115
|
+
|
|
116
|
+
/** The breaks in the document's lists that are checked; every list, checked or not, tells which ordered list sits inside an item. */
|
|
117
|
+
export const listsNumberBreaks = (source: string, lists: readonly ListSpans[], isChecked: (list: ListSpans) => boolean): StructureIssue[] => {
|
|
118
|
+
const nestedLast = nestedLastFinder(
|
|
119
|
+
source,
|
|
120
|
+
lists.map((list) => list.itemSpans),
|
|
121
|
+
);
|
|
122
|
+
return lists.filter(isChecked).flatMap((list) => listNumberBreaks(writtenNumbers(source, list.itemSpans) ?? [], nestedLast));
|
|
123
|
+
};
|