chaffjs 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/api.d.ts +16 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js.map +1 -1
- package/dist/cli-text.d.ts +2 -0
- package/dist/cli-text.d.ts.map +1 -1
- package/dist/cli-text.js +14 -5
- package/dist/cli-text.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/command-help.d.ts +7 -0
- package/dist/command-help.d.ts.map +1 -0
- package/dist/command-help.js +18 -0
- package/dist/command-help.js.map +1 -0
- package/dist/commands/eval.js +2 -2
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/fix-plan.d.ts.map +1 -1
- package/dist/commands/fix-plan.js +11 -1
- package/dist/commands/fix-plan.js.map +1 -1
- package/dist/commands/help.d.ts +4 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +7 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/config/load.d.ts +2 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +1 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/option-problems.js +2 -2
- package/dist/config/option-problems.js.map +1 -1
- package/dist/config/rule-problems.js +2 -2
- package/dist/config/rule-problems.js.map +1 -1
- package/dist/custom/checked.d.ts +9 -0
- package/dist/custom/checked.d.ts.map +1 -0
- package/dist/custom/checked.js +3 -0
- package/dist/custom/checked.js.map +1 -0
- package/dist/custom/dsl-fields.d.ts +27 -0
- package/dist/custom/dsl-fields.d.ts.map +1 -0
- package/dist/custom/dsl-fields.js +86 -0
- package/dist/custom/dsl-fields.js.map +1 -0
- package/dist/custom/load.d.ts.map +1 -1
- package/dist/custom/load.js +2 -0
- package/dist/custom/load.js.map +1 -1
- package/dist/custom/parse.d.ts +14 -3
- package/dist/custom/parse.d.ts.map +1 -1
- package/dist/custom/parse.js +44 -40
- package/dist/custom/parse.js.map +1 -1
- package/dist/custom/problems.d.ts.map +1 -1
- package/dist/custom/problems.js +11 -1
- package/dist/custom/problems.js.map +1 -1
- package/dist/detectors/blank-structure.d.ts.map +1 -1
- package/dist/detectors/blank-structure.js +6 -4
- package/dist/detectors/blank-structure.js.map +1 -1
- package/dist/detectors/clause-shape.d.ts +22 -0
- package/dist/detectors/clause-shape.d.ts.map +1 -0
- package/dist/detectors/clause-shape.js +149 -0
- package/dist/detectors/clause-shape.js.map +1 -0
- package/dist/detectors/code-fences.d.ts +34 -0
- package/dist/detectors/code-fences.d.ts.map +1 -0
- package/dist/detectors/code-fences.js +100 -0
- package/dist/detectors/code-fences.js.map +1 -0
- package/dist/detectors/cross-definitions.d.ts +4 -0
- package/dist/detectors/cross-definitions.d.ts.map +1 -0
- package/dist/detectors/cross-definitions.js +43 -0
- package/dist/detectors/cross-definitions.js.map +1 -0
- package/dist/detectors/cross-facts.d.ts +4 -0
- package/dist/detectors/cross-facts.d.ts.map +1 -0
- package/dist/detectors/cross-facts.js +53 -0
- package/dist/detectors/cross-facts.js.map +1 -0
- package/dist/detectors/cross-registry/cross-doc-duplicate-definition.d.ts +3 -0
- package/dist/detectors/cross-registry/cross-doc-duplicate-definition.d.ts.map +1 -0
- package/dist/detectors/cross-registry/cross-doc-duplicate-definition.js +3 -0
- package/dist/detectors/cross-registry/cross-doc-duplicate-definition.js.map +1 -0
- package/dist/detectors/cross-registry/cross-doc-fact-conflict.d.ts +3 -0
- package/dist/detectors/cross-registry/cross-doc-fact-conflict.d.ts.map +1 -0
- package/dist/detectors/cross-registry/cross-doc-fact-conflict.js +3 -0
- package/dist/detectors/cross-registry/cross-doc-fact-conflict.js.map +1 -0
- package/dist/detectors/custom.d.ts.map +1 -1
- package/dist/detectors/custom.js +4 -1
- package/dist/detectors/custom.js.map +1 -1
- package/dist/detectors/defined-term-form.d.ts +25 -0
- package/dist/detectors/defined-term-form.d.ts.map +1 -0
- package/dist/detectors/defined-term-form.js +170 -0
- package/dist/detectors/defined-term-form.js.map +1 -0
- package/dist/detectors/email-letter.d.ts +46 -0
- package/dist/detectors/email-letter.d.ts.map +1 -0
- package/dist/detectors/email-letter.js +234 -0
- package/dist/detectors/email-letter.js.map +1 -0
- package/dist/detectors/impossible-date.d.ts +20 -0
- package/dist/detectors/impossible-date.d.ts.map +1 -0
- package/dist/detectors/impossible-date.js +105 -0
- package/dist/detectors/impossible-date.js.map +1 -0
- package/dist/detectors/impossible-time.d.ts +18 -0
- package/dist/detectors/impossible-time.d.ts.map +1 -0
- package/dist/detectors/impossible-time.js +116 -0
- package/dist/detectors/impossible-time.js.map +1 -0
- package/dist/detectors/link-shape.d.ts +11 -0
- package/dist/detectors/link-shape.d.ts.map +1 -0
- package/dist/detectors/link-shape.js +56 -0
- package/dist/detectors/link-shape.js.map +1 -0
- package/dist/detectors/mark-shape.d.ts +53 -0
- package/dist/detectors/mark-shape.d.ts.map +1 -0
- package/dist/detectors/mark-shape.js +160 -0
- package/dist/detectors/mark-shape.js.map +1 -0
- package/dist/detectors/registry/adverb-polarity.d.ts +3 -0
- package/dist/detectors/registry/adverb-polarity.d.ts.map +1 -0
- package/dist/detectors/registry/adverb-polarity.js +3 -0
- package/dist/detectors/registry/adverb-polarity.js.map +1 -0
- package/dist/detectors/registry/attachment-missing.d.ts +3 -0
- package/dist/detectors/registry/attachment-missing.d.ts.map +1 -0
- package/dist/detectors/registry/attachment-missing.js +3 -0
- package/dist/detectors/registry/attachment-missing.js.map +1 -0
- package/dist/detectors/registry/bare-url-mix.d.ts +3 -0
- package/dist/detectors/registry/bare-url-mix.d.ts.map +1 -0
- package/dist/detectors/registry/bare-url-mix.js +3 -0
- package/dist/detectors/registry/bare-url-mix.js.map +1 -0
- package/dist/detectors/registry/caps-shouting.d.ts +3 -0
- package/dist/detectors/registry/caps-shouting.d.ts.map +1 -0
- package/dist/detectors/registry/caps-shouting.js +3 -0
- package/dist/detectors/registry/caps-shouting.js.map +1 -0
- package/dist/detectors/registry/code-fence-language.d.ts +3 -0
- package/dist/detectors/registry/code-fence-language.d.ts.map +1 -0
- package/dist/detectors/registry/code-fence-language.js +3 -0
- package/dist/detectors/registry/code-fence-language.js.map +1 -0
- package/dist/detectors/registry/defined-name-repeated.d.ts +3 -0
- package/dist/detectors/registry/defined-name-repeated.d.ts.map +1 -0
- package/dist/detectors/registry/defined-name-repeated.js +3 -0
- package/dist/detectors/registry/defined-name-repeated.js.map +1 -0
- package/dist/detectors/registry/defined-term-form.d.ts +3 -0
- package/dist/detectors/registry/defined-term-form.d.ts.map +1 -0
- package/dist/detectors/registry/defined-term-form.js +3 -0
- package/dist/detectors/registry/defined-term-form.js.map +1 -0
- package/dist/detectors/registry/email-frame.d.ts +3 -0
- package/dist/detectors/registry/email-frame.d.ts.map +1 -0
- package/dist/detectors/registry/email-frame.js +3 -0
- package/dist/detectors/registry/email-frame.js.map +1 -0
- package/dist/detectors/registry/email-subject.d.ts +3 -0
- package/dist/detectors/registry/email-subject.d.ts.map +1 -0
- package/dist/detectors/registry/email-subject.js +3 -0
- package/dist/detectors/registry/email-subject.js.map +1 -0
- package/dist/detectors/registry/ending-run.d.ts +3 -0
- package/dist/detectors/registry/ending-run.d.ts.map +1 -0
- package/dist/detectors/registry/ending-run.js +3 -0
- package/dist/detectors/registry/ending-run.js.map +1 -0
- package/dist/detectors/registry/heading-command.d.ts +3 -0
- package/dist/detectors/registry/heading-command.d.ts.map +1 -0
- package/dist/detectors/registry/heading-command.js +3 -0
- package/dist/detectors/registry/heading-command.js.map +1 -0
- package/dist/detectors/registry/hyphen-dash.d.ts +3 -0
- package/dist/detectors/registry/hyphen-dash.d.ts.map +1 -0
- package/dist/detectors/registry/hyphen-dash.js +3 -0
- package/dist/detectors/registry/hyphen-dash.js.map +1 -0
- package/dist/detectors/registry/image-file-name-alt.d.ts +3 -0
- package/dist/detectors/registry/image-file-name-alt.d.ts.map +1 -0
- package/dist/detectors/registry/image-file-name-alt.js +3 -0
- package/dist/detectors/registry/image-file-name-alt.js.map +1 -0
- package/dist/detectors/registry/impossible-date.d.ts +3 -0
- package/dist/detectors/registry/impossible-date.d.ts.map +1 -0
- package/dist/detectors/registry/impossible-date.js +3 -0
- package/dist/detectors/registry/impossible-date.js.map +1 -0
- package/dist/detectors/registry/impossible-time.d.ts +3 -0
- package/dist/detectors/registry/impossible-time.d.ts.map +1 -0
- package/dist/detectors/registry/impossible-time.js +3 -0
- package/dist/detectors/registry/impossible-time.js.map +1 -0
- package/dist/detectors/registry/latin-abbreviation.d.ts +3 -0
- package/dist/detectors/registry/latin-abbreviation.d.ts.map +1 -0
- package/dist/detectors/registry/latin-abbreviation.js +3 -0
- package/dist/detectors/registry/latin-abbreviation.js.map +1 -0
- package/dist/detectors/registry/link-text-url-mismatch.d.ts +3 -0
- package/dist/detectors/registry/link-text-url-mismatch.d.ts.map +1 -0
- package/dist/detectors/registry/link-text-url-mismatch.js +3 -0
- package/dist/detectors/registry/link-text-url-mismatch.js.map +1 -0
- package/dist/detectors/registry/mark-consistency.d.ts +3 -0
- package/dist/detectors/registry/mark-consistency.d.ts.map +1 -0
- package/dist/detectors/registry/mark-consistency.js +3 -0
- package/dist/detectors/registry/mark-consistency.js.map +1 -0
- package/dist/detectors/registry/origin-particle.d.ts +3 -0
- package/dist/detectors/registry/origin-particle.d.ts.map +1 -0
- package/dist/detectors/registry/origin-particle.js +3 -0
- package/dist/detectors/registry/origin-particle.js.map +1 -0
- package/dist/detectors/registry/request-without-deadline.d.ts +3 -0
- package/dist/detectors/registry/request-without-deadline.d.ts.map +1 -0
- package/dist/detectors/registry/request-without-deadline.js +3 -0
- package/dist/detectors/registry/request-without-deadline.js.map +1 -0
- package/dist/detectors/registry/sentence-spacing.d.ts +3 -0
- package/dist/detectors/registry/sentence-spacing.d.ts.map +1 -0
- package/dist/detectors/registry/sentence-spacing.js +3 -0
- package/dist/detectors/registry/sentence-spacing.js.map +1 -0
- package/dist/detectors/registry/shell-prompt.d.ts +3 -0
- package/dist/detectors/registry/shell-prompt.d.ts.map +1 -0
- package/dist/detectors/registry/shell-prompt.js +3 -0
- package/dist/detectors/registry/shell-prompt.js.map +1 -0
- package/dist/detectors/registry/step-statement.d.ts +3 -0
- package/dist/detectors/registry/step-statement.d.ts.map +1 -0
- package/dist/detectors/registry/step-statement.js +3 -0
- package/dist/detectors/registry/step-statement.js.map +1 -0
- package/dist/detectors/registry/unpaired-parallel.d.ts +3 -0
- package/dist/detectors/registry/unpaired-parallel.d.ts.map +1 -0
- package/dist/detectors/registry/unpaired-parallel.js +3 -0
- package/dist/detectors/registry/unpaired-parallel.js.map +1 -0
- package/dist/detectors/request-owner.d.ts +23 -0
- package/dist/detectors/request-owner.d.ts.map +1 -0
- package/dist/detectors/request-owner.js +110 -0
- package/dist/detectors/request-owner.js.map +1 -0
- package/dist/detectors/technical-docs.d.ts +32 -0
- package/dist/detectors/technical-docs.d.ts.map +1 -0
- package/dist/detectors/technical-docs.js +199 -0
- package/dist/detectors/technical-docs.js.map +1 -0
- package/dist/extension/pack-read.d.ts +21 -0
- package/dist/extension/pack-read.d.ts.map +1 -0
- package/dist/extension/pack-read.js +117 -0
- package/dist/extension/pack-read.js.map +1 -0
- package/dist/extension/plugin-load.d.ts.map +1 -1
- package/dist/extension/plugin-load.js +44 -10
- package/dist/extension/plugin-load.js.map +1 -1
- package/dist/extension/plugin-parse.d.ts.map +1 -1
- package/dist/extension/plugin-parse.js +10 -3
- package/dist/extension/plugin-parse.js.map +1 -1
- package/dist/facts/address-values.d.ts +5 -0
- package/dist/facts/address-values.d.ts.map +1 -0
- package/dist/facts/address-values.js +64 -0
- package/dist/facts/address-values.js.map +1 -0
- package/dist/facts/cross-facts.d.ts +20 -0
- package/dist/facts/cross-facts.d.ts.map +1 -0
- package/dist/facts/cross-facts.js +41 -0
- package/dist/facts/cross-facts.js.map +1 -0
- package/dist/fix-plan/chosen-depth.d.ts +10 -0
- package/dist/fix-plan/chosen-depth.d.ts.map +1 -0
- package/dist/fix-plan/chosen-depth.js +24 -0
- package/dist/fix-plan/chosen-depth.js.map +1 -0
- package/dist/fix-plan/mode.d.ts +13 -4
- package/dist/fix-plan/mode.d.ts.map +1 -1
- package/dist/fix-plan/mode.js +38 -7
- package/dist/fix-plan/mode.js.map +1 -1
- package/dist/fix-plan/plan.d.ts +20 -0
- package/dist/fix-plan/plan.d.ts.map +1 -1
- package/dist/fix-plan/plan.js +23 -5
- package/dist/fix-plan/plan.js.map +1 -1
- package/dist/fix-plan/render.d.ts.map +1 -1
- package/dist/fix-plan/render.js +24 -0
- package/dist/fix-plan/render.js.map +1 -1
- package/dist/fix-plan/text.d.ts +8 -0
- package/dist/fix-plan/text.d.ts.map +1 -1
- package/dist/fix-plan/text.js +36 -10
- package/dist/fix-plan/text.js.map +1 -1
- package/dist/genre-load.d.ts +1 -1
- package/dist/genre-load.d.ts.map +1 -1
- package/dist/genre-load.js +7 -4
- package/dist/genre-load.js.map +1 -1
- package/dist/genre-parse.d.ts +6 -0
- package/dist/genre-parse.d.ts.map +1 -1
- package/dist/genre-parse.js +18 -0
- package/dist/genre-parse.js.map +1 -1
- package/dist/init.js +10 -10
- package/dist/init.js.map +1 -1
- package/dist/known-genres.d.ts +8 -0
- package/dist/known-genres.d.ts.map +1 -0
- package/dist/known-genres.js +17 -0
- package/dist/known-genres.js.map +1 -0
- package/dist/link-shape.d.ts +20 -0
- package/dist/link-shape.d.ts.map +1 -0
- package/dist/link-shape.js +58 -0
- package/dist/link-shape.js.map +1 -0
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +15 -4
- package/dist/reasons.js.map +1 -1
- package/dist/render/explain.d.ts.map +1 -1
- package/dist/render/explain.js +11 -2
- package/dist/render/explain.js.map +1 -1
- package/dist/render/friendly.js +1 -1
- package/dist/render/friendly.js.map +1 -1
- package/dist/render/rules-json.d.ts.map +1 -1
- package/dist/render/rules-json.js +12 -3
- package/dist/render/rules-json.js.map +1 -1
- package/dist/render/rules-table.js +6 -6
- package/dist/render/rules-table.js.map +1 -1
- package/dist/render/semantic.js +2 -2
- package/dist/render/semantic.js.map +1 -1
- package/dist/render/suppressions.js +2 -2
- package/dist/render/suppressions.js.map +1 -1
- package/dist/rewrite-depth.d.ts +22 -0
- package/dist/rewrite-depth.d.ts.map +1 -0
- package/dist/rewrite-depth.js +42 -0
- package/dist/rewrite-depth.js.map +1 -0
- package/dist/rule-fields.d.ts +23 -0
- package/dist/rule-fields.d.ts.map +1 -0
- package/dist/rule-fields.js +64 -0
- package/dist/rule-fields.js.map +1 -0
- package/dist/rule-guide.d.ts +3 -0
- package/dist/rule-guide.d.ts.map +1 -1
- package/dist/rule-guide.js +6 -0
- package/dist/rule-guide.js.map +1 -1
- package/dist/rule-load.d.ts.map +1 -1
- package/dist/rule-load.js +13 -5
- package/dist/rule-load.js.map +1 -1
- package/dist/rule-offs.d.ts +14 -0
- package/dist/rule-offs.d.ts.map +1 -0
- package/dist/rule-offs.js +45 -0
- package/dist/rule-offs.js.map +1 -0
- package/dist/structure/build.d.ts.map +1 -1
- package/dist/structure/build.js +14 -1
- package/dist/structure/build.js.map +1 -1
- package/dist/structure/cross-definitions.d.ts +23 -0
- package/dist/structure/cross-definitions.d.ts.map +1 -0
- package/dist/structure/cross-definitions.js +34 -0
- package/dist/structure/cross-definitions.js.map +1 -0
- package/genres.yaml +14 -313
- package/package.json +3 -3
- package/rules/absolute-exception.yaml +3 -1
- package/rules/abstract-length.yaml +7 -1
- package/rules/acronym-expansion-conflict.yaml +2 -1
- package/rules/adverb-overuse.yaml +7 -1
- package/rules/adverb-without-negation.yaml +60 -0
- package/rules/adversative-ga-repeat.yaml +2 -1
- package/rules/agentless-passive.yaml +10 -1
- package/rules/agreement-slip.yaml +4 -1
- package/rules/ai-generated-composite.yaml +6 -1
- package/rules/ai-structure.yaml +8 -2
- package/rules/ai-tell.yaml +7 -1
- package/rules/all-caps-shouting.yaml +61 -0
- package/rules/announced-count-mismatch.yaml +3 -1
- package/rules/announcing-opener.yaml +7 -1
- package/rules/article-sound.yaml +6 -2
- package/rules/assistant-residue.yaml +4 -1
- package/rules/attachment-not-attached.yaml +112 -0
- package/rules/baito-keigo.yaml +64 -0
- package/rules/bare-url-mix.yaml +86 -0
- package/rules/bold-density.yaml +1 -0
- package/rules/bold-label-list.yaml +9 -1
- package/rules/bracket-nesting.yaml +2 -1
- package/rules/bracket-width-consistency.yaml +64 -0
- package/rules/broken-link.yaml +1 -1
- package/rules/chat-citation-residue.yaml +2 -1
- package/rules/citation-reference-mismatch.yaml +7 -1
- package/rules/citation-style-mix.yaml +7 -1
- package/rules/clause-chain.yaml +6 -1
- package/rules/closing-cliche.yaml +7 -0
- package/rules/code-fence-language-mix.yaml +176 -0
- package/rules/colloquial-opener.yaml +62 -0
- package/rules/colon-lead-in.yaml +7 -1
- package/rules/concrete-evidence-density.yaml +6 -0
- package/rules/contraction-consistency.yaml +4 -1
- package/rules/contrast-framing.yaml +7 -1
- package/rules/cross-doc-duplicate-definition.yaml +70 -0
- package/rules/cross-doc-fact-conflict.yaml +64 -0
- package/rules/cushion-phrase-density.yaml +8 -1
- package/rules/dangling-figure-reference.yaml +3 -1
- package/rules/dangling-reference.yaml +3 -1
- package/rules/date-format-consistency.yaml +3 -2
- package/rules/date-order.yaml +3 -1
- package/rules/date-range-reversed.yaml +3 -1
- package/rules/date-weekday-mismatch.yaml +3 -1
- package/rules/date-without-year.yaml +4 -3
- package/rules/defined-name-repeated.yaml +97 -0
- package/rules/defined-term-form.yaml +113 -0
- package/rules/demonstrative-opener-run.yaml +2 -1
- package/rules/double-keigo.yaml +6 -1
- package/rules/double-negative.yaml +5 -1
- package/rules/doubled-nado.yaml +2 -1
- package/rules/doubled-punctuation.yaml +1 -1
- package/rules/doubled-word.yaml +4 -1
- package/rules/duplicate-definition.yaml +3 -1
- package/rules/duplicate-heading.yaml +1 -1
- package/rules/duration-mismatch.yaml +2 -1
- package/rules/elapsed-years-mismatch.yaml +4 -1
- package/rules/email-greeting-closing.yaml +122 -0
- package/rules/email-subject-length.yaml +112 -0
- package/rules/emoji-density.yaml +3 -1
- package/rules/emoji-heading.yaml +7 -1
- package/rules/empty-intensifier.yaml +4 -0
- package/rules/empty-list-item.yaml +2 -1
- package/rules/empty-section.yaml +1 -1
- package/rules/empty-table-cell.yaml +2 -1
- package/rules/excessive-hedging.yaml +7 -1
- package/rules/exclamation-width-consistency.yaml +64 -0
- package/rules/expletive-construction.yaml +7 -1
- package/rules/fact-conflict.yaml +4 -1
- package/rules/figure-reference-order.yaml +7 -1
- package/rules/fullwidth-alnum-consistency.yaml +2 -2
- package/rules/hankaku-kana.yaml +1 -1
- package/rules/heading-command-missing.yaml +109 -0
- package/rules/heading-echo.yaml +6 -1
- package/rules/heading-level-skip.yaml +3 -3
- package/rules/heading-numbering-mix.yaml +4 -3
- package/rules/hiragana-fukushi.yaml +4 -1
- package/rules/homophone-slip.yaml +5 -1
- package/rules/humble-for-others.yaml +63 -0
- package/rules/hyphen-as-dash.yaml +59 -0
- package/rules/idiom-misuse.yaml +4 -1
- package/rules/image-file-name-alt.yaml +83 -0
- package/rules/impossible-date.yaml +79 -0
- package/rules/impossible-time.yaml +76 -0
- package/rules/internal-jargon.yaml +1 -1
- package/rules/invisible-character.yaml +1 -1
- package/rules/katakana-density.yaml +2 -1
- package/rules/katakana-long-vowel.yaml +1 -1
- package/rules/known-misspelling.yaml +2 -1
- package/rules/kutoten-consistency.yaml +1 -1
- package/rules/latin-abbreviation-form.yaml +58 -0
- package/rules/latin-spacing.yaml +6 -2
- package/rules/link-text-url-mismatch.yaml +72 -0
- package/rules/list-item-form-mix.yaml +7 -1
- package/rules/max-kanji-continuous.yaml +10 -2
- package/rules/max-paragraph-length.yaml +4 -1
- package/rules/max-sentence-length.yaml +29 -21
- package/rules/max-ten.yaml +4 -1
- package/rules/misconversion.yaml +2 -1
- package/rules/modal-conflict.yaml +2 -1
- package/rules/name-variant.yaml +4 -3
- package/rules/ngram-repetition.yaml +5 -0
- package/rules/no-doubled-joshi.yaml +5 -1
- package/rules/no-em-dash.yaml +4 -1
- package/rules/no-lead.yaml +6 -1
- package/rules/no-mixed-desumasu.yaml +5 -2
- package/rules/no-nakaguro-parallel.yaml +3 -0
- package/rules/nominalization.yaml +5 -1
- package/rules/number-style-consistency.yaml +6 -1
- package/rules/number-without-unit.yaml +2 -1
- package/rules/numbering-gap.yaml +1 -1
- package/rules/one-sentence-paragraph-run.yaml +5 -1
- package/rules/orthographic-variant.yaml +4 -1
- package/rules/outside-announced-list.yaml +2 -1
- package/rules/oxford-comma-consistency.yaml +3 -1
- package/rules/padded-intro.yaml +7 -0
- package/rules/paragraph-length-variance.yaml +7 -1
- package/rules/paragraph-restatement.yaml +6 -1
- package/rules/percent-sum-mismatch.yaml +3 -1
- package/rules/person-consistency.yaml +4 -1
- package/rules/preamble-length.yaml +6 -0
- package/rules/preferred-term.yaml +1 -1
- package/rules/proper-noun-density.yaml +8 -1
- package/rules/quote-style-consistency.yaml +66 -0
- package/rules/ra-nuki.yaml +4 -1
- package/rules/redundant-expression.yaml +4 -1
- package/rules/reference-title-mismatch.yaml +4 -3
- package/rules/reference-topic-missing.yaml +2 -1
- package/rules/relative-date-mismatch.yaml +2 -1
- package/rules/repeated-conjunction.yaml +4 -1
- package/rules/repeated-sentence-ending.yaml +62 -0
- package/rules/repeated-sentence-head.yaml +4 -0
- package/rules/request-without-deadline.yaml +92 -0
- package/rules/required-sections.yaml +1 -1
- package/rules/requirement-modal.yaml +1 -1
- package/rules/requirement-smell.yaml +12 -4
- package/rules/rule-of-three.yaml +8 -1
- package/rules/sasete-itadaku.yaml +7 -1
- package/rules/section-length-uniformity.yaml +7 -1
- package/rules/sentence-initial-conjunction-run.yaml +5 -1
- package/rules/sentence-initial-so.yaml +6 -1
- package/rules/sentence-rhythm.yaml +8 -1
- package/rules/sentence-spacing-consistency.yaml +63 -0
- package/rules/shell-prompt-mix.yaml +128 -0
- package/rules/space-before-punctuation.yaml +1 -1
- package/rules/spelling-consistency.yaml +3 -1
- package/rules/step-statement-mix.yaml +76 -0
- package/rules/stock-transition.yaml +8 -1
- package/rules/stray-space.yaml +2 -2
- package/rules/summary-fact-mismatch.yaml +4 -1
- package/rules/table-header-variant.yaml +2 -1
- package/rules/taigen-dome-in-prose.yaml +6 -0
- package/rules/tari-unpaired.yaml +58 -0
- package/rules/teki-overuse.yaml +2 -1
- package/rules/title-case-consistency.yaml +1 -1
- package/rules/title-length.yaml +7 -1
- package/rules/topic-predicate-distance.yaml +6 -1
- package/rules/total-mismatch.yaml +3 -1
- package/rules/translationese-density.yaml +4 -1
- package/rules/unbalanced-bracket.yaml +3 -3
- package/rules/undefined-acronym.yaml +8 -1
- package/rules/unfilled-placeholder.yaml +1 -1
- package/rules/unit-mismatch.yaml +2 -1
- package/rules/unknown-word.yaml +4 -1
- package/rules/unqualified-superlative.yaml +6 -1
- package/rules/unused-definition.yaml +4 -3
- package/rules/url-run-on.yaml +1 -1
- package/rules/use-before-definition.yaml +4 -3
- package/rules/vague-figure-reference.yaml +3 -1
- package/rules/vague-link-text.yaml +2 -1
- package/rules/vague-word-density.yaml +2 -1
- package/rules/very-adjective.yaml +5 -1
- package/rules/weasel-word.yaml +6 -1
- package/rules/wordy-phrase.yaml +6 -1
- package/rules/yori-as-from.yaml +61 -0
- package/src/api.ts +13 -1
- package/src/cli-text.ts +18 -7
- package/src/cli.ts +3 -0
- package/src/command-help.ts +26 -0
- package/src/commands/eval.ts +2 -2
- package/src/commands/fix-plan.ts +13 -1
- package/src/commands/help.ts +8 -0
- package/src/config/load.ts +3 -0
- package/src/config/option-problems.ts +2 -2
- package/src/config/rule-problems.ts +2 -2
- package/src/custom/checked.ts +8 -0
- package/src/custom/dsl-fields.ts +102 -0
- package/src/custom/load.ts +2 -0
- package/src/custom/parse.ts +72 -50
- package/src/custom/problems.ts +18 -2
- package/src/detectors/blank-structure.ts +12 -4
- package/src/detectors/clause-shape.ts +199 -0
- package/src/detectors/code-fences.ts +113 -0
- package/src/detectors/cross-definitions.ts +49 -0
- package/src/detectors/cross-facts.ts +60 -0
- package/src/detectors/cross-registry/cross-doc-duplicate-definition.ts +4 -0
- package/src/detectors/cross-registry/cross-doc-fact-conflict.ts +4 -0
- package/src/detectors/custom.ts +10 -2
- package/src/detectors/defined-term-form.ts +200 -0
- package/src/detectors/email-letter.ts +262 -0
- package/src/detectors/impossible-date.ts +141 -0
- package/src/detectors/impossible-time.ts +151 -0
- package/src/detectors/link-shape.ts +70 -0
- package/src/detectors/mark-shape.ts +202 -0
- package/src/detectors/registry/adverb-polarity.ts +4 -0
- package/src/detectors/registry/attachment-missing.ts +4 -0
- package/src/detectors/registry/bare-url-mix.ts +4 -0
- package/src/detectors/registry/caps-shouting.ts +4 -0
- package/src/detectors/registry/code-fence-language.ts +4 -0
- package/src/detectors/registry/defined-name-repeated.ts +4 -0
- package/src/detectors/registry/defined-term-form.ts +4 -0
- package/src/detectors/registry/email-frame.ts +4 -0
- package/src/detectors/registry/email-subject.ts +4 -0
- package/src/detectors/registry/ending-run.ts +4 -0
- package/src/detectors/registry/heading-command.ts +4 -0
- package/src/detectors/registry/hyphen-dash.ts +4 -0
- package/src/detectors/registry/image-file-name-alt.ts +4 -0
- package/src/detectors/registry/impossible-date.ts +4 -0
- package/src/detectors/registry/impossible-time.ts +4 -0
- package/src/detectors/registry/latin-abbreviation.ts +4 -0
- package/src/detectors/registry/link-text-url-mismatch.ts +4 -0
- package/src/detectors/registry/mark-consistency.ts +4 -0
- package/src/detectors/registry/origin-particle.ts +4 -0
- package/src/detectors/registry/request-without-deadline.ts +4 -0
- package/src/detectors/registry/sentence-spacing.ts +4 -0
- package/src/detectors/registry/shell-prompt.ts +4 -0
- package/src/detectors/registry/step-statement.ts +4 -0
- package/src/detectors/registry/unpaired-parallel.ts +4 -0
- package/src/detectors/request-owner.ts +141 -0
- package/src/detectors/technical-docs.ts +230 -0
- package/src/extension/pack-read.ts +128 -0
- package/src/extension/plugin-load.ts +49 -9
- package/src/extension/plugin-parse.ts +10 -3
- package/src/facts/address-values.ts +74 -0
- package/src/facts/cross-facts.ts +54 -0
- package/src/fix-plan/chosen-depth.ts +28 -0
- package/src/fix-plan/mode.ts +57 -11
- package/src/fix-plan/plan.ts +37 -5
- package/src/fix-plan/render.ts +24 -0
- package/src/fix-plan/text.ts +47 -10
- package/src/genre-load.ts +7 -4
- package/src/genre-parse.ts +19 -0
- package/src/init.ts +10 -10
- package/src/known-genres.ts +19 -0
- package/src/link-shape.ts +62 -0
- package/src/reasons.ts +16 -4
- package/src/render/explain.ts +14 -2
- package/src/render/friendly.ts +1 -1
- package/src/render/rules-json.ts +14 -3
- package/src/render/rules-table.ts +6 -6
- package/src/render/semantic.ts +2 -2
- package/src/render/suppressions.ts +2 -2
- package/src/rewrite-depth.ts +60 -0
- package/src/rule-fields.ts +95 -0
- package/src/rule-guide.ts +9 -0
- package/src/rule-load.ts +10 -4
- package/src/rule-offs.ts +50 -0
- package/src/structure/build.ts +21 -1
- package/src/structure/cross-definitions.ts +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-statement.d.ts","sourceRoot":"","sources":["../../../src/detectors/registry/step-statement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD,eAAO,MAAM,QAAQ,EAAE,QAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-statement.js","sourceRoot":"","sources":["../../../src/detectors/registry/step-statement.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,CAAC,MAAM,QAAQ,GAAa,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unpaired-parallel.d.ts","sourceRoot":"","sources":["../../../src/detectors/registry/unpaired-parallel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD,eAAO,MAAM,QAAQ,EAAE,QAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unpaired-parallel.js","sourceRoot":"","sources":["../../../src/detectors/registry/unpaired-parallel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,CAAC,MAAM,QAAQ,GAAa,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Detector, ProseDocument, Sentence } from "../plugin.ts";
|
|
2
|
+
/** The lexicons the rule reads, by name. A language without them checks nothing. */
|
|
3
|
+
export declare const REQUEST_LEXICONS: {
|
|
4
|
+
readonly ending: "request-ending";
|
|
5
|
+
readonly action: "request-action";
|
|
6
|
+
readonly condition: "request-condition";
|
|
7
|
+
readonly deadline: "request-deadline";
|
|
8
|
+
readonly owner: "request-owner";
|
|
9
|
+
readonly pointer: "request-pointer";
|
|
10
|
+
};
|
|
11
|
+
type Words = Readonly<Record<keyof typeof REQUEST_LEXICONS, readonly string[]>>;
|
|
12
|
+
export declare const containsAny: (text: string, patterns: readonly string[]) => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* A request for an action: an action word next to a request ending (「確認してください」「please send」), not a condition
|
|
15
|
+
* (「ご不明な点があれば…ください」 is an offer), and not a pointer to where to read more (「詳細は資料をご確認ください」).
|
|
16
|
+
* The action has to be close to the ending, or a noun like 検討会 or 履修登録 earlier in the sentence would make one.
|
|
17
|
+
*/
|
|
18
|
+
export declare const isRequest: (text: string, words: Words) => boolean;
|
|
19
|
+
/** The request sentences with neither a deadline nor a person in them or in the sentence after, in the same paragraph or item. */
|
|
20
|
+
export declare const ownerlessRequests: (doc: ProseDocument) => Sentence[];
|
|
21
|
+
export declare const requestWithoutDeadline: Detector;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=request-owner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-owner.d.ts","sourceRoot":"","sources":["../../src/detectors/request-owner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAoB,aAAa,EAAE,QAAQ,EAAuB,MAAM,cAAc,CAAC;AAM7G,oFAAoF;AACpF,eAAO,MAAM,gBAAgB;;;;;;;CAOnB,CAAC;AAEX,KAAK,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,OAAO,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;AAmChF,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,UAAU,SAAS,MAAM,EAAE,KAAG,OAA8C,CAAC;AAIvH;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,OAAO,KAAK,KAAG,OAItD,CAAC;AAuDF,kIAAkI;AAClI,eAAO,MAAM,iBAAiB,GAAI,KAAK,aAAa,KAAG,QAAQ,EAQ9D,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,QAQhC,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { proseText } from "../measure.js";
|
|
2
|
+
import { comparableWords } from "./lexicon-match.js";
|
|
3
|
+
import { escapeRegExp } from "../orthography.js";
|
|
4
|
+
import { inDocumentOrder } from "../structure/issues.js";
|
|
5
|
+
/** The lexicons the rule reads, by name. A language without them checks nothing. */
|
|
6
|
+
export const REQUEST_LEXICONS = {
|
|
7
|
+
ending: "request-ending",
|
|
8
|
+
action: "request-action",
|
|
9
|
+
condition: "request-condition",
|
|
10
|
+
deadline: "request-deadline",
|
|
11
|
+
owner: "request-owner",
|
|
12
|
+
pointer: "request-pointer",
|
|
13
|
+
};
|
|
14
|
+
/** A clock time (14:00, 14時, 2pm) says when as much as a date does; a duration (3時間) does not. */
|
|
15
|
+
const CLOCK = /\d{1,2}\s*(?:[::]\d{2}|時(?!間)|\s?[ap]\.?m\.?(?![a-z]))/iu;
|
|
16
|
+
const patternsOf = (lexicon) => (lexicon ?? []).map((entry) => comparableWords(entry.pattern));
|
|
17
|
+
const wordsOf = (doc) => ({
|
|
18
|
+
ending: patternsOf(doc.lexicons[REQUEST_LEXICONS.ending]),
|
|
19
|
+
action: patternsOf(doc.lexicons[REQUEST_LEXICONS.action]),
|
|
20
|
+
condition: patternsOf(doc.lexicons[REQUEST_LEXICONS.condition]),
|
|
21
|
+
deadline: patternsOf(doc.lexicons[REQUEST_LEXICONS.deadline]),
|
|
22
|
+
owner: patternsOf(doc.lexicons[REQUEST_LEXICONS.owner]),
|
|
23
|
+
pointer: patternsOf(doc.lexicons[REQUEST_LEXICONS.pointer]),
|
|
24
|
+
});
|
|
25
|
+
/** How far apart, in characters, the action word and the request ending may be: the action must be what is requested. */
|
|
26
|
+
const ACTION_REACH = 12;
|
|
27
|
+
/** A Latin word matches whole words only ("by" is not in "maybe"); other scripts have no spaces to bound a word. */
|
|
28
|
+
const matcherOf = (pattern) => /^[\p{Script=Latin}\d]/u.test(pattern)
|
|
29
|
+
? new RegExp(`(?<![\\p{L}\\d])${escapeRegExp(pattern)}(?![\\p{L}\\d])`, "gu")
|
|
30
|
+
: new RegExp(escapeRegExp(pattern), "gu");
|
|
31
|
+
/** Where the lexicon's words occur in the text (after the comparable form: lower case, straight apostrophes). */
|
|
32
|
+
const placesOf = (text, patterns) => {
|
|
33
|
+
const comparable = comparableWords(text);
|
|
34
|
+
return patterns
|
|
35
|
+
.filter((pattern) => pattern !== "")
|
|
36
|
+
.flatMap((pattern) => [...comparable.matchAll(matcherOf(pattern))].map((match) => ({ start: match.index, end: match.index + match[0].length })));
|
|
37
|
+
};
|
|
38
|
+
export const containsAny = (text, patterns) => placesOf(text, patterns).length > 0;
|
|
39
|
+
const gapBetween = (left, right) => Math.max(left.start - right.end, right.start - left.end, 0);
|
|
40
|
+
/**
|
|
41
|
+
* A request for an action: an action word next to a request ending (「確認してください」「please send」), not a condition
|
|
42
|
+
* (「ご不明な点があれば…ください」 is an offer), and not a pointer to where to read more (「詳細は資料をご確認ください」).
|
|
43
|
+
* The action has to be close to the ending, or a noun like 検討会 or 履修登録 earlier in the sentence would make one.
|
|
44
|
+
*/
|
|
45
|
+
export const isRequest = (text, words) => {
|
|
46
|
+
const endings = placesOf(text, words.ending);
|
|
47
|
+
const asked = placesOf(text, words.action).some((action) => endings.some((ending) => gapBetween(action, ending) <= ACTION_REACH));
|
|
48
|
+
return asked && !containsAny(text, words.condition) && !containsAny(text, words.pointer);
|
|
49
|
+
};
|
|
50
|
+
const NAMED = new Set(["PROPN"]);
|
|
51
|
+
/** A proper noun in the request itself (「Ito, please share」) names who; one in the next sentence may be a product or a place. */
|
|
52
|
+
const namesSomeone = (sentence) => (sentence.tokens ?? []).some((token) => NAMED.has(token.pos));
|
|
53
|
+
const datedWithin = (dates, span) => dates.some((date) => date.start >= span.start && date.start < span.end);
|
|
54
|
+
/** Where the sentence's words start and end in its comparable text, found by walking the token surfaces in order. */
|
|
55
|
+
const wordBounds = (comparable, sentence) => {
|
|
56
|
+
const tokens = sentence.tokens;
|
|
57
|
+
if (tokens === undefined || tokens.length === 0)
|
|
58
|
+
return undefined;
|
|
59
|
+
const starts = new Set();
|
|
60
|
+
const ends = new Set();
|
|
61
|
+
tokens.reduce((from, token) => {
|
|
62
|
+
const surface = comparableWords(token.surface);
|
|
63
|
+
const at = surface === "" ? -1 : comparable.indexOf(surface, from);
|
|
64
|
+
if (at === -1)
|
|
65
|
+
return from;
|
|
66
|
+
starts.add(at);
|
|
67
|
+
ends.add(at + surface.length);
|
|
68
|
+
return at + surface.length;
|
|
69
|
+
}, 0);
|
|
70
|
+
return { starts, ends };
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Whether the sentence holds one of the words as whole words. With parts of speech a word must start and end on a word
|
|
74
|
+
* boundary, so 様 is not found in 同様, さん in たくさん, or まで in いままで; without them, as text.
|
|
75
|
+
*/
|
|
76
|
+
const holdsWord = (sentence, patterns) => {
|
|
77
|
+
const comparable = comparableWords(proseText(sentence));
|
|
78
|
+
const bounds = wordBounds(comparable, sentence);
|
|
79
|
+
return placesOf(comparable, patterns).some((place) => bounds === undefined || (bounds.starts.has(place.start) && bounds.ends.has(place.end)));
|
|
80
|
+
};
|
|
81
|
+
/** Whether a sentence says when (a date, a clock time, a deadline word) or who (a role; a name in the request itself). */
|
|
82
|
+
const saysWhenOrWho = (sentence, words, dates, isRequestItself) => datedWithin(dates, sentence.span) ||
|
|
83
|
+
CLOCK.test(proseText(sentence)) ||
|
|
84
|
+
holdsWord(sentence, words.deadline) ||
|
|
85
|
+
holdsWord(sentence, words.owner) ||
|
|
86
|
+
(isRequestItself && namesSomeone(sentence));
|
|
87
|
+
/** A paragraph break or a new list item between two sentences: the second does not continue the first. */
|
|
88
|
+
const BREAK = /\n[^\S\n]*\n|\n[^\S\n]*(?:[-*+]|\d+[.)])[^\S\n]/u;
|
|
89
|
+
const continues = (source, sentence, next) => next !== undefined && !BREAK.test(source.slice(sentence.span.end, next.span.start));
|
|
90
|
+
const dateSpans = (tree) => tree === undefined ? [] : inDocumentOrder(tree).flatMap((node) => (node.kind === "date" ? [node.span] : []));
|
|
91
|
+
/** The request sentences with neither a deadline nor a person in them or in the sentence after, in the same paragraph or item. */
|
|
92
|
+
export const ownerlessRequests = (doc) => {
|
|
93
|
+
const words = wordsOf(doc);
|
|
94
|
+
const dates = dateSpans(doc.structure);
|
|
95
|
+
return doc.sentences.filter((sentence, index) => {
|
|
96
|
+
if (!isRequest(proseText(sentence), words) || saysWhenOrWho(sentence, words, dates, true))
|
|
97
|
+
return false;
|
|
98
|
+
const next = doc.sentences[index + 1];
|
|
99
|
+
return !continues(doc.source, sentence, next) || !saysWhenOrWho(next, words, dates, false);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
export const requestWithoutDeadline = (doc) => ownerlessRequests(doc).map((sentence) => ({
|
|
103
|
+
rule: "request-without-deadline",
|
|
104
|
+
severity: "info",
|
|
105
|
+
line: 0,
|
|
106
|
+
column: 0,
|
|
107
|
+
quote: proseText(sentence),
|
|
108
|
+
values: { offset: sentence.span.start },
|
|
109
|
+
}));
|
|
110
|
+
//# sourceMappingURL=request-owner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-owner.js","sourceRoot":"","sources":["../../src/detectors/request-owner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,oFAAoF;AACpF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,MAAM,EAAE,gBAAgB;IACxB,MAAM,EAAE,gBAAgB;IACxB,SAAS,EAAE,mBAAmB;IAC9B,QAAQ,EAAE,kBAAkB;IAC5B,KAAK,EAAE,eAAe;IACtB,OAAO,EAAE,iBAAiB;CAClB,CAAC;AAIX,kGAAkG;AAClG,MAAM,KAAK,GAAG,0DAA0D,CAAC;AAEzE,MAAM,UAAU,GAAG,CAAC,OAA4B,EAAY,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAE9H,MAAM,OAAO,GAAG,CAAC,GAAkB,EAAS,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzD,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC/D,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7D,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvD,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAC5D,CAAC,CAAC;AAEH,yHAAyH;AACzH,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,oHAAoH;AACpH,MAAM,SAAS,GAAG,CAAC,OAAe,EAAU,EAAE,CAC5C,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC;IACpC,CAAC,CAAC,IAAI,MAAM,CAAC,mBAAmB,YAAY,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;IAC7E,CAAC,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AAI9C,iHAAiH;AACjH,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,QAA2B,EAAW,EAAE;IACtE,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,QAAQ;SACZ,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC;SACnC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AACrJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,QAA2B,EAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAEvH,MAAM,UAAU,GAAG,CAAC,IAAW,EAAE,KAAY,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAEtH;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,KAAY,EAAW,EAAE;IAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;IAClI,OAAO,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3F,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAEjC,iIAAiI;AACjI,MAAM,YAAY,GAAG,CAAC,QAAkB,EAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAEpH,MAAM,WAAW,GAAG,CAAC,KAAsB,EAAE,IAAU,EAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;AAI7I,qHAAqH;AACrH,MAAM,UAAU,GAAG,CAAC,UAAkB,EAAE,QAAkB,EAAsB,EAAE;IAChF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,EAAE,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnE,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;IACN,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAE,QAA2B,EAAW,EAAE;IAC7E,MAAM,UAAU,GAAG,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChJ,CAAC,CAAC;AAEF,0HAA0H;AAC1H,MAAM,aAAa,GAAG,CAAC,QAAkB,EAAE,KAAY,EAAE,KAAsB,EAAE,eAAwB,EAAW,EAAE,CACpH,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/B,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;IACnC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC;IAChC,CAAC,eAAe,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AAE9C,0GAA0G;AAC1G,MAAM,KAAK,GAAG,kDAAkD,CAAC;AAEjE,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,QAAkB,EAAE,IAA0B,EAAoB,EAAE,CACrG,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAEtF,MAAM,SAAS,GAAG,CAAC,IAA+B,EAAU,EAAE,CAC5D,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE/G,kIAAkI;AAClI,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAkB,EAAc,EAAE;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC9C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,IAAI,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxG,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAa,CAAC,GAAkB,EAAa,EAAE,CAChF,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,MAAM;IAChB,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC;IAC1B,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE;CACxC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type CodeFence } from "./code-fences.ts";
|
|
2
|
+
import type { Detector, Token } from "../plugin.ts";
|
|
3
|
+
/** The members of the less used of two kinds: at most limit of them, and fewer than the other kind. */
|
|
4
|
+
export declare const minorityOf: <T>(first: readonly T[], second: readonly T[], limit: number) => readonly T[];
|
|
5
|
+
/** Fences without a language, when they are the fewer kind: a document that mostly leaves the language out is not reported. */
|
|
6
|
+
export declare const untaggedFewer: (fences: readonly CodeFence[], limit: number) => readonly CodeFence[];
|
|
7
|
+
export declare const codeFenceLanguage: Detector;
|
|
8
|
+
export type PromptStyle = "prompt" | "bare" | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Whether a shell block writes its commands after a prompt ($ npm install) or bare (npm install). A block that mixes
|
|
11
|
+
* prompted and unprompted lines shows a command with its output, and is neither. Comment lines (#) are skipped.
|
|
12
|
+
*/
|
|
13
|
+
export declare const promptStyleOf: (fence: CodeFence, prompts: readonly string[]) => PromptStyle;
|
|
14
|
+
export declare const shellPrompt: Detector;
|
|
15
|
+
export declare const isCommandName: (text: string) => boolean;
|
|
16
|
+
/** The heading without its links' text: [`net`](/pkg/net/) names the page it links to, not a command shown below. */
|
|
17
|
+
export declare const withoutLinks: (heading: string) => string;
|
|
18
|
+
/** The commands and options a heading names: its code spans that read as one, and bare flags (--force). */
|
|
19
|
+
export declare const commandsIn: (heading: string) => string[];
|
|
20
|
+
/** Whether the code holds the command as a whole word: --force is not --force-with-lease, init is not initial. */
|
|
21
|
+
export declare const showsCommand: (code: string, command: string) => boolean;
|
|
22
|
+
export declare const headingCommand: Detector;
|
|
23
|
+
/**
|
|
24
|
+
* A step written as a statement: a subject, then its verb. The subject opens with an article or a pronoun (The installer
|
|
25
|
+
* asks, You click), or it is a name or a noun whose verb is inflected (Docker builds). A noun before a base-form verb is
|
|
26
|
+
* not enough: the tagger reads Click and Press there as nouns (Click Save).
|
|
27
|
+
*/
|
|
28
|
+
export declare const isStatement: (tokens: readonly Token[]) => boolean;
|
|
29
|
+
/** A step that opens with its verb: an instruction (Run the installer). */
|
|
30
|
+
export declare const isInstruction: (tokens: readonly Token[]) => boolean;
|
|
31
|
+
export declare const stepStatement: Detector;
|
|
32
|
+
//# sourceMappingURL=technical-docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"technical-docs.d.ts","sourceRoot":"","sources":["../../src/detectors/technical-docs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAgC,KAAK,EAAE,MAAM,cAAc,CAAC;AAIlF,uGAAuG;AACvG,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,OAAO,SAAS,CAAC,EAAE,EAAE,QAAQ,SAAS,CAAC,EAAE,EAAE,OAAO,MAAM,KAAG,SAAS,CAAC,EAGlG,CAAC;AAWF,+HAA+H;AAC/H,eAAO,MAAM,aAAa,GAAI,QAAQ,SAAS,SAAS,EAAE,EAAE,OAAO,MAAM,KAAG,SAAS,SAAS,EAI7F,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,QAM/B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,SAAS,EAAE,SAAS,SAAS,MAAM,EAAE,KAAG,WAM5E,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,QASzB,CAAC;AASF,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,OAI5C,CAAC;AAEF,qHAAqH;AACrH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAY9C,CAAC;AAUF,2GAA2G;AAC3G,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,MAAM,EAOlD,CAAC;AAKF,kHAAkH;AAClH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,OAW5D,CAAC;AAsBF,eAAO,MAAM,cAAc,EAAE,QAS5B,CAAC;AAsBF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,SAAS,KAAK,EAAE,KAAG,OAUtD,CAAC;AAIF,2EAA2E;AAC3E,eAAO,MAAM,aAAa,GAAI,QAAQ,SAAS,KAAK,EAAE,KAAG,OAA6F,CAAC;AAqBvJ,eAAO,MAAM,aAAa,EAAE,QASxB,CAAC"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// Checks a README or a manual needs: code fences tagged with a language or not, shell commands written with and without
|
|
2
|
+
// a prompt, a heading that names a command its section's code never shows, and a step of a numbered procedure written
|
|
3
|
+
// as a statement among instructions. Pure. Shell languages and prompt marks come from the shell-fence-language and
|
|
4
|
+
// shell-prompt lexicons.
|
|
5
|
+
import { codeFences, codeSpans } from "./code-fences.js";
|
|
6
|
+
import { quoteAt } from "./structure-tree.js";
|
|
7
|
+
const patternsOf = (doc, id) => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
|
|
8
|
+
/** The members of the less used of two kinds: at most limit of them, and fewer than the other kind. */
|
|
9
|
+
export const minorityOf = (first, second, limit) => {
|
|
10
|
+
const [fewer, more] = first.length <= second.length ? [first, second] : [second, first];
|
|
11
|
+
return fewer.length > 0 && fewer.length < more.length && fewer.length <= limit ? fewer : [];
|
|
12
|
+
};
|
|
13
|
+
const finding = (doc, rule, offset, values = {}) => ({
|
|
14
|
+
rule,
|
|
15
|
+
severity: "info",
|
|
16
|
+
line: 0,
|
|
17
|
+
column: 0,
|
|
18
|
+
quote: quoteAt(doc.source, offset),
|
|
19
|
+
values: { ...values, offset },
|
|
20
|
+
});
|
|
21
|
+
/** Fences without a language, when they are the fewer kind: a document that mostly leaves the language out is not reported. */
|
|
22
|
+
export const untaggedFewer = (fences, limit) => {
|
|
23
|
+
const untagged = fences.filter((fence) => fence.language === "");
|
|
24
|
+
const tagged = fences.filter((fence) => fence.language !== "");
|
|
25
|
+
return untagged.length > 0 && untagged.length < tagged.length && untagged.length <= limit ? untagged : [];
|
|
26
|
+
};
|
|
27
|
+
export const codeFenceLanguage = (doc, options) => {
|
|
28
|
+
const fences = codeFences(doc.source);
|
|
29
|
+
const tagged = fences.filter((fence) => fence.language !== "").length;
|
|
30
|
+
return untaggedFewer(fences, options.limit).map((fence) => finding(doc, "code-fence-language-mix", fence.start, { tagged, untagged: fences.length - tagged }));
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Whether a shell block writes its commands after a prompt ($ npm install) or bare (npm install). A block that mixes
|
|
34
|
+
* prompted and unprompted lines shows a command with its output, and is neither. Comment lines (#) are skipped.
|
|
35
|
+
*/
|
|
36
|
+
export const promptStyleOf = (fence, prompts) => {
|
|
37
|
+
const lines = fence.lines.map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("#"));
|
|
38
|
+
if (lines.length === 0)
|
|
39
|
+
return undefined;
|
|
40
|
+
const prompted = lines.filter((line) => prompts.some((prompt) => line.startsWith(`${prompt} `))).length;
|
|
41
|
+
if (prompted === lines.length)
|
|
42
|
+
return "prompt";
|
|
43
|
+
return prompted === 0 ? "bare" : undefined;
|
|
44
|
+
};
|
|
45
|
+
export const shellPrompt = (doc, options) => {
|
|
46
|
+
const languages = new Set(patternsOf(doc, "shell-fence-language").map((language) => language.toLowerCase()));
|
|
47
|
+
const prompts = patternsOf(doc, "shell-prompt");
|
|
48
|
+
const shells = codeFences(doc.source).filter((fence) => languages.has(fence.language));
|
|
49
|
+
const prompted = shells.filter((fence) => promptStyleOf(fence, prompts) === "prompt");
|
|
50
|
+
const bare = shells.filter((fence) => promptStyleOf(fence, prompts) === "bare");
|
|
51
|
+
const minority = minorityOf(prompted, bare, options.limit);
|
|
52
|
+
const style = minority === prompted ? "prompt" : "bare";
|
|
53
|
+
return minority.map((fence) => finding(doc, "shell-prompt-mix", fence.start, { majority: style === "prompt" ? bare.length : prompted.length }));
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* A code span that names a command or an option: a flag (--force, -f) or a command with its arguments (npm install). A
|
|
57
|
+
* single plain word (net, init) is as often a package, an endpoint or a type as a command, and is left out.
|
|
58
|
+
*/
|
|
59
|
+
const COMMAND_WORD = /^[a-z][a-z0-9_-]*$/u;
|
|
60
|
+
const FLAG = /^--?[A-Za-z][\w-]*$/u;
|
|
61
|
+
export const isCommandName = (text) => {
|
|
62
|
+
const words = text.trim().split(/\s+/u);
|
|
63
|
+
const first = words[0] ?? "";
|
|
64
|
+
return words.length === 1 ? FLAG.test(first) : COMMAND_WORD.test(first);
|
|
65
|
+
};
|
|
66
|
+
/** The heading without its links' text: [`net`](/pkg/net/) names the page it links to, not a command shown below. */
|
|
67
|
+
export const withoutLinks = (heading) => {
|
|
68
|
+
const pieces = [];
|
|
69
|
+
const state = { at: 0 };
|
|
70
|
+
while (state.at < heading.length) {
|
|
71
|
+
const open = heading.indexOf("[", state.at);
|
|
72
|
+
const close = open === -1 ? -1 : heading.indexOf("]", open);
|
|
73
|
+
if (close === -1)
|
|
74
|
+
break;
|
|
75
|
+
pieces.push(heading.slice(state.at, open), " ");
|
|
76
|
+
state.at = close + 1 + targetLength(heading, close + 1);
|
|
77
|
+
}
|
|
78
|
+
pieces.push(heading.slice(state.at));
|
|
79
|
+
return pieces.join("");
|
|
80
|
+
};
|
|
81
|
+
/** The length of a link's target right after its text: (url), [label] or [] (a reference link); 0 when there is none. */
|
|
82
|
+
const targetLength = (heading, at) => {
|
|
83
|
+
const pair = { "(": ")", "[": "]" };
|
|
84
|
+
const closer = pair[heading.charAt(at)];
|
|
85
|
+
const end = closer === undefined ? -1 : heading.indexOf(closer, at);
|
|
86
|
+
return end === -1 ? 0 : end - at + 1;
|
|
87
|
+
};
|
|
88
|
+
/** The commands and options a heading names: its code spans that read as one, and bare flags (--force). */
|
|
89
|
+
export const commandsIn = (heading) => {
|
|
90
|
+
const spans = codeSpans(withoutLinks(heading)).map((span) => span.text);
|
|
91
|
+
const flags = heading
|
|
92
|
+
.replace(/`[^`]*`/gu, " ")
|
|
93
|
+
.split(/\s+/u)
|
|
94
|
+
.filter((word) => FLAG.test(word) && word.startsWith("--"));
|
|
95
|
+
return [...new Set([...spans.filter(isCommandName), ...flags])];
|
|
96
|
+
};
|
|
97
|
+
const collapse = (text) => text.replace(/\s+/gu, " ");
|
|
98
|
+
const OPTION_CHAR = /[A-Za-z0-9_-]/u;
|
|
99
|
+
/** Whether the code holds the command as a whole word: --force is not --force-with-lease, init is not initial. */
|
|
100
|
+
export const showsCommand = (code, command) => {
|
|
101
|
+
const text = collapse(code);
|
|
102
|
+
const wanted = collapse(command.trim());
|
|
103
|
+
const state = { at: text.indexOf(wanted) };
|
|
104
|
+
while (state.at !== -1) {
|
|
105
|
+
const before = text.charAt(state.at - 1);
|
|
106
|
+
const after = text.charAt(state.at + wanted.length);
|
|
107
|
+
if (!OPTION_CHAR.test(before) && !OPTION_CHAR.test(after))
|
|
108
|
+
return true;
|
|
109
|
+
state.at = text.indexOf(wanted, state.at + 1);
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
};
|
|
113
|
+
const sectionsOf = (doc) => {
|
|
114
|
+
const headings = doc.markup?.headings ?? [];
|
|
115
|
+
return headings.map((heading, index) => {
|
|
116
|
+
const next = headings.slice(index + 1).find((later) => later.depth <= heading.depth);
|
|
117
|
+
return { heading: doc.source.slice(heading.start, heading.end), start: heading.start, body: { start: heading.end, end: next?.start ?? doc.source.length } };
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
/** The code a section shows: its fenced blocks and its inline code spans. Empty when it shows none. */
|
|
121
|
+
const codeOf = (doc, fences, body) => {
|
|
122
|
+
const inFences = fences.filter((fence) => fence.start >= body.start && fence.start < body.end);
|
|
123
|
+
const outside = inFences.reduceRight((text, fence) => `${text.slice(0, fence.start - body.start)}${text.slice(Math.min(fence.end, body.end) - body.start)}`, doc.source.slice(body.start, body.end));
|
|
124
|
+
return [...inFences.flatMap((fence) => fence.lines), ...codeSpans(outside).map((span) => span.text)].join("\n");
|
|
125
|
+
};
|
|
126
|
+
export const headingCommand = (doc) => {
|
|
127
|
+
const fences = codeFences(doc.source);
|
|
128
|
+
return sectionsOf(doc).flatMap((section) => {
|
|
129
|
+
const commands = commandsIn(section.heading);
|
|
130
|
+
if (commands.length === 0)
|
|
131
|
+
return [];
|
|
132
|
+
const code = codeOf(doc, fences, section.body);
|
|
133
|
+
if (code.trim() === "")
|
|
134
|
+
return [];
|
|
135
|
+
return commands.filter((command) => !showsCommand(code, command)).map((command) => finding(doc, "heading-command-missing", section.start, { command }));
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
const ORDERED_ITEM = /^\s*\d{1,3}[.)]\s/u;
|
|
139
|
+
/** What opens a statement: an article or a pronoun (The installer asks, You click, It opens). */
|
|
140
|
+
const SUBJECT_OPENER = new Set(["DET", "PRON"]);
|
|
141
|
+
/** What a subject opens with when it is a name or a noun phrase (Docker builds, Each user gets). */
|
|
142
|
+
const SUBJECT_HEAD = new Set(["DET", "PRON", "PROPN", "NOUN", "ADJ"]);
|
|
143
|
+
/** What may stand between the opener and the verb: the rest of the subject. */
|
|
144
|
+
const SUBJECT_PART = new Set(["DET", "PRON", "PROPN", "NOUN", "ADJ", "ADP"]);
|
|
145
|
+
/** What opens an instruction. The tagger reads a sentence-initial imperative as a noun, an adjective or a name (Click, Open, Restart). */
|
|
146
|
+
const INSTRUCTION_OPENER = new Set(["VERB", "NOUN", "ADJ", "PROPN"]);
|
|
147
|
+
const PREDICATE = new Set(["VERB", "AUX"]);
|
|
148
|
+
const SKIPPED = new Set(["PUNCT", "NUM", "SYM", "X", "SPACE"]);
|
|
149
|
+
/** Steps shorter than this are labels (1. Setup), not instructions or statements. */
|
|
150
|
+
const MIN_STEP_TOKENS = 3;
|
|
151
|
+
/** A list needs this many steps to have a form to keep. */
|
|
152
|
+
const MIN_STEPS = 3;
|
|
153
|
+
/** A verb in a finite, inflected form (starts, built): it has a subject before it. A base form (Save) may be an imperative's object. */
|
|
154
|
+
const isInflected = (token) => token.lemma !== undefined && token.lemma !== "" && token.surface.toLowerCase() !== token.lemma && token.features?.["VerbForm"] !== "Part";
|
|
155
|
+
/**
|
|
156
|
+
* A step written as a statement: a subject, then its verb. The subject opens with an article or a pronoun (The installer
|
|
157
|
+
* asks, You click), or it is a name or a noun whose verb is inflected (Docker builds). A noun before a base-form verb is
|
|
158
|
+
* not enough: the tagger reads Click and Press there as nouns (Click Save).
|
|
159
|
+
*/
|
|
160
|
+
export const isStatement = (tokens) => {
|
|
161
|
+
const words = tokens.filter((token) => !SKIPPED.has(token.pos));
|
|
162
|
+
const [head, ...rest] = words;
|
|
163
|
+
if (head === undefined || words.length < MIN_STEP_TOKENS || !SUBJECT_HEAD.has(head.pos))
|
|
164
|
+
return false;
|
|
165
|
+
const verbAt = rest.findIndex((token) => PREDICATE.has(token.pos));
|
|
166
|
+
const verb = rest[verbAt];
|
|
167
|
+
if (verb === undefined || !rest.slice(0, verbAt).every((token) => SUBJECT_PART.has(token.pos)))
|
|
168
|
+
return false;
|
|
169
|
+
// Punctuation before the verb is no subject: a label (Guests: the users who …) or an opening phrase (On the left bar, select …).
|
|
170
|
+
const interrupted = tokens.some((token) => token.pos === "PUNCT" && token.span.start > head.span.start && token.span.start < verb.span.start);
|
|
171
|
+
return !interrupted && (SUBJECT_OPENER.has(head.pos) || isInflected(verb));
|
|
172
|
+
};
|
|
173
|
+
/** A step that opens with its verb: an instruction (Run the installer). */
|
|
174
|
+
export const isInstruction = (tokens) => INSTRUCTION_OPENER.has(tokens.find((token) => !SKIPPED.has(token.pos))?.pos ?? "");
|
|
175
|
+
const kindOf = (tokens) => {
|
|
176
|
+
if (isStatement(tokens))
|
|
177
|
+
return "statement";
|
|
178
|
+
return isInstruction(tokens) ? "instruction" : "other";
|
|
179
|
+
};
|
|
180
|
+
/** The steps of each numbered list: each item's first sentence, read as a statement or not. */
|
|
181
|
+
const stepLists = (doc) => doc.lists
|
|
182
|
+
.filter((list) => ORDERED_ITEM.test(doc.source.slice(list.span.start, list.span.end)))
|
|
183
|
+
.map((list) => list.itemSpans.flatMap((item) => {
|
|
184
|
+
const sentence = doc.sentences.find((candidate) => candidate.span.start >= item.start && candidate.span.start < item.end);
|
|
185
|
+
// Only the sentence on the item's own line: a note paragraph under it (**NOTE:** …) is not the step.
|
|
186
|
+
const onItemLine = sentence !== undefined && !doc.source.slice(item.start, sentence.span.start).includes("\n");
|
|
187
|
+
return sentence?.tokens === undefined || !onItemLine ? [] : [{ start: sentence.span.start, kind: kindOf(sentence.tokens) }];
|
|
188
|
+
}))
|
|
189
|
+
.filter((steps) => steps.length >= MIN_STEPS);
|
|
190
|
+
export const stepStatement = (doc, options) => stepLists(doc).flatMap((steps) => {
|
|
191
|
+
const statements = steps.filter((step) => step.kind === "statement");
|
|
192
|
+
const instructions = steps.filter((step) => step.kind === "instruction");
|
|
193
|
+
// A procedure is a list most of whose steps are instructions; a numbered list of terms and definitions is not one.
|
|
194
|
+
const isProcedure = instructions.length * 2 > steps.length;
|
|
195
|
+
return isProcedure && statements.length > 0 && statements.length < instructions.length && statements.length <= options.limit
|
|
196
|
+
? statements.map((step) => finding(doc, "step-statement-mix", step.start, { count: instructions.length }))
|
|
197
|
+
: [];
|
|
198
|
+
});
|
|
199
|
+
//# sourceMappingURL=technical-docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"technical-docs.js","sourceRoot":"","sources":["../../src/detectors/technical-docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const PACK_MANIFEST = "chaff-plugin.yaml";
|
|
2
|
+
/** The name in the folder's package.json, if it has one. */
|
|
3
|
+
export declare const packageNameOf: (dir: string) => string | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* The manifest of a pack folder: chaff-plugin.yaml, else package.json's chaff field. undefined when the folder is not
|
|
6
|
+
* a pack (a code plugin, loaded by importing it). A manifest that cannot be read is reported, not taken for "not a pack".
|
|
7
|
+
*/
|
|
8
|
+
export declare const packManifestOf: (dir: string) => {
|
|
9
|
+
readonly manifest: Record<string, unknown>;
|
|
10
|
+
} | {
|
|
11
|
+
readonly message: string;
|
|
12
|
+
} | undefined;
|
|
13
|
+
type Read<T> = {
|
|
14
|
+
readonly value: T;
|
|
15
|
+
} | {
|
|
16
|
+
readonly message: string;
|
|
17
|
+
};
|
|
18
|
+
/** The pack as a plugin's default export: its name and API version from the manifest, its rules, lexicons and styles from its folders. */
|
|
19
|
+
export declare const readPack: (dir: string, manifest: Readonly<Record<string, unknown>>, expectedName: string | undefined) => Read<Record<string, unknown>>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=pack-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-read.d.ts","sourceRoot":"","sources":["../../src/extension/pack-read.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAyCjD,4DAA4D;AAC5D,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,SAGpD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAW5H,CAAC;AAEF,KAAK,IAAI,CAAC,CAAC,IAAI;IAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAoCpE,0IAA0I;AAC1I,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,UAAU,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,cAAc,MAAM,GAAG,SAAS,KAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBjJ,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { parse } from "yaml";
|
|
4
|
+
import { API_VERSION } from "../api.js";
|
|
5
|
+
import { isInside } from "../custom/module-path.js";
|
|
6
|
+
// A rule pack: a plugin written in YAML alone. Its folder holds a manifest (chaff-plugin.yaml, or a chaff field in
|
|
7
|
+
// package.json), rules/*.yaml, lexicons/<language>/<list>.yaml and styles/*.yaml. Read here into the shape a code
|
|
8
|
+
// plugin's default export has, so plugin-parse.ts checks a pack exactly as it checks a code plugin. Nothing is run.
|
|
9
|
+
export const PACK_MANIFEST = "chaff-plugin.yaml";
|
|
10
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11
|
+
const printed = (value) => JSON.stringify(value) ?? typeof value;
|
|
12
|
+
const firstLine = (error) => (error instanceof Error ? error.message : String(error)).split("\n")[0] ?? "";
|
|
13
|
+
/** A YAML file, or why it cannot be read, naming it as the pack's own path (rules/no-tbd.yaml). */
|
|
14
|
+
const readYaml = (dir, path) => {
|
|
15
|
+
try {
|
|
16
|
+
// A link inside the pack that points out of it would read a file the pack does not hold.
|
|
17
|
+
if (!isInside(realpathSync(dir), realpathSync(join(dir, path))))
|
|
18
|
+
return { message: `${path}: it links to a file outside the pack` };
|
|
19
|
+
return { value: parse(readFileSync(join(dir, path), "utf8")) };
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
return { message: `${path}: ${firstLine(error)}` };
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const yamlFilesIn = (dir, folder) => {
|
|
26
|
+
const full = join(dir, folder);
|
|
27
|
+
if (!existsSync(full) || !statSync(full).isDirectory())
|
|
28
|
+
return [];
|
|
29
|
+
return readdirSync(full)
|
|
30
|
+
.filter((file) => file.endsWith(".yaml") || file.endsWith(".yml"))
|
|
31
|
+
.toSorted((left, right) => left.localeCompare(right, "en"))
|
|
32
|
+
.map((file) => `${folder}/${file}`);
|
|
33
|
+
};
|
|
34
|
+
const foldersIn = (dir, folder) => {
|
|
35
|
+
const full = join(dir, folder);
|
|
36
|
+
if (!existsSync(full) || !statSync(full).isDirectory())
|
|
37
|
+
return [];
|
|
38
|
+
return readdirSync(full)
|
|
39
|
+
.filter((name) => statSync(join(full, name)).isDirectory())
|
|
40
|
+
.toSorted((left, right) => left.localeCompare(right, "en"));
|
|
41
|
+
};
|
|
42
|
+
const packageJsonOf = (dir) => {
|
|
43
|
+
const read = existsSync(join(dir, "package.json")) ? readYaml(dir, "package.json") : undefined;
|
|
44
|
+
return read !== undefined && "value" in read && isRecord(read.value) ? read.value : undefined;
|
|
45
|
+
};
|
|
46
|
+
/** The name in the folder's package.json, if it has one. */
|
|
47
|
+
export const packageNameOf = (dir) => {
|
|
48
|
+
const name = packageJsonOf(dir)?.["name"];
|
|
49
|
+
return typeof name === "string" ? name : undefined;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The manifest of a pack folder: chaff-plugin.yaml, else package.json's chaff field. undefined when the folder is not
|
|
53
|
+
* a pack (a code plugin, loaded by importing it). A manifest that cannot be read is reported, not taken for "not a pack".
|
|
54
|
+
*/
|
|
55
|
+
export const packManifestOf = (dir) => {
|
|
56
|
+
if (existsSync(join(dir, PACK_MANIFEST))) {
|
|
57
|
+
const read = readYaml(dir, PACK_MANIFEST);
|
|
58
|
+
if ("message" in read)
|
|
59
|
+
return read;
|
|
60
|
+
// An empty manifest only marks the folder; anything else must be a map.
|
|
61
|
+
if (read.value === null || read.value === undefined)
|
|
62
|
+
return { manifest: {} };
|
|
63
|
+
return isRecord(read.value) ? { manifest: read.value } : { message: `${PACK_MANIFEST}: write a map (apiVersion: 1), not ${printed(read.value)}` };
|
|
64
|
+
}
|
|
65
|
+
const chaff = packageJsonOf(dir)?.["chaff"];
|
|
66
|
+
if (chaff === undefined)
|
|
67
|
+
return undefined;
|
|
68
|
+
return isRecord(chaff) ? { manifest: chaff } : { message: `package.json: chaff must be a map ({ "apiVersion": 1 }), not ${printed(chaff)}` };
|
|
69
|
+
};
|
|
70
|
+
/** Every file's value in the order of the files, or the first that cannot be read. */
|
|
71
|
+
const readAll = (dir, paths) => paths.reduce((done, path) => {
|
|
72
|
+
if ("message" in done)
|
|
73
|
+
return done;
|
|
74
|
+
const read = readYaml(dir, path);
|
|
75
|
+
return "message" in read ? read : { value: [...done.value, read.value] };
|
|
76
|
+
}, { value: [] });
|
|
77
|
+
/** rules/*.yaml: each file holds one rule, or a list of them. */
|
|
78
|
+
const rulesOf = (dir) => {
|
|
79
|
+
const read = readAll(dir, yamlFilesIn(dir, "rules"));
|
|
80
|
+
return "message" in read ? read : { value: read.value.flatMap((value) => (Array.isArray(value) ? value.map((rule) => rule) : [value])) };
|
|
81
|
+
};
|
|
82
|
+
/** lexicons/<language>/<list>.yaml, as a code plugin writes its lexicons: { list: { language: entries } }. */
|
|
83
|
+
const lexiconsOf = (dir) => foldersIn(dir, "lexicons").reduce((done, language) => {
|
|
84
|
+
if ("message" in done)
|
|
85
|
+
return done;
|
|
86
|
+
const paths = yamlFilesIn(dir, `lexicons/${language}`);
|
|
87
|
+
const read = readAll(dir, paths);
|
|
88
|
+
if ("message" in read)
|
|
89
|
+
return read;
|
|
90
|
+
const merged = paths.reduce((acc, path, index) => {
|
|
91
|
+
const list = basename(path).replace(/\.ya?ml$/u, "");
|
|
92
|
+
return { ...acc, [list]: { ...acc[list], [language]: read.value[index] } };
|
|
93
|
+
}, done.value);
|
|
94
|
+
return { value: merged };
|
|
95
|
+
}, { value: {} });
|
|
96
|
+
/** The pack as a plugin's default export: its name and API version from the manifest, its rules, lexicons and styles from its folders. */
|
|
97
|
+
export const readPack = (dir, manifest, expectedName) => {
|
|
98
|
+
const rules = rulesOf(dir);
|
|
99
|
+
if ("message" in rules)
|
|
100
|
+
return rules;
|
|
101
|
+
const lexicons = lexiconsOf(dir);
|
|
102
|
+
if ("message" in lexicons)
|
|
103
|
+
return lexicons;
|
|
104
|
+
const styles = readAll(dir, yamlFilesIn(dir, "styles"));
|
|
105
|
+
if ("message" in styles)
|
|
106
|
+
return styles;
|
|
107
|
+
return {
|
|
108
|
+
value: {
|
|
109
|
+
apiVersion: manifest["apiVersion"] ?? API_VERSION,
|
|
110
|
+
name: manifest["name"] ?? expectedName,
|
|
111
|
+
rules: rules.value,
|
|
112
|
+
lexicons: lexicons.value,
|
|
113
|
+
styles: styles.value,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=pack-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-read.js","sourceRoot":"","sources":["../../src/extension/pack-read.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-load.d.ts","sourceRoot":"","sources":["../../src/extension/plugin-load.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin-load.d.ts","sourceRoot":"","sources":["../../src/extension/plugin-load.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAM7D,OAAO,EAAe,KAAK,YAAY,EAAqB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAO1G,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,CAAC;AA8FvH,6EAA6E;AAC7E,eAAO,MAAM,WAAW,GAAU,QAAQ,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC,KAAG,OAAO,CAAC,aAAa,CAUpG,CAAC"}
|