chaffjs 0.16.0 → 0.18.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/dist/announced-count.d.ts +26 -0
- package/dist/announced-count.d.ts.map +1 -0
- package/dist/announced-count.js +104 -0
- package/dist/announced-count.js.map +1 -0
- package/dist/bare-url.d.ts +14 -0
- package/dist/bare-url.d.ts.map +1 -0
- package/dist/bare-url.js +28 -0
- package/dist/bare-url.js.map +1 -0
- package/dist/baseline.d.ts +5 -0
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +16 -1
- package/dist/baseline.js.map +1 -1
- package/dist/body-section.d.ts +7 -0
- package/dist/body-section.d.ts.map +1 -0
- package/dist/body-section.js +6 -0
- package/dist/body-section.js.map +1 -0
- package/dist/calendar-number.d.ts +9 -2
- package/dist/calendar-number.d.ts.map +1 -1
- package/dist/calendar-number.js +18 -4
- package/dist/calendar-number.js.map +1 -1
- package/dist/cli-args.d.ts +4 -0
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +5 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli-text.d.ts.map +1 -1
- package/dist/cli-text.js +8 -4
- package/dist/cli-text.js.map +1 -1
- package/dist/cli.js +33 -30
- package/dist/cli.js.map +1 -1
- package/dist/closing-numbers.d.ts +20 -0
- package/dist/closing-numbers.d.ts.map +1 -0
- package/dist/closing-numbers.js +56 -0
- package/dist/closing-numbers.js.map +1 -0
- package/dist/commands/compare.d.ts +8 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +72 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +17 -9
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/feedback.d.ts +5 -2
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +11 -5
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +13 -13
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/tree.d.ts +13 -0
- package/dist/commands/tree.d.ts.map +1 -1
- package/dist/commands/tree.js +35 -5
- package/dist/commands/tree.js.map +1 -1
- package/dist/compare/atom.d.ts +31 -0
- package/dist/compare/atom.d.ts.map +1 -0
- package/dist/compare/atom.js +4 -0
- package/dist/compare/atom.js.map +1 -0
- package/dist/compare/clock-time.d.ts +8 -0
- package/dist/compare/clock-time.d.ts.map +1 -0
- package/dist/compare/clock-time.js +65 -0
- package/dist/compare/clock-time.js.map +1 -0
- package/dist/compare/extract.d.ts +15 -0
- package/dist/compare/extract.d.ts.map +1 -0
- package/dist/compare/extract.js +58 -0
- package/dist/compare/extract.js.map +1 -0
- package/dist/compare/fact-text.d.ts +23 -0
- package/dist/compare/fact-text.d.ts.map +1 -0
- package/dist/compare/fact-text.js +47 -0
- package/dist/compare/fact-text.js.map +1 -0
- package/dist/compare/markup-atoms.d.ts +11 -0
- package/dist/compare/markup-atoms.d.ts.map +1 -0
- package/dist/compare/markup-atoms.js +23 -0
- package/dist/compare/markup-atoms.js.map +1 -0
- package/dist/compare/match.d.ts +19 -0
- package/dist/compare/match.d.ts.map +1 -0
- package/dist/compare/match.js +84 -0
- package/dist/compare/match.js.map +1 -0
- package/dist/compare/outcome.d.ts +33 -0
- package/dist/compare/outcome.d.ts.map +1 -0
- package/dist/compare/outcome.js +40 -0
- package/dist/compare/outcome.js.map +1 -0
- package/dist/compare/proper-nouns.d.ts +19 -0
- package/dist/compare/proper-nouns.d.ts.map +1 -0
- package/dist/compare/proper-nouns.js +44 -0
- package/dist/compare/proper-nouns.js.map +1 -0
- package/dist/compare/render.d.ts +9 -0
- package/dist/compare/render.d.ts.map +1 -0
- package/dist/compare/render.js +64 -0
- package/dist/compare/render.js.map +1 -0
- package/dist/compare/spans.d.ts +9 -0
- package/dist/compare/spans.d.ts.map +1 -0
- package/dist/compare/spans.js +11 -0
- package/dist/compare/spans.js.map +1 -0
- package/dist/compare/text-atoms.d.ts +24 -0
- package/dist/compare/text-atoms.d.ts.map +1 -0
- package/dist/compare/text-atoms.js +67 -0
- package/dist/compare/text-atoms.js.map +1 -0
- package/dist/compare/text.d.ts +24 -0
- package/dist/compare/text.d.ts.map +1 -0
- package/dist/compare/text.js +90 -0
- package/dist/compare/text.js.map +1 -0
- package/dist/compare/tree-atoms.d.ts +20 -0
- package/dist/compare/tree-atoms.d.ts.map +1 -0
- package/dist/compare/tree-atoms.js +58 -0
- package/dist/compare/tree-atoms.js.map +1 -0
- package/dist/compare/written-names.d.ts +8 -0
- package/dist/compare/written-names.d.ts.map +1 -0
- package/dist/compare/written-names.js +24 -0
- package/dist/compare/written-names.js.map +1 -0
- package/dist/config/load.d.ts +15 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +5 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/option-problems.d.ts +16 -0
- package/dist/config/option-problems.d.ts.map +1 -0
- package/dist/config/option-problems.js +58 -0
- package/dist/config/option-problems.js.map +1 -0
- package/dist/config/read.d.ts +4 -0
- package/dist/config/read.d.ts.map +1 -0
- package/dist/config/read.js +8 -0
- package/dist/config/read.js.map +1 -0
- package/dist/config/rule-problems.d.ts +2 -4
- package/dist/config/rule-problems.d.ts.map +1 -1
- package/dist/config/rule-problems.js +7 -1
- package/dist/config/rule-problems.js.map +1 -1
- package/dist/config/style.d.ts +16 -0
- package/dist/config/style.d.ts.map +1 -0
- package/dist/config/style.js +36 -0
- package/dist/config/style.js.map +1 -0
- package/dist/config/warnings.d.ts +6 -0
- package/dist/config/warnings.d.ts.map +1 -0
- package/dist/config/warnings.js +10 -0
- package/dist/config/warnings.js.map +1 -0
- package/dist/config/write.d.ts.map +1 -1
- package/dist/config/write.js +17 -4
- package/dist/config/write.js.map +1 -1
- package/dist/custom/bounded-match.d.ts +15 -0
- package/dist/custom/bounded-match.d.ts.map +1 -0
- package/dist/custom/bounded-match.js +43 -0
- package/dist/custom/bounded-match.js.map +1 -0
- package/dist/custom/load.d.ts +8 -0
- package/dist/custom/load.d.ts.map +1 -0
- package/dist/custom/load.js +11 -0
- package/dist/custom/load.js.map +1 -0
- package/dist/custom/parse.d.ts +70 -0
- package/dist/custom/parse.d.ts.map +1 -0
- package/dist/custom/parse.js +215 -0
- package/dist/custom/parse.js.map +1 -0
- package/dist/custom/problems.d.ts +5 -0
- package/dist/custom/problems.d.ts.map +1 -0
- package/dist/custom/problems.js +78 -0
- package/dist/custom/problems.js.map +1 -0
- package/dist/custom/regex-safety.d.ts +11 -0
- package/dist/custom/regex-safety.d.ts.map +1 -0
- package/dist/custom/regex-safety.js +110 -0
- package/dist/custom/regex-safety.js.map +1 -0
- package/dist/custom/token-pattern.d.ts +8 -0
- package/dist/custom/token-pattern.d.ts.map +1 -0
- package/dist/custom/token-pattern.js +75 -0
- package/dist/custom/token-pattern.js.map +1 -0
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +24 -2
- package/dist/detect.js.map +1 -1
- package/dist/detectors/acronym-context.d.ts +4 -0
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +25 -4
- package/dist/detectors/acronym-context.js.map +1 -1
- package/dist/detectors/acronym-expansion.d.ts +2 -0
- package/dist/detectors/acronym-expansion.d.ts.map +1 -1
- package/dist/detectors/acronym-expansion.js +104 -1
- package/dist/detectors/acronym-expansion.js.map +1 -1
- package/dist/detectors/agreement-slip.d.ts +32 -0
- package/dist/detectors/agreement-slip.d.ts.map +1 -0
- package/dist/detectors/agreement-slip.js +137 -0
- package/dist/detectors/agreement-slip.js.map +1 -0
- package/dist/detectors/ai-phrasing.d.ts +20 -0
- package/dist/detectors/ai-phrasing.d.ts.map +1 -0
- package/dist/detectors/ai-phrasing.js +112 -0
- package/dist/detectors/ai-phrasing.js.map +1 -0
- package/dist/detectors/announced-count.d.ts +4 -0
- package/dist/detectors/announced-count.d.ts.map +1 -0
- package/dist/detectors/announced-count.js +20 -0
- package/dist/detectors/announced-count.js.map +1 -0
- package/dist/detectors/broken-link.d.ts +17 -0
- package/dist/detectors/broken-link.d.ts.map +1 -0
- package/dist/detectors/broken-link.js +66 -0
- package/dist/detectors/broken-link.js.map +1 -0
- package/dist/detectors/cited-name.d.ts.map +1 -1
- package/dist/detectors/cited-name.js +4 -4
- package/dist/detectors/cited-name.js.map +1 -1
- package/dist/detectors/cited-title.d.ts +11 -0
- package/dist/detectors/cited-title.d.ts.map +1 -0
- package/dist/detectors/cited-title.js +75 -0
- package/dist/detectors/cited-title.js.map +1 -0
- package/dist/detectors/concrete-evidence.d.ts +1 -1
- package/dist/detectors/concrete-evidence.d.ts.map +1 -1
- package/dist/detectors/concrete-evidence.js +2 -1
- package/dist/detectors/concrete-evidence.js.map +1 -1
- package/dist/detectors/content-morphemes.d.ts +4 -0
- package/dist/detectors/content-morphemes.d.ts.map +1 -0
- package/dist/detectors/content-morphemes.js +12 -0
- package/dist/detectors/content-morphemes.js.map +1 -0
- package/dist/detectors/contrast-frame.d.ts +17 -0
- package/dist/detectors/contrast-frame.d.ts.map +1 -0
- package/dist/detectors/contrast-frame.js +32 -0
- package/dist/detectors/contrast-frame.js.map +1 -0
- package/dist/detectors/custom.d.ts +8 -0
- package/dist/detectors/custom.d.ts.map +1 -0
- package/dist/detectors/custom.js +71 -0
- package/dist/detectors/custom.js.map +1 -0
- package/dist/detectors/dangling-figure.d.ts +4 -0
- package/dist/detectors/dangling-figure.d.ts.map +1 -0
- package/dist/detectors/dangling-figure.js +18 -0
- package/dist/detectors/dangling-figure.js.map +1 -0
- package/dist/detectors/doubled-punctuation.d.ts +9 -0
- package/dist/detectors/doubled-punctuation.d.ts.map +1 -0
- package/dist/detectors/doubled-punctuation.js +33 -0
- package/dist/detectors/doubled-punctuation.js.map +1 -0
- package/dist/detectors/doubled-word.d.ts +5 -0
- package/dist/detectors/doubled-word.d.ts.map +1 -1
- package/dist/detectors/doubled-word.js +24 -11
- package/dist/detectors/doubled-word.js.map +1 -1
- package/dist/detectors/en-shape.d.ts +0 -1
- package/dist/detectors/en-shape.d.ts.map +1 -1
- package/dist/detectors/en-shape.js +0 -235
- package/dist/detectors/en-shape.js.map +1 -1
- package/dist/detectors/enumerated-runs.d.ts +1 -1
- package/dist/detectors/enumerated-runs.d.ts.map +1 -1
- package/dist/detectors/enumerated-runs.js +15 -4
- package/dist/detectors/enumerated-runs.js.map +1 -1
- package/dist/detectors/gram-furniture.d.ts +6 -0
- package/dist/detectors/gram-furniture.d.ts.map +1 -0
- package/dist/detectors/gram-furniture.js +21 -0
- package/dist/detectors/gram-furniture.js.map +1 -0
- package/dist/detectors/gram-place.d.ts +2 -0
- package/dist/detectors/gram-place.d.ts.map +1 -1
- package/dist/detectors/gram-place.js +9 -7
- package/dist/detectors/gram-place.js.map +1 -1
- package/dist/detectors/gram-windows.d.ts +9 -0
- package/dist/detectors/gram-windows.d.ts.map +1 -0
- package/dist/detectors/gram-windows.js +27 -0
- package/dist/detectors/gram-windows.js.map +1 -0
- package/dist/detectors/heading-case.d.ts +2 -0
- package/dist/detectors/heading-case.d.ts.map +1 -1
- package/dist/detectors/heading-case.js +29 -2
- package/dist/detectors/heading-case.js.map +1 -1
- package/dist/detectors/heading-code-words.d.ts +6 -0
- package/dist/detectors/heading-code-words.d.ts.map +1 -0
- package/dist/detectors/heading-code-words.js +29 -0
- package/dist/detectors/heading-code-words.js.map +1 -0
- package/dist/detectors/heading-echo.d.ts.map +1 -1
- package/dist/detectors/heading-echo.js +17 -20
- package/dist/detectors/heading-echo.js.map +1 -1
- package/dist/detectors/heading-level-skip.d.ts +12 -0
- package/dist/detectors/heading-level-skip.d.ts.map +1 -0
- package/dist/detectors/heading-level-skip.js +11 -0
- package/dist/detectors/heading-level-skip.js.map +1 -0
- package/dist/detectors/heading-overlap.d.ts +13 -0
- package/dist/detectors/heading-overlap.d.ts.map +1 -0
- package/dist/detectors/heading-overlap.js +52 -0
- package/dist/detectors/heading-overlap.js.map +1 -0
- package/dist/detectors/image-alt-text.d.ts +3 -0
- package/dist/detectors/image-alt-text.d.ts.map +1 -0
- package/dist/detectors/image-alt-text.js +9 -0
- package/dist/detectors/image-alt-text.js.map +1 -0
- package/dist/detectors/index.d.ts.map +1 -1
- package/dist/detectors/index.js +40 -2
- package/dist/detectors/index.js.map +1 -1
- package/dist/detectors/kutoten-consistency.d.ts +24 -0
- package/dist/detectors/kutoten-consistency.d.ts.map +1 -0
- package/dist/detectors/kutoten-consistency.js +77 -0
- package/dist/detectors/kutoten-consistency.js.map +1 -0
- package/dist/detectors/lead-in.d.ts +1 -0
- package/dist/detectors/lead-in.d.ts.map +1 -1
- package/dist/detectors/lead-in.js +2 -1
- package/dist/detectors/lead-in.js.map +1 -1
- package/dist/detectors/letter-joined-name.d.ts +13 -0
- package/dist/detectors/letter-joined-name.d.ts.map +1 -0
- package/dist/detectors/letter-joined-name.js +11 -0
- package/dist/detectors/letter-joined-name.js.map +1 -0
- package/dist/detectors/lexicon-match.d.ts +4 -0
- package/dist/detectors/lexicon-match.d.ts.map +1 -1
- package/dist/detectors/lexicon-match.js +7 -2
- package/dist/detectors/lexicon-match.js.map +1 -1
- package/dist/detectors/lexicon.d.ts.map +1 -1
- package/dist/detectors/lexicon.js +5 -2
- package/dist/detectors/lexicon.js.map +1 -1
- package/dist/detectors/list-item.d.ts +45 -0
- package/dist/detectors/list-item.d.ts.map +1 -0
- package/dist/detectors/list-item.js +88 -0
- package/dist/detectors/list-item.js.map +1 -0
- package/dist/detectors/list-items.d.ts +31 -0
- package/dist/detectors/list-items.d.ts.map +1 -0
- package/dist/detectors/list-items.js +113 -0
- package/dist/detectors/list-items.js.map +1 -0
- package/dist/detectors/list-lead-in.d.ts +7 -0
- package/dist/detectors/list-lead-in.d.ts.map +1 -0
- package/dist/detectors/list-lead-in.js +28 -0
- package/dist/detectors/list-lead-in.js.map +1 -0
- package/dist/detectors/list-sentence.d.ts +65 -0
- package/dist/detectors/list-sentence.d.ts.map +1 -0
- package/dist/detectors/list-sentence.js +105 -0
- package/dist/detectors/list-sentence.js.map +1 -0
- package/dist/detectors/list-view.d.ts +34 -0
- package/dist/detectors/list-view.d.ts.map +1 -0
- package/dist/detectors/list-view.js +137 -0
- package/dist/detectors/list-view.js.map +1 -0
- package/dist/detectors/long-vowel.d.ts +7 -0
- package/dist/detectors/long-vowel.d.ts.map +1 -0
- package/dist/detectors/long-vowel.js +57 -0
- package/dist/detectors/long-vowel.js.map +1 -0
- package/dist/detectors/markup-finding.d.ts +6 -0
- package/dist/detectors/markup-finding.d.ts.map +1 -0
- package/dist/detectors/markup-finding.js +19 -0
- package/dist/detectors/markup-finding.js.map +1 -0
- package/dist/detectors/name-numeral.d.ts +1 -1
- package/dist/detectors/name-numeral.d.ts.map +1 -1
- package/dist/detectors/name-numeral.js +2 -7
- package/dist/detectors/name-numeral.js.map +1 -1
- package/dist/detectors/orthography.d.ts.map +1 -1
- package/dist/detectors/orthography.js +16 -12
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/oxford-comma.d.ts +9 -0
- package/dist/detectors/oxford-comma.d.ts.map +1 -0
- package/dist/detectors/oxford-comma.js +246 -0
- package/dist/detectors/oxford-comma.js.map +1 -0
- package/dist/detectors/place-run.d.ts.map +1 -1
- package/dist/detectors/place-run.js +10 -6
- package/dist/detectors/place-run.js.map +1 -1
- package/dist/detectors/placeholder-text.d.ts +9 -0
- package/dist/detectors/placeholder-text.d.ts.map +1 -0
- package/dist/detectors/placeholder-text.js +18 -0
- package/dist/detectors/placeholder-text.js.map +1 -0
- package/dist/detectors/quote-around.d.ts +3 -0
- package/dist/detectors/quote-around.d.ts.map +1 -0
- package/dist/detectors/quote-around.js +8 -0
- package/dist/detectors/quote-around.js.map +1 -0
- package/dist/detectors/register.d.ts +11 -3
- package/dist/detectors/register.d.ts.map +1 -1
- package/dist/detectors/register.js +28 -9
- package/dist/detectors/register.js.map +1 -1
- package/dist/detectors/roman-numeral.d.ts +2 -0
- package/dist/detectors/roman-numeral.d.ts.map +1 -1
- package/dist/detectors/roman-numeral.js +2 -0
- package/dist/detectors/roman-numeral.js.map +1 -1
- package/dist/detectors/sentence-ending.d.ts +17 -1
- package/dist/detectors/sentence-ending.d.ts.map +1 -1
- package/dist/detectors/sentence-ending.js +13 -7
- package/dist/detectors/sentence-ending.js.map +1 -1
- package/dist/detectors/sentence-length.d.ts.map +1 -1
- package/dist/detectors/sentence-length.js +13 -4
- package/dist/detectors/sentence-length.js.map +1 -1
- package/dist/detectors/signals.d.ts +8 -0
- package/dist/detectors/signals.d.ts.map +1 -1
- package/dist/detectors/signals.js +94 -54
- package/dist/detectors/signals.js.map +1 -1
- package/dist/detectors/stacked-hedge.d.ts +0 -7
- package/dist/detectors/stacked-hedge.d.ts.map +1 -1
- package/dist/detectors/stacked-hedge.js +6 -3
- package/dist/detectors/stacked-hedge.js.map +1 -1
- package/dist/detectors/stray-space.d.ts +7 -0
- package/dist/detectors/stray-space.d.ts.map +1 -0
- package/dist/detectors/stray-space.js +34 -0
- package/dist/detectors/stray-space.js.map +1 -0
- package/dist/detectors/structure-tree.d.ts +6 -0
- package/dist/detectors/structure-tree.d.ts.map +1 -1
- package/dist/detectors/structure-tree.js +37 -1
- package/dist/detectors/structure-tree.js.map +1 -1
- package/dist/detectors/structure.d.ts +4 -4
- package/dist/detectors/structure.d.ts.map +1 -1
- package/dist/detectors/structure.js +7 -6
- package/dist/detectors/structure.js.map +1 -1
- package/dist/detectors/superlative-name.d.ts.map +1 -1
- package/dist/detectors/superlative-name.js +8 -5
- package/dist/detectors/superlative-name.js.map +1 -1
- package/dist/detectors/superlative-scope.d.ts.map +1 -1
- package/dist/detectors/superlative-scope.js +9 -4
- package/dist/detectors/superlative-scope.js.map +1 -1
- package/dist/detectors/token-column.d.ts +46 -0
- package/dist/detectors/token-column.d.ts.map +1 -0
- package/dist/detectors/token-column.js +95 -0
- package/dist/detectors/token-column.js.map +1 -0
- package/dist/detectors/unbalanced-bracket.d.ts +22 -0
- package/dist/detectors/unbalanced-bracket.d.ts.map +1 -0
- package/dist/detectors/unbalanced-bracket.js +119 -0
- package/dist/detectors/unbalanced-bracket.js.map +1 -0
- package/dist/detectors/url-run-on.d.ts +9 -0
- package/dist/detectors/url-run-on.d.ts.map +1 -0
- package/dist/detectors/url-run-on.js +19 -0
- package/dist/detectors/url-run-on.js.map +1 -0
- package/dist/document-sections.d.ts +13 -0
- package/dist/document-sections.d.ts.map +1 -0
- package/dist/document-sections.js +32 -0
- package/dist/document-sections.js.map +1 -0
- package/dist/document.d.ts +11 -4
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +99 -95
- package/dist/document.js.map +1 -1
- package/dist/email-parts.d.ts +28 -0
- package/dist/email-parts.d.ts.map +1 -0
- package/dist/email-parts.js +230 -0
- package/dist/email-parts.js.map +1 -0
- package/dist/eval.d.ts +2 -1
- package/dist/eval.d.ts.map +1 -1
- package/dist/eval.js +16 -4
- package/dist/eval.js.map +1 -1
- package/dist/figure-references.d.ts +30 -0
- package/dist/figure-references.d.ts.map +1 -0
- package/dist/figure-references.js +76 -0
- package/dist/figure-references.js.map +1 -0
- package/dist/files.d.ts +2 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +4 -0
- package/dist/files.js.map +1 -1
- package/dist/genre-parse.d.ts +5 -1
- package/dist/genre-parse.d.ts.map +1 -1
- package/dist/genre-parse.js +16 -3
- package/dist/genre-parse.js.map +1 -1
- package/dist/genre-suggest.d.ts.map +1 -1
- package/dist/genre-suggest.js +15 -1
- package/dist/genre-suggest.js.map +1 -1
- package/dist/heading-label.d.ts +22 -0
- package/dist/heading-label.d.ts.map +1 -0
- package/dist/heading-label.js +50 -0
- package/dist/heading-label.js.map +1 -0
- package/dist/in-page-nav.d.ts +4 -1
- package/dist/in-page-nav.d.ts.map +1 -1
- package/dist/in-page-nav.js +53 -18
- package/dist/in-page-nav.js.map +1 -1
- package/dist/joined-view.d.ts.map +1 -1
- package/dist/joined-view.js +1 -0
- package/dist/joined-view.js.map +1 -1
- package/dist/levels.d.ts +5 -1
- package/dist/levels.d.ts.map +1 -1
- package/dist/levels.js +9 -0
- package/dist/levels.js.map +1 -1
- package/dist/line-paragraphs.d.ts +8 -0
- package/dist/line-paragraphs.d.ts.map +1 -1
- package/dist/line-paragraphs.js +36 -11
- package/dist/line-paragraphs.js.map +1 -1
- package/dist/long-vowel.d.ts +35 -0
- package/dist/long-vowel.d.ts.map +1 -0
- package/dist/long-vowel.js +71 -0
- package/dist/long-vowel.js.map +1 -0
- package/dist/markdown-node.d.ts +19 -0
- package/dist/markdown-node.d.ts.map +1 -0
- package/dist/markdown-node.js +6 -0
- package/dist/markdown-node.js.map +1 -0
- package/dist/markdown-read.d.ts +17 -0
- package/dist/markdown-read.d.ts.map +1 -0
- package/dist/markdown-read.js +37 -0
- package/dist/markdown-read.js.map +1 -0
- package/dist/markup.d.ts +22 -0
- package/dist/markup.d.ts.map +1 -0
- package/dist/markup.js +180 -0
- package/dist/markup.js.map +1 -0
- package/dist/mask.d.ts.map +1 -1
- package/dist/mask.js +10 -16
- package/dist/mask.js.map +1 -1
- package/dist/number-name.d.ts +21 -5
- package/dist/number-name.d.ts.map +1 -1
- package/dist/number-name.js +120 -18
- package/dist/number-name.js.map +1 -1
- package/dist/opening-line.d.ts +3 -0
- package/dist/opening-line.d.ts.map +1 -0
- package/dist/opening-line.js +14 -0
- package/dist/opening-line.js.map +1 -0
- package/dist/orthography.d.ts +7 -1
- package/dist/orthography.d.ts.map +1 -1
- package/dist/orthography.js +16 -5
- package/dist/orthography.js.map +1 -1
- package/dist/page-furniture.d.ts +5 -2
- package/dist/page-furniture.d.ts.map +1 -1
- package/dist/page-furniture.js +8 -2
- package/dist/page-furniture.js.map +1 -1
- package/dist/paragraph-length.d.ts +7 -0
- package/dist/paragraph-length.d.ts.map +1 -0
- package/dist/paragraph-length.js +10 -0
- package/dist/paragraph-length.js.map +1 -0
- package/dist/plain-source.d.ts +1 -0
- package/dist/plain-source.d.ts.map +1 -1
- package/dist/plain-source.js +2 -1
- package/dist/plain-source.js.map +1 -1
- package/dist/plugin.d.ts +121 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/profile/for-file.d.ts.map +1 -1
- package/dist/profile/for-file.js +3 -1
- package/dist/profile/for-file.js.map +1 -1
- package/dist/quoted-span.d.ts +0 -2
- package/dist/quoted-span.d.ts.map +1 -1
- package/dist/quoted-span.js +9 -4
- package/dist/quoted-span.js.map +1 -1
- package/dist/reasons.d.ts +3 -0
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +6 -0
- package/dist/reasons.js.map +1 -1
- package/dist/reference-lists.d.ts +3 -0
- package/dist/reference-lists.d.ts.map +1 -0
- package/dist/reference-lists.js +75 -0
- package/dist/reference-lists.js.map +1 -0
- package/dist/render/explain.d.ts +7 -1
- package/dist/render/explain.d.ts.map +1 -1
- package/dist/render/explain.js +36 -12
- package/dist/render/explain.js.map +1 -1
- package/dist/render/friendly.d.ts.map +1 -1
- package/dist/render/friendly.js +19 -9
- package/dist/render/friendly.js.map +1 -1
- package/dist/render/options.d.ts +7 -0
- package/dist/render/options.d.ts.map +1 -0
- package/dist/render/options.js +50 -0
- package/dist/render/options.js.map +1 -0
- package/dist/render/rules-json.d.ts +4 -1
- package/dist/render/rules-json.d.ts.map +1 -1
- package/dist/render/rules-json.js +102 -12
- package/dist/render/rules-json.js.map +1 -1
- package/dist/render/rules-table.d.ts +4 -0
- package/dist/render/rules-table.d.ts.map +1 -0
- package/dist/render/rules-table.js +70 -0
- package/dist/render/rules-table.js.map +1 -0
- package/dist/render/sarif.js +4 -4
- package/dist/render/sarif.js.map +1 -1
- package/dist/render/semantic.js +3 -3
- package/dist/render/semantic.js.map +1 -1
- package/dist/render/severity-name.d.ts +6 -0
- package/dist/render/severity-name.d.ts.map +1 -0
- package/dist/render/severity-name.js +7 -0
- package/dist/render/severity-name.js.map +1 -0
- package/dist/render/text.d.ts +7 -2
- package/dist/render/text.d.ts.map +1 -1
- package/dist/render/text.js +15 -4
- package/dist/render/text.js.map +1 -1
- package/dist/resolve-genre.d.ts +1 -1
- package/dist/resolve-genre.d.ts.map +1 -1
- package/dist/resolve-genre.js +4 -1
- package/dist/resolve-genre.js.map +1 -1
- package/dist/rule-genres.d.ts +24 -0
- package/dist/rule-genres.d.ts.map +1 -0
- package/dist/rule-genres.js +11 -0
- package/dist/rule-genres.js.map +1 -0
- package/dist/rule-guide.d.ts +54 -0
- package/dist/rule-guide.d.ts.map +1 -0
- package/dist/rule-guide.js +81 -0
- package/dist/rule-guide.js.map +1 -0
- package/dist/rule-load.d.ts.map +1 -1
- package/dist/rule-load.js +94 -32
- package/dist/rule-load.js.map +1 -1
- package/dist/rule-options.d.ts +50 -0
- package/dist/rule-options.d.ts.map +1 -0
- package/dist/rule-options.js +106 -0
- package/dist/rule-options.js.map +1 -0
- package/dist/run-semantic.d.ts +3 -1
- package/dist/run-semantic.d.ts.map +1 -1
- package/dist/run-semantic.js +8 -3
- package/dist/run-semantic.js.map +1 -1
- package/dist/run.d.ts +15 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +57 -10
- package/dist/run.js.map +1 -1
- package/dist/semantic.d.ts +1 -1
- package/dist/semantic.d.ts.map +1 -1
- package/dist/semantic.js +10 -3
- package/dist/semantic.js.map +1 -1
- package/dist/sentence-shape.d.ts.map +1 -1
- package/dist/sentence-shape.js +4 -4
- package/dist/sentence-shape.js.map +1 -1
- package/dist/setting-problems.d.ts +2 -1
- package/dist/setting-problems.d.ts.map +1 -1
- package/dist/setting-problems.js +6 -1
- package/dist/setting-problems.js.map +1 -1
- package/dist/span-cut.d.ts +6 -0
- package/dist/span-cut.d.ts.map +1 -0
- package/dist/span-cut.js +22 -0
- package/dist/span-cut.js.map +1 -0
- package/dist/span-merge.d.ts +4 -0
- package/dist/span-merge.d.ts.map +1 -0
- package/dist/span-merge.js +12 -0
- package/dist/span-merge.js.map +1 -0
- package/dist/speaker-labels.d.ts +4 -0
- package/dist/speaker-labels.d.ts.map +1 -0
- package/dist/speaker-labels.js +106 -0
- package/dist/speaker-labels.js.map +1 -0
- package/dist/stray-space.d.ts +17 -0
- package/dist/stray-space.d.ts.map +1 -0
- package/dist/stray-space.js +66 -0
- package/dist/stray-space.js.map +1 -0
- package/dist/structure/aside-depth.d.ts +21 -0
- package/dist/structure/aside-depth.d.ts.map +1 -0
- package/dist/structure/aside-depth.js +65 -0
- package/dist/structure/aside-depth.js.map +1 -0
- package/dist/structure/build.d.ts +5 -1
- package/dist/structure/build.d.ts.map +1 -1
- package/dist/structure/build.js +29 -17
- package/dist/structure/build.js.map +1 -1
- package/dist/structure/closed-pairs.d.ts +8 -0
- package/dist/structure/closed-pairs.d.ts.map +1 -0
- package/dist/structure/closed-pairs.js +22 -0
- package/dist/structure/closed-pairs.js.map +1 -0
- package/dist/structure/date-range.d.ts +21 -0
- package/dist/structure/date-range.d.ts.map +1 -0
- package/dist/structure/date-range.js +45 -0
- package/dist/structure/date-range.js.map +1 -0
- package/dist/structure/known-mentions.d.ts +18 -0
- package/dist/structure/known-mentions.d.ts.map +1 -0
- package/dist/structure/known-mentions.js +78 -0
- package/dist/structure/known-mentions.js.map +1 -0
- package/dist/structure/numbering.d.ts +1 -0
- package/dist/structure/numbering.d.ts.map +1 -1
- package/dist/structure/numbering.js +11 -6
- package/dist/structure/numbering.js.map +1 -1
- package/dist/structure/of.d.ts +3 -1
- package/dist/structure/of.d.ts.map +1 -1
- package/dist/structure/of.js +5 -1
- package/dist/structure/of.js.map +1 -1
- package/dist/structure/percent-sum.d.ts +16 -0
- package/dist/structure/percent-sum.d.ts.map +1 -0
- package/dist/structure/percent-sum.js +104 -0
- package/dist/structure/percent-sum.js.map +1 -0
- package/dist/structure/quoted-number.d.ts +8 -0
- package/dist/structure/quoted-number.d.ts.map +1 -0
- package/dist/structure/quoted-number.js +34 -0
- package/dist/structure/quoted-number.js.map +1 -0
- package/dist/structure/relative-find.d.ts.map +1 -1
- package/dist/structure/relative-find.js +34 -46
- package/dist/structure/relative-find.js.map +1 -1
- package/dist/structure/relative-resolve.d.ts.map +1 -1
- package/dist/structure/relative-resolve.js +94 -42
- package/dist/structure/relative-resolve.js.map +1 -1
- package/dist/structure/runs.d.ts +2 -0
- package/dist/structure/runs.d.ts.map +1 -1
- package/dist/structure/runs.js +2 -2
- package/dist/structure/runs.js.map +1 -1
- package/dist/structure/sexp.d.ts +1 -1
- package/dist/structure/sexp.d.ts.map +1 -1
- package/dist/structure/sexp.js +18 -6
- package/dist/structure/sexp.js.map +1 -1
- package/dist/structure/total.d.ts +3 -0
- package/dist/structure/total.d.ts.map +1 -1
- package/dist/structure/total.js +2 -2
- package/dist/structure/total.js.map +1 -1
- package/dist/structure/universal.d.ts +14 -2
- package/dist/structure/universal.d.ts.map +1 -1
- package/dist/structure/universal.js +17 -2
- package/dist/structure/universal.js.map +1 -1
- package/dist/structure/wrapped-tail.d.ts +14 -7
- package/dist/structure/wrapped-tail.d.ts.map +1 -1
- package/dist/structure/wrapped-tail.js +33 -8
- package/dist/structure/wrapped-tail.js.map +1 -1
- package/dist/style-load.d.ts +4 -0
- package/dist/style-load.d.ts.map +1 -0
- package/dist/style-load.js +28 -0
- package/dist/style-load.js.map +1 -0
- package/dist/style-parse.d.ts +19 -0
- package/dist/style-parse.d.ts.map +1 -0
- package/dist/style-parse.js +60 -0
- package/dist/style-parse.js.map +1 -0
- package/dist/subheading-line.d.ts +6 -0
- package/dist/subheading-line.d.ts.map +1 -0
- package/dist/subheading-line.js +57 -0
- package/dist/subheading-line.js.map +1 -0
- package/dist/team-names.d.ts.map +1 -1
- package/dist/team-names.js +11 -14
- package/dist/team-names.js.map +1 -1
- package/dist/template-syntax.d.ts +17 -0
- package/dist/template-syntax.d.ts.map +1 -0
- package/dist/template-syntax.js +140 -0
- package/dist/template-syntax.js.map +1 -0
- package/dist/text-above.d.ts +19 -0
- package/dist/text-above.d.ts.map +1 -0
- package/dist/text-above.js +43 -0
- package/dist/text-above.js.map +1 -0
- package/dist/text-figures.d.ts +10 -0
- package/dist/text-figures.d.ts.map +1 -0
- package/dist/text-figures.js +131 -0
- package/dist/text-figures.js.map +1 -0
- package/dist/trailing-aside.d.ts +2 -0
- package/dist/trailing-aside.d.ts.map +1 -0
- package/dist/trailing-aside.js +53 -0
- package/dist/trailing-aside.js.map +1 -0
- package/dist/tree-walk.d.ts +18 -0
- package/dist/tree-walk.d.ts.map +1 -0
- package/dist/tree-walk.js +45 -0
- package/dist/tree-walk.js.map +1 -0
- package/genres.yaml +60 -2
- package/package.json +5 -3
- package/reference-headings.yaml +17 -0
- package/rules/adverb-overuse.yaml +19 -0
- package/rules/agentless-passive.yaml +19 -0
- package/rules/agreement-slip.yaml +49 -0
- package/rules/ai-generated-composite.yaml +102 -0
- package/rules/ai-tell.yaml +23 -0
- package/rules/announced-count-mismatch.yaml +57 -0
- package/rules/announcing-opener.yaml +51 -0
- package/rules/assistant-residue.yaml +52 -0
- package/rules/bold-density.yaml +31 -0
- package/rules/broken-link.yaml +65 -0
- package/rules/closing-cliche.yaml +33 -0
- package/rules/colon-lead-in.yaml +59 -0
- package/rules/concrete-evidence-density.yaml +41 -0
- package/rules/contraction-consistency.yaml +18 -0
- package/rules/contrast-framing.yaml +57 -0
- package/rules/cushion-phrase-density.yaml +25 -0
- package/rules/dangling-figure-reference.yaml +61 -0
- package/rules/dangling-reference.yaml +53 -1
- package/rules/date-order.yaml +33 -1
- package/rules/date-range-reversed.yaml +46 -0
- package/rules/date-weekday-mismatch.yaml +17 -1
- package/rules/double-keigo.yaml +16 -0
- package/rules/doubled-punctuation.yaml +45 -0
- package/rules/doubled-word.yaml +17 -1
- package/rules/duplicate-definition.yaml +59 -1
- package/rules/emoji-density.yaml +25 -0
- package/rules/empty-conclusion.yaml +29 -0
- package/rules/empty-intensifier.yaml +19 -0
- package/rules/excessive-hedging.yaml +19 -0
- package/rules/expletive-construction.yaml +19 -0
- package/rules/heading-echo.yaml +32 -0
- package/rules/heading-level-skip.yaml +78 -0
- package/rules/hiragana-fukushi.yaml +16 -0
- package/rules/image-alt-text.yaml +54 -0
- package/rules/internal-jargon.yaml +21 -0
- package/rules/katakana-long-vowel.yaml +98 -0
- package/rules/kutoten-consistency.yaml +53 -0
- package/rules/latin-spacing.yaml +23 -4
- package/rules/max-kanji-continuous.yaml +16 -0
- package/rules/max-paragraph-length.yaml +42 -2
- package/rules/max-sentence-length.yaml +36 -0
- package/rules/ngram-repetition.yaml +29 -2
- package/rules/no-doubled-joshi.yaml +16 -0
- package/rules/no-em-dash.yaml +25 -0
- package/rules/no-mixed-desumasu.yaml +27 -2
- package/rules/no-nakaguro-parallel.yaml +20 -0
- package/rules/numbering-gap.yaml +53 -1
- package/rules/oxford-comma-consistency.yaml +19 -1
- package/rules/padded-intro.yaml +19 -0
- package/rules/paragraph-length-variance.yaml +49 -0
- package/rules/percent-sum-mismatch.yaml +58 -0
- package/rules/preamble-length.yaml +56 -0
- package/rules/preferred-term.yaml +27 -0
- package/rules/proper-noun-density.yaml +26 -0
- package/rules/repeated-conjunction.yaml +47 -0
- package/rules/repeated-sentence-head.yaml +23 -0
- package/rules/required-sections.yaml +49 -0
- package/rules/risk-disclosure.yaml +22 -0
- package/rules/rule-of-three.yaml +97 -0
- package/rules/sasete-itadaku.yaml +18 -0
- package/rules/section-length-uniformity.yaml +89 -0
- package/rules/sentence-initial-conjunction-run.yaml +18 -0
- package/rules/sentence-rhythm.yaml +25 -0
- package/rules/stock-transition.yaml +55 -0
- package/rules/stray-space.yaml +56 -0
- package/rules/taigen-dome-in-prose.yaml +19 -0
- package/rules/title-case-consistency.yaml +42 -0
- package/rules/total-mismatch.yaml +37 -1
- package/rules/unbalanced-bracket.yaml +56 -0
- package/rules/undefined-acronym.yaml +23 -0
- package/rules/unfilled-placeholder.yaml +50 -0
- package/rules/unqualified-superlative.yaml +19 -0
- package/rules/unsourced-number.yaml +16 -0
- package/rules/url-run-on.yaml +45 -0
- package/skills/chaff/SKILL.md +70 -0
- package/src/announced-count.ts +148 -0
- package/src/bare-url.ts +35 -0
- package/src/baseline.ts +17 -1
- package/src/body-section.ts +7 -0
- package/src/calendar-number.ts +33 -10
- package/src/cli-args.ts +6 -0
- package/src/cli-text.ts +8 -4
- package/src/cli.ts +37 -37
- package/src/closing-numbers.ts +72 -0
- package/src/commands/compare.ts +80 -0
- package/src/commands/eval.ts +19 -8
- package/src/commands/feedback.ts +12 -6
- package/src/commands/test.ts +20 -17
- package/src/commands/tree.ts +41 -5
- package/src/compare/atom.ts +33 -0
- package/src/compare/clock-time.ts +86 -0
- package/src/compare/extract.ts +78 -0
- package/src/compare/fact-text.ts +68 -0
- package/src/compare/markup-atoms.ts +29 -0
- package/src/compare/match.ts +105 -0
- package/src/compare/outcome.ts +70 -0
- package/src/compare/proper-nouns.ts +65 -0
- package/src/compare/render.ts +102 -0
- package/src/compare/spans.ts +17 -0
- package/src/compare/text-atoms.ts +95 -0
- package/src/compare/text.ts +120 -0
- package/src/compare/tree-atoms.ts +80 -0
- package/src/compare/written-names.ts +26 -0
- package/src/config/load.ts +21 -0
- package/src/config/option-problems.ts +70 -0
- package/src/config/read.ts +8 -0
- package/src/config/rule-problems.ts +12 -2
- package/src/config/style.ts +42 -0
- package/src/config/warnings.ts +13 -0
- package/src/config/write.ts +18 -4
- package/src/custom/bounded-match.ts +58 -0
- package/src/custom/load.ts +15 -0
- package/src/custom/parse.ts +274 -0
- package/src/custom/problems.ts +89 -0
- package/src/custom/regex-safety.ts +118 -0
- package/src/custom/token-pattern.ts +84 -0
- package/src/detect.ts +28 -2
- package/src/detectors/acronym-context.ts +32 -4
- package/src/detectors/acronym-expansion.ts +132 -1
- package/src/detectors/agreement-slip.ts +191 -0
- package/src/detectors/ai-phrasing.ts +137 -0
- package/src/detectors/announced-count.ts +25 -0
- package/src/detectors/broken-link.ts +90 -0
- package/src/detectors/cited-name.ts +6 -5
- package/src/detectors/cited-title.ts +96 -0
- package/src/detectors/concrete-evidence.ts +3 -2
- package/src/detectors/content-morphemes.ts +19 -0
- package/src/detectors/contrast-frame.ts +54 -0
- package/src/detectors/custom.ts +89 -0
- package/src/detectors/dangling-figure.ts +22 -0
- package/src/detectors/doubled-punctuation.ts +49 -0
- package/src/detectors/doubled-word.ts +19 -4
- package/src/detectors/en-shape.ts +0 -269
- package/src/detectors/enumerated-runs.ts +13 -4
- package/src/detectors/gram-furniture.ts +30 -0
- package/src/detectors/gram-place.ts +9 -5
- package/src/detectors/gram-windows.ts +31 -0
- package/src/detectors/heading-case.ts +30 -2
- package/src/detectors/heading-code-words.ts +35 -0
- package/src/detectors/heading-echo.ts +18 -22
- package/src/detectors/heading-level-skip.ts +19 -0
- package/src/detectors/heading-overlap.ts +65 -0
- package/src/detectors/image-alt-text.ts +11 -0
- package/src/detectors/index.ts +49 -2
- package/src/detectors/kutoten-consistency.ts +96 -0
- package/src/detectors/lead-in.ts +3 -1
- package/src/detectors/letter-joined-name.ts +15 -0
- package/src/detectors/lexicon-match.ts +9 -2
- package/src/detectors/lexicon.ts +6 -2
- package/src/detectors/list-item.ts +122 -0
- package/src/detectors/list-items.ts +163 -0
- package/src/detectors/list-lead-in.ts +33 -0
- package/src/detectors/list-sentence.ts +157 -0
- package/src/detectors/list-view.ts +157 -0
- package/src/detectors/long-vowel.ts +66 -0
- package/src/detectors/markup-finding.ts +24 -0
- package/src/detectors/name-numeral.ts +4 -2
- package/src/detectors/orthography.ts +24 -18
- package/src/detectors/oxford-comma.ts +297 -0
- package/src/detectors/place-run.ts +7 -4
- package/src/detectors/placeholder-text.ts +27 -0
- package/src/detectors/quote-around.ts +9 -0
- package/src/detectors/register.ts +37 -10
- package/src/detectors/roman-numeral.ts +3 -0
- package/src/detectors/sentence-ending.ts +14 -7
- package/src/detectors/sentence-length.ts +16 -5
- package/src/detectors/signals.ts +110 -53
- package/src/detectors/stacked-hedge.ts +6 -3
- package/src/detectors/stray-space.ts +40 -0
- package/src/detectors/structure-tree.ts +45 -1
- package/src/detectors/structure.ts +13 -6
- package/src/detectors/superlative-name.ts +7 -4
- package/src/detectors/superlative-scope.ts +8 -3
- package/src/detectors/token-column.ts +149 -0
- package/src/detectors/unbalanced-bracket.ts +153 -0
- package/src/detectors/url-run-on.ts +27 -0
- package/src/document-sections.ts +46 -0
- package/src/document.ts +116 -127
- package/src/email-parts.ts +269 -0
- package/src/eval.ts +14 -4
- package/src/figure-references.ts +112 -0
- package/src/files.ts +5 -0
- package/src/genre-parse.ts +30 -5
- package/src/genre-suggest.ts +15 -2
- package/src/heading-label.ts +55 -0
- package/src/in-page-nav.ts +48 -19
- package/src/joined-view.ts +1 -0
- package/src/levels.ts +14 -1
- package/src/line-paragraphs.ts +56 -10
- package/src/long-vowel.ts +99 -0
- package/src/markdown-node.ts +19 -0
- package/src/markdown-read.ts +44 -0
- package/src/markup.ts +210 -0
- package/src/mask.ts +10 -19
- package/src/number-name.ts +152 -25
- package/src/opening-line.ts +17 -0
- package/src/orthography.ts +20 -5
- package/src/page-furniture.ts +11 -2
- package/src/paragraph-length.ts +9 -0
- package/src/plain-source.ts +2 -1
- package/src/plugin.ts +107 -1
- package/src/profile/for-file.ts +3 -1
- package/src/quoted-span.ts +10 -4
- package/src/reasons.ts +9 -0
- package/src/reference-lists.ts +91 -0
- package/src/render/explain.ts +47 -13
- package/src/render/friendly.ts +20 -9
- package/src/render/options.ts +58 -0
- package/src/render/rules-json.ts +130 -14
- package/src/render/rules-table.ts +91 -0
- package/src/render/sarif.ts +4 -4
- package/src/render/semantic.ts +3 -3
- package/src/render/severity-name.ts +10 -0
- package/src/render/text.ts +21 -7
- package/src/resolve-genre.ts +4 -1
- package/src/rule-genres.ts +25 -0
- package/src/rule-guide.ts +135 -0
- package/src/rule-load.ts +98 -33
- package/src/rule-options.ts +131 -0
- package/src/run-semantic.ts +28 -20
- package/src/run.ts +78 -11
- package/src/semantic.ts +11 -3
- package/src/sentence-shape.ts +4 -5
- package/src/setting-problems.ts +7 -1
- package/src/span-cut.ts +28 -0
- package/src/span-merge.ts +13 -0
- package/src/speaker-labels.ts +129 -0
- package/src/stray-space.ts +81 -0
- package/src/structure/aside-depth.ts +67 -0
- package/src/structure/build.ts +38 -19
- package/src/structure/closed-pairs.ts +20 -0
- package/src/structure/date-range.ts +69 -0
- package/src/structure/known-mentions.ts +96 -0
- package/src/structure/numbering.ts +9 -5
- package/src/structure/of.ts +11 -3
- package/src/structure/percent-sum.ts +135 -0
- package/src/structure/quoted-number.ts +36 -0
- package/src/structure/relative-find.ts +34 -47
- package/src/structure/relative-resolve.ts +104 -42
- package/src/structure/runs.ts +2 -2
- package/src/structure/sexp.ts +17 -5
- package/src/structure/total.ts +2 -2
- package/src/structure/universal.ts +24 -4
- package/src/structure/wrapped-tail.ts +38 -13
- package/src/style-load.ts +28 -0
- package/src/style-parse.ts +77 -0
- package/src/subheading-line.ts +68 -0
- package/src/team-names.ts +13 -13
- package/src/template-syntax.ts +164 -0
- package/src/text-above.ts +49 -0
- package/src/text-figures.ts +147 -0
- package/src/trailing-aside.ts +50 -0
- package/src/tree-walk.ts +48 -0
- package/styles/bunkacho.yaml +25 -0
- package/styles/ieice.yaml +29 -0
- package/styles/jis-z8301-2011.yaml +25 -0
package/src/render/friendly.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Finding, RuleDefinition } from "../plugin.ts";
|
|
2
2
|
import type { RunResult } from "../run.ts";
|
|
3
|
-
import { MARK,
|
|
3
|
+
import { MARK, filledText, messageOf } from "./text.ts";
|
|
4
4
|
import { tally } from "./summary.ts";
|
|
5
5
|
import { counted } from "./plural.ts";
|
|
6
6
|
import { uiLanguageOf, type Texts } from "../ui.ts";
|
|
@@ -45,29 +45,39 @@ const QUOTE_LIMIT = 120;
|
|
|
45
45
|
|
|
46
46
|
const indent = (text: string, pad: string): string[] => text.split("\n").map((line) => `${pad}${line}`);
|
|
47
47
|
|
|
48
|
-
const quoteOf = (
|
|
49
|
-
const text =
|
|
48
|
+
const quoteOf = (quote: string): string[] => {
|
|
49
|
+
const text = quote.replace(/\s+/gu, " ").trim();
|
|
50
50
|
if (text.length === 0) return [];
|
|
51
51
|
return ["", ...indent(text.length > QUOTE_LIMIT ? `${text.slice(0, QUOTE_LIMIT)}…` : text, " ")];
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
/** 一つの文から出た指摘は同じ文を引く。長い文に指摘が多いとき、指摘ごとに文を整え直さない。 */
|
|
55
|
+
const quotesOf = (): ((quote: string) => readonly string[]) => {
|
|
56
|
+
const known = new Map<string, readonly string[]>();
|
|
57
|
+
return (quote) => {
|
|
58
|
+
const lines = known.get(quote) ?? quoteOf(quote);
|
|
59
|
+
known.set(quote, lines);
|
|
60
|
+
return lines;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
54
64
|
/**
|
|
55
65
|
* 1 件につき 4 つを出す。どれが欠けても、書いた人は動けない。
|
|
56
66
|
* 引用 / 何が起きているか / なぜ問題か / どう直すか
|
|
57
67
|
* rule の id は「ゆるめる」コマンドの中にだけ出す。最初に読むのは name。
|
|
58
68
|
*/
|
|
59
|
-
const block = (finding: Finding, rule: RuleDefinition, language: string): string[] => [
|
|
69
|
+
const block = (finding: Finding, rule: RuleDefinition, language: string, quoted: readonly string[]): string[] => [
|
|
60
70
|
"",
|
|
61
71
|
// "12 行目" and "line 12" take the same width on a terminal, so the rule ends in the same column in both.
|
|
62
72
|
`─── ${TEXT[uiLanguageOf(language)].line(finding.line)} ${"─".repeat(Math.max(0, RULE - String(finding.line).length - 8))}`,
|
|
63
|
-
...
|
|
73
|
+
...quoted,
|
|
64
74
|
"",
|
|
65
|
-
` ${MARK[finding.severity] ?? "·"} ${
|
|
75
|
+
` ${MARK[finding.severity] ?? "·"} ${filledText(rule.name, finding, language)}`,
|
|
66
76
|
"",
|
|
67
77
|
...indent(messageOf(rule, finding, language), " "),
|
|
68
|
-
...indent(
|
|
78
|
+
...indent(filledText(rule.why, finding, language), " "),
|
|
69
79
|
"",
|
|
70
|
-
...indent(`→ ${
|
|
80
|
+
...indent(`→ ${filledText(rule.how_to_fix, finding, language)}`, " "),
|
|
71
81
|
"",
|
|
72
82
|
` ${TEXT[uiLanguageOf(language)].relax}: npx chaff relax ${finding.rule}`,
|
|
73
83
|
"",
|
|
@@ -82,9 +92,10 @@ export const renderFriendly = (
|
|
|
82
92
|
notes: readonly string[] = [],
|
|
83
93
|
): string => {
|
|
84
94
|
const byId = new Map(rules.map((rule) => [rule.id, rule]));
|
|
95
|
+
const quoted = quotesOf();
|
|
85
96
|
const blocks = result.findings.flatMap((finding) => {
|
|
86
97
|
const rule = byId.get(finding.rule);
|
|
87
|
-
return rule === undefined ? [] : block(finding, rule, language);
|
|
98
|
+
return rule === undefined ? [] : block(finding, rule, language, quoted(finding.quote));
|
|
88
99
|
});
|
|
89
100
|
const text = TEXT[uiLanguageOf(language)];
|
|
90
101
|
const closing = [
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { OptionValue, RuleDefinition } from "../plugin.ts";
|
|
2
|
+
import { DEFAULT_SOURCE, settleOptions, type OptionLayer } from "../rule-options.ts";
|
|
3
|
+
import { localized } from "./text.ts";
|
|
4
|
+
import type { Texts } from "../ui.ts";
|
|
5
|
+
import { uiLanguageOf } from "../ui.ts";
|
|
6
|
+
|
|
7
|
+
const printed = (value: OptionValue): string => (Array.isArray(value) ? `[${value.join(", ")}]` : String(value));
|
|
8
|
+
|
|
9
|
+
/** A rule's options for rules --json: what each decides, what it may be, its default, its value now and which setting gave it. */
|
|
10
|
+
export const optionsJson = (rule: RuleDefinition, layers: readonly OptionLayer[]): Record<string, unknown> | undefined => {
|
|
11
|
+
if (rule.options === undefined) return undefined;
|
|
12
|
+
const settled = settleOptions(rule.id, rule.options, layers);
|
|
13
|
+
return Object.fromEntries(
|
|
14
|
+
Object.entries(rule.options).map(([name, option]) => [
|
|
15
|
+
name,
|
|
16
|
+
{
|
|
17
|
+
kind: option.kind,
|
|
18
|
+
about: option.about,
|
|
19
|
+
...(option.kind === "choice" ? { choices: option.choiceNames } : {}),
|
|
20
|
+
default: option.default,
|
|
21
|
+
now: settled[name]?.value ?? option.default,
|
|
22
|
+
from: settled[name]?.from ?? DEFAULT_SOURCE,
|
|
23
|
+
},
|
|
24
|
+
]),
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const TEXT: Texts<{ readonly heading: string; readonly byDefault: string; readonly from: (source: string) => string; readonly howTo: (id: string) => string }> =
|
|
29
|
+
{
|
|
30
|
+
ja: {
|
|
31
|
+
heading: "オプション(chaff.yaml の options で決めます):",
|
|
32
|
+
byDefault: "既定",
|
|
33
|
+
from: (source) => `${source} から`,
|
|
34
|
+
howTo: (id) => `決める: chaff.yaml に options: { ${id}: { <名前>: <値> } } を書く`,
|
|
35
|
+
},
|
|
36
|
+
en: {
|
|
37
|
+
heading: "Options (set under options in chaff.yaml):",
|
|
38
|
+
byDefault: "default",
|
|
39
|
+
from: (source) => `from ${source}`,
|
|
40
|
+
howTo: (id) => `Set one: write options: { ${id}: { <name>: <value> } } in chaff.yaml`,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** A rule's options for explain: each one's value now and where it came from, what it decides, and each choice's meaning. */
|
|
45
|
+
export const optionLines = (rule: RuleDefinition, layers: readonly OptionLayer[], language: string): string[] => {
|
|
46
|
+
if (rule.options === undefined) return [];
|
|
47
|
+
const text = TEXT[uiLanguageOf(language)];
|
|
48
|
+
const settled = settleOptions(rule.id, rule.options, layers);
|
|
49
|
+
const lines = Object.entries(rule.options).flatMap(([name, option]) => {
|
|
50
|
+
const now = settled[name];
|
|
51
|
+
const source = now === undefined || now.from === DEFAULT_SOURCE ? text.byDefault : text.from(now.from);
|
|
52
|
+
const choices = Object.entries(option.choiceNames).map(
|
|
53
|
+
([choice, meaning]) => ` ${choice === now?.value ? "→" : " "} ${choice.padEnd(11)}${localized(meaning, language)}`,
|
|
54
|
+
);
|
|
55
|
+
return [` ${name}: ${printed(now?.value ?? option.default)} (${source})`, ` ${localized(option.about, language)}`, ...choices];
|
|
56
|
+
});
|
|
57
|
+
return ["", ` ${text.heading}`, ...lines, "", ` ${text.howTo(rule.id)}`];
|
|
58
|
+
};
|
package/src/render/rules-json.ts
CHANGED
|
@@ -1,58 +1,104 @@
|
|
|
1
|
-
import { definedLevels, resolve } from "../levels.ts";
|
|
1
|
+
import { definedLevels, resolve, severityAt } from "../levels.ts";
|
|
2
2
|
import type { Config } from "../config/load.ts";
|
|
3
|
-
import type { RuleDefinition } from "../plugin.ts";
|
|
3
|
+
import type { Level, Localized, RuleDefinition } from "../plugin.ts";
|
|
4
|
+
import { readableText } from "./text.ts";
|
|
4
5
|
import { uiLanguageOf, type Texts } from "../ui.ts";
|
|
5
|
-
import { presetLevels } from "../genre-load.ts";
|
|
6
|
-
import type
|
|
6
|
+
import { loadGenres, presetLevels } from "../genre-load.ts";
|
|
7
|
+
import { presetLevelsOf, type PresetLevels } from "../genre-parse.ts";
|
|
8
|
+
import { RULE_GROUPS, groupTextOf } from "../rule-guide.ts";
|
|
9
|
+
import { standingIn } from "../rule-genres.ts";
|
|
10
|
+
import { optionsJson } from "./options.ts";
|
|
11
|
+
import { styleLevelSource } from "../config/style.ts";
|
|
12
|
+
import { loadStyles } from "../style-load.ts";
|
|
13
|
+
import type { OptionLayer } from "../rule-options.ts";
|
|
7
14
|
|
|
8
15
|
const TEXT: Texts<{
|
|
9
16
|
readonly offBySetting: string;
|
|
10
17
|
readonly offByGenre: (genre: string) => string;
|
|
18
|
+
readonly offUnsuited: (genre: string) => string;
|
|
11
19
|
readonly offExperimental: string;
|
|
12
20
|
readonly valuesNote: string;
|
|
13
21
|
readonly reason: string;
|
|
14
22
|
readonly byFile: string;
|
|
23
|
+
readonly optionsByFile: string;
|
|
24
|
+
readonly fromStyleNote: readonly string[];
|
|
15
25
|
}> = {
|
|
16
26
|
ja: {
|
|
17
27
|
offBySetting: "設定で止めている",
|
|
18
28
|
offByGenre: (genre) => `ジャンル ${genre} では見ない`,
|
|
29
|
+
offUnsuited: (genre) => `ジャンル ${genre} の文書には向かない rule(use_for)`,
|
|
19
30
|
offExperimental: "experimental な rule は既定で動かさない",
|
|
20
31
|
valuesNote: "この 4 語のかわりに数字を直接書いてもよい。4 語のほうを勧める。",
|
|
21
32
|
reason: "<理由>",
|
|
22
33
|
byFile: "chaff.yaml の rules に <rule-id>: <level> を足す。既定のままのものは書かない。",
|
|
34
|
+
optionsByFile: "options を持つ rule は、chaff.yaml の options に <rule-id>: { <option>: <value> } を足す。",
|
|
35
|
+
fromStyleNote: [
|
|
36
|
+
"チームの書き方の決まり(例: です・ます、1 文 80 字まで)を一つずつ読む。",
|
|
37
|
+
"決まりごとに、summary と level_meaning が合う rule を選ぶ。数の決まりは levels の数と比べ、合う段階を選ぶか数を直接書く。",
|
|
38
|
+
"文書の種類が分かれば genre を決める。rules[].genres で、そのジャンルで動くか・止まるかを確かめる。",
|
|
39
|
+
"表記の決まりは prefer、社内用語は jargon、必須の見出しは required_sections に書く。",
|
|
40
|
+
"既定と同じものは書かない。書いたら npx chaff explain <rule-id> と、決まりに沿った短い見本で確かめる。",
|
|
41
|
+
],
|
|
23
42
|
},
|
|
24
43
|
en: {
|
|
25
44
|
offBySetting: "turned off in the settings",
|
|
26
45
|
offByGenre: (genre) => `the ${genre} genre does not check it`,
|
|
46
|
+
offUnsuited: (genre) => `not a rule for ${genre} documents (use_for)`,
|
|
27
47
|
offExperimental: "experimental rules do not run by default",
|
|
28
48
|
valuesNote: "A number may be written instead of these four words. The words are recommended.",
|
|
29
49
|
reason: "<reason>",
|
|
30
50
|
byFile: "Add <rule-id>: <level> under rules in chaff.yaml. Leave out anything at its default.",
|
|
51
|
+
optionsByFile: "For a rule with options, add <rule-id>: { <option>: <value> } under options in chaff.yaml.",
|
|
52
|
+
fromStyleNote: [
|
|
53
|
+
"Read the team's style note one requirement at a time (for example: polite endings, sentences of at most 80 characters).",
|
|
54
|
+
"For each requirement, pick the rule whose summary and level_meaning match. For a number, compare it with the rule's levels and pick a level, or write the number itself.",
|
|
55
|
+
"If the kind of document is known, set genre, and check rules[].genres for whether each rule runs or is off in it.",
|
|
56
|
+
"Put spellings under prefer, in-house words under jargon, and required headings under required_sections.",
|
|
57
|
+
"Leave out anything at its default. Then check each rule with npx chaff explain <rule-id> and a short sample that follows the note.",
|
|
58
|
+
],
|
|
31
59
|
},
|
|
32
60
|
};
|
|
33
61
|
|
|
34
62
|
const now = (rule: RuleDefinition, config: Config, genre: string, text: (typeof TEXT)["ja"], preset: PresetLevels): Record<string, unknown> => {
|
|
63
|
+
// A run leaves out a rule whose use_for does not cover the genre before it reads any level.
|
|
64
|
+
if (standingIn(rule, genre, {}).kind === "unsuited") return { level: "off", why_off: text.offUnsuited(genre) };
|
|
35
65
|
const explicit = config.rules[rule.id] ?? preset[rule.id];
|
|
36
66
|
if (explicit === "off" && config.rules[rule.id] === undefined) return { level: "off", why_off: text.offByGenre(genre) };
|
|
37
67
|
if (explicit === "off") return { level: "off", why_off: text.offBySetting };
|
|
38
|
-
const limit = rule.
|
|
68
|
+
const limit = rule.level_sets === "severity" ? undefined : config.limits[rule.id];
|
|
39
69
|
if (limit !== undefined) return { level: "normal", limit, set_as: "number" };
|
|
40
|
-
if (explicit !== undefined) return { level: explicit,
|
|
70
|
+
if (explicit !== undefined) return { level: explicit, ...effectAt(rule, explicit, genre) };
|
|
41
71
|
if (rule.status === "experimental" && !config.experimental) {
|
|
42
72
|
return { level: "off", why_off: text.offExperimental, turn_on_with: `npx chaff lint --experimental` };
|
|
43
73
|
}
|
|
44
|
-
return { level: "normal",
|
|
74
|
+
return { level: "normal", ...effectAt(rule, "normal", genre) };
|
|
45
75
|
};
|
|
46
76
|
|
|
77
|
+
/** The level a rule runs at now, and why it is off when it is: what `chaff rules` shows in its table. */
|
|
78
|
+
export const nowFor = (rule: RuleDefinition, config: Config, language: string, genre: string): Record<string, unknown> =>
|
|
79
|
+
now(rule, config, genre, TEXT[uiLanguageOf(language)], presetLevels(genre));
|
|
80
|
+
|
|
81
|
+
/** What a level does to a rule: the limit it counts to, or, with nothing to count, the severity of its findings. */
|
|
82
|
+
const effectAt = (rule: RuleDefinition, level: Exclude<Level, "off">, genre: string): Record<string, unknown> =>
|
|
83
|
+
rule.level_sets === "severity" ? { severity: severityAt(rule, level, genre) } : { limit: resolve(rule, level, genre).limit };
|
|
84
|
+
|
|
47
85
|
const yourSetting = (rule: RuleDefinition, config: Config): Record<string, unknown> | null => {
|
|
48
86
|
const level = config.rules[rule.id];
|
|
49
87
|
if (level === undefined) return null;
|
|
50
|
-
const
|
|
51
|
-
|
|
88
|
+
const from = styleLevelSource(config, rule.id) ?? config.path;
|
|
89
|
+
const limit = rule.level_sets === "severity" ? undefined : config.limits[rule.id];
|
|
90
|
+
return limit === undefined ? { level, from } : { level, limit, from };
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** The house style chaff.yaml names: what it decides and the guideline it follows, so an AI can say where a setting came from. */
|
|
94
|
+
const styleOf = (config: Config): Record<string, unknown> | null => {
|
|
95
|
+
const style = loadStyles().find((entry) => entry.id === config.applied?.style);
|
|
96
|
+
return style === undefined ? null : { id: style.id, name: style.name, summary: style.summary, source: style.source };
|
|
52
97
|
};
|
|
53
98
|
|
|
54
99
|
/** ジャンルで数字が変わる rule があるので、いま効いている表と既定の表の両方を出す。 */
|
|
55
100
|
const levelsOf = (rule: RuleDefinition, genre: string): Record<string, unknown> => {
|
|
101
|
+
if (rule.level_sets === "severity") return { levels: severitiesOf(rule, genre) };
|
|
56
102
|
const effective = Object.fromEntries(
|
|
57
103
|
definedLevels(rule)
|
|
58
104
|
.filter((level) => level !== "off")
|
|
@@ -62,33 +108,103 @@ const levelsOf = (rule: RuleDefinition, genre: string): Record<string, unknown>
|
|
|
62
108
|
return overridden ? { levels: effective, levels_default: rule.levels, levels_from: "by_genre" } : { levels: rule.levels };
|
|
63
109
|
};
|
|
64
110
|
|
|
111
|
+
const severitiesOf = (rule: RuleDefinition, genre: string): Record<string, string> =>
|
|
112
|
+
Object.fromEntries(
|
|
113
|
+
definedLevels(rule)
|
|
114
|
+
.filter((level) => level !== "off")
|
|
115
|
+
.map((level) => [level, severityAt(rule, level, genre)]),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
/** 指摘が無いので、置き場所は rule の言葉で読ませる。言語はどれも出す。 */
|
|
119
|
+
const readableInEvery = (rule: RuleDefinition, field: Localized): Localized =>
|
|
120
|
+
Object.fromEntries(Object.keys(field).map((language) => [language, readableText(rule, field, language)]));
|
|
121
|
+
|
|
122
|
+
const READER_LANGUAGES = ["ja", "en"];
|
|
123
|
+
|
|
124
|
+
/** How the rule stands in every genre with no chaff.yaml, so an AI can pick a genre before it picks levels. */
|
|
125
|
+
const genresOf = (rule: RuleDefinition): Record<string, Record<string, string>> => {
|
|
126
|
+
const data = loadGenres();
|
|
127
|
+
return Object.fromEntries(
|
|
128
|
+
data.genres.map((genre) => {
|
|
129
|
+
const standing = standingIn(rule, genre.id, presetLevelsOf(data, genre.id));
|
|
130
|
+
return [genre.id, standing.kind === "on" ? { runs: "on", level: standing.level } : { runs: standing.kind }];
|
|
131
|
+
}),
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** The plain-language part of the rule file: what it finds, an example, what it leaves alone, what a level means. */
|
|
136
|
+
const guideOf = (rule: RuleDefinition): Record<string, unknown> => ({
|
|
137
|
+
group: rule.guide?.group ?? null,
|
|
138
|
+
summary: rule.guide?.summary ?? {},
|
|
139
|
+
example: rule.guide?.examples ?? {},
|
|
140
|
+
not_flagged: rule.guide?.notFlagged ?? {},
|
|
141
|
+
level_meaning: rule.guide?.levelMeaning ?? {},
|
|
142
|
+
languages: rule.languages ?? READER_LANGUAGES,
|
|
143
|
+
requires: rule.requires,
|
|
144
|
+
genres: genresOf(rule),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const groupsOf = (): Record<string, unknown>[] =>
|
|
148
|
+
RULE_GROUPS.map((group) => ({
|
|
149
|
+
id: group,
|
|
150
|
+
name: Object.fromEntries(READER_LANGUAGES.map((language) => [language, groupTextOf(language, group).name])),
|
|
151
|
+
note: Object.fromEntries(READER_LANGUAGES.map((language) => [language, groupTextOf(language, group).note])),
|
|
152
|
+
}));
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* What the local-rules release adds. Named now so an AI reading the JSON knows they are coming and does not invent them.
|
|
156
|
+
* Filled in when they ship: the style presets under style:, the custom_rules types, and each rule's options.
|
|
157
|
+
*/
|
|
158
|
+
const COMING = {
|
|
159
|
+
style_presets: { status: "coming", presets: [] },
|
|
160
|
+
custom_rule_types: { status: "coming", planned: ["words", "pattern", "tokens", "module"] },
|
|
161
|
+
rule_options: { status: "coming", note: "Each rule's options (with their types and allowed values) will be listed under options." },
|
|
162
|
+
};
|
|
163
|
+
|
|
65
164
|
/** AI に設定を書かせるときの入口。推測せずに書けるだけの情報を 1 つに入れる。spec §19.3。 */
|
|
66
|
-
export const rulesJson = (
|
|
165
|
+
export const rulesJson = (
|
|
166
|
+
rules: readonly RuleDefinition[],
|
|
167
|
+
config: Config,
|
|
168
|
+
language: string,
|
|
169
|
+
genre: string,
|
|
170
|
+
optionLayers: readonly OptionLayer[] = [],
|
|
171
|
+
): string => {
|
|
67
172
|
const text = TEXT[uiLanguageOf(language)];
|
|
68
173
|
const preset = presetLevels(genre);
|
|
69
174
|
return JSON.stringify(
|
|
70
175
|
{
|
|
71
|
-
|
|
176
|
+
// 2: rules gained group, summary, example, not_flagged, level_meaning, languages, requires and genres,
|
|
177
|
+
// and groups and the coming local-rules fields were added. Nothing from 1 was removed or renamed.
|
|
178
|
+
schema_version: 2,
|
|
72
179
|
config_file: "chaff.yaml",
|
|
73
180
|
detected: { genre, language },
|
|
181
|
+
...(config.applied === undefined ? {} : { style: styleOf(config) }),
|
|
74
182
|
values_you_can_use: ["strict", "normal", "relaxed", "off"],
|
|
75
183
|
values_note: text.valuesNote,
|
|
184
|
+
groups: groupsOf(),
|
|
185
|
+
...COMING,
|
|
76
186
|
rules: rules.map((rule) => ({
|
|
77
187
|
id: rule.id,
|
|
78
188
|
layer: rule.layer,
|
|
79
189
|
status: rule.status,
|
|
80
|
-
name: rule.name,
|
|
81
|
-
why: rule.why,
|
|
82
|
-
how_to_fix: rule.how_to_fix,
|
|
190
|
+
name: readableInEvery(rule, rule.name),
|
|
191
|
+
why: readableInEvery(rule, rule.why),
|
|
192
|
+
how_to_fix: readableInEvery(rule, rule.how_to_fix),
|
|
83
193
|
use_for: rule.use_for,
|
|
194
|
+
level_sets: rule.level_sets,
|
|
84
195
|
...levelsOf(rule, genre),
|
|
85
196
|
levels_you_can_set: definedLevels(rule),
|
|
86
197
|
your_setting: yourSetting(rule, config),
|
|
87
198
|
now: now(rule, config, genre, text, preset),
|
|
199
|
+
...(rule.options === undefined ? {} : { options: optionsJson(rule, optionLayers) }),
|
|
200
|
+
...(rule.custom === undefined ? {} : { defined_in: "chaff.yaml custom_rules", custom: rule.custom }),
|
|
201
|
+
...guideOf(rule),
|
|
88
202
|
})),
|
|
203
|
+
how_to_write_settings_from_a_style_note: text.fromStyleNote,
|
|
89
204
|
how_to_change: {
|
|
90
205
|
by_command: ["relax", "strict", "off"].map((command) => `npx chaff ${command} <rule-id> --why "${text.reason}"`),
|
|
91
206
|
by_file: text.byFile,
|
|
207
|
+
options_by_file: text.optionsByFile,
|
|
92
208
|
},
|
|
93
209
|
},
|
|
94
210
|
null,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Config } from "../config/load.ts";
|
|
2
|
+
import type { RuleDefinition } from "../plugin.ts";
|
|
3
|
+
import { groupTextOf, rulesByGroup } from "../rule-guide.ts";
|
|
4
|
+
import { uiLanguageOf, type Texts } from "../ui.ts";
|
|
5
|
+
import { nowFor } from "./rules-json.ts";
|
|
6
|
+
|
|
7
|
+
// `chaff rules`: every rule, grouped the way the reference groups them, with the level it runs at now.
|
|
8
|
+
// `chaff rules --json` carries the same and more, for an AI to read.
|
|
9
|
+
|
|
10
|
+
type RunsWhen = "default" | "experimental" | "team" | "test";
|
|
11
|
+
|
|
12
|
+
const TEXT: Texts<{
|
|
13
|
+
readonly heading: (genre: string, count: number) => string;
|
|
14
|
+
readonly runsWhen: Readonly<Record<RunsWhen, string>>;
|
|
15
|
+
readonly ungrouped: string;
|
|
16
|
+
readonly footer: readonly string[];
|
|
17
|
+
}> = {
|
|
18
|
+
ja: {
|
|
19
|
+
heading: (genre, count) => `chaff のルール ${count} 本(ジャンル ${genre})`,
|
|
20
|
+
runsWhen: { default: "既定", experimental: "試験中", team: "要設定", test: "AI" },
|
|
21
|
+
ungrouped: "(グループ未設定)",
|
|
22
|
+
footer: [
|
|
23
|
+
"既定: 何も書かなくても動く 試験中: --experimental か chaff.yaml で動く",
|
|
24
|
+
"要設定: chaff.yaml に語や見出しを書いたときだけ AI: npx chaff test で動く",
|
|
25
|
+
"",
|
|
26
|
+
"詳しく: npx chaff explain <rule>",
|
|
27
|
+
"AI に渡す: npx chaff rules --json",
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
en: {
|
|
31
|
+
heading: (genre, count) => `chaff's ${count} rules (genre ${genre})`,
|
|
32
|
+
runsWhen: { default: "default", experimental: "experimental", team: "needs list", test: "AI" },
|
|
33
|
+
ungrouped: "(no group yet)",
|
|
34
|
+
footer: [
|
|
35
|
+
"default: runs with no settings experimental: runs with --experimental or a level in chaff.yaml",
|
|
36
|
+
"needs list: runs only on words or headings listed in chaff.yaml AI: runs with npx chaff test",
|
|
37
|
+
"",
|
|
38
|
+
"More on one rule: npx chaff explain <rule>",
|
|
39
|
+
"For an AI: npx chaff rules --json",
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const runsWhenOf = (rule: RuleDefinition): RunsWhen => {
|
|
45
|
+
if (rule.layer === "L4") return "test";
|
|
46
|
+
if (rule.guide?.group === "team") return "team";
|
|
47
|
+
return rule.status === "experimental" ? "experimental" : "default";
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** Columns line up in a terminal only if a wide (CJK) character counts as two. */
|
|
51
|
+
const widthOf = (text: string): number => Array.from(text).reduce((sum, char) => sum + ((char.codePointAt(0) ?? 0) >= 0x2e80 ? 2 : 1), 0);
|
|
52
|
+
|
|
53
|
+
const pad = (text: string, width: number): string => `${text}${" ".repeat(Math.max(0, width - widthOf(text)))}`;
|
|
54
|
+
|
|
55
|
+
/** "normal (100)", "strict (error)", or "off". */
|
|
56
|
+
const levelNow = (now: Record<string, unknown>): string => {
|
|
57
|
+
const level = typeof now["level"] === "string" ? now["level"] : "";
|
|
58
|
+
const detail = now["limit"] ?? now["severity"];
|
|
59
|
+
return level !== "off" && (typeof detail === "number" || typeof detail === "string") ? `${level} (${String(detail)})` : level;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type Row = { readonly id: string; readonly level: string; readonly runs: string; readonly summary: string };
|
|
63
|
+
|
|
64
|
+
/** A rule for one language only does not run on the others' documents, whatever its level says. */
|
|
65
|
+
const forLanguage = (rule: RuleDefinition, language: string): boolean => rule.languages === undefined || rule.languages.includes(language);
|
|
66
|
+
|
|
67
|
+
const rowOf = (rule: RuleDefinition, config: Config, language: string, genre: string): Row => ({
|
|
68
|
+
id: rule.id,
|
|
69
|
+
level: forLanguage(rule, language) ? levelNow(nowFor(rule, config, language, genre)) : `off (${(rule.languages ?? []).join("/")})`,
|
|
70
|
+
runs: TEXT[uiLanguageOf(language)].runsWhen[runsWhenOf(rule)],
|
|
71
|
+
summary: rule.guide?.summary[uiLanguageOf(language)] ?? "",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const lineOf = (row: Row, widths: { id: number; level: number; runs: number }): string =>
|
|
75
|
+
` ${pad(row.id, widths.id)} ${pad(row.level, widths.level)} ${pad(row.runs, widths.runs)} ${row.summary}`.trimEnd();
|
|
76
|
+
|
|
77
|
+
export const rulesTable = (rules: readonly RuleDefinition[], config: Config, language: string, genre: string): string => {
|
|
78
|
+
const text = TEXT[uiLanguageOf(language)];
|
|
79
|
+
const grouped = rulesByGroup(rules, (rule) => rule.guide?.group).map(({ group, rules: members }) => ({ name: groupTextOf(language, group).name, members }));
|
|
80
|
+
// A rule added without its plain-language fields still shows, so the table never hides a rule that runs.
|
|
81
|
+
const ungrouped = { name: text.ungrouped, members: rules.filter((rule) => rule.guide?.group === undefined) };
|
|
82
|
+
const groups = [...grouped, ungrouped].map(({ name, members }) => ({ name, rows: members.map((rule) => rowOf(rule, config, language, genre)) }));
|
|
83
|
+
const rows = groups.flatMap((group) => group.rows);
|
|
84
|
+
const widths = {
|
|
85
|
+
id: Math.max(...rows.map((row) => widthOf(row.id))),
|
|
86
|
+
level: Math.max(...rows.map((row) => widthOf(row.level))),
|
|
87
|
+
runs: Math.max(...rows.map((row) => widthOf(row.runs))),
|
|
88
|
+
};
|
|
89
|
+
const body = groups.filter((group) => group.rows.length > 0).flatMap((group) => ["", group.name, ...group.rows.map((row) => lineOf(row, widths))]);
|
|
90
|
+
return [text.heading(genre, rows.length), ...body, "", ...text.footer].join("\n");
|
|
91
|
+
};
|
package/src/render/sarif.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { messageOf, readableText } from "./text.ts";
|
|
2
2
|
import type { Finding, RuleDefinition, Severity } from "../plugin.ts";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -48,10 +48,10 @@ const ruleFor = (located: Located): RuleDefinition | undefined => located.rules.
|
|
|
48
48
|
const sarifRule = (rule: RuleDefinition, language: string): SarifRule => ({
|
|
49
49
|
id: ruleIdOf(rule.id),
|
|
50
50
|
name: rule.id,
|
|
51
|
-
shortDescription: { text:
|
|
51
|
+
shortDescription: { text: readableText(rule, rule.name, language) },
|
|
52
52
|
// なぜ直すのかと、どう直すのかを一緒に上げる。指摘だけでは書いた人が動けない。
|
|
53
|
-
fullDescription: { text:
|
|
54
|
-
help: { text:
|
|
53
|
+
fullDescription: { text: readableText(rule, rule.why, language) },
|
|
54
|
+
help: { text: readableText(rule, rule.how_to_fix, language) },
|
|
55
55
|
properties: { tags: [rule.layer, ...rule.use_for] },
|
|
56
56
|
});
|
|
57
57
|
|
package/src/render/semantic.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { UserCheck } from "../checks.ts";
|
|
|
3
3
|
import type { Narrowing } from "../look-at.ts";
|
|
4
4
|
import type { Job as Plan, SemanticResult } from "../run-semantic.ts";
|
|
5
5
|
import { uiLanguageOf, type Texts, type UiLanguage } from "../ui.ts";
|
|
6
|
-
import { MARK, localized } from "./text.ts";
|
|
6
|
+
import { MARK, fill, localized } from "./text.ts";
|
|
7
7
|
import { counted, formFor } from "./plural.ts";
|
|
8
8
|
|
|
9
9
|
const RULE = 60;
|
|
@@ -129,13 +129,13 @@ const block = (finding: Finding, named: Named, language: UiLanguage): string[] =
|
|
|
129
129
|
const confidence = finding.values["confidence"];
|
|
130
130
|
const reason = String(finding.values["reason"] ?? "");
|
|
131
131
|
const sure = confidence === undefined ? "" : ` ${text.confidence(String(confidence))}`;
|
|
132
|
-
const fix = named.howToFix.length > 0 ? ["", ...indent(`→ ${named.howToFix}`, " ")] : [];
|
|
132
|
+
const fix = named.howToFix.length > 0 ? ["", ...indent(`→ ${fill(named.howToFix, finding.values)}`, " ")] : [];
|
|
133
133
|
return [
|
|
134
134
|
"",
|
|
135
135
|
// "12 行目" and "line 12" take the same width on a terminal, so the rule ends in the same column in both.
|
|
136
136
|
`─── ${text.line(finding.line)} ${"─".repeat(Math.max(0, RULE - String(finding.line).length - 8))}`,
|
|
137
137
|
"",
|
|
138
|
-
` ${MARK[finding.severity] ?? "·"} ${named.name}${sure}`,
|
|
138
|
+
` ${MARK[finding.severity] ?? "·"} ${fill(named.name, finding.values)}${sure}`,
|
|
139
139
|
"",
|
|
140
140
|
...indent(reason, " "),
|
|
141
141
|
...fix,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Severity } from "../plugin.ts";
|
|
2
|
+
import type { Texts } from "../ui.ts";
|
|
3
|
+
|
|
4
|
+
/** A severity as the summary line names it (エラー / 注意 / 参考, error / warning / note). */
|
|
5
|
+
export const SEVERITY_NAME: Texts<Readonly<Record<Severity, string>>> = {
|
|
6
|
+
ja: { error: "エラー", warning: "注意", info: "参考" },
|
|
7
|
+
en: { error: "error", warning: "warning", info: "note" },
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const withArticle = (word: string): string => (/^[aeiou]/u.test(word) ? `an ${word}` : `a ${word}`);
|
package/src/render/text.ts
CHANGED
|
@@ -6,23 +6,37 @@ export const localized = (field: Localized, language: string): string => field[l
|
|
|
6
6
|
/** `{count}` is the value; `{count|word|words}` is the form that agrees with it (English only; Japanese has no plural). */
|
|
7
7
|
const PLACEHOLDER = /\{(\w+)(?:\|([^|{}]*)\|([^|{}]*))?\}/gu;
|
|
8
8
|
|
|
9
|
-
const fill = (template: string, values: Readonly<Record<string, string | number>>): string =>
|
|
9
|
+
export const fill = (template: string, values: Readonly<Record<string, string | number>>): string =>
|
|
10
10
|
template.replace(PLACEHOLDER, (whole, key: string, singular: string | undefined, plural: string | undefined) => {
|
|
11
11
|
const value = values[key];
|
|
12
12
|
if (value === undefined) return whole;
|
|
13
13
|
return singular === undefined || plural === undefined ? String(value) : formFor(value, singular, plural);
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
/** A template as the rule reference shows it: each agreeing form as its plural ("{count} such words"). */
|
|
17
|
-
export const templateForReading = (template: string): string =>
|
|
18
|
-
template.replace(PLACEHOLDER, (whole,
|
|
19
|
-
singular === undefined || plural === undefined ? whole : plural,
|
|
16
|
+
/** A template as the rule reference shows it: each agreeing form as its plural ("{count} such words"), each value as its reading when given. */
|
|
17
|
+
export const templateForReading = (template: string, readings: Readonly<Record<string, string>> = {}): string =>
|
|
18
|
+
template.replace(PLACEHOLDER, (whole, key: string, singular: string | undefined, plural: string | undefined) =>
|
|
19
|
+
singular === undefined || plural === undefined ? (readings[key] ?? whole) : plural,
|
|
20
20
|
);
|
|
21
21
|
|
|
22
|
+
/** A rule's text for one finding, with the finding's values in it. */
|
|
23
|
+
export const filledText = (field: Localized, finding: Finding, language: string): string => fill(localized(field, language), finding.values);
|
|
24
|
+
|
|
25
|
+
/** A rule's text where no finding fills it (explain, rules --json, the rule reference): each value as the rule's words for it. */
|
|
26
|
+
export const readableText = (rule: Pick<RuleDefinition, "placeholders">, field: Localized, language: string): string => {
|
|
27
|
+
// The same fallback as the text itself: an English-only rule read in Japanese still gets its English words.
|
|
28
|
+
const readings = Object.fromEntries(
|
|
29
|
+
Object.entries(rule.placeholders ?? {}).flatMap(([key, reading]) => {
|
|
30
|
+
const words = localized(reading, language);
|
|
31
|
+
return words === "" ? [] : [[key, words]];
|
|
32
|
+
}),
|
|
33
|
+
);
|
|
34
|
+
return templateForReading(localized(field, language), readings);
|
|
35
|
+
};
|
|
36
|
+
|
|
22
37
|
const templateOf = (rule: RuleDefinition, finding: Finding): Localized =>
|
|
23
38
|
(finding.variant === undefined ? undefined : rule.messages[finding.variant]) ?? rule.message;
|
|
24
39
|
|
|
25
|
-
export const messageOf = (rule: RuleDefinition, finding: Finding, language: string): string =>
|
|
26
|
-
fill(localized(templateOf(rule, finding), language), finding.values);
|
|
40
|
+
export const messageOf = (rule: RuleDefinition, finding: Finding, language: string): string => filledText(templateOf(rule, finding), finding, language);
|
|
27
41
|
|
|
28
42
|
export const MARK: Readonly<Record<string, string>> = { error: "✖", warning: "⚠", info: "·" };
|
package/src/resolve-genre.ts
CHANGED
|
@@ -3,17 +3,20 @@ import type { Config } from "./config/load.ts";
|
|
|
3
3
|
import type { GenreSource } from "./cli-text.ts";
|
|
4
4
|
import { frontMatterGenre, GENRES, guessGenre } from "./genre.ts";
|
|
5
5
|
import { unknownFrontMatterGenre } from "./genre-check.ts";
|
|
6
|
+
import { plainSource } from "./plain-source.ts";
|
|
6
7
|
|
|
7
8
|
/** unread: a genre the front matter wrote that chaff does not know, when the front matter was looked at. */
|
|
8
9
|
type ResolvedGenre = { readonly genre: string; readonly from: GenreSource; readonly unread?: string | undefined };
|
|
9
10
|
|
|
10
|
-
export const resolveGenre = (path: string,
|
|
11
|
+
export const resolveGenre = (path: string, text: string, config: Config, cliGenre?: string): ResolvedGenre => {
|
|
11
12
|
// コマンドで指定したものが最優先。その実行だけの指定だから、設定より強い。
|
|
12
13
|
if (cliGenre !== undefined) return { genre: cliGenre, from: "--genre" };
|
|
13
14
|
// パスごとの上書きが次。「全体はこう、ここだけは違う」を書けるようにする。
|
|
14
15
|
const override = applyByPath(config.byPath, config.baseDir, path);
|
|
15
16
|
if (override.genre !== undefined) return { genre: override.genre, from: "by_path" };
|
|
16
17
|
if (config.genre !== undefined) return { genre: config.genre, from: "config" };
|
|
18
|
+
// front matter と行頭の手がかりは、buildDocument と同じく BOM と CRLF / CR をそろえた本文で読む。
|
|
19
|
+
const source = plainSource(text);
|
|
17
20
|
const guess = guessGenre(path, source, frontMatterGenre(source));
|
|
18
21
|
const unread = unknownFrontMatterGenre(source, GENRES);
|
|
19
22
|
return guess === undefined ? { genre: "blog/tech", from: "default", unread } : { genre: guess.genre, from: guess.from, unread };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Level, RuleDefinition } from "./plugin.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How a rule stands in one genre, with no chaff.yaml: the same order of precedence as a run (use_for, then the genre's
|
|
5
|
+
* preset, then the rule's status).
|
|
6
|
+
* unsuited: the rule is not for this kind of document (use_for), and does not run
|
|
7
|
+
* genre-off: the genre's preset turns it off
|
|
8
|
+
* experimental: it runs only with --experimental or a level in chaff.yaml
|
|
9
|
+
* on: it runs, at this level
|
|
10
|
+
*/
|
|
11
|
+
export type GenreStanding =
|
|
12
|
+
| { readonly kind: "unsuited" }
|
|
13
|
+
| { readonly kind: "genre-off" }
|
|
14
|
+
| { readonly kind: "experimental" }
|
|
15
|
+
| { readonly kind: "on"; readonly level: Exclude<Level, "off">; readonly byPreset: boolean };
|
|
16
|
+
|
|
17
|
+
type RuleFacts = Pick<RuleDefinition, "id" | "status" | "use_for">;
|
|
18
|
+
|
|
19
|
+
export const standingIn = (rule: RuleFacts, genre: string, preset: Readonly<Record<string, Level>>): GenreStanding => {
|
|
20
|
+
if (!rule.use_for.some((target) => genre.startsWith(target))) return { kind: "unsuited" };
|
|
21
|
+
const fromPreset = preset[rule.id];
|
|
22
|
+
if (fromPreset === "off") return { kind: "genre-off" };
|
|
23
|
+
if (fromPreset !== undefined) return { kind: "on", level: fromPreset, byPreset: true };
|
|
24
|
+
return rule.status === "experimental" ? { kind: "experimental" } : { kind: "on", level: "normal", byPreset: false };
|
|
25
|
+
};
|