chaffjs 0.18.0 → 0.19.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 +52 -56
- package/bin/chaff.js +17 -2
- package/dist/acronym-expansions.d.ts +26 -0
- package/dist/acronym-expansions.d.ts.map +1 -0
- package/dist/acronym-expansions.js +88 -0
- package/dist/acronym-expansions.js.map +1 -0
- package/dist/announced-count.d.ts.map +1 -1
- package/dist/announced-count.js +44 -10
- package/dist/announced-count.js.map +1 -1
- package/dist/announced-list.d.ts +30 -0
- package/dist/announced-list.d.ts.map +1 -0
- package/dist/announced-list.js +95 -0
- package/dist/announced-list.js.map +1 -0
- package/dist/api.d.ts +168 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +10 -0
- package/dist/api.js.map +1 -0
- package/dist/cli-text.d.ts +0 -1
- package/dist/cli-text.d.ts.map +1 -1
- package/dist/cli-text.js +6 -14
- package/dist/cli-text.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +58 -62
- package/dist/cli.js.map +1 -1
- package/dist/closing-paragraph.d.ts +7 -0
- package/dist/closing-paragraph.d.ts.map +1 -0
- package/dist/closing-paragraph.js +22 -0
- package/dist/closing-paragraph.js.map +1 -0
- package/dist/commands/compare.d.ts +8 -1
- package/dist/commands/compare.d.ts.map +1 -1
- package/dist/commands/compare.js +9 -17
- package/dist/commands/compare.js.map +1 -1
- package/dist/commands/document-commands.d.ts +9 -0
- package/dist/commands/document-commands.d.ts.map +1 -0
- package/dist/commands/document-commands.js +17 -0
- package/dist/commands/document-commands.js.map +1 -0
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +3 -2
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/facts.d.ts +8 -0
- package/dist/commands/facts.d.ts.map +1 -0
- package/dist/commands/facts.js +30 -0
- package/dist/commands/facts.js.map +1 -0
- package/dist/commands/feedback.d.ts +10 -0
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +25 -1
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/fix-plan.d.ts +13 -0
- package/dist/commands/fix-plan.d.ts.map +1 -0
- package/dist/commands/fix-plan.js +44 -0
- package/dist/commands/fix-plan.js.map +1 -0
- package/dist/commands/outline.d.ts +8 -0
- package/dist/commands/outline.d.ts.map +1 -0
- package/dist/commands/outline.js +43 -0
- package/dist/commands/outline.js.map +1 -0
- package/dist/commands/read-document.d.ts +14 -0
- package/dist/commands/read-document.d.ts.map +1 -0
- package/dist/commands/read-document.js +21 -0
- package/dist/commands/read-document.js.map +1 -0
- package/dist/commands/suppressions.d.ts +7 -0
- package/dist/commands/suppressions.d.ts.map +1 -0
- package/dist/commands/suppressions.js +9 -0
- package/dist/commands/suppressions.js.map +1 -0
- package/dist/commands/test.js +1 -1
- package/dist/commands/test.js.map +1 -1
- package/dist/compare/clock-time.d.ts.map +1 -1
- package/dist/compare/clock-time.js +5 -2
- package/dist/compare/clock-time.js.map +1 -1
- package/dist/compare/distinct.d.ts +9 -0
- package/dist/compare/distinct.d.ts.map +1 -0
- package/dist/compare/distinct.js +12 -0
- package/dist/compare/distinct.js.map +1 -0
- package/dist/compare/extract.d.ts.map +1 -1
- package/dist/compare/extract.js +7 -5
- package/dist/compare/extract.js.map +1 -1
- package/dist/compare/fact-key.d.ts +17 -0
- package/dist/compare/fact-key.d.ts.map +1 -0
- package/dist/compare/fact-key.js +25 -0
- package/dist/compare/fact-key.js.map +1 -0
- package/dist/compare/fact-text.d.ts +5 -0
- package/dist/compare/fact-text.d.ts.map +1 -1
- package/dist/compare/fact-text.js +16 -2
- package/dist/compare/fact-text.js.map +1 -1
- package/dist/compare/facts-render.d.ts +17 -0
- package/dist/compare/facts-render.d.ts.map +1 -0
- package/dist/compare/facts-render.js +43 -0
- package/dist/compare/facts-render.js.map +1 -0
- package/dist/compare/facts-text.d.ts +15 -0
- package/dist/compare/facts-text.d.ts.map +1 -0
- package/dist/compare/facts-text.js +27 -0
- package/dist/compare/facts-text.js.map +1 -0
- package/dist/compare/match.d.ts +1 -0
- package/dist/compare/match.d.ts.map +1 -1
- package/dist/compare/match.js +1 -1
- package/dist/compare/match.js.map +1 -1
- package/dist/compare/outcome.d.ts +4 -1
- package/dist/compare/outcome.d.ts.map +1 -1
- package/dist/compare/outcome.js +10 -4
- package/dist/compare/outcome.js.map +1 -1
- package/dist/compare/proper-nouns.d.ts +3 -3
- package/dist/compare/proper-nouns.d.ts.map +1 -1
- package/dist/compare/proper-nouns.js +2 -3
- package/dist/compare/proper-nouns.js.map +1 -1
- package/dist/compare/render.d.ts +4 -0
- package/dist/compare/render.d.ts.map +1 -1
- package/dist/compare/render.js +2 -2
- package/dist/compare/render.js.map +1 -1
- package/dist/compare/text-atoms.d.ts +5 -2
- package/dist/compare/text-atoms.d.ts.map +1 -1
- package/dist/compare/text-atoms.js +7 -5
- package/dist/compare/text-atoms.js.map +1 -1
- package/dist/compare/text.d.ts.map +1 -1
- package/dist/compare/text.js +2 -2
- package/dist/compare/text.js.map +1 -1
- package/dist/config/load.d.ts +8 -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.d.ts +3 -2
- package/dist/config/option-problems.d.ts.map +1 -1
- package/dist/config/option-problems.js +4 -3
- package/dist/config/option-problems.js.map +1 -1
- package/dist/config/style.d.ts +5 -0
- package/dist/config/style.d.ts.map +1 -1
- package/dist/config/style.js +13 -1
- package/dist/config/style.js.map +1 -1
- package/dist/custom/load.d.ts +6 -3
- package/dist/custom/load.d.ts.map +1 -1
- package/dist/custom/load.js +10 -2
- package/dist/custom/load.js.map +1 -1
- package/dist/custom/module-path.d.ts +11 -0
- package/dist/custom/module-path.d.ts.map +1 -0
- package/dist/custom/module-path.js +15 -0
- package/dist/custom/module-path.js.map +1 -0
- package/dist/custom/parse.d.ts +17 -3
- package/dist/custom/parse.d.ts.map +1 -1
- package/dist/custom/parse.js +57 -14
- package/dist/custom/parse.js.map +1 -1
- package/dist/custom/problems.d.ts +4 -1
- package/dist/custom/problems.d.ts.map +1 -1
- package/dist/custom/problems.js +56 -39
- package/dist/custom/problems.js.map +1 -1
- package/dist/detect-language.js +1 -1
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +9 -3
- package/dist/detect.js.map +1 -1
- package/dist/detectors/ai-phrasing.d.ts +4 -1
- package/dist/detectors/ai-phrasing.d.ts.map +1 -1
- package/dist/detectors/ai-phrasing.js +6 -2
- package/dist/detectors/ai-phrasing.js.map +1 -1
- package/dist/detectors/bold-label.d.ts +10 -0
- package/dist/detectors/bold-label.d.ts.map +1 -0
- package/dist/detectors/bold-label.js +44 -0
- package/dist/detectors/bold-label.js.map +1 -0
- package/dist/detectors/dangling-figure.d.ts +5 -2
- package/dist/detectors/dangling-figure.d.ts.map +1 -1
- package/dist/detectors/dangling-figure.js +5 -3
- package/dist/detectors/dangling-figure.js.map +1 -1
- package/dist/detectors/definition-use.d.ts +8 -0
- package/dist/detectors/definition-use.d.ts.map +1 -0
- package/dist/detectors/definition-use.js +32 -0
- package/dist/detectors/definition-use.js.map +1 -0
- package/dist/detectors/doubled-punctuation.d.ts.map +1 -1
- package/dist/detectors/doubled-punctuation.js +4 -2
- package/dist/detectors/doubled-punctuation.js.map +1 -1
- package/dist/detectors/duplicate-heading.d.ts +14 -0
- package/dist/detectors/duplicate-heading.d.ts.map +1 -0
- package/dist/detectors/duplicate-heading.js +39 -0
- package/dist/detectors/duplicate-heading.js.map +1 -0
- package/dist/detectors/empty-section.d.ts +8 -0
- package/dist/detectors/empty-section.d.ts.map +1 -0
- package/dist/detectors/empty-section.js +16 -0
- package/dist/detectors/empty-section.js.map +1 -0
- package/dist/detectors/fullwidth-alnum.d.ts +24 -0
- package/dist/detectors/fullwidth-alnum.d.ts.map +1 -0
- package/dist/detectors/fullwidth-alnum.js +88 -0
- package/dist/detectors/fullwidth-alnum.js.map +1 -0
- package/dist/detectors/hankaku-kana.d.ts +9 -0
- package/dist/detectors/hankaku-kana.d.ts.map +1 -0
- package/dist/detectors/hankaku-kana.js +27 -0
- package/dist/detectors/hankaku-kana.js.map +1 -0
- package/dist/detectors/heading-code-words.js +2 -2
- package/dist/detectors/heading-code-words.js.map +1 -1
- package/dist/detectors/index.d.ts.map +1 -1
- package/dist/detectors/index.js +36 -0
- package/dist/detectors/index.js.map +1 -1
- package/dist/detectors/invisible-character.d.ts +20 -0
- package/dist/detectors/invisible-character.d.ts.map +1 -0
- package/dist/detectors/invisible-character.js +143 -0
- package/dist/detectors/invisible-character.js.map +1 -0
- package/dist/detectors/kutoten-consistency.js +2 -2
- package/dist/detectors/kutoten-consistency.js.map +1 -1
- package/dist/detectors/lexicon-match.d.ts +10 -1
- package/dist/detectors/lexicon-match.d.ts.map +1 -1
- package/dist/detectors/lexicon-match.js +26 -1
- package/dist/detectors/lexicon-match.js.map +1 -1
- package/dist/detectors/lexicon.d.ts +6 -1
- package/dist/detectors/lexicon.d.ts.map +1 -1
- package/dist/detectors/lexicon.js +31 -13
- package/dist/detectors/lexicon.js.map +1 -1
- package/dist/detectors/list-sentence.d.ts +3 -1
- package/dist/detectors/list-sentence.d.ts.map +1 -1
- package/dist/detectors/list-sentence.js +26 -1
- package/dist/detectors/list-sentence.js.map +1 -1
- package/dist/detectors/long-vowel.d.ts.map +1 -1
- package/dist/detectors/long-vowel.js +18 -4
- package/dist/detectors/long-vowel.js.map +1 -1
- package/dist/detectors/markup-finding.d.ts +3 -1
- package/dist/detectors/markup-finding.d.ts.map +1 -1
- package/dist/detectors/markup-finding.js +10 -0
- package/dist/detectors/markup-finding.js.map +1 -1
- package/dist/detectors/modal-conflict.d.ts +4 -0
- package/dist/detectors/modal-conflict.d.ts.map +1 -0
- package/dist/detectors/modal-conflict.js +22 -0
- package/dist/detectors/modal-conflict.js.map +1 -0
- package/dist/detectors/name-variant.d.ts +4 -0
- package/dist/detectors/name-variant.d.ts.map +1 -0
- package/dist/detectors/name-variant.js +13 -0
- package/dist/detectors/name-variant.js.map +1 -0
- package/dist/detectors/nominalization.d.ts +11 -0
- package/dist/detectors/nominalization.d.ts.map +1 -0
- package/dist/detectors/nominalization.js +56 -0
- package/dist/detectors/nominalization.js.map +1 -0
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +59 -28
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/outside-announced-list.d.ts +4 -0
- package/dist/detectors/outside-announced-list.d.ts.map +1 -0
- package/dist/detectors/outside-announced-list.js +24 -0
- package/dist/detectors/outside-announced-list.js.map +1 -0
- package/dist/detectors/oxford-comma.d.ts.map +1 -1
- package/dist/detectors/oxford-comma.js +1 -0
- package/dist/detectors/oxford-comma.js.map +1 -1
- package/dist/detectors/phrase-match.d.ts +4 -1
- package/dist/detectors/phrase-match.d.ts.map +1 -1
- package/dist/detectors/phrase-match.js +26 -7
- package/dist/detectors/phrase-match.js.map +1 -1
- package/dist/detectors/ra-nuki.d.ts +9 -0
- package/dist/detectors/ra-nuki.d.ts.map +1 -0
- package/dist/detectors/ra-nuki.js +30 -0
- package/dist/detectors/ra-nuki.js.map +1 -0
- package/dist/detectors/requirement-modal.d.ts +5 -0
- package/dist/detectors/requirement-modal.d.ts.map +1 -0
- package/dist/detectors/requirement-modal.js +54 -0
- package/dist/detectors/requirement-modal.js.map +1 -0
- package/dist/detectors/requirement-smell.d.ts +4 -0
- package/dist/detectors/requirement-smell.d.ts.map +1 -0
- package/dist/detectors/requirement-smell.js +41 -0
- package/dist/detectors/requirement-smell.js.map +1 -0
- package/dist/detectors/space-before-punctuation.d.ts +8 -0
- package/dist/detectors/space-before-punctuation.d.ts.map +1 -0
- package/dist/detectors/space-before-punctuation.js +24 -0
- package/dist/detectors/space-before-punctuation.js.map +1 -0
- package/dist/detectors/spelling-variety.d.ts +23 -0
- package/dist/detectors/spelling-variety.d.ts.map +1 -0
- package/dist/detectors/spelling-variety.js +59 -0
- package/dist/detectors/spelling-variety.js.map +1 -0
- package/dist/detectors/structure-tree.d.ts.map +1 -1
- package/dist/detectors/structure-tree.js +3 -1
- package/dist/detectors/structure-tree.js.map +1 -1
- package/dist/detectors/structure.d.ts.map +1 -1
- package/dist/detectors/structure.js +16 -2
- package/dist/detectors/structure.js.map +1 -1
- package/dist/detectors/superlative-comparison.d.ts +20 -0
- package/dist/detectors/superlative-comparison.d.ts.map +1 -0
- package/dist/detectors/superlative-comparison.js +32 -0
- package/dist/detectors/superlative-comparison.js.map +1 -0
- package/dist/detectors/url-run-on.d.ts.map +1 -1
- package/dist/detectors/url-run-on.js +6 -1
- package/dist/detectors/url-run-on.js.map +1 -1
- package/dist/detectors/vague-figure-pointer.d.ts +10 -0
- package/dist/detectors/vague-figure-pointer.d.ts.map +1 -0
- package/dist/detectors/vague-figure-pointer.js +46 -0
- package/dist/detectors/vague-figure-pointer.js.map +1 -0
- package/dist/detectors/word-list.d.ts +2 -0
- package/dist/detectors/word-list.d.ts.map +1 -1
- package/dist/detectors/word-list.js +4 -1
- package/dist/detectors/word-list.js.map +1 -1
- package/dist/document.d.ts +9 -3
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +55 -32
- package/dist/document.js.map +1 -1
- package/dist/extension/document-view.d.ts +7 -0
- package/dist/extension/document-view.d.ts.map +1 -0
- package/dist/extension/document-view.js +91 -0
- package/dist/extension/document-view.js.map +1 -0
- package/dist/extension/failure-text.d.ts +5 -0
- package/dist/extension/failure-text.d.ts.map +1 -0
- package/dist/extension/failure-text.js +33 -0
- package/dist/extension/failure-text.js.map +1 -0
- package/dist/extension/import-default.d.ts +7 -0
- package/dist/extension/import-default.d.ts.map +1 -0
- package/dist/extension/import-default.js +21 -0
- package/dist/extension/import-default.js.map +1 -0
- package/dist/extension/load.d.ts +28 -0
- package/dist/extension/load.d.ts.map +1 -0
- package/dist/extension/load.js +51 -0
- package/dist/extension/load.js.map +1 -0
- package/dist/extension/module-detector.d.ts +21 -0
- package/dist/extension/module-detector.d.ts.map +1 -0
- package/dist/extension/module-detector.js +49 -0
- package/dist/extension/module-detector.js.map +1 -0
- package/dist/extension/plugin-load.d.ts +9 -0
- package/dist/extension/plugin-load.d.ts.map +1 -0
- package/dist/extension/plugin-load.js +68 -0
- package/dist/extension/plugin-load.js.map +1 -0
- package/dist/extension/plugin-name.d.ts +8 -0
- package/dist/extension/plugin-name.d.ts.map +1 -0
- package/dist/extension/plugin-name.js +22 -0
- package/dist/extension/plugin-name.js.map +1 -0
- package/dist/extension/plugin-parse.d.ts +41 -0
- package/dist/extension/plugin-parse.d.ts.map +1 -0
- package/dist/extension/plugin-parse.js +156 -0
- package/dist/extension/plugin-parse.js.map +1 -0
- package/dist/extension/problem-text.d.ts +5 -0
- package/dist/extension/problem-text.d.ts.map +1 -0
- package/dist/extension/problem-text.js +74 -0
- package/dist/extension/problem-text.js.map +1 -0
- package/dist/extension/real-path.d.ts +3 -0
- package/dist/extension/real-path.d.ts.map +1 -0
- package/dist/extension/real-path.js +8 -0
- package/dist/extension/real-path.js.map +1 -0
- package/dist/extension/returned-findings.d.ts +17 -0
- package/dist/extension/returned-findings.d.ts.map +1 -0
- package/dist/extension/returned-findings.js +48 -0
- package/dist/extension/returned-findings.js.map +1 -0
- package/dist/extension/rule-export.d.ts +13 -0
- package/dist/extension/rule-export.d.ts.map +1 -0
- package/dist/extension/rule-export.js +16 -0
- package/dist/extension/rule-export.js.map +1 -0
- package/dist/feedback/draft.d.ts +2 -0
- package/dist/feedback/draft.d.ts.map +1 -1
- package/dist/feedback/draft.js +3 -0
- package/dist/feedback/draft.js.map +1 -1
- package/dist/figure-references.d.ts +11 -2
- package/dist/figure-references.d.ts.map +1 -1
- package/dist/figure-references.js +50 -13
- package/dist/figure-references.js.map +1 -1
- package/dist/finding-order.d.ts +9 -0
- package/dist/finding-order.d.ts.map +1 -0
- package/dist/finding-order.js +3 -0
- package/dist/finding-order.js.map +1 -0
- package/dist/fix-plan/mode.d.ts +21 -0
- package/dist/fix-plan/mode.d.ts.map +1 -0
- package/dist/fix-plan/mode.js +16 -0
- package/dist/fix-plan/mode.js.map +1 -0
- package/dist/fix-plan/plan.d.ts +77 -0
- package/dist/fix-plan/plan.d.ts.map +1 -0
- package/dist/fix-plan/plan.js +100 -0
- package/dist/fix-plan/plan.js.map +1 -0
- package/dist/fix-plan/render.d.ts +6 -0
- package/dist/fix-plan/render.d.ts.map +1 -0
- package/dist/fix-plan/render.js +101 -0
- package/dist/fix-plan/render.js.map +1 -0
- package/dist/fix-plan/text.d.ts +35 -0
- package/dist/fix-plan/text.d.ts.map +1 -0
- package/dist/fix-plan/text.js +95 -0
- package/dist/fix-plan/text.js.map +1 -0
- package/dist/language-sample.d.ts +2 -0
- package/dist/language-sample.d.ts.map +1 -0
- package/dist/language-sample.js +41 -0
- package/dist/language-sample.js.map +1 -0
- package/dist/link-line.d.ts +8 -0
- package/dist/link-line.d.ts.map +1 -0
- package/dist/link-line.js +12 -0
- package/dist/link-line.js.map +1 -0
- package/dist/long-vowel.d.ts +9 -6
- package/dist/long-vowel.d.ts.map +1 -1
- package/dist/long-vowel.js +15 -8
- package/dist/long-vowel.js.map +1 -1
- package/dist/markup.d.ts.map +1 -1
- package/dist/markup.js +4 -2
- package/dist/markup.js.map +1 -1
- package/dist/name-variants.d.ts +25 -0
- package/dist/name-variants.d.ts.map +1 -0
- package/dist/name-variants.js +181 -0
- package/dist/name-variants.js.map +1 -0
- package/dist/node-version.d.ts +7 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +19 -0
- package/dist/node-version.js.map +1 -0
- package/dist/not-run.d.ts +14 -0
- package/dist/not-run.d.ts.map +1 -0
- package/dist/not-run.js +12 -0
- package/dist/not-run.js.map +1 -0
- package/dist/orthography.d.ts +8 -1
- package/dist/orthography.d.ts.map +1 -1
- package/dist/orthography.js +33 -12
- package/dist/orthography.js.map +1 -1
- package/dist/outline/render.d.ts +18 -0
- package/dist/outline/render.d.ts.map +1 -0
- package/dist/outline/render.js +60 -0
- package/dist/outline/render.js.map +1 -0
- package/dist/outline/shape.d.ts +26 -0
- package/dist/outline/shape.d.ts.map +1 -0
- package/dist/outline/shape.js +37 -0
- package/dist/outline/shape.js.map +1 -0
- package/dist/outline/text.d.ts +21 -0
- package/dist/outline/text.d.ts.map +1 -0
- package/dist/outline/text.js +30 -0
- package/dist/outline/text.js.map +1 -0
- package/dist/plugin.d.ts +24 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/reasons.d.ts +1 -0
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +2 -0
- package/dist/reasons.js.map +1 -1
- package/dist/render/compact.d.ts +3 -1
- package/dist/render/compact.d.ts.map +1 -1
- package/dist/render/compact.js +8 -2
- package/dist/render/compact.js.map +1 -1
- package/dist/render/explain.d.ts +3 -1
- package/dist/render/explain.d.ts.map +1 -1
- package/dist/render/explain.js +32 -15
- package/dist/render/explain.js.map +1 -1
- package/dist/render/rules-json.d.ts.map +1 -1
- package/dist/render/rules-json.js +16 -12
- package/dist/render/rules-json.js.map +1 -1
- package/dist/render/suppressions.d.ts +3 -0
- package/dist/render/suppressions.d.ts.map +1 -1
- package/dist/render/suppressions.js +20 -1
- package/dist/render/suppressions.js.map +1 -1
- package/dist/rule-guide.d.ts +19 -0
- package/dist/rule-guide.d.ts.map +1 -1
- package/dist/rule-guide.js +14 -0
- package/dist/rule-guide.js.map +1 -1
- package/dist/run-semantic.d.ts.map +1 -1
- package/dist/run-semantic.js +2 -1
- package/dist/run-semantic.js.map +1 -1
- package/dist/run.d.ts +5 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +31 -14
- package/dist/run.js.map +1 -1
- package/dist/setting-problems.d.ts.map +1 -1
- package/dist/setting-problems.js +3 -1
- package/dist/setting-problems.js.map +1 -1
- package/dist/spacing-minority.d.ts +16 -0
- package/dist/spacing-minority.d.ts.map +1 -0
- package/dist/spacing-minority.js +23 -0
- package/dist/spacing-minority.js.map +1 -0
- package/dist/stet-block.d.ts +5 -0
- package/dist/stet-block.d.ts.map +1 -0
- package/dist/stet-block.js +59 -0
- package/dist/stet-block.js.map +1 -0
- package/dist/stet.d.ts +4 -0
- package/dist/stet.d.ts.map +1 -1
- package/dist/stet.js +31 -11
- package/dist/stet.js.map +1 -1
- package/dist/structure/date-range.d.ts +10 -0
- package/dist/structure/date-range.d.ts.map +1 -1
- package/dist/structure/date-range.js +33 -1
- package/dist/structure/date-range.js.map +1 -1
- package/dist/structure/definition-use.d.ts +32 -0
- package/dist/structure/definition-use.d.ts.map +1 -0
- package/dist/structure/definition-use.js +102 -0
- package/dist/structure/definition-use.js.map +1 -0
- package/dist/structure/lazy-tree.d.ts +8 -0
- package/dist/structure/lazy-tree.d.ts.map +1 -0
- package/dist/structure/lazy-tree.js +14 -0
- package/dist/structure/lazy-tree.js.map +1 -0
- package/dist/structure/modal-conflict.d.ts +28 -0
- package/dist/structure/modal-conflict.d.ts.map +1 -0
- package/dist/structure/modal-conflict.js +74 -0
- package/dist/structure/modal-conflict.js.map +1 -0
- package/dist/structure/numbered-clauses.d.ts +4 -0
- package/dist/structure/numbered-clauses.d.ts.map +1 -0
- package/dist/structure/numbered-clauses.js +9 -0
- package/dist/structure/numbered-clauses.js.map +1 -0
- package/dist/structure/universal.d.ts.map +1 -1
- package/dist/structure/universal.js +8 -2
- package/dist/structure/universal.js.map +1 -1
- package/dist/style-parse.d.ts +6 -0
- package/dist/style-parse.d.ts.map +1 -1
- package/dist/style-parse.js +32 -4
- package/dist/style-parse.js.map +1 -1
- package/dist/subheading-line.d.ts +19 -2
- package/dist/subheading-line.d.ts.map +1 -1
- package/dist/subheading-line.js +39 -11
- package/dist/subheading-line.js.map +1 -1
- package/dist/tag-coverage.d.ts +8 -0
- package/dist/tag-coverage.d.ts.map +1 -0
- package/dist/tag-coverage.js +7 -0
- package/dist/tag-coverage.js.map +1 -0
- package/genres.yaml +42 -0
- package/package.json +7 -3
- package/rules/acronym-expansion-conflict.yaml +82 -0
- package/rules/adverb-overuse.yaml +2 -2
- package/rules/agentless-passive.yaml +28 -0
- package/rules/ai-tell.yaml +34 -0
- package/rules/announced-count-mismatch.yaml +2 -2
- package/rules/announcing-opener.yaml +31 -0
- package/rules/assistant-residue.yaml +30 -0
- package/rules/bold-density.yaml +28 -0
- package/rules/bold-label-list.yaml +81 -0
- package/rules/closing-cliche.yaml +27 -2
- package/rules/colon-lead-in.yaml +28 -4
- package/rules/contrast-framing.yaml +33 -2
- package/rules/cushion-phrase-density.yaml +32 -5
- package/rules/dangling-reference.yaml +1 -0
- package/rules/date-order.yaml +1 -0
- package/rules/date-range-reversed.yaml +2 -2
- package/rules/double-negative.yaml +51 -0
- package/rules/doubled-punctuation.yaml +2 -2
- package/rules/doubled-word.yaml +2 -2
- package/rules/duplicate-heading.yaml +78 -0
- package/rules/emoji-density.yaml +5 -4
- package/rules/empty-intensifier.yaml +25 -0
- package/rules/empty-section.yaml +74 -0
- package/rules/excessive-hedging.yaml +32 -4
- package/rules/fullwidth-alnum-consistency.yaml +53 -0
- package/rules/hankaku-kana.yaml +41 -0
- package/rules/image-alt-text.yaml +1 -1
- package/rules/invisible-character.yaml +63 -0
- package/rules/katakana-long-vowel.yaml +10 -9
- package/rules/latin-spacing.yaml +12 -5
- package/rules/max-kanji-continuous.yaml +1 -0
- package/rules/max-paragraph-length.yaml +1 -0
- package/rules/max-sentence-length.yaml +26 -0
- package/rules/modal-conflict.yaml +106 -0
- package/rules/name-variant.yaml +88 -0
- package/rules/no-doubled-joshi.yaml +1 -0
- package/rules/no-em-dash.yaml +26 -2
- package/rules/no-mixed-desumasu.yaml +1 -0
- package/rules/nominalization.yaml +89 -0
- package/rules/outside-announced-list.yaml +80 -0
- package/rules/padded-intro.yaml +25 -0
- package/rules/paragraph-length-variance.yaml +26 -2
- package/rules/preferred-term.yaml +1 -0
- package/rules/proper-noun-density.yaml +14 -5
- package/rules/ra-nuki.yaml +43 -0
- package/rules/requirement-modal.yaml +94 -0
- package/rules/requirement-smell.yaml +70 -0
- package/rules/rule-of-three.yaml +46 -0
- package/rules/section-length-uniformity.yaml +26 -2
- package/rules/sentence-rhythm.yaml +26 -0
- package/rules/space-before-punctuation.yaml +41 -0
- package/rules/spelling-consistency.yaml +47 -0
- package/rules/stock-transition.yaml +33 -2
- package/rules/taigen-dome-in-prose.yaml +14 -0
- package/rules/total-mismatch.yaml +1 -0
- package/rules/undefined-acronym.yaml +1 -0
- package/rules/unqualified-superlative.yaml +5 -4
- package/rules/unused-definition.yaml +75 -0
- package/rules/use-before-definition.yaml +77 -0
- package/rules/vague-figure-reference.yaml +66 -0
- package/skills/chaff/SKILL.md +108 -8
- package/src/acronym-expansions.ts +106 -0
- package/src/announced-count.ts +53 -11
- package/src/announced-list.ts +120 -0
- package/src/api.ts +154 -0
- package/src/cli-text.ts +6 -11
- package/src/cli.ts +64 -63
- package/src/closing-paragraph.ts +24 -0
- package/src/commands/compare.ts +11 -18
- package/src/commands/document-commands.ts +19 -0
- package/src/commands/eval.ts +3 -2
- package/src/commands/facts.ts +33 -0
- package/src/commands/feedback.ts +33 -1
- package/src/commands/fix-plan.ts +53 -0
- package/src/commands/outline.ts +49 -0
- package/src/commands/read-document.ts +24 -0
- package/src/commands/suppressions.ts +19 -0
- package/src/commands/test.ts +1 -1
- package/src/compare/clock-time.ts +5 -2
- package/src/compare/distinct.ts +13 -0
- package/src/compare/extract.ts +7 -5
- package/src/compare/fact-key.ts +31 -0
- package/src/compare/fact-text.ts +21 -2
- package/src/compare/facts-render.ts +63 -0
- package/src/compare/facts-text.ts +41 -0
- package/src/compare/match.ts +1 -1
- package/src/compare/outcome.ts +14 -4
- package/src/compare/proper-nouns.ts +4 -4
- package/src/compare/render.ts +2 -2
- package/src/compare/text-atoms.ts +7 -6
- package/src/compare/text.ts +3 -2
- package/src/config/load.ts +9 -0
- package/src/config/option-problems.ts +6 -4
- package/src/config/style.ts +14 -1
- package/src/custom/load.ts +11 -3
- package/src/custom/module-path.ts +23 -0
- package/src/custom/parse.ts +67 -18
- package/src/custom/problems.ts +63 -41
- package/src/detect-language.ts +1 -1
- package/src/detect.ts +10 -3
- package/src/detectors/ai-phrasing.ts +6 -2
- package/src/detectors/bold-label.ts +55 -0
- package/src/detectors/dangling-figure.ts +8 -4
- package/src/detectors/definition-use.ts +41 -0
- package/src/detectors/doubled-punctuation.ts +5 -2
- package/src/detectors/duplicate-heading.ts +47 -0
- package/src/detectors/empty-section.ts +21 -0
- package/src/detectors/fullwidth-alnum.ts +118 -0
- package/src/detectors/hankaku-kana.ts +38 -0
- package/src/detectors/heading-code-words.ts +2 -2
- package/src/detectors/index.ts +36 -0
- package/src/detectors/invisible-character.ts +190 -0
- package/src/detectors/kutoten-consistency.ts +2 -2
- package/src/detectors/lexicon-match.ts +33 -1
- package/src/detectors/lexicon.ts +40 -13
- package/src/detectors/list-sentence.ts +45 -4
- package/src/detectors/long-vowel.ts +20 -4
- package/src/detectors/markup-finding.ts +16 -1
- package/src/detectors/modal-conflict.ts +26 -0
- package/src/detectors/name-variant.ts +15 -0
- package/src/detectors/nominalization.ts +73 -0
- package/src/detectors/orthography.ts +77 -27
- package/src/detectors/outside-announced-list.ts +25 -0
- package/src/detectors/oxford-comma.ts +1 -0
- package/src/detectors/phrase-match.ts +27 -7
- package/src/detectors/ra-nuki.ts +38 -0
- package/src/detectors/requirement-modal.ts +67 -0
- package/src/detectors/requirement-smell.ts +52 -0
- package/src/detectors/space-before-punctuation.ts +32 -0
- package/src/detectors/spelling-variety.ts +81 -0
- package/src/detectors/structure-tree.ts +3 -1
- package/src/detectors/structure.ts +17 -3
- package/src/detectors/superlative-comparison.ts +47 -0
- package/src/detectors/url-run-on.ts +7 -1
- package/src/detectors/vague-figure-pointer.ts +58 -0
- package/src/detectors/word-list.ts +6 -1
- package/src/document.ts +88 -41
- package/src/extension/document-view.ts +109 -0
- package/src/extension/failure-text.ts +46 -0
- package/src/extension/import-default.ts +13 -0
- package/src/extension/load.ts +97 -0
- package/src/extension/module-detector.ts +61 -0
- package/src/extension/plugin-load.ts +82 -0
- package/src/extension/plugin-name.ts +26 -0
- package/src/extension/plugin-parse.ts +229 -0
- package/src/extension/problem-text.ts +103 -0
- package/src/extension/real-path.ts +10 -0
- package/src/extension/returned-findings.ts +62 -0
- package/src/extension/rule-export.ts +23 -0
- package/src/feedback/draft.ts +6 -0
- package/src/figure-references.ts +73 -12
- package/src/finding-order.ts +3 -0
- package/src/fix-plan/mode.ts +34 -0
- package/src/fix-plan/plan.ts +181 -0
- package/src/fix-plan/render.ts +128 -0
- package/src/fix-plan/text.ts +133 -0
- package/src/language-sample.ts +48 -0
- package/src/link-line.ts +13 -0
- package/src/long-vowel.ts +18 -8
- package/src/markup.ts +4 -2
- package/src/name-variants.ts +217 -0
- package/src/node-version.ts +22 -0
- package/src/not-run.ts +16 -0
- package/src/orthography.ts +40 -11
- package/src/outline/render.ts +85 -0
- package/src/outline/shape.ts +72 -0
- package/src/outline/text.ts +50 -0
- package/src/plugin.ts +21 -4
- package/src/reasons.ts +3 -0
- package/src/render/compact.ts +13 -3
- package/src/render/explain.ts +47 -20
- package/src/render/rules-json.ts +18 -12
- package/src/render/suppressions.ts +30 -2
- package/src/rule-guide.ts +38 -0
- package/src/run-semantic.ts +2 -1
- package/src/run.ts +37 -17
- package/src/setting-problems.ts +3 -1
- package/src/spacing-minority.ts +27 -0
- package/src/stet-block.ts +60 -0
- package/src/stet.ts +41 -15
- package/src/structure/date-range.ts +49 -1
- package/src/structure/definition-use.ts +130 -0
- package/src/structure/lazy-tree.ts +15 -0
- package/src/structure/modal-conflict.ts +86 -0
- package/src/structure/numbered-clauses.ts +11 -0
- package/src/structure/universal.ts +10 -2
- package/src/style-parse.ts +38 -3
- package/src/subheading-line.ts +51 -13
- package/src/tag-coverage.ts +13 -0
- package/styles/ieice.yaml +5 -4
- package/styles/jis-z8301-2011.yaml +5 -2
- package/styles/jis-z8301-2019.yaml +31 -0
- package/styles/koyobun.yaml +35 -0
- package/dist/legal-address.d.ts +0 -2
- package/dist/legal-address.d.ts.map +0 -1
- package/dist/legal-address.js +0 -16
- package/dist/legal-address.js.map +0 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import type { Token } from "./plugin.ts";
|
|
2
|
+
|
|
3
|
+
// 同じ名前(人・会社・製品)を、文書の中で少しだけ違う形に書いた所。どの形が正しいかは決めず、少ないほうを指す。
|
|
4
|
+
// 三通りで同じ名前と見る。書き方の違いだけ(GitHub と Github、Mac OS と macOS)、読みが同じ(山田太郎 と 山田太朗)、
|
|
5
|
+
// 英字の一字違い(Microsoft と Microsft)。一字違いは別の名前でもありうるので、多いほうが二度以上、少ないほうが一度だけのときに限る。
|
|
6
|
+
|
|
7
|
+
/** words は名前の語(記号を除く)。読みが同じ二つの名前が、どの語で違うかを見るため。 */
|
|
8
|
+
export type NameMention = { readonly surface: string; readonly offset: number; readonly reading: string | undefined; readonly words: readonly string[] };
|
|
9
|
+
|
|
10
|
+
export type NameVariant = { readonly mention: NameMention; readonly usual: string; readonly kind: "spelling" | "reading" | "near" };
|
|
11
|
+
|
|
12
|
+
const NAME = "PROPN";
|
|
13
|
+
/**
|
|
14
|
+
* 名前の語のあいだに挟まってよい記号(AT&T、Rolls-Royce、ジョン・スミス)。読点は挟まない。
|
|
15
|
+
* 並べた名前(Zeebrugge, Kerk、Cook, Lisa)を一つの名前にしてしまう。
|
|
16
|
+
*/
|
|
17
|
+
const JOINERS: ReadonlySet<string> = new Set(["&", "-", "・"]);
|
|
18
|
+
const LETTER = /\p{L}/u;
|
|
19
|
+
|
|
20
|
+
/** 名前の語。字を含むもの。記号だけの語(wiki の '' )を固有名詞と読む解析器がある。 */
|
|
21
|
+
const isName = (token: Token | undefined): boolean => token?.pos === NAME && LETTER.test(token.surface);
|
|
22
|
+
|
|
23
|
+
/** 固有名詞の続き。記号一つを挟んで固有名詞が続けば、一つの名前。 */
|
|
24
|
+
const runsOf = (tokens: readonly Token[]): Token[][] => {
|
|
25
|
+
const runs: Token[][] = [];
|
|
26
|
+
const current: Token[] = [];
|
|
27
|
+
const close = (): void => {
|
|
28
|
+
if (current.length > 0) runs.push(current.splice(0));
|
|
29
|
+
};
|
|
30
|
+
tokens.forEach((token, index) => {
|
|
31
|
+
const bridges = JOINERS.has(token.surface) && current.length > 0 && isName(tokens[index + 1]);
|
|
32
|
+
if (isName(token) || bridges) current.push(token);
|
|
33
|
+
else close();
|
|
34
|
+
});
|
|
35
|
+
close();
|
|
36
|
+
return runs;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const LOWER = /\p{Ll}/u;
|
|
40
|
+
const UPPER = /\p{Lu}/u;
|
|
41
|
+
const isUpperOnly = (text: string): boolean => UPPER.test(text) && !LOWER.test(text);
|
|
42
|
+
/** 小文字の英字だけの語(the、issue)。日本語の解析器は英単語を固有名詞と読むので、ふつうの語と名前の区別がつかない。 */
|
|
43
|
+
const LOWER_LATIN_ONLY = /^[a-z\s-]+$/u;
|
|
44
|
+
/** 行末で切った語のハイフン(Internet-⏎Drafts)。空白をまとめると "Internet- Drafts" になる。 */
|
|
45
|
+
const WRAPPED_HYPHEN = /-\s+/gu;
|
|
46
|
+
/** 名前の前後に付いた引用の印(wiki の斜体 ''、Hbase')。名前の一部ではない。 */
|
|
47
|
+
const QUOTE_MARKS: ReadonlySet<string> = new Set(["'", "’", '"', "“", "”"]);
|
|
48
|
+
|
|
49
|
+
const withoutEdgeQuotes = (text: string): string => {
|
|
50
|
+
const chars = [...text];
|
|
51
|
+
const start = chars.findIndex((char) => !QUOTE_MARKS.has(char));
|
|
52
|
+
const end = chars.findLastIndex((char) => !QUOTE_MARKS.has(char));
|
|
53
|
+
return start < 0 ? "" : chars.slice(start, end + 1).join("");
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* 名前として比べないもの。@ で始まる SNS のアカウント(@SpaceX は SpaceX の別の書き方ではない)と、一字の語を含むもの
|
|
57
|
+
* (Attachment S、Appendix B は札で、空白を詰めると Attachments と同じ形になる)。
|
|
58
|
+
*/
|
|
59
|
+
const NOT_COMPARED = /@|(?:^|\s)\p{L}(?:\s|$)/u;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 文の語から、名前の現れ。surface は source の上の書いたまま(折り返しの空白は一つにまとめる)。
|
|
63
|
+
* 大文字だけの名前(ACME INC、NASA)は外す。契約書の署名欄や略語で、ふつうの書き方の別の形ではない。小文字の英字だけの語も外す。
|
|
64
|
+
*/
|
|
65
|
+
export const mentionsIn = (tokens: readonly Token[], source: string): NameMention[] =>
|
|
66
|
+
runsOf(tokens).flatMap((run) => {
|
|
67
|
+
const first = run[0];
|
|
68
|
+
const last = run.at(-1);
|
|
69
|
+
if (first === undefined || last === undefined) return [];
|
|
70
|
+
const written = source.slice(first.span.start, last.span.end).replaceAll(WRAPPED_HYPHEN, "-").replaceAll(/\s+/gu, " ");
|
|
71
|
+
const surface = withoutEdgeQuotes(written);
|
|
72
|
+
if (surface === "" || isUpperOnly(surface) || LOWER_LATIN_ONLY.test(surface) || NOT_COMPARED.test(surface)) return [];
|
|
73
|
+
const words = run.filter((token) => !JOINERS.has(token.surface));
|
|
74
|
+
const readings = words.map((token) => token.reading);
|
|
75
|
+
const reading = readings.every((value) => value !== undefined && value !== "") ? readings.join("") : undefined;
|
|
76
|
+
return [{ surface, offset: first.span.start, reading, words: words.map((token) => token.surface) }];
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/** 比べる形。幅(AWS と AWS)、大文字小文字、空白と記号は名前を変えない。 */
|
|
80
|
+
export const nameKey = (surface: string): string =>
|
|
81
|
+
surface
|
|
82
|
+
.normalize("NFKC")
|
|
83
|
+
.toLowerCase()
|
|
84
|
+
.replaceAll(/[\s\p{P}\p{S}]/gu, "");
|
|
85
|
+
|
|
86
|
+
type Tally = { readonly surface: string; readonly first: NameMention; readonly count: number };
|
|
87
|
+
|
|
88
|
+
const talliesOf = (mentions: readonly NameMention[]): Tally[] => {
|
|
89
|
+
const tallies = new Map<string, { surface: string; first: NameMention; count: number }>();
|
|
90
|
+
mentions.forEach((mention) => {
|
|
91
|
+
const tally = tallies.get(mention.surface);
|
|
92
|
+
if (tally === undefined) tallies.set(mention.surface, { surface: mention.surface, first: mention, count: 1 });
|
|
93
|
+
else tally.count += 1;
|
|
94
|
+
});
|
|
95
|
+
return [...tallies.values()];
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** 多いほう。同数なら先に書いたほう。 */
|
|
99
|
+
const usualOf = (group: readonly Tally[]): Tally | undefined =>
|
|
100
|
+
group.toSorted((left, right) => right.count - left.count || left.first.offset - right.first.offset)[0];
|
|
101
|
+
|
|
102
|
+
const groupBy = (tallies: readonly Tally[], keysOf: (tally: Tally) => readonly string[]): Tally[][] => {
|
|
103
|
+
const groups = new Map<string, Tally[]>();
|
|
104
|
+
tallies.forEach((tally) =>
|
|
105
|
+
keysOf(tally).forEach((key) => {
|
|
106
|
+
const group = groups.get(key);
|
|
107
|
+
if (group === undefined) groups.set(key, [tally]);
|
|
108
|
+
else group.push(tally);
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
return [...groups.values()].filter((group) => group.length > 1);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 組の中で、それぞれの書き方を、同じ名前と言える相手(alike)のうち多いほうと比べる。組全体で一番多いものとだけ比べると、
|
|
116
|
+
* 同じ読みの別の名前(山田太郎 と 矢間田多労)が多ければ、本当の書き分け(山田太朗)が隠れる。
|
|
117
|
+
*/
|
|
118
|
+
const variantsIn = (groups: readonly Tally[][], kind: NameVariant["kind"], alike: (tally: Tally, other: Tally) => boolean = () => true): NameVariant[] =>
|
|
119
|
+
groups.flatMap((group) =>
|
|
120
|
+
group.flatMap((tally) => {
|
|
121
|
+
const usual = usualOf([tally, ...group.filter((other) => other !== tally && alike(tally, other))]);
|
|
122
|
+
return usual === undefined || usual === tally ? [] : [{ mention: tally.first, usual: usual.surface, kind }];
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 読みが同じでも、別の名前のことが多い(毅 と 敦士、札幌 と サッポロ)。語が二つ以上あり、違うのが一語だけのとき
|
|
128
|
+
* (山田太郎 と 山田太朗)に限る。
|
|
129
|
+
*/
|
|
130
|
+
const oneWordApart = (tally: Tally, usual: Tally): boolean => {
|
|
131
|
+
const words = tally.first.words;
|
|
132
|
+
const others = usual.first.words;
|
|
133
|
+
return words.length >= 2 && words.length === others.length && words.filter((word, index) => word !== others[index]).length === 1;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/** 一字違いを比べる語の長さ。短い語(Iran と Iraq、RET と REU、II と VI)は一字違いでも別の語。 */
|
|
137
|
+
const MIN_NEAR_LENGTH = 5;
|
|
138
|
+
const LATIN_WORD = /^[a-z]+$/u;
|
|
139
|
+
|
|
140
|
+
const wordsOf = (surface: string): string[] => surface.toLowerCase().split(/[\s-]+/u);
|
|
141
|
+
|
|
142
|
+
/** 一字の置き換えか、隣どうしの入れ替え(Microsfot)。 */
|
|
143
|
+
const isSwapOrReplace = (left: string, right: string): boolean => {
|
|
144
|
+
const differ = [...left].flatMap((char, index) => (char === right.charAt(index) ? [] : [index]));
|
|
145
|
+
const [first, second] = differ;
|
|
146
|
+
if (differ.length === 1) return true;
|
|
147
|
+
return (
|
|
148
|
+
differ.length === 2 &&
|
|
149
|
+
first !== undefined &&
|
|
150
|
+
second === first + 1 &&
|
|
151
|
+
left.charAt(first) === right.charAt(second) &&
|
|
152
|
+
left.charAt(second) === right.charAt(first)
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 語の中の一字の抜け。語の終わりの抜け(Service と Services、America と American)は語の形の違い、頭の抜け(State と XState)は
|
|
158
|
+
* 別の名前で、書き損じではない。
|
|
159
|
+
*/
|
|
160
|
+
const isInnerDrop = (longer: string, shorter: string): boolean =>
|
|
161
|
+
[...longer].some((_char, index) => index > 0 && index < longer.length - 1 && longer.slice(0, index) + longer.slice(index + 1) === shorter);
|
|
162
|
+
|
|
163
|
+
/** 二つの語が一字違いか。英字だけの、長さ 5 以上の語で。 */
|
|
164
|
+
export const isNearWord = (left: string, right: string): boolean => {
|
|
165
|
+
if (left === right || !LATIN_WORD.test(left) || !LATIN_WORD.test(right) || Math.min(left.length, right.length) < MIN_NEAR_LENGTH) return false;
|
|
166
|
+
if (left.length === right.length) return isSwapOrReplace(left, right);
|
|
167
|
+
if (left.length === right.length + 1) return isInnerDrop(left, right);
|
|
168
|
+
return right.length === left.length + 1 && isInnerDrop(right, left);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/** 語の一つを伏せた形。ほかの語が同じ二つの名前は、同じ形を一つ持つ。 */
|
|
172
|
+
const maskedKeys = (tally: Tally): string[] => {
|
|
173
|
+
const words = wordsOf(tally.surface);
|
|
174
|
+
return words.map((_word, index) => words.map((word, at) => (at === index ? "*" : word)).join(" "));
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const differingWords = (left: Tally, right: Tally): readonly [string, string] | undefined => {
|
|
178
|
+
const leftWords = wordsOf(left.surface);
|
|
179
|
+
const rightWords = wordsOf(right.surface);
|
|
180
|
+
const at = leftWords.findIndex((word, index) => word !== rightWords[index]);
|
|
181
|
+
const [leftWord, rightWord] = [leftWords[at], rightWords[at]];
|
|
182
|
+
return leftWords.length === rightWords.length && leftWord !== undefined && rightWord !== undefined ? [leftWord, rightWord] : undefined;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/** 一語だけが一字違いで、相手が二度以上、こちらが一度だけ。 */
|
|
186
|
+
const isSlipOf = (tally: Tally, other: Tally): boolean => {
|
|
187
|
+
if (tally.count !== 1 || other.count < 2) return false;
|
|
188
|
+
const words = differingWords(tally, other);
|
|
189
|
+
return words !== undefined && isNearWord(...words);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const nearVariants = (tallies: readonly Tally[]): NameVariant[] => variantsIn(groupBy(tallies, maskedKeys), "near", isSlipOf);
|
|
193
|
+
|
|
194
|
+
/** 同じ名前の、少ないほうの書き方。書き方ごとに最初の現れを一つ。同じ現れを二つの見方が言えば、先の見方だけ。 */
|
|
195
|
+
export const nameVariants = (mentions: readonly NameMention[]): NameVariant[] => {
|
|
196
|
+
const tallies = talliesOf(mentions);
|
|
197
|
+
const found = [
|
|
198
|
+
...variantsIn(
|
|
199
|
+
groupBy(tallies, (tally) => [nameKey(tally.surface)]),
|
|
200
|
+
"spelling",
|
|
201
|
+
),
|
|
202
|
+
...variantsIn(
|
|
203
|
+
groupBy(tallies, (tally) => (tally.first.reading === undefined ? [] : [tally.first.reading])),
|
|
204
|
+
"reading",
|
|
205
|
+
oneWordApart,
|
|
206
|
+
),
|
|
207
|
+
...nearVariants(tallies),
|
|
208
|
+
];
|
|
209
|
+
const reported = new Set<string>();
|
|
210
|
+
return found
|
|
211
|
+
.filter((variant) => {
|
|
212
|
+
if (reported.has(variant.mention.surface)) return false;
|
|
213
|
+
reported.add(variant.mention.surface);
|
|
214
|
+
return true;
|
|
215
|
+
})
|
|
216
|
+
.toSorted((left, right) => left.mention.offset - right.mention.offset);
|
|
217
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// bin/chaff.js loads this before the CLI, on whatever Node.js the person has. Keep it free of imports and of syntax
|
|
2
|
+
// that old releases cannot parse (`??`, `?.`): running there is its whole job.
|
|
3
|
+
|
|
4
|
+
type Env = Readonly<Record<string, string | undefined>>;
|
|
5
|
+
|
|
6
|
+
/** The lowest major version an engines range such as ">=24" names, or undefined for a range of another shape. */
|
|
7
|
+
export const requiredMajorOf = (range: unknown): number | undefined => {
|
|
8
|
+
const match = /^\s*>=\s*v?(\d+)/u.exec(String(range));
|
|
9
|
+
return match === null ? undefined : Number(match[1]);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const isJapaneseLocale = (env: Env): boolean => /^ja/iu.test(env["LC_ALL"] || env["LC_MESSAGES"] || env["LANG"] || "");
|
|
13
|
+
|
|
14
|
+
/** What to print before stopping when this Node.js is older than the engines range; undefined when it is new enough. */
|
|
15
|
+
export const tooOldMessage = (version: string, range: unknown, env: Env): string | undefined => {
|
|
16
|
+
const required = requiredMajorOf(range);
|
|
17
|
+
const major = Number(version.split(".")[0]);
|
|
18
|
+
if (required === undefined || Number.isNaN(major) || major >= required) return undefined;
|
|
19
|
+
return isJapaneseLocale(env)
|
|
20
|
+
? `chaff は Node.js ${String(required)} 以上で動きます。いまは v${version} です。https://nodejs.org/ja から LTS を入れてください。`
|
|
21
|
+
: `chaff needs Node.js ${String(required)} or later. This is v${version}. Install the LTS from https://nodejs.org/en`;
|
|
22
|
+
};
|
package/src/not-run.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Skipped } from "./run.ts";
|
|
2
|
+
|
|
3
|
+
/** A rule someone asked about that did not run in this check, with why, and whether --experimental would run it. */
|
|
4
|
+
export type NotRun = { readonly rule: string; readonly why: string; readonly needsExperimental: boolean };
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Pure: of the rules named in `ruleIds`, those this check skipped. A command that looks a rule's findings up (feedback,
|
|
8
|
+
* suppressions) says this instead of "none": no findings from a rule that did not run is not "checked and fine".
|
|
9
|
+
* --experimental is suggested only where it is the reason, not for a rule chaff.yaml or the genre turned off.
|
|
10
|
+
*/
|
|
11
|
+
export const notRunAmong = (ruleIds: readonly string[], skipped: readonly Skipped[]): NotRun[] => {
|
|
12
|
+
const asked = new Set(ruleIds);
|
|
13
|
+
return skipped
|
|
14
|
+
.filter((entry) => asked.has(entry.rule))
|
|
15
|
+
.map((entry) => ({ rule: entry.rule, why: entry.why, needsExperimental: entry.offUntilExperimental === true }));
|
|
16
|
+
};
|
package/src/orthography.ts
CHANGED
|
@@ -152,13 +152,25 @@ export const hyphenGroups = (text: string): string[] => text.split(HYPHEN).filte
|
|
|
152
152
|
|
|
153
153
|
const isCodeChar = (char: string | undefined): boolean => DIGIT.test(char ?? "") || isHyphen(char);
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
/** digit を含む、isPart の字の並び。 */
|
|
156
|
+
const runAround = (chars: readonly string[], digit: number, isPart: (char: string | undefined) => boolean): string => {
|
|
156
157
|
let [first, last] = [digit, digit];
|
|
157
|
-
while (first > 0 &&
|
|
158
|
-
while (last < chars.length - 1 &&
|
|
159
|
-
return
|
|
158
|
+
while (first > 0 && isPart(chars[first - 1])) first -= 1;
|
|
159
|
+
while (last < chars.length - 1 && isPart(chars[last + 1])) last += 1;
|
|
160
|
+
return chars.slice(first, last + 1).join("");
|
|
160
161
|
};
|
|
161
162
|
|
|
163
|
+
const isDottedChar = (char: string | undefined): boolean => DIGIT.test(char ?? "") || char === ".";
|
|
164
|
+
|
|
165
|
+
/** 「1.0.0」「3.1.2」のように . でつないだ 3 組以上の数字は、版や項目の番号で数量ではない。2 組(「1.5 倍」)は小数なので数える。 */
|
|
166
|
+
const isDottedCode = (chars: readonly string[], digit: number): boolean =>
|
|
167
|
+
runAround(chars, digit, isDottedChar)
|
|
168
|
+
.split(".")
|
|
169
|
+
.filter((group) => group !== "").length >= MIN_CODE_GROUPS;
|
|
170
|
+
|
|
171
|
+
const isCode = (chars: readonly string[], digit: number): boolean =>
|
|
172
|
+
hyphenGroups(runAround(chars, digit, isCodeChar)).length >= MIN_CODE_GROUPS || isDottedCode(chars, digit);
|
|
173
|
+
|
|
162
174
|
/** 日本語との境目にある数字が、数えない書き方(「第3条」の番地、「073-489-5909」の符号)か。 */
|
|
163
175
|
const isUncountedNumber = (chars: readonly string[], index: number): boolean => {
|
|
164
176
|
const [left, right] = [chars[index], chars[index + 1]];
|
|
@@ -201,13 +213,30 @@ export const latinBoundaries = (text: string, written: string = text): Boundary[
|
|
|
201
213
|
};
|
|
202
214
|
|
|
203
215
|
/**
|
|
204
|
-
*
|
|
216
|
+
* 二通りの書き方(true と false)が混ざっているとき、そろえるべき少数派。どちらか一方しか無ければ undefined。
|
|
205
217
|
* 同数なら、文書が先に使った書き方をその文書の書き方とみなし、後から出た書き方を少数派にする。
|
|
206
218
|
*/
|
|
207
|
-
export const
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
if (
|
|
211
|
-
if (
|
|
212
|
-
return !(
|
|
219
|
+
export const minorityOf = (written: readonly boolean[]): boolean | undefined => {
|
|
220
|
+
const yes = written.filter(Boolean).length;
|
|
221
|
+
const no = written.length - yes;
|
|
222
|
+
if (yes === 0 || no === 0) return undefined;
|
|
223
|
+
if (yes !== no) return yes < no;
|
|
224
|
+
return !(written[0] ?? false);
|
|
213
225
|
};
|
|
226
|
+
|
|
227
|
+
const PERCENT = 100;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 二通りに書き分けたもの(side が true か false)のうち、少ないほうのもの。少ないほうが全体の limitPercent パーセントを超えるなら、
|
|
231
|
+
* 文書が使い分けていると見て空。どちらか一方しか無くても空。
|
|
232
|
+
*/
|
|
233
|
+
export const minorityWithin = <T>(items: readonly T[], side: (item: T) => boolean, limitPercent: number): T[] => {
|
|
234
|
+
const minority = minorityOf(items.map(side));
|
|
235
|
+
if (minority === undefined) return [];
|
|
236
|
+
const odd = items.filter((item) => side(item) === minority);
|
|
237
|
+
return odd.length * PERCENT > limitPercent * items.length ? [] : odd;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/** 空けるか詰めるかの少数派。種類(英字・数字の前・数字の後ろ)ごとに数える。 */
|
|
241
|
+
export const minorityStyle = (boundaries: readonly { readonly spaced: boolean }[]): boolean | undefined =>
|
|
242
|
+
minorityOf(boundaries.map((boundary) => boundary.spaced));
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { LengthUnit } from "../plugin.ts";
|
|
2
|
+
import type { Outline, OutlineEntry, Shape } from "./shape.ts";
|
|
3
|
+
import type { OutlineText } from "./text.ts";
|
|
4
|
+
|
|
5
|
+
/** One file's outline as `chaff outline` shows it. */
|
|
6
|
+
export type DocumentOutline = { readonly path: string; readonly language: string; readonly outline: Outline };
|
|
7
|
+
|
|
8
|
+
type Measure = { readonly name: string; readonly value: (shape: Shape, unit: LengthUnit) => string };
|
|
9
|
+
|
|
10
|
+
/** The shape's measures in the order they are shown. */
|
|
11
|
+
const measuresOf = (text: OutlineText): readonly Measure[] => [
|
|
12
|
+
{ name: text.headings, value: (shape) => String(shape.headings) },
|
|
13
|
+
{ name: text.averageSection, value: (shape, unit) => text.length(shape.averageSectionLength, unit) },
|
|
14
|
+
{ name: text.lists, value: (shape) => `${String(shape.listPercent)}%` },
|
|
15
|
+
{ name: text.bold, value: (shape) => String(shape.bold) },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
/** The shape's measures on one line: 見出し 6、節の平均 120 字、… / headings 6, average section 80 words, … */
|
|
19
|
+
export const shapeMeasures = (shape: Shape, unit: LengthUnit, text: OutlineText): string =>
|
|
20
|
+
measuresOf(text)
|
|
21
|
+
.map((measure) => text.measure(measure.name, measure.value(shape, unit)))
|
|
22
|
+
.join(text.separator);
|
|
23
|
+
|
|
24
|
+
const shapeLine = (document: DocumentOutline, text: OutlineText): string =>
|
|
25
|
+
text.shapeOf(document.path, shapeMeasures(document.outline.shape, document.outline.unit, text));
|
|
26
|
+
|
|
27
|
+
const headingOf = (entry: OutlineEntry, text: OutlineText): string => (entry.depth === 0 ? text.lead : `${"#".repeat(entry.depth)} ${entry.heading}`);
|
|
28
|
+
|
|
29
|
+
/** A heading indented by its depth, where it is, and how long its own text is. */
|
|
30
|
+
const entryLine = (entry: OutlineEntry, document: DocumentOutline, text: OutlineText): string => {
|
|
31
|
+
const indent = " ".repeat(Math.max(entry.depth - 1, 0));
|
|
32
|
+
const length = text.length(entry.length, document.outline.unit);
|
|
33
|
+
return ` ${indent}${headingOf(entry, text)} (${document.path}:${String(entry.line)}) ${length}`;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const outlineBlock = (document: DocumentOutline, text: OutlineText): string[] => [
|
|
37
|
+
shapeLine(document, text),
|
|
38
|
+
"",
|
|
39
|
+
...document.outline.entries.map((entry) => entryLine(entry, document, text)),
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
/** Each measure before and after, so a restructure shows as numbers that moved. */
|
|
43
|
+
const changeBlock = (before: DocumentOutline, after: DocumentOutline, text: OutlineText): string[] => [
|
|
44
|
+
"",
|
|
45
|
+
text.changed(before.path, after.path),
|
|
46
|
+
...measuresOf(text).map(
|
|
47
|
+
(measure) => ` ${measure.name}: ${measure.value(before.outline.shape, before.outline.unit)} → ${measure.value(after.outline.shape, after.outline.unit)}`,
|
|
48
|
+
),
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
/** For a person: each file's shape and outline, then, for two files, how each measure moved. */
|
|
52
|
+
export const renderOutlineFriendly = (documents: readonly DocumentOutline[], text: OutlineText): string => {
|
|
53
|
+
const [before, after] = documents;
|
|
54
|
+
const outlines = documents.flatMap((document, index) => [...(index > 0 ? [""] : []), ...outlineBlock(document, text)]);
|
|
55
|
+
return [...outlines, ...(before !== undefined && after !== undefined ? changeBlock(before, after, text) : [])].join("\n");
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const COMPACT_UNIT: Readonly<Record<LengthUnit, string>> = { char: "chars", word: "words" };
|
|
59
|
+
|
|
60
|
+
const compactEntry = (entry: OutlineEntry, document: DocumentOutline): string => {
|
|
61
|
+
const heading = entry.depth === 0 ? "lead" : `h${String(entry.depth)} ${entry.heading}`;
|
|
62
|
+
return `${document.path}:${String(entry.line)}: ${heading} (${String(entry.length)} ${COMPACT_UNIT[document.outline.unit]})`;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** For grep: one section per line, then each file's shape. */
|
|
66
|
+
export const renderOutlineCompact = (documents: readonly DocumentOutline[], text: OutlineText): string =>
|
|
67
|
+
[
|
|
68
|
+
...documents.flatMap((document) => document.outline.entries.map((entry) => compactEntry(entry, document))),
|
|
69
|
+
...documents.map((document) => shapeLine(document, text)),
|
|
70
|
+
].join("\n");
|
|
71
|
+
|
|
72
|
+
const outlineJson = (document: DocumentOutline): Readonly<Record<string, unknown>> => ({
|
|
73
|
+
path: document.path,
|
|
74
|
+
language: document.language,
|
|
75
|
+
unit: document.outline.unit,
|
|
76
|
+
shape: document.outline.shape,
|
|
77
|
+
outline: document.outline.entries,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/** For an AI: one file's outline and shape, or `before` and `after` for two. */
|
|
81
|
+
export const renderOutlineJson = (documents: readonly DocumentOutline[]): string => {
|
|
82
|
+
const [before, after] = documents;
|
|
83
|
+
const body = before !== undefined && after !== undefined ? { before: outlineJson(before), after: outlineJson(after) } : documents.map(outlineJson)[0];
|
|
84
|
+
return JSON.stringify(body, null, 2);
|
|
85
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { lengthOf } from "../measure.ts";
|
|
2
|
+
import { lineStarts, placeOf } from "../position.ts";
|
|
3
|
+
import type { LengthUnit, ProseDocument, Section, Sentence } from "../plugin.ts";
|
|
4
|
+
import { coversOffset, spanIndex } from "../compare/spans.ts";
|
|
5
|
+
|
|
6
|
+
/** One section: its heading's depth (0 for the text before the first heading), its words, its line, and its own length. */
|
|
7
|
+
export type OutlineEntry = { readonly depth: number; readonly heading: string; readonly line: number; readonly length: number };
|
|
8
|
+
|
|
9
|
+
/** The measures a restructure moves. Lengths are in the document's unit: characters for Japanese, words for English. */
|
|
10
|
+
export type Shape = {
|
|
11
|
+
readonly headings: number;
|
|
12
|
+
/** The mean length of the sections that have text, rounded. */
|
|
13
|
+
readonly averageSectionLength: number;
|
|
14
|
+
/** The share of the body text inside list items, as a rounded percentage. */
|
|
15
|
+
readonly listPercent: number;
|
|
16
|
+
/** Bold spans (Markdown `**…**`). */
|
|
17
|
+
readonly bold: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type Outline = { readonly unit: LengthUnit; readonly entries: readonly OutlineEntry[]; readonly shape: Shape };
|
|
21
|
+
|
|
22
|
+
const PERCENT = 100;
|
|
23
|
+
|
|
24
|
+
const lengthOfAll = (sentences: readonly Sentence[], unit: LengthUnit): number => sentences.reduce((sum, sentence) => sum + lengthOf(sentence, unit), 0);
|
|
25
|
+
|
|
26
|
+
/** The text before the first heading is listed only when there is some: a title line alone has nothing above it. */
|
|
27
|
+
const isListed = (entry: OutlineEntry): boolean => entry.depth > 0 || entry.length > 0;
|
|
28
|
+
|
|
29
|
+
/** Where each heading starts, keyed by where it ends: a section begins after its heading, past a Setext underline. */
|
|
30
|
+
type HeadingStarts = ReadonlyMap<number, number>;
|
|
31
|
+
|
|
32
|
+
const headingStartsOf = (doc: ProseDocument): HeadingStarts => new Map((doc.markup?.headings ?? []).map((heading) => [heading.end, heading.start]));
|
|
33
|
+
|
|
34
|
+
/** A heading's first line; for the text above the first heading, the line its text starts on, below any front matter. */
|
|
35
|
+
const startOf = (section: Section, headingStarts: HeadingStarts): number =>
|
|
36
|
+
section.depth === 0 ? (section.sentences[0]?.span.start ?? section.span.start) : (headingStarts.get(section.span.start) ?? section.span.start);
|
|
37
|
+
|
|
38
|
+
type Place = { readonly lineOf: (offset: number) => number; readonly headingStarts: HeadingStarts };
|
|
39
|
+
|
|
40
|
+
const entryOf = (section: Section, unit: LengthUnit, place: Place): OutlineEntry => ({
|
|
41
|
+
depth: section.depth,
|
|
42
|
+
heading: section.heading,
|
|
43
|
+
line: place.lineOf(startOf(section, place.headingStarts)),
|
|
44
|
+
length: lengthOfAll(section.sentences, unit),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const averageOf = (lengths: readonly number[]): number =>
|
|
48
|
+
lengths.length === 0 ? 0 : Math.round(lengths.reduce((sum, length) => sum + length, 0) / lengths.length);
|
|
49
|
+
|
|
50
|
+
const listPercentOf = (doc: ProseDocument): number => {
|
|
51
|
+
const lists = spanIndex(doc.listSpans);
|
|
52
|
+
const total = lengthOfAll(doc.sentences, doc.lengthUnit);
|
|
53
|
+
const inLists = lengthOfAll(
|
|
54
|
+
doc.sentences.filter((sentence) => coversOffset(lists, sentence.span.start)),
|
|
55
|
+
doc.lengthUnit,
|
|
56
|
+
);
|
|
57
|
+
return total === 0 ? 0 : Math.round((inLists / total) * PERCENT);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** The document's outline and its shape, measured from the same reading lint uses. */
|
|
61
|
+
export const outlineOf = (doc: ProseDocument): Outline => {
|
|
62
|
+
const starts = lineStarts(doc.source);
|
|
63
|
+
const place: Place = { lineOf: (offset) => placeOf(starts, offset).line, headingStarts: headingStartsOf(doc) };
|
|
64
|
+
const entries = doc.sections.map((section) => entryOf(section, doc.lengthUnit, place)).filter(isListed);
|
|
65
|
+
const shape: Shape = {
|
|
66
|
+
headings: entries.filter((entry) => entry.depth > 0).length,
|
|
67
|
+
averageSectionLength: averageOf(entries.map((entry) => entry.length).filter((length) => length > 0)),
|
|
68
|
+
listPercent: listPercentOf(doc),
|
|
69
|
+
bold: doc.sections.reduce((sum, section) => sum + section.strongCount, 0),
|
|
70
|
+
};
|
|
71
|
+
return { unit: doc.lengthUnit, entries, shape };
|
|
72
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Texts } from "../ui.ts";
|
|
2
|
+
import type { LengthUnit } from "../plugin.ts";
|
|
3
|
+
import { counted } from "../render/plural.ts";
|
|
4
|
+
|
|
5
|
+
export type OutlineText = {
|
|
6
|
+
readonly usage: string;
|
|
7
|
+
/** How a length is written: 120 字 / 120 words. */
|
|
8
|
+
readonly length: (count: number, unit: LengthUnit) => string;
|
|
9
|
+
/** The text before the first heading, in place of a heading. */
|
|
10
|
+
readonly lead: string;
|
|
11
|
+
readonly headings: string;
|
|
12
|
+
readonly averageSection: string;
|
|
13
|
+
readonly lists: string;
|
|
14
|
+
readonly bold: string;
|
|
15
|
+
readonly separator: string;
|
|
16
|
+
/** The line that names the file and gives its shape. */
|
|
17
|
+
readonly shapeOf: (path: string, measures: string) => string;
|
|
18
|
+
readonly measure: (name: string, value: string) => string;
|
|
19
|
+
/** The heading of the before/after block. */
|
|
20
|
+
readonly changed: (before: string, after: string) => string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const OUTLINE_TEXT: Texts<OutlineText> = {
|
|
24
|
+
ja: {
|
|
25
|
+
usage: "使い方: chaff outline <file> [<書き直した後>] [--compact | --json] [--language ja|en|…] [--genre <ジャンル>]",
|
|
26
|
+
length: (count, unit) => (unit === "char" ? `${String(count)} 字` : `${String(count)} 語`),
|
|
27
|
+
lead: "(最初の見出しの前)",
|
|
28
|
+
headings: "見出し",
|
|
29
|
+
averageSection: "節の平均",
|
|
30
|
+
lists: "箇条書き",
|
|
31
|
+
bold: "太字",
|
|
32
|
+
separator: "、",
|
|
33
|
+
shapeOf: (path, measures) => `${path} の構成: ${measures}`,
|
|
34
|
+
measure: (name, value) => `${name} ${value}`,
|
|
35
|
+
changed: (before, after) => `構成の変化(${before} → ${after})`,
|
|
36
|
+
},
|
|
37
|
+
en: {
|
|
38
|
+
usage: "usage: chaff outline <file> [<rewritten>] [--compact | --json] [--language ja|en|…] [--genre <genre>]",
|
|
39
|
+
length: (count, unit) => (unit === "char" ? counted(count, "character") : counted(count, "word")),
|
|
40
|
+
lead: "(before the first heading)",
|
|
41
|
+
headings: "headings",
|
|
42
|
+
averageSection: "average section",
|
|
43
|
+
lists: "in lists",
|
|
44
|
+
bold: "bold",
|
|
45
|
+
separator: ", ",
|
|
46
|
+
shapeOf: (path, measures) => `${path} outline: ${measures}`,
|
|
47
|
+
measure: (name, value) => `${name} ${value}`,
|
|
48
|
+
changed: (before, after) => `How the shape changed (${before} → ${after})`,
|
|
49
|
+
},
|
|
50
|
+
};
|
package/src/plugin.ts
CHANGED
|
@@ -62,6 +62,10 @@ export type LexiconEntry = {
|
|
|
62
62
|
readonly instead_of?: string | undefined;
|
|
63
63
|
/** 語が、かかる語のどちら側に立つか。語順が言語で違うものを語彙表が言う(範囲の「で」は前、"in" は後ろ)。 */
|
|
64
64
|
readonly position?: "before" | "after" | undefined;
|
|
65
|
+
/** How to rewrite this one phrase, in the lexicon's language. chaff fix-plan prints it next to the rule's own direction. */
|
|
66
|
+
readonly rewrite?: string | undefined;
|
|
67
|
+
/** 語の組の名前。同じ組の語どうしだけを比べる rule が使う(対応する OS を言う語と、対応する言語を言う語を分ける)。 */
|
|
68
|
+
readonly group?: string | undefined;
|
|
65
69
|
/** pattern を adapter が語に分けたもの。品詞が読めるときだけ core が入れる。語彙表を書く側は書かない。 */
|
|
66
70
|
readonly tokens?: readonly Token[] | undefined;
|
|
67
71
|
};
|
|
@@ -188,8 +192,15 @@ export type StructurePatterns = {
|
|
|
188
192
|
readonly continuesSentence?: (number: string, rest: string) => boolean;
|
|
189
193
|
/** 数の書き方(「二十二」「3」)を数にする。相対の参照の「前二項」「前条第二項」が使う。 */
|
|
190
194
|
readonly number?: (text: string) => number | undefined;
|
|
195
|
+
/** text の at のすぐ前に書いた文書の名前(「民法の」「…(平成二十年厚生労働省告示第五十九号)」「この規則の」)。名前が無ければ undefined。 */
|
|
196
|
+
readonly namedDocument?: DocumentNamer;
|
|
191
197
|
};
|
|
192
198
|
|
|
199
|
+
/** 位置のすぐ前に書いた文書の名前。self はこの文書を指す名前(「この規則」「本規約」)。 */
|
|
200
|
+
export type NamedDocument = { readonly name: string; readonly self: boolean };
|
|
201
|
+
|
|
202
|
+
export type DocumentNamer = (text: string, at: number) => NamedDocument | undefined;
|
|
203
|
+
|
|
193
204
|
export type StructureKind = "doc" | "section" | "chapter" | "article" | "item" | "definition" | "reference" | "obligation" | "quantity" | "date";
|
|
194
205
|
|
|
195
206
|
/** 番地の付いた木の節点。すべて元の文書の位置(UTF-16)と行を持つ。 */
|
|
@@ -231,8 +242,8 @@ export type Section = {
|
|
|
231
242
|
|
|
232
243
|
export type Paragraph = { readonly span: Span; readonly sentences: readonly Sentence[] };
|
|
233
244
|
|
|
234
|
-
/** 箇条書き 1
|
|
235
|
-
export type BulletList = { readonly span: Span; readonly items: readonly number[] };
|
|
245
|
+
/** 箇条書き 1 つ。items は項目の文字数(空白を除く)、itemSpans は同じ順の項目の範囲。 */
|
|
246
|
+
export type BulletList = { readonly span: Span; readonly items: readonly number[]; readonly itemSpans: readonly Span[] };
|
|
236
247
|
|
|
237
248
|
/**
|
|
238
249
|
* detector に渡る唯一の入り口。core が I/O を済ませてから呼ぶ。
|
|
@@ -339,6 +350,8 @@ export type ProseDocument = {
|
|
|
339
350
|
readonly profile?: DocumentProfile | undefined;
|
|
340
351
|
/** 本文でないもの(コード・HTML・強調の印)を同じ長さの空白で覆った source。位置は source と同じ。 */
|
|
341
352
|
readonly prose?: string | undefined;
|
|
353
|
+
/** 位置のすぐ前に書いた文書の名前を読む。言語パッケージが読めなければ無い。 */
|
|
354
|
+
readonly namedDocument?: DocumentNamer | undefined;
|
|
342
355
|
/** メールの引用した返信(前置きの行と「> 」の行)。ほかの人の言葉なので、見出しにも木にも入れない。 */
|
|
343
356
|
readonly replyQuotes?: readonly Span[] | undefined;
|
|
344
357
|
/** 記法の手がかり(見出し・画像・リンク)。記法を読む rule だけが触れ、触れたときに作る。 */
|
|
@@ -474,8 +487,10 @@ export type RuleDefinition = {
|
|
|
474
487
|
readonly severity: Severity;
|
|
475
488
|
/** Options beyond the level (the direction and length for katakana-long-vowel). Most rules have none. */
|
|
476
489
|
readonly options?: Readonly<Record<string, RuleOption>>;
|
|
477
|
-
/** A rule a team defined under custom_rules in chaff.yaml: what it looks for. Built-in rules have none. */
|
|
490
|
+
/** A rule a team defined under custom_rules in chaff.yaml, or a plugin ships: what it looks for. Built-in rules have none. */
|
|
478
491
|
readonly custom?: CustomSpec;
|
|
492
|
+
/** The name of the plugin that ships the rule, which is also its id's prefix (foo in foo/rule-id). Only a plugin's rules have it. */
|
|
493
|
+
readonly plugin?: string;
|
|
479
494
|
/** What the rule reference tells a reader who is not an engineer: its group, one line, a before and after. */
|
|
480
495
|
readonly guide?: RuleGuide;
|
|
481
496
|
};
|
|
@@ -490,8 +505,10 @@ export type TokenCondition = {
|
|
|
490
505
|
/**
|
|
491
506
|
* What a team's rule looks for. words: spellings to avoid, each with the one to use (or none, to only point at it).
|
|
492
507
|
* pattern: a regular expression, checked before it runs. tokens: a run of tokens from the language adapter.
|
|
508
|
+
* module: a detector the team wrote in JavaScript; module as written in chaff.yaml, file where it resolved to.
|
|
493
509
|
*/
|
|
494
510
|
export type CustomSpec =
|
|
495
511
|
| { readonly type: "words"; readonly words: readonly { readonly avoid: string; readonly use: string }[] }
|
|
496
512
|
| { readonly type: "pattern"; readonly pattern: string; readonly flags: string }
|
|
497
|
-
| { readonly type: "tokens"; readonly tokens: readonly TokenCondition[] }
|
|
513
|
+
| { readonly type: "tokens"; readonly tokens: readonly TokenCondition[] }
|
|
514
|
+
| { readonly type: "module"; readonly module: string; readonly file: string };
|
package/src/reasons.ts
CHANGED
|
@@ -6,6 +6,7 @@ export type Reasons = {
|
|
|
6
6
|
readonly otherLanguage: (language: string) => string;
|
|
7
7
|
readonly noCapability: (capability: string) => string;
|
|
8
8
|
readonly noTags: string;
|
|
9
|
+
readonly unreadTags: string;
|
|
9
10
|
readonly semantic: string;
|
|
10
11
|
readonly experimental: string;
|
|
11
12
|
readonly turnedOff: string;
|
|
@@ -29,6 +30,7 @@ export const REASONS: Texts<Reasons> = {
|
|
|
29
30
|
otherLanguage: (language) => `${language} 向けの rule ではないため`,
|
|
30
31
|
noCapability: (capability) => `この言語では${CAPABILITY_NAME.ja[capability] ?? capability}が使えないため`,
|
|
31
32
|
noTags: "アダプタが品詞を返さなかったため",
|
|
33
|
+
unreadTags: "言語のパッケージがこの文書を読めなかったため(品詞の取れない段落があります)",
|
|
32
34
|
semantic: "意味を読む検査のため(npx chaff test で動きます)",
|
|
33
35
|
experimental: "まだ試験中のため",
|
|
34
36
|
turnedOff: "設定で止めているため",
|
|
@@ -46,6 +48,7 @@ export const REASONS: Texts<Reasons> = {
|
|
|
46
48
|
otherLanguage: (language) => `not a rule for ${language}`,
|
|
47
49
|
noCapability: (capability) => `${CAPABILITY_NAME.en[capability] ?? capability} is not available for this language`,
|
|
48
50
|
noTags: "the language package returned no parts of speech",
|
|
51
|
+
unreadTags: "the language package could not read this document (some paragraphs have no parts of speech)",
|
|
49
52
|
semantic: "it reads meaning; npx chaff test runs it",
|
|
50
53
|
experimental: "still experimental",
|
|
51
54
|
turnedOff: "turned off in the settings",
|