chaffjs 0.17.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 +2 -0
- package/dist/calendar-number.d.ts.map +1 -1
- package/dist/calendar-number.js +9 -2
- 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/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 +2 -4
- 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 +2 -0
- package/dist/detectors/acronym-context.d.ts.map +1 -1
- package/dist/detectors/acronym-context.js +12 -4
- package/dist/detectors/acronym-context.js.map +1 -1
- 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/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/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 +7 -4
- 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/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 +34 -1
- 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/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/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 +14 -10
- package/dist/detectors/orthography.js.map +1 -1
- package/dist/detectors/oxford-comma.d.ts +7 -1
- package/dist/detectors/oxford-comma.d.ts.map +1 -1
- package/dist/detectors/oxford-comma.js +135 -229
- package/dist/detectors/oxford-comma.js.map +1 -1
- 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 +67 -46
- package/dist/detectors/signals.js.map +1 -1
- 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 +1 -3
- package/dist/detectors/structure.d.ts.map +1 -1
- package/dist/detectors/structure.js +3 -4
- 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 +90 -98
- 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/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 +33 -10
- 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.js +8 -5
- 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 +119 -17
- package/dist/number-name.js.map +1 -1
- package/dist/orthography.d.ts +2 -0
- package/dist/orthography.d.ts.map +1 -1
- package/dist/orthography.js +9 -4
- 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/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 +115 -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.map +1 -1
- package/dist/quoted-span.js +8 -3
- 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 +87 -33
- 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.d.ts +13 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +54 -10
- package/dist/run.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/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 +76 -30
- 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/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 +26 -0
- 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 +14 -1
- 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 +28 -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 +31 -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 +33 -0
- package/rules/max-sentence-length.yaml +32 -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 +18 -0
- 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 +18 -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 +22 -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 +18 -4
- package/src/cli-args.ts +6 -0
- package/src/cli-text.ts +8 -4
- package/src/cli.ts +37 -37
- 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 +2 -4
- 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 +16 -4
- 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/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/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 +8 -4
- package/src/detectors/heading-level-skip.ts +19 -0
- package/src/detectors/image-alt-text.ts +11 -0
- package/src/detectors/index.ts +43 -1
- package/src/detectors/kutoten-consistency.ts +96 -0
- package/src/detectors/lead-in.ts +3 -1
- package/src/detectors/lexicon-match.ts +9 -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 +23 -17
- package/src/detectors/oxford-comma.ts +178 -283
- 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 +80 -46
- package/src/detectors/structure-tree.ts +45 -1
- package/src/detectors/structure.ts +3 -4
- 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 +106 -138
- 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/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 +52 -9
- 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 +8 -8
- package/src/number-name.ts +151 -24
- package/src/orthography.ts +10 -3
- package/src/page-furniture.ts +11 -2
- package/src/plain-source.ts +2 -1
- package/src/plugin.ts +101 -1
- package/src/profile/for-file.ts +3 -1
- package/src/quoted-span.ts +9 -3
- 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 +91 -34
- package/src/rule-options.ts +131 -0
- package/src/run.ts +74 -11
- package/src/sentence-shape.ts +4 -5
- package/src/setting-problems.ts +7 -1
- package/src/span-cut.ts +28 -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 +77 -30
- 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/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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { escapeRegExp } from "../orthography.ts";
|
|
2
|
-
import { ROMAN_NUMERAL } from "./roman-numeral.ts";
|
|
2
|
+
import { ROMAN_NUMERAL, romanRangeOf } from "./roman-numeral.ts";
|
|
3
3
|
import { citationKeySpans } from "./citation-key.ts";
|
|
4
4
|
import { dottedNameSpans } from "./dotted-name.ts";
|
|
5
5
|
import { letterJoinedNameSpans } from "./letter-joined-name.ts";
|
|
@@ -24,6 +24,8 @@ export type NotationWords = {
|
|
|
24
24
|
readonly emphasis: readonly string[];
|
|
25
25
|
/** 番号を後ろに書く、文書の区切りの名前(Part、Section、Title)。 */
|
|
26
26
|
readonly divisions: readonly string[];
|
|
27
|
+
/** 番号を後ろに書く、点の付いた略した名前(Vol.、No.、FIG.)。 */
|
|
28
|
+
readonly abbreviatedLabels: readonly string[];
|
|
27
29
|
/** 速記録が大文字で書く発言者の姓の前に置く敬称(Mr.、Mrs.、Madam)。 */
|
|
28
30
|
readonly honorifics: readonly string[];
|
|
29
31
|
/** 大文字で書く姓の前に置く肩書き(Prime Minister、Governor)。後ろに略語も来る(the President NASA memo)ので、名前の形を求める。 */
|
|
@@ -44,11 +46,21 @@ const ANY_MERIDIEM = String.raw`[AaPp]\.?[Mm]\.?`;
|
|
|
44
46
|
const AMOUNT = String.raw`(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?`;
|
|
45
47
|
|
|
46
48
|
/**
|
|
47
|
-
*
|
|
48
|
-
* CD や CI
|
|
49
|
+
* 区切りの名前や略した名前のすぐ後ろの番号(Part II、Section VIII、TITLE IV、Vol. XLIII、FIG. 3、FIGS. 1A-1C)。名前は語彙表の
|
|
50
|
+
* 書き方か、全部大文字。ローマ数字は範囲(Part II-IV)も番号。CD や CI のようにローマ数字としても読める略語は、この位置で
|
|
51
|
+
* なければ略語のまま数える。
|
|
49
52
|
*/
|
|
50
53
|
const divisionOf = (words: readonly string[]): string => oneOf(words.flatMap((word) => [word, word.toUpperCase()]));
|
|
51
54
|
|
|
55
|
+
/** 図や表の番号は短い(FIG. 3、TABLE 12、FIG. 1A)。長い数(FIG. 12345)の前の大文字は略語のまま数える。 */
|
|
56
|
+
const SHORT_NUMBER = String.raw`\d{1,3}[A-Za-z]?`;
|
|
57
|
+
const NUMBER_END = String.raw`(?![\p{L}\p{N}_&])`;
|
|
58
|
+
|
|
59
|
+
const numberedPatterns = (words: NotationWords): readonly RegExp[] => {
|
|
60
|
+
const label = String.raw`(?<![\p{L}\p{N}_])${divisionOf([...words.divisions, ...words.abbreviatedLabels])}\s+`;
|
|
61
|
+
return [new RegExp(`${label}${romanRangeOf(ROMAN_NUMERAL)}${NUMBER_END}`, "gu"), new RegExp(`${label}${SHORT_NUMBER}${NUMBER_END}`, "gu")];
|
|
62
|
+
};
|
|
63
|
+
|
|
52
64
|
/** 敬称のすぐ後ろの大文字の姓(Mr. HAWLEY、Dr. O'NEIL)。速記録は発言者をこう書き、略語ではない。 */
|
|
53
65
|
const SURNAME_IN_CAPITALS = String.raw`[A-Z]+(?:['’-][A-Z]+)*(?![\p{L}\p{N}_])`;
|
|
54
66
|
|
|
@@ -71,7 +83,7 @@ const patternsOf = (words: NotationWords): readonly RegExp[] => [
|
|
|
71
83
|
new RegExp(String.raw`(?<![\w.,])${AMOUNT}\s*${oneOf(words.currencies)}`, "gu"),
|
|
72
84
|
new RegExp(String.raw`,\s+${oneOf(words.usStates)}\s+\d{5}(?:-\d{4})?(?!\d)`, "gu"),
|
|
73
85
|
new RegExp(oneOf(words.emphasis), "gu"),
|
|
74
|
-
|
|
86
|
+
...numberedPatterns(words),
|
|
75
87
|
new RegExp(String.raw`(?<![\p{L}\p{N}_])${oneOf(words.honorifics)}\s+${SURNAME_IN_CAPITALS}`, "gu"),
|
|
76
88
|
...titledName(oneOf(words.titles)),
|
|
77
89
|
];
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { Detector, Finding, Lexicon, LexiconEntry, ProseDocument, Sentence } from "../plugin.ts";
|
|
2
|
+
import { wordsOf } from "./structure.ts";
|
|
3
|
+
import { MIN_DOCUMENT_LENGTH } from "./signals.ts";
|
|
4
|
+
import { entryIn, entryOpens } from "./lexicon-match.ts";
|
|
5
|
+
import { contrastSentences, type ContrastWords } from "./contrast-frame.ts";
|
|
6
|
+
import { placeholderSpans } from "./placeholder-text.ts";
|
|
7
|
+
import { colonLeadIns } from "./list-lead-in.ts";
|
|
8
|
+
|
|
9
|
+
// 生成文に多い形。語はどれも言語パッケージの語彙表が持ち、ここは形だけを知る。
|
|
10
|
+
|
|
11
|
+
const PER = 1000;
|
|
12
|
+
/** 密度は小数 1 桁まで。日本語の 1000 字あたりは 1 と 2 の間で人と生成文が分かれる。 */
|
|
13
|
+
const TENTHS = 10;
|
|
14
|
+
/** 重みの合計を 10 倍した点で比べる(ai-tell と同じ)。重み 0.5 の言い回し 2 つで 10。 */
|
|
15
|
+
const SCORE_SCALE = 10;
|
|
16
|
+
/** 1 つは重なりではない。短い文書では 1 つでも密度が上限を超えるので、数でも止める。 */
|
|
17
|
+
const PILE = 2;
|
|
18
|
+
|
|
19
|
+
/** 当たった文と語。offset は指摘する位置で、無ければ文の頭。 */
|
|
20
|
+
type Hit = { readonly sentence: Sentence; readonly matched: string; readonly offset?: number };
|
|
21
|
+
|
|
22
|
+
const findingOf = (hit: Hit, values: Readonly<Record<string, number>>): Finding => ({
|
|
23
|
+
rule: "",
|
|
24
|
+
severity: "info",
|
|
25
|
+
line: 0,
|
|
26
|
+
column: 0,
|
|
27
|
+
quote: hit.sentence.text.trim(),
|
|
28
|
+
values: { matched: hit.matched, ...values, offset: hit.offset ?? hit.sentence.span.start },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/** 1000 語(日本語は 1000 字)あたりの数が上限を超えたら、当たった文をすべて言う。短い文書は密度が暴れるので測らない。 */
|
|
32
|
+
const densityFindings = (doc: ProseDocument, hits: readonly Hit[], limit: number): Finding[] => {
|
|
33
|
+
const length = wordsOf(doc);
|
|
34
|
+
if (hits.length < PILE || length < MIN_DOCUMENT_LENGTH[doc.lengthUnit]) return [];
|
|
35
|
+
const density = Math.round((hits.length / length) * PER * TENTHS) / TENTHS;
|
|
36
|
+
return density <= limit ? [] : hits.map((hit) => findingOf(hit, { count: hits.length, density, limit }));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const firstIn = (sentence: Sentence, lexicon: Lexicon): LexiconEntry | undefined => lexicon.find((entry) => entryIn(sentence, entry));
|
|
40
|
+
|
|
41
|
+
const contrastWordsOf = (doc: ProseDocument, frames: Lexicon): ContrastWords => ({
|
|
42
|
+
frames,
|
|
43
|
+
leads: doc.lexicons["contrast-lead"] ?? [],
|
|
44
|
+
turns: doc.lexicons["contrast-turn"] ?? [],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
/** 対比の枠(It's not X, it's Y、単なる X ではなく)。1 つなら論点の整理だが、重なると言い回しの癖になる。 */
|
|
48
|
+
export const contrastFraming: Detector = (doc, options): Finding[] => {
|
|
49
|
+
const words = contrastWordsOf(doc, options.lexicon ?? []);
|
|
50
|
+
const hits = contrastSentences(doc.sentences, words).map((sentence) => ({
|
|
51
|
+
sentence,
|
|
52
|
+
matched: (firstIn(sentence, words.frames) ?? firstIn(sentence, words.leads))?.pattern ?? "",
|
|
53
|
+
}));
|
|
54
|
+
return densityFindings(doc, hits, options.limit);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** 語彙表の語で始まる文。 */
|
|
58
|
+
const openerHits = (doc: ProseDocument, lexicon: Lexicon): Hit[] =>
|
|
59
|
+
doc.sentences.flatMap((sentence) => {
|
|
60
|
+
const opener = lexicon.find((entry) => entryOpens(sentence, entry));
|
|
61
|
+
return opener === undefined ? [] : [{ sentence, matched: opener.pattern }];
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
/** 文頭の決まった接ぎ(Moreover、さらに)の密度。話を運ぶ語(However、また)は語彙表に入れない。 */
|
|
65
|
+
export const openerDensity: Detector = (doc, options): Finding[] => densityFindings(doc, openerHits(doc, options.lexicon ?? []), options.limit);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 予告の文頭(重要なのは、Here's the thing)の数。limit は指摘に要る数。
|
|
69
|
+
* 密度ではなく数で見る。人の記事も長さによらず 1 つ 2 つは書き、生成文は短い記事にも重ねる。
|
|
70
|
+
*/
|
|
71
|
+
export const openerPile: Detector = (doc, options): Finding[] => {
|
|
72
|
+
const hits = openerHits(doc, options.lexicon ?? []);
|
|
73
|
+
return hits.length === 0 || hits.length < options.limit ? [] : hits.map((hit) => findingOf(hit, { count: hits.length, limit: options.limit }));
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/** コロンで箇条書きへ渡す文(以下の通りです:)。1 つなら案内だが、節ごとに続くと説明が箇条書きの前置きだけになる。 */
|
|
77
|
+
export const colonLeadIn: Detector = (doc, options): Finding[] => {
|
|
78
|
+
const hits = colonLeadIns(doc.sentences, doc.lists, doc.listSpans, doc.source).map((sentence) => ({ sentence, matched: sentence.text.trim() }));
|
|
79
|
+
return densityFindings(doc, hits, options.limit);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const distinct = (lexicon: Lexicon): LexiconEntry[] => [...new Map(lexicon.map((entry) => [entry.pattern.toLowerCase(), entry])).values()];
|
|
83
|
+
|
|
84
|
+
const weightOf = (entry: LexiconEntry): number => entry.weight ?? 1;
|
|
85
|
+
|
|
86
|
+
const keyOf = (entry: LexiconEntry): string => entry.pattern.toLowerCase();
|
|
87
|
+
|
|
88
|
+
type Tally = { readonly score: number; readonly counted: ReadonlySet<string>; readonly hits: readonly Hit[] };
|
|
89
|
+
|
|
90
|
+
const NOTHING: Tally = { score: 0, counted: new Set(), hits: [] };
|
|
91
|
+
|
|
92
|
+
/** 1 つの文を足す。重みは、まだ数えていない語のうち最も重いもの。文の語はすべて数えたことにする。 */
|
|
93
|
+
const withSentence = (tally: Tally, sentence: Sentence, inSentence: readonly LexiconEntry[]): Tally => {
|
|
94
|
+
const fresh = inSentence.filter((entry) => !tally.counted.has(keyOf(entry)));
|
|
95
|
+
const added = fresh.length === 0 ? 0 : Math.max(...fresh.map(weightOf));
|
|
96
|
+
const matched = (fresh[0] ?? inSentence[0])?.pattern ?? "";
|
|
97
|
+
return {
|
|
98
|
+
score: tally.score + added,
|
|
99
|
+
counted: new Set([...tally.counted, ...inSentence.map(keyOf)]),
|
|
100
|
+
hits: [...tally.hits, { sentence, matched }],
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 1 つの文は 1 つの言い回しとして数える(Let me know if you'd like a more detailed breakdown は礼 1 つ)。
|
|
106
|
+
* 前の文で数えた語は、別の文にあっても数えない(I hope this helps を 2 回書いても礼 1 つ)。
|
|
107
|
+
*/
|
|
108
|
+
const tallyOf = (sentences: readonly Sentence[], entries: readonly LexiconEntry[]): Tally =>
|
|
109
|
+
sentences.reduce<Tally>((tally, sentence) => {
|
|
110
|
+
const inSentence = entries.filter((entry) => entryIn(sentence, entry));
|
|
111
|
+
return inSentence.length === 0 ? tally : withSentence(tally, sentence, inSentence);
|
|
112
|
+
}, NOTHING);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 会話の返事の名残(As of my last knowledge update、私の知識は)。重みを足した点が上限に届いたら、当たった文をすべて言う。
|
|
116
|
+
* 名残そのもの(知識の期限、AI としての断り)は 1 つで届き、人も書く礼(I hope this helps)は 2 つ重なって届く。
|
|
117
|
+
*/
|
|
118
|
+
export const assistantResidue: Detector = (doc, options): Finding[] => {
|
|
119
|
+
const tally = tallyOf(doc.sentences, distinct(options.lexicon ?? []));
|
|
120
|
+
const score = Math.round(tally.score * SCORE_SCALE);
|
|
121
|
+
if (tally.hits.length === 0 || score < options.limit) return [];
|
|
122
|
+
return tally.hits.map((hit) => findingOf(hit, { count: tally.counted.size, density: score, limit: options.limit }));
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/** 埋め忘れた雛形の空欄([Your Name]、【会社名】)。limit は指摘に要る数。 */
|
|
126
|
+
export const unfilledPlaceholder: Detector = (doc, options): Finding[] => {
|
|
127
|
+
const words = options.lexicon ?? [];
|
|
128
|
+
const blanks = doc.sentences.flatMap((sentence) =>
|
|
129
|
+
placeholderSpans(sentence.text, words).map((span) => ({
|
|
130
|
+
sentence,
|
|
131
|
+
matched: sentence.text.slice(span.start, span.end),
|
|
132
|
+
offset: sentence.span.start + span.start,
|
|
133
|
+
})),
|
|
134
|
+
);
|
|
135
|
+
if (blanks.length === 0 || blanks.length < options.limit) return [];
|
|
136
|
+
return blanks.map((blank) => findingOf(blank, { count: blanks.length, limit: options.limit }));
|
|
137
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
2
|
+
import { announcedCountMismatches, type CountWords } from "../announced-count.ts";
|
|
3
|
+
import { quoteAt } from "./structure-tree.ts";
|
|
4
|
+
|
|
5
|
+
const patternsOf = (doc: ProseDocument, id: string, position?: "before" | "after"): string[] =>
|
|
6
|
+
(doc.lexicons[id] ?? []).filter((entry) => position === undefined || entry.position === position).map((entry) => entry.pattern);
|
|
7
|
+
|
|
8
|
+
const countWordsOf = (doc: ProseDocument): CountWords => ({
|
|
9
|
+
anchors: patternsOf(doc, "count-anchor"),
|
|
10
|
+
numbers: patternsOf(doc, "count-number"),
|
|
11
|
+
counters: patternsOf(doc, "count-counter"),
|
|
12
|
+
hedgesBefore: patternsOf(doc, "count-hedge", "before"),
|
|
13
|
+
hedgesAfter: patternsOf(doc, "count-hedge", "after"),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/** 予告の数(以下の3点)と、すぐ下の箇条書きの項目の数が違う。 */
|
|
17
|
+
export const announcedCount: Detector = (doc): Finding[] =>
|
|
18
|
+
announcedCountMismatches(doc.source, doc.lists, countWordsOf(doc)).map((mismatch) => ({
|
|
19
|
+
rule: "announced-count-mismatch",
|
|
20
|
+
severity: "warning",
|
|
21
|
+
line: 0,
|
|
22
|
+
column: 0,
|
|
23
|
+
quote: quoteAt(doc.source, mismatch.offset),
|
|
24
|
+
values: { phrase: mismatch.phrase, announced: mismatch.announced, listed: mismatch.listed, offset: mismatch.offset },
|
|
25
|
+
}));
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Detector, Finding, Markup, ProseDocument, Span } from "../plugin.ts";
|
|
2
|
+
import { findingAt, markupOf, quoteOf } from "./markup-finding.ts";
|
|
3
|
+
|
|
4
|
+
/** ページの先頭を指す書き方。見出しが無くても行き先がある。 */
|
|
5
|
+
const PAGE_TOP = new Set(["", "top"]);
|
|
6
|
+
|
|
7
|
+
/** 名前を比べる形。字と数字だけを小文字で残す。見出しから名前を作る決まりは表示するものごとに違う(空白を - にする・記号を消す)ので、その違いを畳む。 */
|
|
8
|
+
export const anchorKey = (name: string): string => name.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "");
|
|
9
|
+
|
|
10
|
+
/** 同じ見出しが二つあると、表示するものは二つ目以降に -1、-2 を付ける。 */
|
|
11
|
+
const DUPLICATE_SUFFIX = /-(\d+)$/u;
|
|
12
|
+
|
|
13
|
+
const decoded = (fragment: string): string => {
|
|
14
|
+
try {
|
|
15
|
+
return decodeURIComponent(fragment);
|
|
16
|
+
} catch {
|
|
17
|
+
return fragment;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** 「&」を and と読んで名前を作るもの(M&IE → m-and-ie)もある。 */
|
|
22
|
+
const namesOf = (text: string): string[] => [...new Set([text, text.replaceAll("&", " and ")])];
|
|
23
|
+
|
|
24
|
+
const keysOf = (name: string): string[] => [...new Set(namesOf(name).map(anchorKey))];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 文書の中の名前を持つところ。headings は見出しから作る名前の形ごとの数(-1、-2 は見出しだけに付く)。
|
|
28
|
+
* ids は書き手が付けた名前そのもの。見出しと違って作り方の違いが無いので、書いたとおりに比べる。
|
|
29
|
+
*/
|
|
30
|
+
export type Anchors = { readonly ids: ReadonlySet<string>; readonly headings: ReadonlyMap<string, number> };
|
|
31
|
+
|
|
32
|
+
export const anchorsOf = (markup: Markup): Anchors => ({
|
|
33
|
+
ids: markup.ids,
|
|
34
|
+
headings: markup.headings
|
|
35
|
+
.flatMap((heading) => keysOf(heading.text))
|
|
36
|
+
.reduce((counts, key) => counts.set(key, (counts.get(key) ?? 0) + 1), new Map<string, number>()),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/** `#setup-2` は、同じ形の見出しが 3 つ以上あるときだけ行き先がある(二つ目が -1)。 */
|
|
40
|
+
const reachesDuplicate = (fragment: string, headings: ReadonlyMap<string, number>): boolean => {
|
|
41
|
+
const suffix = DUPLICATE_SUFFIX.exec(fragment);
|
|
42
|
+
if (suffix === null) return false;
|
|
43
|
+
return (headings.get(anchorKey(fragment.slice(0, suffix.index))) ?? 0) > Number(suffix[1]);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** `#…` の行き先が、文書の中の見出しか id を指しているか。 */
|
|
47
|
+
export const reachesAnchor = (destination: string, anchors: Anchors): boolean => {
|
|
48
|
+
const fragment = decoded(destination.slice(1));
|
|
49
|
+
if (PAGE_TOP.has(fragment.toLowerCase())) return true;
|
|
50
|
+
return anchors.ids.has(fragment) || anchors.headings.has(anchorKey(fragment)) || reachesDuplicate(fragment, anchors.headings);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 参照の形で書いたのに名前の定義(`[label]: url`)が無いもの(`[text][label]`、`[text][]`)。字のまま表示される。
|
|
55
|
+
* 定義があれば CommonMark はリンクにするので、字のまま残った参照の形は定義が無い。英数字のすぐ後ろの括弧(A[i][j])は配列の添字。
|
|
56
|
+
*/
|
|
57
|
+
const REFERENCE_LIKE = /(?<![\\A-Za-z0-9_\]])\[([^[\]\n]+)\]\[([^[\]\n]*)\]/gu;
|
|
58
|
+
|
|
59
|
+
/** 数だけの括弧([1][2]、[3, 4])は、参照の記法ではなく文献の番号を並べたもの。 */
|
|
60
|
+
const CITATION_NUMBERS = /^[\d\s,,、–-]+$/u;
|
|
61
|
+
|
|
62
|
+
/** 画像の参照(`![alt][label]`)の頭の印。指摘の範囲に含める。 */
|
|
63
|
+
const IMAGE_MARK = "!";
|
|
64
|
+
|
|
65
|
+
export const unresolvedReferences = (source: string, markup: Markup): Span[] =>
|
|
66
|
+
markup.texts.flatMap((text) =>
|
|
67
|
+
[...source.slice(text.start, text.end).matchAll(REFERENCE_LIKE)]
|
|
68
|
+
.filter((match) => !CITATION_NUMBERS.test(match[1] ?? ""))
|
|
69
|
+
.map((match) => ({ start: text.start + match.index, end: text.start + match.index + match[0].length }))
|
|
70
|
+
.map((span) => (source.charAt(span.start - 1) === IMAGE_MARK ? { start: span.start - 1, end: span.end } : span)),
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const emptyLinks = (doc: ProseDocument, markup: Markup): Finding[] =>
|
|
74
|
+
markup.links.filter((link) => link.destination.trim() === "").map((link) => findingAt(doc, link, { link: quoteOf(doc.source, link) }, "empty"));
|
|
75
|
+
|
|
76
|
+
const missingAnchors = (doc: ProseDocument, markup: Markup): Finding[] => {
|
|
77
|
+
const anchors = anchorsOf(markup);
|
|
78
|
+
return markup.links
|
|
79
|
+
.filter((link) => link.destination.startsWith("#") && !reachesAnchor(link.destination, anchors))
|
|
80
|
+
.map((link) => findingAt(doc, link, { link: quoteOf(doc.source, link), target: link.destination }, "anchor"));
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const brokenLink: Detector = (doc): Finding[] => {
|
|
84
|
+
const markup = markupOf(doc);
|
|
85
|
+
if (markup === undefined) return [];
|
|
86
|
+
const references = unresolvedReferences(doc.source, markup).map((span) => findingAt(doc, span, { link: quoteOf(doc.source, span) }, "reference"));
|
|
87
|
+
return [...emptyLinks(doc, markup), ...missingAnchors(doc, markup), ...references].toSorted(
|
|
88
|
+
(left, right) => Number(left.values["offset"]) - Number(right.values["offset"]),
|
|
89
|
+
);
|
|
90
|
+
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { StructureNode, Token } from "../plugin.ts";
|
|
2
|
+
import { preOrder } from "../tree-walk.ts";
|
|
2
3
|
|
|
3
4
|
/** 他の文書を指す参照(民法第709条の第709条)の始まりの位置から、その文書の名前(民法)へ。 */
|
|
4
5
|
export type CitedNames = ReadonlyMap<number, string>;
|
|
5
6
|
|
|
6
|
-
const namedReferences = (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
7
|
+
const namedReferences = (root: StructureNode): (readonly [number, string])[] =>
|
|
8
|
+
preOrder(root).flatMap((node) => {
|
|
9
|
+
const document = node.attrs["document"];
|
|
10
|
+
return node.kind === "reference" && typeof document === "string" ? [[node.span.start, document] as const] : [];
|
|
11
|
+
});
|
|
11
12
|
|
|
12
13
|
export const citedNamesOf = (structure: StructureNode | undefined): CitedNames => new Map(structure === undefined ? [] : namedReferences(structure));
|
|
13
14
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Token } from "../plugin.ts";
|
|
2
|
+
import { MINOR_WORDS } from "./heading-case.ts";
|
|
3
|
+
import { columnOf, firstIn, lastIn, type Column } from "./token-column.ts";
|
|
4
|
+
|
|
5
|
+
// 引用した題名(誌名・論文名・書名)。題名の中の読点は題名を付けた人のもので、書き手が並べかたを選んだものではない。
|
|
6
|
+
|
|
7
|
+
const isCapitalised = (token: Token): boolean => /^\p{Lu}/u.test(token.surface);
|
|
8
|
+
|
|
9
|
+
/** 題名の中でつなぐ記号。ハイフン(Low-Inflation)と、副題の前のコロン(Maximum Employment: A Shortfalls Approach)。 */
|
|
10
|
+
const TITLE_JOINERS: ReadonlySet<string> = new Set(["-", ":"]);
|
|
11
|
+
|
|
12
|
+
/** 題名の中の語。大文字で始まる語と、Title Case でも小文字のままの語(of, and, a)と、つなぐ記号。 */
|
|
13
|
+
const isTitleWord = (token: Token): boolean => isCapitalised(token) || MINOR_WORDS.has(token.surface) || TITLE_JOINERS.has(token.surface);
|
|
14
|
+
|
|
15
|
+
/** 題名の中の区切り。左は読点もまたぐ(Journal of Money, Credit)。 */
|
|
16
|
+
const inLeftRun = (token: Token): boolean => isTitleWord(token) || token.surface === ",";
|
|
17
|
+
|
|
18
|
+
/** 2 つの語の間が空白だけか。覆った強調の印(*Journal)や記号を挟めば、題名の語の続きはそこで切れる。 */
|
|
19
|
+
const adjoins = (source: string, left: Token | undefined, right: Token | undefined): boolean =>
|
|
20
|
+
left === undefined || right === undefined || source.slice(left.span.end, right.span.start).trim() === "";
|
|
21
|
+
|
|
22
|
+
const LIST_CONJUNCTIONS: ReadonlySet<string> = new Set(["and", "or"]);
|
|
23
|
+
|
|
24
|
+
const isPhraseWord = (token: Token): boolean => (isCapitalised(token) || MINOR_WORDS.has(token.surface)) && !LIST_CONJUNCTIONS.has(token.surface);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 題名の語の続きの切れ目。左の続きは、題名の語でも読点でもない語か、次の語との間に空白以外を挟む語で切れる。
|
|
28
|
+
* 右の続きは、題名の語でない語か、前の語との間に空白以外を挟む語で切れる。
|
|
29
|
+
*/
|
|
30
|
+
type Runs = { readonly leftBreak: Column; readonly rightBreak: Column; readonly capital: Column; readonly phrasePair: Column };
|
|
31
|
+
|
|
32
|
+
const runsOf = (tokens: readonly Token[], source: string): Runs => ({
|
|
33
|
+
leftBreak: columnOf(tokens, (token, index) => !inLeftRun(token) || !adjoins(source, token, tokens[index + 1])),
|
|
34
|
+
rightBreak: columnOf(tokens, (token, index) => !isTitleWord(token) || !adjoins(source, tokens[index - 1], token)),
|
|
35
|
+
capital: columnOf(tokens, isCapitalised),
|
|
36
|
+
phrasePair: columnOf(tokens, (token, index) => index > 0 && isPhraseWord(token) && isPhraseWord(tokens[index - 1] ?? token)),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* and / or の左の、題名の語の続きの頭。最初の大文字の語から。小文字の語から始めると、引用符の中の並び(‘the UK, France and
|
|
41
|
+
* Spain’)や、論文名のあとの編者の並び(," in Heather Boushey, Ryan Nunn, and Jay Shambaugh, eds.)まで題名と読む。
|
|
42
|
+
*/
|
|
43
|
+
const leftStart = (runs: Runs, at: number): number | undefined => {
|
|
44
|
+
const stop = lastIn(runs.leftBreak, { start: 0, end: at });
|
|
45
|
+
const start = firstIn(runs.capital, { start: stop + 1, end: at });
|
|
46
|
+
return start === -1 ? undefined : start;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** and / or の右の、題名の語の続きの最後の大文字の語。 */
|
|
50
|
+
const rightEnd = (runs: Runs, at: number, length: number): number | undefined => {
|
|
51
|
+
const stop = firstIn(runs.rightBreak, { start: at + 1, end: length });
|
|
52
|
+
const last = lastIn(runs.capital, { start: at + 1, end: stop === -1 ? length : stop });
|
|
53
|
+
return last === -1 ? undefined : last;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** 印を探す幅。いちばん長い印(***)と、読点・引用符・空白が収まる。 */
|
|
57
|
+
const MARK_REACH = 8;
|
|
58
|
+
|
|
59
|
+
/** 題名の最初の語にくっついた開きの印(“ ‘ " ' * _)。 */
|
|
60
|
+
const OPENING = /(?:["'“‘]|\*{1,3}|_{1,3})$/u;
|
|
61
|
+
/** 題名の直後の閉じの印。句読点を挟んでよい(Employment,”)。印の後ろが語なら、語の中の字(TO_CHAR、Madrid’s)。 */
|
|
62
|
+
const CLOSING = /^[,.;:!?]?(?:["'”’]|\*{1,3}|_{1,3})(?![\p{L}\p{N}])/u;
|
|
63
|
+
/** 引用した論文名のあとの読点と閉じる引用符。そのあとの題名は誌名("Three Lessons," Journal of Money, Credit and Banking)。 */
|
|
64
|
+
const AFTER_QUOTED_TITLE = /,\s*["'”’]\s*$/u;
|
|
65
|
+
/** 誌名のあとは、巻号や頁へ続く読点か文の終わり。述語が続けば(“Done,” Smith, Jones and Brown argued)主語の並び。 */
|
|
66
|
+
const VENUE_END = /^\s*(?:[,;.]|$)/u;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 語の続きに、2 語以上の句があるか(Journal of Money、Their Nature、The Update)。1 語ずつの名前の並び
|
|
70
|
+
* (‘Paris, Rome and Madrid’)は、引用符の中でも書き手が並べたもの。
|
|
71
|
+
*/
|
|
72
|
+
const holdsPhrase = (runs: Runs, start: number, end: number): boolean => firstIn(runs.phrasePair, { start: start + 1, end: end + 1 }) !== -1;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 文の and / or が、引用した題名の中にあるか。and / or の両隣が Title Case の語の続きで、2 語以上の句を含み、その続きが
|
|
76
|
+
* 引用符か強調の印で囲まれているか、引用符で閉じた論文名のすぐ後ろにあって読点か文の終わりが続く(誌名)とき。
|
|
77
|
+
* 本文の固有名詞の並び(Login.gov, TTS Engineering and USAi)や著者の並びは囲まれていないので、題名と読まない。
|
|
78
|
+
* 文を一度だけ読み、どの位置の問いにも続きを読み直さずに答える。
|
|
79
|
+
*/
|
|
80
|
+
export const citedTitles = (tokens: readonly Token[], source: string): ((at: number) => boolean) => {
|
|
81
|
+
const runs = runsOf(tokens, source);
|
|
82
|
+
return (at) => {
|
|
83
|
+
const start = leftStart(runs, at);
|
|
84
|
+
const end = rightEnd(runs, at, tokens.length);
|
|
85
|
+
const first = start === undefined ? undefined : tokens[start];
|
|
86
|
+
const last = end === undefined ? undefined : tokens[end];
|
|
87
|
+
if (start === undefined || end === undefined || first === undefined || last === undefined) return false;
|
|
88
|
+
if (!holdsPhrase(runs, start, end)) return false;
|
|
89
|
+
const before = source.slice(Math.max(0, first.span.start - MARK_REACH), first.span.start);
|
|
90
|
+
const after = source.slice(last.span.end, last.span.end + MARK_REACH);
|
|
91
|
+
return (OPENING.test(before) && CLOSING.test(after)) || (AFTER_QUOTED_TITLE.test(before) && VENUE_END.test(after));
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/** at の and / or が、引用した題名の中にあるか。 */
|
|
96
|
+
export const inCitedTitle = (tokens: readonly Token[], at: number, source: string): boolean => citedTitles(tokens, source)(at);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Span, StructureKind, StructureNode, Token } from "../plugin.ts";
|
|
2
|
+
import { preOrder } from "../tree-walk.ts";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 形態素解析が数と読んだ語(UD の NumType=Card)。漢数字の「二割」「十五分」も、算用数字と同じ具体的な数。
|
|
@@ -27,5 +28,5 @@ export const startsWithin = (section: Span, spans: readonly Span[]): boolean =>
|
|
|
27
28
|
/** 構造の木が読んだ参照(第3条・Section VI)・数量・日付。どれも読み手が確かめに行ける具体物。 */
|
|
28
29
|
const EVIDENCE: ReadonlySet<StructureKind> = new Set(["reference", "quantity", "date"]);
|
|
29
30
|
|
|
30
|
-
export const evidenceSpans = (
|
|
31
|
-
|
|
31
|
+
export const evidenceSpans = (root: StructureNode | undefined): Span[] =>
|
|
32
|
+
root === undefined ? [] : preOrder(root).flatMap((node) => (EVIDENCE.has(node.kind) ? [node.span] : []));
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Lexicon, LexiconEntry, Sentence } from "../plugin.ts";
|
|
2
|
+
import { escapeRegExp } from "../orthography.ts";
|
|
3
|
+
import { comparableText, comparableWords, entryIn, entryOpens, entryRanges } from "./lexicon-match.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 対比の枠の語。frames は 1 つで枠になる語(not only、だけでなく)。
|
|
7
|
+
* leads は打ち消し(it's not、単なる)で、turns(it's、but、ではなく)が後ろに来たときだけ枠になる。同じ文の後ろか、次の文の頭。
|
|
8
|
+
* 打ち消しの頭に立つ返しの語(It's not ready. It's not tested. の 2 つ目の It's)は返しではなく、次の打ち消し。
|
|
9
|
+
*/
|
|
10
|
+
export type ContrastWords = { readonly frames: Lexicon; readonly leads: Lexicon; readonly turns: Lexicon };
|
|
11
|
+
|
|
12
|
+
const lowered = (entry: LexiconEntry): string => comparableWords(entry.pattern);
|
|
13
|
+
|
|
14
|
+
type Range = { readonly start: number; readonly end: number };
|
|
15
|
+
|
|
16
|
+
/** 返しの語が、それより長い打ち消しの頭にあるか(It's not の It's)。同じ長さなら返しのまま(ではなく は打ち消しでも返しでもある)。 */
|
|
17
|
+
const opensLongerLead = (found: Range, leads: readonly Range[]): boolean => leads.some((lead) => lead.start === found.start && lead.end > found.end);
|
|
18
|
+
|
|
19
|
+
const answersAfter = (leadRange: Range, turns: readonly Range[], leads: readonly Range[]): boolean =>
|
|
20
|
+
turns.some((found) => found.start >= leadRange.end && !opensLongerLead(found, leads));
|
|
21
|
+
|
|
22
|
+
/** 文字列の中で word が現れる範囲、左から順に。 */
|
|
23
|
+
const rangesOf = (text: string, word: string): Range[] =>
|
|
24
|
+
[...text.matchAll(new RegExp(escapeRegExp(word), "gu"))].map((match) => ({ start: match.index, end: match.index + word.length }));
|
|
25
|
+
|
|
26
|
+
/** 品詞が無ければ位置を語で言えないので、空白をまとめた文字列の位置で比べる。 */
|
|
27
|
+
const textTurnAfter = (sentence: Sentence, lead: LexiconEntry, words: ContrastWords): boolean => {
|
|
28
|
+
const text = comparableText(sentence);
|
|
29
|
+
const leads = words.leads.flatMap((entry) => rangesOf(text, lowered(entry)));
|
|
30
|
+
const turns = words.turns.flatMap((entry) => rangesOf(text, lowered(entry)));
|
|
31
|
+
return rangesOf(text, lowered(lead)).some((range) => answersAfter(range, turns, leads));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** 打ち消しの語より後ろに、返しの語があるか。打ち消しそのもの(it's not の it's)と、次の打ち消しの頭は返しに数えない。 */
|
|
35
|
+
const turnAfter = (sentence: Sentence, lead: LexiconEntry, words: ContrastWords): boolean => {
|
|
36
|
+
if (sentence.tokens === undefined || lead.tokens === undefined) return textTurnAfter(sentence, lead, words);
|
|
37
|
+
const leads = words.leads.flatMap((entry) => entryRanges(sentence, entry));
|
|
38
|
+
const turns = words.turns.flatMap((entry) => entryRanges(sentence, entry));
|
|
39
|
+
return entryRanges(sentence, lead).some((range) => answersAfter(range, turns, leads));
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** 次の文が返しの語で始まり、それ自体が打ち消しで始まっていないか。 */
|
|
43
|
+
const nextTurns = (next: Sentence | undefined, words: ContrastWords): boolean =>
|
|
44
|
+
next !== undefined && words.turns.some((turn) => entryOpens(next, turn)) && !words.leads.some((lead) => entryOpens(next, lead));
|
|
45
|
+
|
|
46
|
+
const answered = (sentence: Sentence, next: Sentence | undefined, words: ContrastWords): boolean =>
|
|
47
|
+
words.leads.some((lead) => entryIn(sentence, lead) && (turnAfter(sentence, lead, words) || nextTurns(next, words)));
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 対比の枠で書いた文。「X ではなく Y」「It's not X. It's Y.」の形で、打ち消した側の文を返す。
|
|
51
|
+
* 2 文にまたがる枠も 1 つと数える。返しの文は数えない。
|
|
52
|
+
*/
|
|
53
|
+
export const contrastSentences = (sentences: readonly Sentence[], words: ContrastWords): Sentence[] =>
|
|
54
|
+
sentences.filter((sentence, index) => words.frames.some((frame) => entryIn(sentence, frame)) || answered(sentence, sentences[index + 1], words));
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Detector, Finding, Sentence, Span } from "../plugin.ts";
|
|
2
|
+
import { occurrencesOutside } from "../orthography.ts";
|
|
3
|
+
import { tokenRuns } from "../custom/token-pattern.ts";
|
|
4
|
+
import { joinedView, type JoinedView } from "../joined-view.ts";
|
|
5
|
+
import { boundedMatches } from "../custom/bounded-match.ts";
|
|
6
|
+
|
|
7
|
+
// The detectors behind a team's custom_rules. Each reports every place it finds, at the rule's level; the spec comes from
|
|
8
|
+
// the rule (DetectorOptions.custom). Positions are the document's, like every other finding.
|
|
9
|
+
|
|
10
|
+
type Hit = { readonly sentence: Sentence; readonly offset: number; readonly matched: string; readonly preferred: string };
|
|
11
|
+
|
|
12
|
+
const findingOf = (hit: Hit): Finding => ({
|
|
13
|
+
rule: "",
|
|
14
|
+
severity: "warning",
|
|
15
|
+
line: 0,
|
|
16
|
+
column: 0,
|
|
17
|
+
quote: hit.sentence.text.trim(),
|
|
18
|
+
values: { matched: hit.matched, preferred: hit.preferred, offset: hit.sentence.span.start + hit.offset },
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The sentence with the line breaks that fall inside a word taken out (「関\nする」 reads 「関する」), so words and patterns
|
|
23
|
+
* are found as the reader reads them. Positions found in it go back to the sentence's own.
|
|
24
|
+
*/
|
|
25
|
+
const readAsWritten = (sentence: Sentence): JoinedView =>
|
|
26
|
+
joinedView(
|
|
27
|
+
sentence.text,
|
|
28
|
+
(sentence.wrapBreaks ?? []).map((span) => ({ start: span.start - sentence.span.start, end: span.end - sentence.span.start })),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
/** A match at [start, end) of the joined text, as a hit at the sentence's own position. */
|
|
32
|
+
const hitAt = (sentence: Sentence, view: JoinedView, start: number, end: number, preferred: string): Hit => ({
|
|
33
|
+
sentence,
|
|
34
|
+
offset: view.toSource({ start, end }).start,
|
|
35
|
+
matched: view.text.slice(start, end),
|
|
36
|
+
preferred,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/** source[start, end) with the line breaks inside words taken out: the text of a run of tokens as the reader reads it. */
|
|
40
|
+
const withoutBreaks = (source: string, start: number, end: number, breaks: readonly Span[]): string =>
|
|
41
|
+
breaks
|
|
42
|
+
.filter((span) => span.start >= start && span.end <= end)
|
|
43
|
+
.toReversed()
|
|
44
|
+
.reduce((text, span) => `${text.slice(0, span.start - start)}${text.slice(span.end - start)}`, source.slice(start, end));
|
|
45
|
+
|
|
46
|
+
/** words: each spelling to avoid, outside the spelling to use (「ユーザ」 inside 「ユーザー」 is not reported). */
|
|
47
|
+
export const customWords: Detector = (doc, options): Finding[] => {
|
|
48
|
+
const spec = options.custom;
|
|
49
|
+
if (spec?.type !== "words") return [];
|
|
50
|
+
return doc.sentences.flatMap((sentence) => {
|
|
51
|
+
const view = readAsWritten(sentence);
|
|
52
|
+
return spec.words.flatMap((pair) =>
|
|
53
|
+
occurrencesOutside(view.text, pair.avoid, pair.use).map((start) => findingOf(hitAt(sentence, view, start, start + pair.avoid.length, pair.use))),
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** pattern: each match of the team's regular expression in a sentence. Checked when chaff.yaml was read, and run with a time limit. */
|
|
59
|
+
export const customPattern: Detector = (doc, options): Finding[] => {
|
|
60
|
+
const spec = options.custom;
|
|
61
|
+
if (spec?.type !== "pattern") return [];
|
|
62
|
+
const views = doc.sentences.map(readAsWritten);
|
|
63
|
+
const matches = boundedMatches(
|
|
64
|
+
spec.pattern,
|
|
65
|
+
spec.flags,
|
|
66
|
+
views.map((view) => view.text),
|
|
67
|
+
);
|
|
68
|
+
return doc.sentences.flatMap((sentence, at) => {
|
|
69
|
+
const view = views[at];
|
|
70
|
+
if (view === undefined) return [];
|
|
71
|
+
return (matches[at] ?? []).map((match) => findingOf(hitAt(sentence, view, match.index, match.index + match.text.length, "")));
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** tokens: each run of tokens that meets the conditions in order, quoted from its first token to its last, line breaks inside words taken out. */
|
|
76
|
+
export const customTokens: Detector = (doc, options): Finding[] => {
|
|
77
|
+
const spec = options.custom;
|
|
78
|
+
if (spec?.type !== "tokens") return [];
|
|
79
|
+
return doc.sentences.flatMap((sentence) => {
|
|
80
|
+
const tokens = sentence.tokens ?? [];
|
|
81
|
+
return tokenRuns(tokens, spec.tokens).flatMap(([first, last]) => {
|
|
82
|
+
const [start, end] = [tokens[first]?.span.start, tokens[last]?.span.end];
|
|
83
|
+
if (start === undefined || end === undefined) return [];
|
|
84
|
+
return [
|
|
85
|
+
findingOf({ sentence, offset: start - sentence.span.start, matched: withoutBreaks(doc.source, start, end, sentence.wrapBreaks ?? []), preferred: "" }),
|
|
86
|
+
];
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Detector, Finding, ProseDocument } from "../plugin.ts";
|
|
2
|
+
import { danglingFigures, type LabelWords } from "../figure-references.ts";
|
|
3
|
+
import { quoteAt } from "./structure-tree.ts";
|
|
4
|
+
|
|
5
|
+
const patternsOf = (doc: ProseDocument, id: string): string[] => (doc.lexicons[id] ?? []).map((entry) => entry.pattern);
|
|
6
|
+
|
|
7
|
+
const labelWordsOf = (doc: ProseDocument): LabelWords => ({
|
|
8
|
+
labels: (doc.lexicons["figure-label"] ?? []).map((entry) => ({ word: entry.pattern, kind: entry.instead_of ?? entry.pattern })),
|
|
9
|
+
elsewhere: patternsOf(doc, "figure-elsewhere"),
|
|
10
|
+
counters: patternsOf(doc, "count-counter"),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/** 本文が指す図・表・付録の番号が、キャプションにも見出しにも無い。 */
|
|
14
|
+
export const danglingFigure: Detector = (doc): Finding[] =>
|
|
15
|
+
danglingFigures(doc.source, doc.prose ?? doc.source, labelWordsOf(doc), doc.links).map((dangling) => ({
|
|
16
|
+
rule: "dangling-figure-reference",
|
|
17
|
+
severity: "warning",
|
|
18
|
+
line: 0,
|
|
19
|
+
column: 0,
|
|
20
|
+
quote: quoteAt(doc.source, dangling.offset),
|
|
21
|
+
values: { label: dangling.label, offset: dangling.offset },
|
|
22
|
+
}));
|