slopless 0.2.4 → 0.2.6

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 +18 -106
  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 +16 -3
  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 +58 -49
  189. package/slopless.textlintrc.json +5 -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,134 @@
1
+ [
2
+ {
3
+ "category": "body sensation",
4
+ "id": "heart-chest",
5
+ "purpose": "Reports stock heartbeat-as-emotion body shorthand from Slop Forensics narrative ngrams.",
6
+ "slots": {
7
+ "motion": ["pounded", "pounding", "hammered", "raced", "racing"],
8
+ "possessive": ["her", "his", "my", "their"]
9
+ },
10
+ "templates": [
11
+ "heart {motion} in {possessive} chest",
12
+ "heart {motion} against {possessive} ribs"
13
+ ]
14
+ },
15
+ {
16
+ "category": "body sensation",
17
+ "id": "spine-shiver",
18
+ "purpose": "Reports stock shiver or chill spine reaction from Slop Forensics narrative ngrams.",
19
+ "slots": {
20
+ "reaction": ["chill", "shiver", "shivers"],
21
+ "verb": ["ran", "run", "sent"]
22
+ },
23
+ "templates": [
24
+ "{reaction} {verb} down her spine",
25
+ "{reaction} {verb} down his spine",
26
+ "{reaction} {verb} down my spine",
27
+ "{reaction} {verb} down their spine",
28
+ "{verb} {reaction} down her spine",
29
+ "{verb} {reaction} down his spine",
30
+ "{verb} {reaction} down my spine",
31
+ "{verb} {reaction} down their spine"
32
+ ]
33
+ },
34
+ {
35
+ "category": "body sensation",
36
+ "id": "breath-throat",
37
+ "purpose": "Reports stock breath-catching reaction from Slop Forensics narrative ngrams.",
38
+ "slots": {
39
+ "possessive": ["her", "his", "my", "their"]
40
+ },
41
+ "templates": ["breath caught in {possessive} throat"]
42
+ },
43
+ {
44
+ "category": "voice beat",
45
+ "id": "speech-voice-quality",
46
+ "purpose": "Reports dialogue tags padded with stock voice-quality beats from Slop Forensics narrative ngrams.",
47
+ "slots": {
48
+ "quality": [
49
+ "barely audible",
50
+ "barely a whisper",
51
+ "firm",
52
+ "low",
53
+ "soft",
54
+ "steady",
55
+ "trembling"
56
+ ],
57
+ "speechVerb": ["asked", "replied", "said", "whispered"]
58
+ },
59
+ "templates": [
60
+ "{speechVerb} voice {quality}",
61
+ "{speechVerb} in a voice {quality}",
62
+ "{speechVerb} her voice {quality}",
63
+ "{speechVerb} his voice {quality}",
64
+ "{speechVerb} their voice {quality}"
65
+ ]
66
+ },
67
+ {
68
+ "category": "voice beat",
69
+ "id": "voice-laced",
70
+ "purpose": "Reports stock emotion-as-voice-material phrasing from Slop Forensics narrative ngrams.",
71
+ "slots": {
72
+ "emotion": ["fear", "pain", "regret", "sadness", "wonder"],
73
+ "speechVerb": ["asked", "replied", "said", "whispered"]
74
+ },
75
+ "templates": [
76
+ "{speechVerb} voice laced with {emotion}",
77
+ "{speechVerb} her voice laced with {emotion}",
78
+ "{speechVerb} his voice laced with {emotion}",
79
+ "{speechVerb} their voice laced with {emotion}"
80
+ ]
81
+ },
82
+ {
83
+ "category": "atmosphere",
84
+ "id": "air-thick",
85
+ "purpose": "Reports stock atmosphere-as-thick-air phrasing from Slop Forensics narrative ngrams.",
86
+ "slots": {
87
+ "quality": ["scent", "tension", "unease"]
88
+ },
89
+ "templates": [
90
+ "air hung thick",
91
+ "air was thick with {quality}",
92
+ "air thick with {quality}"
93
+ ]
94
+ },
95
+ {
96
+ "category": "atmosphere",
97
+ "id": "hung-in-air",
98
+ "purpose": "Reports stock words or silence hanging in the air from Slop Forensics narrative ngrams.",
99
+ "slots": {
100
+ "subject": ["silence", "words"]
101
+ },
102
+ "templates": [
103
+ "{subject} hung in the air",
104
+ "{subject} hung heavy in the air"
105
+ ]
106
+ },
107
+ {
108
+ "category": "atmosphere",
109
+ "id": "long-shadows",
110
+ "purpose": "Reports stock light-and-shadow atmosphere phrasing from Slop Forensics narrative ngrams.",
111
+ "slots": {
112
+ "surface": ["floor", "ground", "room", "wall", "walls"]
113
+ },
114
+ "templates": ["casting long shadows", "long shadows across the {surface}"]
115
+ },
116
+ {
117
+ "category": "time passage",
118
+ "id": "days-turned-weeks",
119
+ "purpose": "Reports stock compressed time-passage phrasing from Slop Forensics narrative ngrams.",
120
+ "slots": {},
121
+ "templates": ["days turned into weeks", "days turned to weeks"]
122
+ },
123
+ {
124
+ "category": "time passage",
125
+ "id": "sun-horizon",
126
+ "purpose": "Reports stock sunset transition phrasing from Slop Forensics narrative ngrams.",
127
+ "slots": {},
128
+ "templates": [
129
+ "sun began to set",
130
+ "sun dipped below the horizon",
131
+ "sun dipped beneath the horizon"
132
+ ]
133
+ }
134
+ ]
@@ -0,0 +1,322 @@
1
+ import { allParagraphs } from "../../shared/text/sections.js";
2
+ import { splitSentences } from "../../shared/text/sentences.js";
3
+ import { wordTokens } from "../../shared/text/tokens.js";
4
+ import { emitTextlintFinding } from "../../adapters/textlint/report.js";
5
+ const MAX_SIMPLE_SENTENCE_TOKENS = 14;
6
+ const MIN_RUN_LENGTH = 3;
7
+ const SUBORDINATING_MARKERS = new Set([
8
+ "after",
9
+ "although",
10
+ "as",
11
+ "because",
12
+ "before",
13
+ "if",
14
+ "once",
15
+ "since",
16
+ "though",
17
+ "unless",
18
+ "until",
19
+ "when",
20
+ "whenever",
21
+ "where",
22
+ "whereas",
23
+ "while"
24
+ ]);
25
+ const PRONOUN_SUBJECTS = new Set(["he", "it", "she", "they", "we", "you"]);
26
+ const POSSESSIVE_SUBJECT_OPENERS = new Set([
27
+ "her",
28
+ "his",
29
+ "its",
30
+ "my",
31
+ "our",
32
+ "their",
33
+ "your"
34
+ ]);
35
+ const BODY_AND_CAMERA_NOUNS = new Set([
36
+ "arm",
37
+ "arms",
38
+ "body",
39
+ "breath",
40
+ "chest",
41
+ "ear",
42
+ "ears",
43
+ "eye",
44
+ "eyes",
45
+ "face",
46
+ "finger",
47
+ "fingers",
48
+ "foot",
49
+ "feet",
50
+ "hand",
51
+ "hands",
52
+ "head",
53
+ "heart",
54
+ "leg",
55
+ "legs",
56
+ "mouth",
57
+ "paw",
58
+ "paws",
59
+ "posture",
60
+ "shoulder",
61
+ "shoulders",
62
+ "stomach",
63
+ "tail",
64
+ "voice"
65
+ ]);
66
+ const WEAK_ACTION_VERBS = new Set([
67
+ "angled",
68
+ "angle",
69
+ "blink",
70
+ "blinked",
71
+ "climb",
72
+ "climbed",
73
+ "cross",
74
+ "crossed",
75
+ "crouch",
76
+ "crouched",
77
+ "flatten",
78
+ "flattened",
79
+ "hear",
80
+ "heard",
81
+ "gaze",
82
+ "gazed",
83
+ "glance",
84
+ "glanced",
85
+ "hang",
86
+ "hung",
87
+ "listen",
88
+ "listened",
89
+ "look",
90
+ "looked",
91
+ "nod",
92
+ "nodded",
93
+ "observe",
94
+ "observed",
95
+ "pick",
96
+ "picked",
97
+ "pull",
98
+ "pulled",
99
+ "rested",
100
+ "run",
101
+ "ran",
102
+ "shift",
103
+ "shifted",
104
+ "sit",
105
+ "sat",
106
+ "stand",
107
+ "stood",
108
+ "stare",
109
+ "stared",
110
+ "step",
111
+ "stepped",
112
+ "stop",
113
+ "stopped",
114
+ "turn",
115
+ "turned",
116
+ "twitch",
117
+ "twitched",
118
+ "tie",
119
+ "tied",
120
+ "wait",
121
+ "waited",
122
+ "walk",
123
+ "walked",
124
+ "watch",
125
+ "watched"
126
+ ]);
127
+ const LINKING_VERBS = new Set([
128
+ "am",
129
+ "are",
130
+ "be",
131
+ "been",
132
+ "being",
133
+ "felt",
134
+ "is",
135
+ "looked",
136
+ "seemed",
137
+ "was",
138
+ "were"
139
+ ]);
140
+ const SENSORIAL_COMPLEMENTS = new Set([
141
+ "cold",
142
+ "dark",
143
+ "heavy",
144
+ "haze",
145
+ "blur",
146
+ "fog",
147
+ "low",
148
+ "quiet",
149
+ "sharp",
150
+ "still",
151
+ "tight",
152
+ "tired"
153
+ ]);
154
+ function tokenAt(tokens, index) {
155
+ return tokens[index];
156
+ }
157
+ function hasSubordinatingMarker(tokens) {
158
+ return tokens.some((token) => SUBORDINATING_MARKERS.has(token.normalized));
159
+ }
160
+ function isCapitalized(token) {
161
+ const first = token.text[0];
162
+ if (first === undefined) {
163
+ return false;
164
+ }
165
+ return (first.toLocaleUpperCase("en") === first &&
166
+ first.toLocaleLowerCase("en") !== first);
167
+ }
168
+ function subjectKind(tokens) {
169
+ const first = tokenAt(tokens, 0);
170
+ if (first === undefined) {
171
+ return undefined;
172
+ }
173
+ if (PRONOUN_SUBJECTS.has(first.normalized)) {
174
+ return "pronoun";
175
+ }
176
+ if (POSSESSIVE_SUBJECT_OPENERS.has(first.normalized)) {
177
+ return tokens.some((token) => BODY_AND_CAMERA_NOUNS.has(token.normalized))
178
+ ? "possessive"
179
+ : undefined;
180
+ }
181
+ if (first.normalized === "the") {
182
+ return "article-noun";
183
+ }
184
+ if (isCapitalized(first)) {
185
+ return "name";
186
+ }
187
+ return undefined;
188
+ }
189
+ function negatedActionVerb(tokens) {
190
+ const auxiliary = tokenAt(tokens, 1);
191
+ const negation = tokenAt(tokens, 2);
192
+ const verb = tokenAt(tokens, 3);
193
+ if (auxiliary?.normalized !== "did" ||
194
+ negation?.normalized !== "not" ||
195
+ verb === undefined ||
196
+ !WEAK_ACTION_VERBS.has(verb.normalized)) {
197
+ return undefined;
198
+ }
199
+ return verb.normalized;
200
+ }
201
+ function firstWeakActionVerb(tokens) {
202
+ const negated = negatedActionVerb(tokens);
203
+ if (negated !== undefined) {
204
+ return negated;
205
+ }
206
+ for (const token of tokens.slice(1, 8)) {
207
+ if (WEAK_ACTION_VERBS.has(token.normalized)) {
208
+ return token.normalized;
209
+ }
210
+ }
211
+ return undefined;
212
+ }
213
+ function hasSensorialComplement(tokens) {
214
+ return tokens.some((token) => SENSORIAL_COMPLEMENTS.has(token.normalized));
215
+ }
216
+ function firstLinkingVerb(tokens) {
217
+ for (const token of tokens.slice(1, 8)) {
218
+ if (LINKING_VERBS.has(token.normalized)) {
219
+ return token.normalized;
220
+ }
221
+ }
222
+ return undefined;
223
+ }
224
+ function classifySentence(sentence) {
225
+ const tokens = wordTokens(sentence.text);
226
+ if (tokens.length < 3 || tokens.length > MAX_SIMPLE_SENTENCE_TOKENS) {
227
+ return undefined;
228
+ }
229
+ if (hasSubordinatingMarker(tokens)) {
230
+ return undefined;
231
+ }
232
+ const kind = subjectKind(tokens);
233
+ if (kind === undefined) {
234
+ return undefined;
235
+ }
236
+ const weakActionVerb = firstWeakActionVerb(tokens);
237
+ if (weakActionVerb !== undefined) {
238
+ return {
239
+ actionKind: "weak-action",
240
+ sentence,
241
+ subjectKind: kind,
242
+ verb: weakActionVerb
243
+ };
244
+ }
245
+ const linkingVerb = firstLinkingVerb(tokens);
246
+ if (linkingVerb !== undefined && hasSensorialComplement(tokens)) {
247
+ return {
248
+ actionKind: "linking",
249
+ sentence,
250
+ subjectKind: kind,
251
+ verb: linkingVerb
252
+ };
253
+ }
254
+ return undefined;
255
+ }
256
+ function isCadenceRun(sentences) {
257
+ const weakActionCount = sentences.filter((sentence) => sentence.actionKind === "weak-action").length;
258
+ return weakActionCount >= 2;
259
+ }
260
+ function findFlatActionRuns(text) {
261
+ const sentences = splitSentences(text);
262
+ const runs = [];
263
+ let current = [];
264
+ for (const sentence of sentences) {
265
+ const cadenceSentence = classifySentence(sentence);
266
+ if (cadenceSentence === undefined) {
267
+ if (current.length >= MIN_RUN_LENGTH && isCadenceRun(current)) {
268
+ const first = current[0];
269
+ const last = current.at(-1);
270
+ if (first !== undefined && last !== undefined) {
271
+ runs.push({
272
+ end: last.sentence.end,
273
+ sentences: current,
274
+ start: first.sentence.start
275
+ });
276
+ }
277
+ }
278
+ current = [];
279
+ continue;
280
+ }
281
+ current.push(cadenceSentence);
282
+ }
283
+ if (current.length >= MIN_RUN_LENGTH && isCadenceRun(current)) {
284
+ const first = current[0];
285
+ const last = current.at(-1);
286
+ if (first !== undefined && last !== undefined) {
287
+ runs.push({
288
+ end: last.sentence.end,
289
+ sentences: current,
290
+ start: first.sentence.start
291
+ });
292
+ }
293
+ }
294
+ return runs;
295
+ }
296
+ const rule = (context) => {
297
+ const { Syntax } = context;
298
+ return {
299
+ [Syntax.Document](node) {
300
+ for (const item of allParagraphs(node)) {
301
+ const match = findFlatActionRuns(item.source.text)[0];
302
+ if (match === undefined) {
303
+ continue;
304
+ }
305
+ const verbs = [
306
+ ...new Set(match.sentences.map((sentence) => sentence.verb))
307
+ ].join(", ");
308
+ emitTextlintFinding(context, {
309
+ node: item.paragraph,
310
+ ruleId: "narrative-slop:flat-action-cadence",
311
+ message: `Flat action cadence: ${match.sentences.length} adjacent short simple sentences use subject-action beats (${verbs}). Vary the rhythm or add causal/sensory development.`,
312
+ range: {
313
+ start: item.source.originalStartFor(match.start),
314
+ end: item.source.originalEndFor(match.end)
315
+ }
316
+ });
317
+ }
318
+ }
319
+ };
320
+ };
321
+ export default rule;
322
+ //# sourceMappingURL=flat-action-cadence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flat-action-cadence.js","sourceRoot":"","sources":["../../../src/rules/narrative-slop/flat-action-cadence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,cAAc,EAEf,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAc,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAexE,MAAM,0BAA0B,GAAG,EAAE,CAAC;AACtC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,OAAO;IACP,UAAU;IACV,IAAI;IACJ,SAAS;IACT,QAAQ;IACR,IAAI;IACJ,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,MAAM;IACN,UAAU;IACV,OAAO;IACP,SAAS;IACT,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AAE3E,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IACzC,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;IACJ,KAAK;IACL,OAAO;IACP,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,KAAK;IACL,MAAM;IACN,MAAM;IACN,QAAQ;IACR,OAAO;IACP,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,QAAQ;IACR,SAAS;IACT,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,KAAK;IACL,MAAM;IACN,OAAO;IACP,KAAK;IACL,MAAM;IACN,SAAS;IACT,UAAU;IACV,WAAW;IACX,SAAS;IACT,MAAM;IACN,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,QAAQ;IACR,OAAO;IACP,OAAO;IACP,SAAS;IACT,OAAO;IACP,SAAS;IACT,OAAO;IACP,SAAS;IACT,QAAQ;IACR,UAAU;IACV,SAAS;IACT,WAAW;IACX,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,MAAM;IACN,MAAM;IACN,QAAQ;IACR,UAAU;IACV,MAAM;IACN,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,SAAS;IACT,UAAU;IACV,MAAM;IACN,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,KAAK;IACL,OAAO;IACP,SAAS;IACT,KAAK;IACL,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,QAAQ;IACR,MAAM;IACN,SAAS;IACT,MAAM;IACN,SAAS;IACT,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,KAAK;IACL,MAAM;IACN,MAAM;IACN,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,OAAO;IACP,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,MAAM;IACN,OAAO;IACP,MAAM;IACN,IAAI;IACJ,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;CACR,CAAC,CAAC;AAEH,SAAS,OAAO,CAAC,MAAwB,EAAE,KAAa;IACtD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAwB;IACtD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,aAAa,CAAC,KAAY;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,KAAK;QACvC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,KAAK,CACxC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAClB,MAAwB;IAExB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,0BAA0B,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACxE,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;QAC/B,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAwB;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChC,IACE,SAAS,EAAE,UAAU,KAAK,KAAK;QAC/B,QAAQ,EAAE,UAAU,KAAK,KAAK;QAC9B,IAAI,KAAK,SAAS;QAClB,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EACvC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC,UAAU,CAAC;AACzB,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAwB;IACnD,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvC,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC,UAAU,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAwB;IACtD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAwB;IAChD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC,UAAU,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CACvB,QAAuB;IAEvB,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,0BAA0B,EAAE,CAAC;QACpE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO;YACL,UAAU,EAAE,aAAa;YACzB,QAAQ;YACR,WAAW,EAAE,IAAI;YACjB,IAAI,EAAE,cAAc;SACrB,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,WAAW,KAAK,SAAS,IAAI,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChE,OAAO;YACL,UAAU,EAAE,SAAS;YACrB,QAAQ;YACR,WAAW,EAAE,IAAI;YACjB,IAAI,EAAE,WAAW;SAClB,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,YAAY,CAAC,SAAqC;IACzD,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CACtC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,KAAK,aAAa,CACpD,CAAC,MAAM,CAAC;IAET,OAAO,eAAe,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAiB,EAAE,CAAC;IAC9B,IAAI,OAAO,GAAsB,EAAE,CAAC;IAEpC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,eAAe,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,OAAO,CAAC,MAAM,IAAI,cAAc,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBACzB,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC9C,IAAI,CAAC,IAAI,CAAC;wBACR,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;wBACtB,SAAS,EAAE,OAAO;wBAClB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK;qBAC5B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;YACb,SAAS;QACX,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,IAAI,cAAc,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC;gBACR,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;gBACtB,SAAS,EAAE,OAAO;gBAClB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK;aAC5B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,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,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,SAAS;gBACX,CAAC;gBAED,MAAM,KAAK,GAAG;oBACZ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;iBAC7D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEb,mBAAmB,CAAC,OAAO,EAAE;oBAC3B,IAAI,EAAE,IAAI,CAAC,SAAS;oBACpB,MAAM,EAAE,oCAAoC;oBAC5C,OAAO,EAAE,wBAAwB,KAAK,CAAC,SAAS,CAAC,MAAM,8DAA8D,KAAK,uDAAuD;oBACjL,KAAK,EAAE;wBACL,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC;wBAChD,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;qBAC3C;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -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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"}