slopless 0.2.5 → 0.2.7

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.
Files changed (283) hide show
  1. package/README.md +43 -124
  2. package/dist/adapters/textlint/report.js +51 -0
  3. package/dist/adapters/textlint/report.js.map +1 -0
  4. package/dist/adapters/textlint/units.js +28 -0
  5. package/dist/adapters/textlint/units.js.map +1 -0
  6. package/dist/cli.js +77 -5
  7. package/dist/cli.js.map +1 -1
  8. package/dist/index.js +4 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/presets/everything.js +8 -1
  11. package/dist/presets/everything.js.map +1 -1
  12. package/dist/registries/academic-slop.js +5 -0
  13. package/dist/registries/academic-slop.js.map +1 -0
  14. package/dist/registries/metrics.js +6 -6
  15. package/dist/registries/metrics.js.map +1 -1
  16. package/dist/registries/narrative-slop.js +11 -0
  17. package/dist/registries/narrative-slop.js.map +1 -0
  18. package/dist/registries/orthography.js +6 -6
  19. package/dist/registries/orthography.js.map +1 -1
  20. package/dist/registries/phrases.js +13 -9
  21. package/dist/registries/phrases.js.map +1 -1
  22. package/dist/registries/semantic-thinness.js +1 -1
  23. package/dist/registries/semantic-thinness.js.map +1 -1
  24. package/dist/registries/syntactic-patterns/authority.js +1 -1
  25. package/dist/registries/syntactic-patterns/authority.js.map +1 -1
  26. package/dist/registries/syntactic-patterns/closers.js +4 -4
  27. package/dist/registries/syntactic-patterns/closers.js.map +1 -1
  28. package/dist/registries/syntactic-patterns/contrast.js +3 -3
  29. package/dist/registries/syntactic-patterns/contrast.js.map +1 -1
  30. package/dist/registries/syntactic-patterns/generalization.js +2 -2
  31. package/dist/registries/syntactic-patterns/generalization.js.map +1 -1
  32. package/dist/registries/syntactic-patterns/lead-ins.js +5 -5
  33. package/dist/registries/syntactic-patterns/lead-ins.js.map +1 -1
  34. package/dist/registries/syntactic-patterns/llm-artifacts.js +1 -1
  35. package/dist/registries/syntactic-patterns/llm-artifacts.js.map +1 -1
  36. package/dist/registries/syntactic-patterns/repetition.js +4 -4
  37. package/dist/registries/syntactic-patterns/repetition.js.map +1 -1
  38. package/dist/registries/term-policy.js +2 -2
  39. package/dist/registries/term-policy.js.map +1 -1
  40. package/dist/registries/words.js +4 -4
  41. package/dist/registries/words.js.map +1 -1
  42. package/dist/reporting/reports.js +92 -0
  43. package/dist/reporting/reports.js.map +1 -0
  44. package/dist/reporting/types.js +2 -0
  45. package/dist/reporting/types.js.map +1 -0
  46. package/dist/rules/academic-slop/data/tortured-phrases.json +8 -0
  47. package/dist/rules/academic-slop/tortured-phrases.js +27 -0
  48. package/dist/rules/academic-slop/tortured-phrases.js.map +1 -0
  49. package/dist/{families → rules}/metrics/avg-sentence-length.js +8 -4
  50. package/dist/rules/metrics/avg-sentence-length.js.map +1 -0
  51. package/dist/{families → rules}/metrics/coleman-liau.js +8 -4
  52. package/dist/rules/metrics/coleman-liau.js.map +1 -0
  53. package/dist/{families → rules}/metrics/flesch-kincaid.js +8 -4
  54. package/dist/rules/metrics/flesch-kincaid.js.map +1 -0
  55. package/dist/{families → rules}/metrics/gunning-fog.js +8 -4
  56. package/dist/rules/metrics/gunning-fog.js.map +1 -0
  57. package/dist/rules/metrics/paragraph-length.js +25 -0
  58. package/dist/rules/metrics/paragraph-length.js.map +1 -0
  59. package/dist/{families → rules}/metrics/word-repetition.js +8 -4
  60. package/dist/rules/metrics/word-repetition.js.map +1 -0
  61. package/dist/rules/narrative-slop/body-action-density.js +198 -0
  62. package/dist/rules/narrative-slop/body-action-density.js.map +1 -0
  63. package/dist/rules/narrative-slop/data/narrative-cliches.json +134 -0
  64. package/dist/rules/narrative-slop/flat-action-cadence.js +322 -0
  65. package/dist/rules/narrative-slop/flat-action-cadence.js.map +1 -0
  66. package/dist/rules/narrative-slop/narrative-cliches.js +46 -0
  67. package/dist/rules/narrative-slop/narrative-cliches.js.map +1 -0
  68. package/dist/rules/narrative-slop/perception-verb-density.js +84 -0
  69. package/dist/rules/narrative-slop/perception-verb-density.js.map +1 -0
  70. package/dist/{families → rules}/orthography/colon-dramatic.js +11 -7
  71. package/dist/rules/orthography/colon-dramatic.js.map +1 -0
  72. package/dist/{families → rules}/orthography/em-dashes.js +11 -7
  73. package/dist/rules/orthography/em-dashes.js.map +1 -0
  74. package/dist/{families → rules}/orthography/exclamation-density.js +11 -7
  75. package/dist/rules/orthography/exclamation-density.js.map +1 -0
  76. package/dist/{families → rules}/orthography/fake-timestamps.js +11 -7
  77. package/dist/rules/orthography/fake-timestamps.js.map +1 -0
  78. package/dist/{families → rules}/orthography/sentence-case.js +7 -2
  79. package/dist/rules/orthography/sentence-case.js.map +1 -0
  80. package/dist/{families → rules}/orthography/smart-quotes.js +11 -7
  81. package/dist/rules/orthography/smart-quotes.js.map +1 -0
  82. package/dist/rules/phrases/cliches.js +43 -0
  83. package/dist/rules/phrases/cliches.js.map +1 -0
  84. package/dist/rules/phrases/corporate-speak.js +32 -0
  85. package/dist/rules/phrases/corporate-speak.js.map +1 -0
  86. package/dist/rules/phrases/data/cliche-templates.json +20 -0
  87. package/dist/{families → rules}/phrases/data/cliches.json +73 -1
  88. package/dist/rules/phrases/data/corporate-abstraction-patterns.json +80 -0
  89. package/dist/{families → rules}/phrases/data/corporate-speak.json +0 -3
  90. package/dist/rules/phrases/data/llm-disclaimer-expansions.json +4 -0
  91. package/dist/{families → rules}/phrases/data/prohibited-phrases.json +0 -1
  92. package/dist/rules/phrases/data/redundancy-patterns.json +74 -0
  93. package/dist/rules/phrases/data/wordiness-patterns.json +53 -0
  94. package/dist/rules/phrases/humble-bragger.js +30 -0
  95. package/dist/rules/phrases/humble-bragger.js.map +1 -0
  96. package/dist/{families → rules}/phrases/jargon-faker.js +11 -7
  97. package/dist/rules/phrases/jargon-faker.js.map +1 -0
  98. package/dist/{families → rules}/phrases/llm-disclaimer.js +21 -8
  99. package/dist/rules/phrases/llm-disclaimer.js.map +1 -0
  100. package/dist/rules/phrases/prohibited-phrases.js +27 -0
  101. package/dist/rules/phrases/prohibited-phrases.js.map +1 -0
  102. package/dist/rules/phrases/redundancy.js +27 -0
  103. package/dist/rules/phrases/redundancy.js.map +1 -0
  104. package/dist/{families → rules}/phrases/skunked-terms.js +8 -4
  105. package/dist/rules/phrases/skunked-terms.js.map +1 -0
  106. package/dist/{families → rules}/phrases/uncomparables.js +8 -4
  107. package/dist/rules/phrases/uncomparables.js.map +1 -0
  108. package/dist/rules/phrases/wordiness.js +27 -0
  109. package/dist/rules/phrases/wordiness.js.map +1 -0
  110. package/dist/rules/semantic-thinness/patterns/abstract-personification-line.json +23 -0
  111. package/dist/rules/semantic-thinness/patterns/emotion-as-substance.json +95 -0
  112. package/dist/rules/semantic-thinness/patterns/fixed-metaphor-frame.json +32 -0
  113. package/dist/rules/semantic-thinness/patterns/sensory-instead-of-frame.json +40 -0
  114. package/dist/rules/semantic-thinness/patterns/summary-fog-transition.json +30 -0
  115. package/dist/{families → rules}/semantic-thinness/private/pattern-data-a.js +2 -0
  116. package/dist/rules/semantic-thinness/private/pattern-data-a.js.map +1 -0
  117. package/dist/rules/semantic-thinness/private/pattern-data-b.js.map +1 -0
  118. package/dist/rules/semantic-thinness/private/pattern-data-c.js +17 -0
  119. package/dist/rules/semantic-thinness/private/pattern-data-c.js.map +1 -0
  120. package/dist/rules/semantic-thinness/private/pattern-data-d.js.map +1 -0
  121. package/dist/rules/semantic-thinness/private/pattern-data.js.map +1 -0
  122. package/dist/rules/semantic-thinness/private/pattern-matcher.js.map +1 -0
  123. package/dist/{families → rules}/semantic-thinness/semantic-thinness.js +11 -7
  124. package/dist/rules/semantic-thinness/semantic-thinness.js.map +1 -0
  125. package/dist/{families → rules}/syntactic-patterns/authority/authority-padding.js +11 -7
  126. package/dist/rules/syntactic-patterns/authority/authority-padding.js.map +1 -0
  127. package/dist/{families → rules}/syntactic-patterns/closers/affirmation-closers.js +20 -13
  128. package/dist/rules/syntactic-patterns/closers/affirmation-closers.js.map +1 -0
  129. package/dist/{families → rules}/syntactic-patterns/closers/boilerplate-conclusion.js +11 -7
  130. package/dist/rules/syntactic-patterns/closers/boilerplate-conclusion.js.map +1 -0
  131. package/dist/{families → rules}/syntactic-patterns/closers/false-question.js +11 -7
  132. package/dist/rules/syntactic-patterns/closers/false-question.js.map +1 -0
  133. package/dist/{families → rules}/syntactic-patterns/closers/summative-closer.js +11 -7
  134. package/dist/rules/syntactic-patterns/closers/summative-closer.js.map +1 -0
  135. package/dist/{families → rules}/syntactic-patterns/contrast/blame-reframe.js +11 -7
  136. package/dist/rules/syntactic-patterns/contrast/blame-reframe.js.map +1 -0
  137. package/dist/{families → rules}/syntactic-patterns/contrast/contrastive-aphorism.js +10 -7
  138. package/dist/rules/syntactic-patterns/contrast/contrastive-aphorism.js.map +1 -0
  139. package/dist/rules/syntactic-patterns/contrast/negation-reframe.js +24 -0
  140. package/dist/rules/syntactic-patterns/contrast/negation-reframe.js.map +1 -0
  141. package/dist/{families → rules}/syntactic-patterns/contrast/private/negation-reframe-matcher.js +22 -5
  142. package/dist/rules/syntactic-patterns/contrast/private/negation-reframe-matcher.js.map +1 -0
  143. package/dist/{families → rules}/syntactic-patterns/contrast/private/negation-reframe-parts.js +55 -0
  144. package/dist/rules/syntactic-patterns/contrast/private/negation-reframe-parts.js.map +1 -0
  145. package/dist/rules/syntactic-patterns/contrast/private/negative-slop-frames.js +103 -0
  146. package/dist/rules/syntactic-patterns/contrast/private/negative-slop-frames.js.map +1 -0
  147. package/dist/{families → rules}/syntactic-patterns/generalization/softening-language.js +11 -7
  148. package/dist/rules/syntactic-patterns/generalization/softening-language.js.map +1 -0
  149. package/dist/{families → rules}/syntactic-patterns/generalization/universalizing-claims.js +11 -7
  150. package/dist/rules/syntactic-patterns/generalization/universalizing-claims.js.map +1 -0
  151. package/dist/{families → rules}/syntactic-patterns/lead-ins/boilerplate-framing.js +11 -7
  152. package/dist/rules/syntactic-patterns/lead-ins/boilerplate-framing.js.map +1 -0
  153. package/dist/{families → rules}/syntactic-patterns/lead-ins/generic-signposting.js +11 -7
  154. package/dist/rules/syntactic-patterns/lead-ins/generic-signposting.js.map +1 -0
  155. package/dist/{families → rules}/syntactic-patterns/lead-ins/lesson-framing.js +11 -7
  156. package/dist/rules/syntactic-patterns/lead-ins/lesson-framing.js.map +1 -0
  157. package/dist/rules/syntactic-patterns/lead-ins/llm-openers.js +28 -0
  158. package/dist/rules/syntactic-patterns/lead-ins/llm-openers.js.map +1 -0
  159. package/dist/{families → rules}/syntactic-patterns/lead-ins/observer-guidance.js +11 -7
  160. package/dist/rules/syntactic-patterns/lead-ins/observer-guidance.js.map +1 -0
  161. package/dist/rules/syntactic-patterns/llm-artifacts/data/response-wrapper-patterns.json +33 -0
  162. package/dist/{families → rules}/syntactic-patterns/llm-artifacts/response-wrapper.js +55 -10
  163. package/dist/rules/syntactic-patterns/llm-artifacts/response-wrapper.js.map +1 -0
  164. package/dist/{families → rules}/syntactic-patterns/repetition/demonstrative-emphasis.js +11 -7
  165. package/dist/rules/syntactic-patterns/repetition/demonstrative-emphasis.js.map +1 -0
  166. package/dist/{families → rules}/syntactic-patterns/repetition/empty-emphasis.js +11 -7
  167. package/dist/rules/syntactic-patterns/repetition/empty-emphasis.js.map +1 -0
  168. package/dist/{families → rules}/syntactic-patterns/repetition/fragment-stacking.js +11 -7
  169. package/dist/rules/syntactic-patterns/repetition/fragment-stacking.js.map +1 -0
  170. package/dist/{families → rules}/syntactic-patterns/repetition/triple-repeat.js +13 -9
  171. package/dist/rules/syntactic-patterns/repetition/triple-repeat.js.map +1 -0
  172. package/dist/{families → rules}/term-policy/recommended-terms.js +8 -4
  173. package/dist/rules/term-policy/recommended-terms.js.map +1 -0
  174. package/dist/{families → rules}/term-policy/required-terms.js +8 -4
  175. package/dist/rules/term-policy/required-terms.js.map +1 -0
  176. package/dist/rules/types.js +2 -0
  177. package/dist/rules/types.js.map +1 -0
  178. package/dist/{families → rules}/words/hedge-stacking.js +11 -7
  179. package/dist/rules/words/hedge-stacking.js.map +1 -0
  180. package/dist/{families → rules}/words/llm-vocabulary.js +8 -4
  181. package/dist/rules/words/llm-vocabulary.js.map +1 -0
  182. package/dist/rules/words/prohibited-words.js +21 -0
  183. package/dist/rules/words/prohibited-words.js.map +1 -0
  184. package/dist/{families → rules}/words/simplicity.js +11 -7
  185. package/dist/rules/words/simplicity.js.map +1 -0
  186. package/dist/shared/matchers/phrases.js +74 -0
  187. package/dist/shared/matchers/phrases.js.map +1 -1
  188. package/package.json +57 -49
  189. package/skills/slopless/SKILL.md +63 -0
  190. package/dist/families/metrics/avg-sentence-length.js.map +0 -1
  191. package/dist/families/metrics/coleman-liau.js.map +0 -1
  192. package/dist/families/metrics/flesch-kincaid.js.map +0 -1
  193. package/dist/families/metrics/gunning-fog.js.map +0 -1
  194. package/dist/families/metrics/paragraph-length.js +0 -21
  195. package/dist/families/metrics/paragraph-length.js.map +0 -1
  196. package/dist/families/metrics/word-repetition.js.map +0 -1
  197. package/dist/families/orthography/colon-dramatic.js.map +0 -1
  198. package/dist/families/orthography/em-dashes.js.map +0 -1
  199. package/dist/families/orthography/exclamation-density.js.map +0 -1
  200. package/dist/families/orthography/fake-timestamps.js.map +0 -1
  201. package/dist/families/orthography/sentence-case.js.map +0 -1
  202. package/dist/families/orthography/smart-quotes.js.map +0 -1
  203. package/dist/families/phrases/cliches.js +0 -17
  204. package/dist/families/phrases/cliches.js.map +0 -1
  205. package/dist/families/phrases/corporate-speak.js +0 -23
  206. package/dist/families/phrases/corporate-speak.js.map +0 -1
  207. package/dist/families/phrases/humble-bragger.js +0 -26
  208. package/dist/families/phrases/humble-bragger.js.map +0 -1
  209. package/dist/families/phrases/jargon-faker.js.map +0 -1
  210. package/dist/families/phrases/llm-disclaimer.js.map +0 -1
  211. package/dist/families/phrases/prohibited-phrases.js +0 -17
  212. package/dist/families/phrases/prohibited-phrases.js.map +0 -1
  213. package/dist/families/phrases/skunked-terms.js.map +0 -1
  214. package/dist/families/phrases/uncomparables.js.map +0 -1
  215. package/dist/families/semantic-thinness/private/pattern-data-a.js.map +0 -1
  216. package/dist/families/semantic-thinness/private/pattern-data-b.js.map +0 -1
  217. package/dist/families/semantic-thinness/private/pattern-data-c.js +0 -9
  218. package/dist/families/semantic-thinness/private/pattern-data-c.js.map +0 -1
  219. package/dist/families/semantic-thinness/private/pattern-data-d.js.map +0 -1
  220. package/dist/families/semantic-thinness/private/pattern-data.js.map +0 -1
  221. package/dist/families/semantic-thinness/private/pattern-matcher.js.map +0 -1
  222. package/dist/families/semantic-thinness/semantic-thinness.js.map +0 -1
  223. package/dist/families/syntactic-patterns/authority/authority-padding.js.map +0 -1
  224. package/dist/families/syntactic-patterns/closers/affirmation-closers.js.map +0 -1
  225. package/dist/families/syntactic-patterns/closers/boilerplate-conclusion.js.map +0 -1
  226. package/dist/families/syntactic-patterns/closers/false-question.js.map +0 -1
  227. package/dist/families/syntactic-patterns/closers/summative-closer.js.map +0 -1
  228. package/dist/families/syntactic-patterns/contrast/blame-reframe.js.map +0 -1
  229. package/dist/families/syntactic-patterns/contrast/contrastive-aphorism.js.map +0 -1
  230. package/dist/families/syntactic-patterns/contrast/negation-reframe.js +0 -20
  231. package/dist/families/syntactic-patterns/contrast/negation-reframe.js.map +0 -1
  232. package/dist/families/syntactic-patterns/contrast/private/negation-reframe-matcher.js.map +0 -1
  233. package/dist/families/syntactic-patterns/contrast/private/negation-reframe-parts.js.map +0 -1
  234. package/dist/families/syntactic-patterns/generalization/softening-language.js.map +0 -1
  235. package/dist/families/syntactic-patterns/generalization/universalizing-claims.js.map +0 -1
  236. package/dist/families/syntactic-patterns/lead-ins/boilerplate-framing.js.map +0 -1
  237. package/dist/families/syntactic-patterns/lead-ins/generic-signposting.js.map +0 -1
  238. package/dist/families/syntactic-patterns/lead-ins/lesson-framing.js.map +0 -1
  239. package/dist/families/syntactic-patterns/lead-ins/llm-openers.js +0 -24
  240. package/dist/families/syntactic-patterns/lead-ins/llm-openers.js.map +0 -1
  241. package/dist/families/syntactic-patterns/lead-ins/observer-guidance.js.map +0 -1
  242. package/dist/families/syntactic-patterns/llm-artifacts/response-wrapper.js.map +0 -1
  243. package/dist/families/syntactic-patterns/repetition/demonstrative-emphasis.js.map +0 -1
  244. package/dist/families/syntactic-patterns/repetition/empty-emphasis.js.map +0 -1
  245. package/dist/families/syntactic-patterns/repetition/fragment-stacking.js.map +0 -1
  246. package/dist/families/syntactic-patterns/repetition/triple-repeat.js.map +0 -1
  247. package/dist/families/term-policy/recommended-terms.js.map +0 -1
  248. package/dist/families/term-policy/required-terms.js.map +0 -1
  249. package/dist/families/words/hedge-stacking.js.map +0 -1
  250. package/dist/families/words/llm-vocabulary.js.map +0 -1
  251. package/dist/families/words/prohibited-words.js +0 -17
  252. package/dist/families/words/prohibited-words.js.map +0 -1
  253. package/dist/families/words/simplicity.js.map +0 -1
  254. /package/dist/{families → rules}/phrases/data/skunked-terms.json +0 -0
  255. /package/dist/{families → rules}/phrases/data/uncomparables.json +0 -0
  256. /package/dist/{families → rules}/semantic-thinness/patterns/abstract-contrast.json +0 -0
  257. /package/dist/{families → rules}/semantic-thinness/patterns/abstract-metaphor-claim.json +0 -0
  258. /package/dist/{families → rules}/semantic-thinness/patterns/body-emotion-shorthand.json +0 -0
  259. /package/dist/{families → rules}/semantic-thinness/patterns/body-knows.json +0 -0
  260. /package/dist/{families → rules}/semantic-thinness/patterns/deictic-summary.json +0 -0
  261. /package/dist/{families → rules}/semantic-thinness/patterns/empty-atmosphere-shift.json +0 -0
  262. /package/dist/{families → rules}/semantic-thinness/patterns/empty-emotional-weather.json +0 -0
  263. /package/dist/{families → rules}/semantic-thinness/patterns/empty-scene-state.json +0 -0
  264. /package/dist/{families → rules}/semantic-thinness/patterns/empty-scene-transition.json +0 -0
  265. /package/dist/{families → rules}/semantic-thinness/patterns/gaze-choreography.json +0 -0
  266. /package/dist/{families → rules}/semantic-thinness/patterns/generic-lesson-extraction.json +0 -0
  267. /package/dist/{families → rules}/semantic-thinness/patterns/generic-pressure-or-stakes.json +0 -0
  268. /package/dist/{families → rules}/semantic-thinness/patterns/generic-realization.json +0 -0
  269. /package/dist/{families → rules}/semantic-thinness/patterns/hollow-significance.json +0 -0
  270. /package/dist/{families → rules}/semantic-thinness/patterns/low-information-physical-blocking.json +0 -0
  271. /package/dist/{families → rules}/semantic-thinness/patterns/point-is-frame.json +0 -0
  272. /package/dist/{families → rules}/semantic-thinness/patterns/real-work-begins.json +0 -0
  273. /package/dist/{families → rules}/semantic-thinness/patterns/silence-as-actor.json +0 -0
  274. /package/dist/{families → rules}/semantic-thinness/patterns/something-shifted.json +0 -0
  275. /package/dist/{families → rules}/semantic-thinness/patterns/truth-answer-moves.json +0 -0
  276. /package/dist/{families → rules}/semantic-thinness/patterns/vague-connective-payoff.json +0 -0
  277. /package/dist/{families → rules}/semantic-thinness/patterns/vague-threshold-change.json +0 -0
  278. /package/dist/{families → rules}/semantic-thinness/private/pattern-data-b.js +0 -0
  279. /package/dist/{families → rules}/semantic-thinness/private/pattern-data-d.js +0 -0
  280. /package/dist/{families → rules}/semantic-thinness/private/pattern-data.js +0 -0
  281. /package/dist/{families → rules}/semantic-thinness/private/pattern-matcher.js +0 -0
  282. /package/dist/{families → rules}/words/data/prohibited-words.json +0 -0
  283. /package/dist/{families → rules}/words/data/simplicity-pairs.json +0 -0
@@ -0,0 +1,46 @@
1
+ import { findUnquotedTokenTemplateMatches } from "../../shared/matchers/phrases.js";
2
+ import { allParagraphSentences } from "../../shared/text/sections.js";
3
+ import { wordTokens } from "../../shared/text/tokens.js";
4
+ import narrativeClichePatterns from "./data/narrative-cliches.json" with { type: "json" };
5
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
6
+ const NARRATIVE_CLICHE_PATTERNS = narrativeClichePatterns;
7
+ const PATTERNS_BY_ID = new Map(NARRATIVE_CLICHE_PATTERNS.map((pattern) => [pattern.id, pattern]));
8
+ const CONCRETE_CAUSE_MARKERS = [" because ", " since "];
9
+ function hasConcreteCause(sentence) {
10
+ const normalized = ` ${sentence.toLocaleLowerCase("en")} `;
11
+ return CONCRETE_CAUSE_MARKERS.some((marker) => normalized.includes(marker));
12
+ }
13
+ const rule = (context) => {
14
+ const { Syntax } = context;
15
+ return {
16
+ [Syntax.Document](node) {
17
+ for (const item of allParagraphSentences(node)) {
18
+ if (wordTokens(item.sentence.text).length > 80) {
19
+ continue;
20
+ }
21
+ if (hasConcreteCause(item.sentence.text)) {
22
+ continue;
23
+ }
24
+ const match = findUnquotedTokenTemplateMatches(item.sentence.text, NARRATIVE_CLICHE_PATTERNS)[0];
25
+ if (match === undefined) {
26
+ continue;
27
+ }
28
+ const pattern = PATTERNS_BY_ID.get(match.patternId);
29
+ if (pattern === undefined) {
30
+ continue;
31
+ }
32
+ emitTextlintFinding(context, {
33
+ node: item.paragraph,
34
+ ruleId: "narrative-slop:narrative-cliches",
35
+ message: `Narrative cliche (${pattern.category}/${match.patternId}): ${pattern.purpose} Matched template: ${match.template}`,
36
+ range: {
37
+ start: item.source.originalStartFor(item.sentence.start + match.start),
38
+ end: item.source.originalEndFor(item.sentence.start + match.end)
39
+ }
40
+ });
41
+ }
42
+ }
43
+ };
44
+ };
45
+ export default rule;
46
+ //# sourceMappingURL=narrative-cliches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrative-cliches.js","sourceRoot":"","sources":["../../../src/rules/narrative-slop/narrative-cliches.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,gCAAgC,EAEjC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,uBAAuB,MAAM,+BAA+B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAOxE,MAAM,yBAAyB,GAC7B,uBAA4D,CAAC;AAE/D,MAAM,cAAc,GAAG,IAAI,GAAG,CAC5B,yBAAyB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAClE,CAAC;AACF,MAAM,sBAAsB,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAExD,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,UAAU,GAAG,IAAI,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;IAC3D,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,IAAI,GAAuB,CAAC,OAAO,EAAE,EAAE;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,OAAO;QACL,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAqB;YACrC,KAAK,MAAM,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/C,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;oBAC/C,SAAS;gBACX,CAAC;gBAED,IAAI,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzC,SAAS;gBACX,CAAC;gBAED,MAAM,KAAK,GAAG,gCAAgC,CAC5C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAClB,yBAAyB,CAC1B,CAAC,CAAC,CAAC,CAAC;gBACL,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,SAAS;gBACX,CAAC;gBAED,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBACpD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,SAAS;gBACX,CAAC;gBAED,mBAAmB,CAAC,OAAO,EAAE;oBAC3B,IAAI,EAAE,IAAI,CAAC,SAAS;oBACpB,MAAM,EAAE,kCAAkC;oBAC1C,OAAO,EAAE,qBAAqB,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,MAAM,OAAO,CAAC,OAAO,sBAAsB,KAAK,CAAC,QAAQ,EAAE;oBAC5H,KAAK,EAAE;wBACL,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CACjC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAClC;wBACD,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC;qBACjE;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,84 @@
1
+ import { emitTextlintReports } from "../../adapters/textlint/report.js";
2
+ import { paragraphUnits } from "../../adapters/textlint/units.js";
3
+ import { densityReports } from "../../reporting/reports.js";
4
+ import { wordTokens } from "../../shared/text/tokens.js";
5
+ const PERCEPTION_VERBS = new Set([
6
+ "look",
7
+ "looks",
8
+ "looked",
9
+ "looking",
10
+ "watch",
11
+ "watches",
12
+ "watched",
13
+ "watching",
14
+ "stare",
15
+ "stares",
16
+ "stared",
17
+ "staring",
18
+ "gaze",
19
+ "gazes",
20
+ "gazed",
21
+ "gazing",
22
+ "glance",
23
+ "glances",
24
+ "glanced",
25
+ "glancing",
26
+ "observe",
27
+ "observes",
28
+ "observed",
29
+ "observing"
30
+ ]);
31
+ const PURPOSE_LOOK_PARTICLES = new Set(["for", "up", "under", "into"]);
32
+ const MAX_PARAGRAPH_TOKENS = 80;
33
+ const MAX_WINDOW_TOKENS = 45;
34
+ const MIN_PARAGRAPH_HITS = 3;
35
+ const MIN_WINDOW_HITS = 2;
36
+ const WINDOW_SENTENCES = 3;
37
+ const GROUP = "perception verb";
38
+ const RULE_ID = "narrative-slop:perception-verb-density";
39
+ function isPurposeLook(tokens, index) {
40
+ const token = tokens[index];
41
+ const next = tokens[index + 1];
42
+ return (token !== undefined &&
43
+ token.normalized.startsWith("look") &&
44
+ next !== undefined &&
45
+ PURPOSE_LOOK_PARTICLES.has(next.normalized));
46
+ }
47
+ function perceptionDetections(unit) {
48
+ const tokens = wordTokens(unit.text);
49
+ return tokens
50
+ .filter((token, index) => {
51
+ return (PERCEPTION_VERBS.has(token.normalized) && !isPurposeLook(tokens, index));
52
+ })
53
+ .map((token) => ({
54
+ evidence: unit.text.slice(token.start, token.end),
55
+ group: GROUP,
56
+ label: token.normalized,
57
+ range: { end: token.end, start: token.start },
58
+ ruleId: RULE_ID,
59
+ unitId: unit.id
60
+ }));
61
+ }
62
+ const rule = (context) => {
63
+ const { Syntax } = context;
64
+ return {
65
+ [Syntax.Document](node) {
66
+ const units = paragraphUnits(node);
67
+ const unitsById = new Map(units.map((unit) => [unit.id, unit]));
68
+ for (const unit of units) {
69
+ const reports = densityReports(unit, perceptionDetections(unit), {
70
+ groups: [GROUP],
71
+ maxParagraphTokens: MAX_PARAGRAPH_TOKENS,
72
+ maxWindowTokens: MAX_WINDOW_TOKENS,
73
+ message: (match) => `Perception verb density: ${match.count} perception verbs in a short span (${match.labels.join(", ")}).`,
74
+ paragraphMinimumHits: MIN_PARAGRAPH_HITS,
75
+ windowMinimumHits: MIN_WINDOW_HITS,
76
+ windowSentences: WINDOW_SENTENCES
77
+ });
78
+ emitTextlintReports(context, unitsById, reports);
79
+ }
80
+ }
81
+ };
82
+ };
83
+ export default rule;
84
+ //# sourceMappingURL=perception-verb-density.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perception-verb-density.js","sourceRoot":"","sources":["../../../src/rules/narrative-slop/perception-verb-density.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { RuleHelper } from "textlint-rule-helper";
2
2
  import { sourceText } from "../../shared/text/traverse.js";
3
3
  import { countWhitespaceSeparatedWords } from "../../shared/text/whitespace.js";
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
4
5
  const MAX_DRAMATIC_AFTER_COLON_WORDS = 5;
5
6
  function firstNonWhitespaceIndex(text) {
6
7
  for (let index = 0; index < text.length; index += 1) {
@@ -88,7 +89,7 @@ function findDramaticColonMatches(text) {
88
89
  return matches;
89
90
  }
90
91
  const rule = (context) => {
91
- const { Syntax, RuleError, locator, report } = context;
92
+ const { Syntax } = context;
92
93
  const helper = new RuleHelper(context);
93
94
  const ignoredParents = [
94
95
  Syntax.List,
@@ -103,12 +104,15 @@ const rule = (context) => {
103
104
  }
104
105
  const source = sourceText(node);
105
106
  for (const match of findDramaticColonMatches(source.text)) {
106
- report(node, new RuleError(`Dramatic colon found: "${match.text}". Rewrite without the short reveal after the colon.`, {
107
- padding: locator.range([
108
- source.originalStartFor(match.start),
109
- source.originalEndFor(match.end)
110
- ])
111
- }));
107
+ emitTextlintFinding(context, {
108
+ node: node,
109
+ ruleId: "orthography:colon-dramatic",
110
+ message: `Dramatic colon found: "${match.text}". Rewrite without the short reveal after the colon.`,
111
+ range: {
112
+ start: source.originalStartFor(match.start),
113
+ end: source.originalEndFor(match.end)
114
+ }
115
+ });
112
116
  }
113
117
  }
114
118
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colon-dramatic.js","sourceRoot":"","sources":["../../../src/rules/orthography/colon-dramatic.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { RuleHelper } from "textlint-rule-helper";
2
2
  import { sourceText } from "../../shared/text/traverse.js";
3
3
  import { isWhitespace } from "../../shared/text/whitespace.js";
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
4
5
  const CLOSED_EM_DASH = "\u2014";
5
6
  function isClosedEmDash(text, index) {
6
7
  if (text[index] !== CLOSED_EM_DASH) {
@@ -9,7 +10,7 @@ function isClosedEmDash(text, index) {
9
10
  return !isWhitespace(text[index - 1]) && !isWhitespace(text[index + 1]);
10
11
  }
11
12
  const rule = (context) => {
12
- const { Syntax, RuleError, locator, report } = context;
13
+ const { Syntax } = context;
13
14
  const helper = new RuleHelper(context);
14
15
  const ignoredParents = [
15
16
  Syntax.List,
@@ -27,12 +28,15 @@ const rule = (context) => {
27
28
  if (!isClosedEmDash(source.text, index)) {
28
29
  continue;
29
30
  }
30
- report(node, new RuleError("Closed em dash found. Replace it with a comma, colon, parenthesis, or spaced dash.", {
31
- padding: locator.range([
32
- source.originalStartFor(index),
33
- source.originalEndFor(index + CLOSED_EM_DASH.length)
34
- ])
35
- }));
31
+ emitTextlintFinding(context, {
32
+ node: node,
33
+ ruleId: "orthography:em-dashes",
34
+ message: "Closed em dash found. Replace it with a comma, colon, parenthesis, or spaced dash.",
35
+ range: {
36
+ start: source.originalStartFor(index),
37
+ end: source.originalEndFor(index + CLOSED_EM_DASH.length)
38
+ }
39
+ });
36
40
  }
37
41
  }
38
42
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"em-dashes.js","sourceRoot":"","sources":["../../../src/rules/orthography/em-dashes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEhC,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,cAAc,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,IAAI,GAAuB,CAAC,OAAO,EAAE,EAAE;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG;QACrB,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,SAAS;KACjB,CAAC;IAEF,OAAO;QACL,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAmB;YACpC,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAEhC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;gBAC3D,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;oBACxC,SAAS;gBACX,CAAC;gBAED,mBAAmB,CAAC,OAAO,EAAE;oBAC3B,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,uBAAuB;oBAC/B,OAAO,EACL,oFAAoF;oBACtF,KAAK,EAAE;wBACL,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;wBACrC,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC;qBAC1D;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { RuleHelper } from "textlint-rule-helper";
2
2
  import { sourceText } from "../../shared/text/traverse.js";
3
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
3
4
  const MAX_EXCLAMATIONS_PER_PARAGRAPH = 1;
4
5
  function countExclamations(text) {
5
6
  let count = 0;
@@ -19,7 +20,7 @@ function firstExclamationIndex(text) {
19
20
  return undefined;
20
21
  }
21
22
  const rule = (context) => {
22
- const { Syntax, RuleError, locator, report } = context;
23
+ const { Syntax } = context;
23
24
  const helper = new RuleHelper(context);
24
25
  const ignoredParents = [
25
26
  Syntax.List,
@@ -38,12 +39,15 @@ const rule = (context) => {
38
39
  return;
39
40
  }
40
41
  const index = firstExclamationIndex(source.text) ?? 0;
41
- report(node, new RuleError(`Paragraph has ${count} exclamation marks. Keep at most ${MAX_EXCLAMATIONS_PER_PARAGRAPH}.`, {
42
- padding: locator.range([
43
- source.originalStartFor(index),
44
- source.originalEndFor(index + 1)
45
- ])
46
- }));
42
+ emitTextlintFinding(context, {
43
+ node: node,
44
+ ruleId: "orthography:exclamation-density",
45
+ message: `Paragraph has ${count} exclamation marks. Keep at most ${MAX_EXCLAMATIONS_PER_PARAGRAPH}.`,
46
+ range: {
47
+ start: source.originalStartFor(index),
48
+ end: source.originalEndFor(index + 1)
49
+ }
50
+ });
47
51
  }
48
52
  };
49
53
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclamation-density.js","sourceRoot":"","sources":["../../../src/rules/orthography/exclamation-density.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,MAAM,8BAA8B,GAAG,CAAC,CAAC;AAEzC,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,IAAI,GAAuB,CAAC,OAAO,EAAE,EAAE;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG;QACrB,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,SAAS;KACjB,CAAC;IAEF,OAAO;QACL,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAmB;YACpC,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAE7C,IAAI,KAAK,IAAI,8BAA8B,EAAE,CAAC;gBAC5C,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEtD,mBAAmB,CAAC,OAAO,EAAE;gBAC3B,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,iCAAiC;gBACzC,OAAO,EAAE,iBAAiB,KAAK,oCAAoC,8BAA8B,GAAG;gBACpG,KAAK,EAAE;oBACL,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC;oBACrC,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC,CAAC;iBACtC;aACF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { RuleHelper } from "textlint-rule-helper";
2
2
  import { splitSentences } from "../../shared/text/sentences.js";
3
3
  import { sourceText } from "../../shared/text/traverse.js";
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
4
5
  function isAsciiDigit(character) {
5
6
  return character !== undefined && character >= "0" && character <= "9";
6
7
  }
@@ -74,7 +75,7 @@ function findSentenceTimestampMatches(text) {
74
75
  return matches;
75
76
  }
76
77
  const rule = (context) => {
77
- const { Syntax, RuleError, locator, report } = context;
78
+ const { Syntax } = context;
78
79
  const helper = new RuleHelper(context);
79
80
  const ignoredParents = [
80
81
  Syntax.List,
@@ -89,12 +90,15 @@ const rule = (context) => {
89
90
  }
90
91
  const source = sourceText(node);
91
92
  for (const match of findSentenceTimestampMatches(source.text)) {
92
- report(node, new RuleError(`Fake timestamp found: "${match.text}". Remove fabricated clock specificity.`, {
93
- padding: locator.range([
94
- source.originalStartFor(match.start),
95
- source.originalEndFor(match.end)
96
- ])
97
- }));
93
+ emitTextlintFinding(context, {
94
+ node: node,
95
+ ruleId: "orthography:fake-timestamps",
96
+ message: `Fake timestamp found: "${match.text}". Remove fabricated clock specificity.`,
97
+ range: {
98
+ start: source.originalStartFor(match.start),
99
+ end: source.originalEndFor(match.end)
100
+ }
101
+ });
98
102
  }
99
103
  }
100
104
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-timestamps.js","sourceRoot":"","sources":["../../../src/rules/orthography/fake-timestamps.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { RuleHelper } from "textlint-rule-helper";
2
2
  import { sourceText } from "../../shared/text/traverse.js";
3
3
  import { splitWhitespace } from "../../shared/text/whitespace.js";
4
+ import { emitTextlintNodeFinding } from "../../adapters/textlint/report.js";
4
5
  const MAX_CAPITALIZED_NON_FIRST_WORDS = 2;
5
6
  const MAX_RUST_HEADING_DEPTH = 2;
6
7
  function isUppercaseLetter(character) {
@@ -37,7 +38,7 @@ function countCapitalizedNonFirstWords(text) {
37
38
  return count;
38
39
  }
39
40
  const rule = (context) => {
40
- const { Syntax, RuleError, report } = context;
41
+ const { Syntax } = context;
41
42
  const helper = new RuleHelper(context);
42
43
  const ignoredParents = [
43
44
  Syntax.List,
@@ -58,7 +59,11 @@ const rule = (context) => {
58
59
  if (count <= MAX_CAPITALIZED_NON_FIRST_WORDS) {
59
60
  return;
60
61
  }
61
- report(node, new RuleError(`Heading looks like title case. Use sentence case; found ${count} capitalized non-first words.`));
62
+ emitTextlintNodeFinding(context, {
63
+ node: node,
64
+ ruleId: "orthography:sentence-case",
65
+ message: `Heading looks like title case. Use sentence case; found ${count} capitalized non-first words.`
66
+ });
62
67
  }
63
68
  };
64
69
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentence-case.js","sourceRoot":"","sources":["../../../src/rules/orthography/sentence-case.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { RuleHelper } from "textlint-rule-helper";
2
2
  import { splitSentences } from "../../shared/text/sentences.js";
3
3
  import { sourceText } from "../../shared/text/traverse.js";
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
4
5
  const SMART_QUOTES = new Set(["\u201C", "\u201D", "\u2018", "\u2019"]);
5
6
  function findSmartQuotes(text) {
6
7
  const matches = [];
@@ -24,7 +25,7 @@ function findSmartQuotes(text) {
24
25
  return matches;
25
26
  }
26
27
  const rule = (context) => {
27
- const { Syntax, RuleError, locator, report } = context;
28
+ const { Syntax } = context;
28
29
  const helper = new RuleHelper(context);
29
30
  const ignoredParents = [
30
31
  Syntax.List,
@@ -39,12 +40,15 @@ const rule = (context) => {
39
40
  }
40
41
  const source = sourceText(node);
41
42
  for (const match of findSmartQuotes(source.text)) {
42
- report(node, new RuleError(`Smart quotes found: "${match.matchedText}". Replace curly quotes with straight quotes.`, {
43
- padding: locator.range([
44
- source.originalStartFor(match.start),
45
- source.originalEndFor(match.end)
46
- ])
47
- }));
43
+ emitTextlintFinding(context, {
44
+ node: node,
45
+ ruleId: "orthography:smart-quotes",
46
+ message: `Smart quotes found: "${match.matchedText}". Replace curly quotes with straight quotes.`,
47
+ range: {
48
+ start: source.originalStartFor(match.start),
49
+ end: source.originalEndFor(match.end)
50
+ }
51
+ });
48
52
  }
49
53
  }
50
54
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-quotes.js","sourceRoot":"","sources":["../../../src/rules/orthography/smart-quotes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAQvE,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,KAAyB,CAAC;QAC9B,IAAI,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEzB,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAClE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC5D,SAAS;YACX,CAAC;YAED,KAAK,KAAK,KAAK,CAAC;YAChB,GAAG,GAAG,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;YAC/B,WAAW,IAAI,SAAS,CAAC;QAC3B,CAAC;QAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,IAAI,GAAuB,CAAC,OAAO,EAAE,EAAE;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG;QACrB,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,SAAS;KACjB,CAAC;IAEF,OAAO;QACL,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAmB;YACpC,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAEhC,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjD,mBAAmB,CAAC,OAAO,EAAE;oBAC3B,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,0BAA0B;oBAClC,OAAO,EAAE,wBAAwB,KAAK,CAAC,WAAW,+CAA+C;oBACjG,KAAK,EAAE;wBACL,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC;wBAC3C,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;qBACtC;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { RuleHelper } from "textlint-rule-helper";
2
+ import cliches from "./data/cliches.json" with { type: "json" };
3
+ import clicheTemplates from "./data/cliche-templates.json" with { type: "json" };
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
5
+ import { findUnquotedPhraseMatches, findUnquotedTokenTemplateMatches } from "../../shared/matchers/phrases.js";
6
+ function uniqueMatches(matches) {
7
+ const seen = new Set();
8
+ return matches.filter((match) => {
9
+ const key = `${match.start}:${match.end}:${match.text.toLowerCase()}`;
10
+ if (seen.has(key)) {
11
+ return false;
12
+ }
13
+ seen.add(key);
14
+ return true;
15
+ });
16
+ }
17
+ const rule = (context) => {
18
+ const { Syntax, getSource } = context;
19
+ const helper = new RuleHelper(context);
20
+ const ignoredParents = [Syntax.Link, Syntax.LinkReference];
21
+ return {
22
+ [Syntax.Str](node) {
23
+ if (helper.isChildNode(node, ignoredParents)) {
24
+ return;
25
+ }
26
+ const text = getSource(node);
27
+ const matches = uniqueMatches([
28
+ ...findUnquotedPhraseMatches(text, cliches),
29
+ ...findUnquotedTokenTemplateMatches(text, clicheTemplates)
30
+ ]);
31
+ for (const match of matches) {
32
+ emitTextlintFinding(context, {
33
+ node: node,
34
+ ruleId: "phrases:cliches",
35
+ message: `Cliche found: "${match.text}". Replace it with specific wording.`,
36
+ range: { start: match.start, end: match.end }
37
+ });
38
+ }
39
+ }
40
+ };
41
+ };
42
+ export default rule;
43
+ //# sourceMappingURL=cliches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliches.js","sourceRoot":"","sources":["../../../src/rules/phrases/cliches.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,OAAO,MAAM,qBAAqB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChE,OAAO,eAAe,MAAM,8BAA8B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAEL,yBAAyB,EACzB,gCAAgC,EACjC,MAAM,kCAAkC,CAAC;AAE1C,SAAS,aAAa,CAAC,OAA+B;IACpD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9B,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACtE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,IAAI,GAAuB,CAAC,OAAO,EAAE,EAAE;IAC3C,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO;QACL,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI;YACf,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAE7B,MAAM,OAAO,GAAG,aAAa,CAAC;gBAC5B,GAAG,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC;gBAC3C,GAAG,gCAAgC,CAAC,IAAI,EAAE,eAAe,CAAC;aAC3D,CAAC,CAAC;YAEH,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,mBAAmB,CAAC,OAAO,EAAE;oBAC3B,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,iBAAiB;oBACzB,OAAO,EAAE,kBAAkB,KAAK,CAAC,IAAI,sCAAsC;oBAC3E,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { RuleHelper } from "textlint-rule-helper";
2
+ import corporateAbstractionPatterns from "./data/corporate-abstraction-patterns.json" with { type: "json" };
3
+ import corporateSpeak from "./data/corporate-speak.json" with { type: "json" };
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
5
+ import { findUnquotedPhraseMatches, findUnquotedTokenTemplateMatches } from "../../shared/matchers/phrases.js";
6
+ const rule = (context) => {
7
+ const { Syntax, getSource } = context;
8
+ const helper = new RuleHelper(context);
9
+ const ignoredParents = [Syntax.Link, Syntax.LinkReference];
10
+ return {
11
+ [Syntax.Str](node) {
12
+ if (helper.isChildNode(node, ignoredParents)) {
13
+ return;
14
+ }
15
+ const text = getSource(node);
16
+ const matches = [
17
+ ...findUnquotedPhraseMatches(text, corporateSpeak),
18
+ ...findUnquotedTokenTemplateMatches(text, corporateAbstractionPatterns)
19
+ ];
20
+ for (const match of matches) {
21
+ emitTextlintFinding(context, {
22
+ node: node,
23
+ ruleId: "phrases:corporate-speak",
24
+ message: `Corporate-speak phrase found: "${match.text}". Replace it with specific wording.`,
25
+ range: { start: match.start, end: match.end }
26
+ });
27
+ }
28
+ }
29
+ };
30
+ };
31
+ export default rule;
32
+ //# sourceMappingURL=corporate-speak.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corporate-speak.js","sourceRoot":"","sources":["../../../src/rules/phrases/corporate-speak.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,4BAA4B,MAAM,4CAA4C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC5G,OAAO,cAAc,MAAM,6BAA6B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EACL,yBAAyB,EACzB,gCAAgC,EACjC,MAAM,kCAAkC,CAAC;AAE1C,MAAM,IAAI,GAAuB,CAAC,OAAO,EAAE,EAAE;IAC3C,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO;QACL,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI;YACf,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAE7B,MAAM,OAAO,GAAG;gBACd,GAAG,yBAAyB,CAAC,IAAI,EAAE,cAAc,CAAC;gBAClD,GAAG,gCAAgC,CAAC,IAAI,EAAE,4BAA4B,CAAC;aACxE,CAAC;YAEF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,mBAAmB,CAAC,OAAO,EAAE;oBAC3B,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,yBAAyB;oBACjC,OAAO,EAAE,kCAAkC,KAAK,CAAC,IAAI,sCAAsC;oBAC3F,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "id": "possessive-cliches",
4
+ "slots": {
5
+ "possessive": ["my", "your", "his", "her", "their", "our"]
6
+ },
7
+ "templates": [
8
+ "air {possessive} dirty laundry",
9
+ "all {possessive} eggs in one basket",
10
+ "banging {possessive} head against a brick wall",
11
+ "blow {possessive} own horn",
12
+ "burn {possessive} bridges",
13
+ "burst {possessive} bubble",
14
+ "cat got {possessive} tongue",
15
+ "count {possessive} chickens before they hatch",
16
+ "hold {possessive} tongue",
17
+ "watch {possessive} tongue"
18
+ ]
19
+ }
20
+ ]