@faircopy/rules-nlp 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -0
- package/dist/index.d.ts +77 -1
- package/dist/index.js +635 -44
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,18 +11,24 @@ Load the ruleset once, then configure rules with bare rule IDs:
|
|
|
11
11
|
```ts
|
|
12
12
|
rulesets: ['@faircopy/rules-nlp'],
|
|
13
13
|
rules: {
|
|
14
|
+
'no-absolute-intensifiers': 'warn',
|
|
15
|
+
'no-adverb-overuse': 'warn',
|
|
14
16
|
'no-expletive-openers': 'warn',
|
|
15
17
|
'no-filter-words': 'warn',
|
|
16
18
|
'no-future-promises': 'warn',
|
|
17
19
|
'no-hedge-words': 'warn',
|
|
18
20
|
'no-empty-transformation-claims': 'warn',
|
|
19
21
|
'no-passive-voice': 'warn',
|
|
22
|
+
'no-qualifier-creep': 'warn',
|
|
20
23
|
'no-redundant-pairs': 'warn',
|
|
24
|
+
'no-vague-comparatives': 'warn',
|
|
21
25
|
'no-weak-modals': 'warn',
|
|
22
26
|
'no-stacked-adjectives': 'warn',
|
|
23
27
|
'no-nominalized-phrases': 'warn',
|
|
24
28
|
'no-pronoun-led-claims': 'warn',
|
|
25
29
|
'no-buzzword-stacks': 'warn',
|
|
30
|
+
'no-complex-readability': 'warn',
|
|
31
|
+
'no-overly-complex-sentences': 'warn',
|
|
26
32
|
'no-vague-quantifiers': 'warn',
|
|
27
33
|
'no-meaningless-modifiers': 'warn',
|
|
28
34
|
'no-superlative-claims': 'warn',
|
|
@@ -35,6 +41,8 @@ Package-qualified IDs like `@faircopy/rules-nlp/no-passive-voice` still work and
|
|
|
35
41
|
|
|
36
42
|
| Rule | Description |
|
|
37
43
|
|---|---|
|
|
44
|
+
| `no-absolute-intensifiers` | Flag intensifiers before absolute adjectives like `very unique` |
|
|
45
|
+
| `no-adverb-overuse` | Flag sentences with more than two adverbs ending in `-ly` |
|
|
38
46
|
| `no-empty-transformation-claims` | Flag broad transformation cliches like `transform the way teams work` |
|
|
39
47
|
| `no-expletive-openers` | Flag sentence openings like `There are` |
|
|
40
48
|
| `no-filter-words` | Ban filter phrases like `I think` and `it seems` |
|
|
@@ -42,12 +50,202 @@ Package-qualified IDs like `@faircopy/rules-nlp/no-passive-voice` still work and
|
|
|
42
50
|
| `no-hedge-words` | Flag hedge words like `kind of` and `somewhat` |
|
|
43
51
|
| `no-jargon` | Flag business jargon like `leverage` and `circle back` |
|
|
44
52
|
| `no-passive-voice` | Flag likely passive-voice constructions |
|
|
53
|
+
| `no-qualifier-creep` | Flag stacked qualifiers or intensifiers like `very really good` |
|
|
45
54
|
| `no-redundant-pairs` | Flag redundant fixed phrases like `first and foremost` |
|
|
55
|
+
| `no-vague-comparatives` | Flag comparative claims that omit a clear baseline |
|
|
46
56
|
| `no-weak-modals` | Flag hedged modal claims like `can help` and `might improve` |
|
|
47
57
|
| `no-stacked-adjectives` | Flag noun phrases with multiple adjectives before the noun |
|
|
48
58
|
| `no-nominalized-phrases` | Flag nominalized `X of Y` phrases like `optimization of onboarding` |
|
|
49
59
|
| `no-pronoun-led-claims` | Flag vague sentence openers like `This helps` and `It enables` |
|
|
50
60
|
| `no-buzzword-stacks` | Flag sentences overloaded with abstract benefit nouns |
|
|
61
|
+
| `no-complex-readability` | Flag prose whose Flesch-Kincaid grade level exceeds a target |
|
|
62
|
+
| `no-overly-complex-sentences` | Flag sentences overloaded with coordinating or subordinating conjunctions |
|
|
51
63
|
| `no-vague-quantifiers` | Flag bare quantifiers without numeric anchors |
|
|
52
64
|
| `no-meaningless-modifiers` | Flag intensifiers like `very` and `obviously` that add no information |
|
|
53
65
|
| `no-superlative-claims` | Flag unproven superlatives like `best` and `world-class` |
|
|
66
|
+
| `sentence-complexity` | Flag sentences that exceed a word or clause threshold |
|
|
67
|
+
|
|
68
|
+
### `no-absolute-intensifiers`
|
|
69
|
+
|
|
70
|
+
Absolute adjectives already express an extreme, so intensifiers such as `very` are redundant.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
rules: {
|
|
74
|
+
'no-absolute-intensifiers': 'warn',
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Options:
|
|
79
|
+
|
|
80
|
+
| Option | Type | Default | Description |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `intensifiers` | `string[]` | `['very', 'really', 'completely', ...]` | Words or phrases to treat as intensifiers |
|
|
83
|
+
| `absolutes` | `string[]` | `['unique', 'finished', 'destroyed', ...]` | Absolute adjectives that should not be intensified |
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
'no-absolute-intensifiers': ['warn', {
|
|
89
|
+
intensifiers: ['very', 'highly'],
|
|
90
|
+
absolutes: ['unique', 'critical'],
|
|
91
|
+
}]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `sentence-complexity`
|
|
95
|
+
|
|
96
|
+
Long, clause-heavy sentences are harder to read. This rule flags any sentence that exceeds a configurable word count or contains too many finite-verb clauses, and suggests splitting it into shorter sentences.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
rules: {
|
|
100
|
+
'sentence-complexity': 'warn',
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Options:
|
|
105
|
+
|
|
106
|
+
| Option | Type | Default | Description |
|
|
107
|
+
|---|---|---|---|
|
|
108
|
+
| `maxWordCount` | `number` | `25` | Maximum words allowed per sentence |
|
|
109
|
+
| `maxClauseCount` | `number` | `3` | Maximum finite-verb clauses allowed per sentence |
|
|
110
|
+
|
|
111
|
+
Example with custom thresholds:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
'sentence-complexity': ['warn', {
|
|
115
|
+
maxWordCount: 20,
|
|
116
|
+
maxClauseCount: 2,
|
|
117
|
+
}]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Flagged example:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
The engineer reviewed the requirements and wrote the code and ran the tests and deployed the application while the team watched and celebrated the release together.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Suggested fix: split the sentence around each independent clause.
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
The engineer reviewed the requirements. They wrote the code, ran the tests, and deployed the application. The team watched and celebrated the release together.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `no-overly-complex-sentences`
|
|
133
|
+
|
|
134
|
+
Sentences packed with conjunctions are often run-ons or nested too deeply. This rule flags any sentence that exceeds a configurable number of coordinating conjunctions, subordinating conjunctions, or total conjunctions.
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
rules: {
|
|
138
|
+
'no-overly-complex-sentences': 'warn',
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Options:
|
|
143
|
+
|
|
144
|
+
| Option | Type | Default | Description |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `maxConjunctions` | `number` | `4` | Maximum total conjunctions allowed per sentence |
|
|
147
|
+
| `maxCoordinating` | `number` | `3` | Maximum coordinating conjunctions allowed per sentence |
|
|
148
|
+
| `maxSubordinating` | `number` | `2` | Maximum subordinating conjunctions allowed per sentence |
|
|
149
|
+
| `coordinating` | `string[]` | `['and', 'but', 'or', 'nor', 'yet', 'so']` | Words treated as coordinating conjunctions |
|
|
150
|
+
| `subordinating` | `string[]` | `['because', 'although', 'though', 'while', 'since', 'unless', 'if', 'when', 'after', 'before', 'until', 'whether', 'once']` | Words treated as subordinating conjunctions |
|
|
151
|
+
| `allowList` | `string[]` | `[]` | Words to ignore when counting |
|
|
152
|
+
|
|
153
|
+
Example with custom thresholds:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
'no-overly-complex-sentences': ['warn', {
|
|
157
|
+
maxConjunctions: 3,
|
|
158
|
+
maxCoordinating: 2,
|
|
159
|
+
maxSubordinating: 1,
|
|
160
|
+
}]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Flagged example:
|
|
164
|
+
|
|
165
|
+
```text
|
|
166
|
+
I ran and swam and biked and hiked and climbed.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Suggested fix: split the list into shorter sentences or use a bulleted list.
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
I ran, swam, and biked. Then I hiked and climbed.
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Some words, such as `since` or `so`, can be prepositions or adverbs in certain contexts. If the rule is too noisy for your copy, add the word to `allowList`.
|
|
176
|
+
|
|
177
|
+
### `no-vague-comparatives`
|
|
178
|
+
|
|
179
|
+
Comparative claims like `faster`, `easier`, or `more efficient` only persuade when the reader knows the baseline. This rule flags comparative adjectives and adverbs that are not paired with `than` in the same sentence.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
rules: {
|
|
183
|
+
'no-vague-comparatives': 'warn',
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Options:
|
|
188
|
+
|
|
189
|
+
| Option | Type | Default | Description |
|
|
190
|
+
|---|---|---|---|
|
|
191
|
+
| `comparatives` | `string[]` | `['better', 'worse', 'more', 'less', 'faster', 'slower', 'easier', 'harder', 'stronger', 'weaker', 'higher', 'lower', 'bigger', 'smaller', 'greater']` | Comparative words or phrases that require a baseline |
|
|
192
|
+
| `requireThan` | `boolean` | `true` | Whether a `than` in the same sentence suppresses the diagnostic |
|
|
193
|
+
|
|
194
|
+
Example with custom settings:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
'no-vague-comparatives': ['warn', {
|
|
198
|
+
comparatives: ['superior', 'inferior', 'better'],
|
|
199
|
+
requireThan: true,
|
|
200
|
+
}]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Flagged example:
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
Our editor is faster. It is also easier to use.
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Suggested fix: add a concrete baseline.
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
Our editor is faster than the old one. It is also easier to use than a spreadsheet.
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `no-qualifier-creep`
|
|
216
|
+
|
|
217
|
+
Stacked qualifiers or intensifiers dilute a claim and make it sound hedged. This rule flags sequences of two or more qualifiers before an adjective or adverb.
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
rules: {
|
|
221
|
+
'no-qualifier-creep': 'warn',
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Options:
|
|
226
|
+
|
|
227
|
+
| Option | Type | Default | Description |
|
|
228
|
+
|---|---|---|---|
|
|
229
|
+
| `qualifiers` | `string[]` | `['very', 'really', 'quite', ...]` | Words treated as qualifiers or intensifiers |
|
|
230
|
+
| `maxQualifiers` | `number` | `1` | Maximum qualifiers allowed in a row before the excess are flagged |
|
|
231
|
+
|
|
232
|
+
Example with custom settings:
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
'no-qualifier-creep': ['warn', {
|
|
236
|
+
qualifiers: ['very', 'really', 'quite'],
|
|
237
|
+
maxQualifiers: 1,
|
|
238
|
+
}]
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Flagged example:
|
|
242
|
+
|
|
243
|
+
```text
|
|
244
|
+
The result is very really quite good.
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Suggested fix: keep the strongest qualifier or replace the phrase with concrete evidence.
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
The result is excellent.
|
|
251
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import { Rule } from '@faircopy/core';
|
|
2
2
|
|
|
3
|
+
interface NoAbsoluteIntensifiersOptions {
|
|
4
|
+
intensifiers?: string[];
|
|
5
|
+
absolutes?: string[];
|
|
6
|
+
}
|
|
7
|
+
declare const noAbsoluteIntensifiers: Rule<NoAbsoluteIntensifiersOptions>;
|
|
8
|
+
|
|
9
|
+
interface NoAdverbOveruseOptions {
|
|
10
|
+
/** Maximum number of -ly adverbs allowed per sentence before the rest are flagged. */
|
|
11
|
+
maxAdverbs?: number;
|
|
12
|
+
/** Adverbs that are allowed and do not count toward the threshold. */
|
|
13
|
+
allowedAdverbs?: string[];
|
|
14
|
+
}
|
|
15
|
+
declare const noAdverbOveruse: Rule<NoAdverbOveruseOptions>;
|
|
16
|
+
|
|
3
17
|
interface NoBuzzwordStacksOptions {
|
|
4
18
|
terms?: string[];
|
|
5
19
|
maxTermsPerSentence?: number;
|
|
6
20
|
}
|
|
7
21
|
declare const noBuzzwordStacks: Rule<NoBuzzwordStacksOptions>;
|
|
8
22
|
|
|
23
|
+
interface NoComplexReadabilityOptions {
|
|
24
|
+
/** Target Flesch-Kincaid grade level. Text scoring above this is flagged. */
|
|
25
|
+
maxGradeLevel?: number;
|
|
26
|
+
/** Minimum sentence count before scoring. Shorter passages are too noisy. */
|
|
27
|
+
minSentences?: number;
|
|
28
|
+
/** Minimum word count before scoring. */
|
|
29
|
+
minWords?: number;
|
|
30
|
+
}
|
|
31
|
+
declare const noComplexReadability: Rule<NoComplexReadabilityOptions>;
|
|
32
|
+
|
|
9
33
|
interface NoExpletiveOpenersOptions {
|
|
10
34
|
phrases?: string[];
|
|
11
35
|
}
|
|
@@ -47,6 +71,34 @@ interface NoNominalizedPhrasesOptions {
|
|
|
47
71
|
}
|
|
48
72
|
declare const noNominalizedPhrases: Rule<NoNominalizedPhrasesOptions>;
|
|
49
73
|
|
|
74
|
+
interface NoOverlyComplexSentencesOptions {
|
|
75
|
+
/** Maximum total conjunctions allowed in a single sentence. */
|
|
76
|
+
maxConjunctions?: number;
|
|
77
|
+
/** Maximum coordinating conjunctions allowed in a single sentence. */
|
|
78
|
+
maxCoordinating?: number;
|
|
79
|
+
/** Maximum subordinating conjunctions allowed in a single sentence. */
|
|
80
|
+
maxSubordinating?: number;
|
|
81
|
+
/** Words or phrases to treat as coordinating conjunctions. */
|
|
82
|
+
coordinating?: string[];
|
|
83
|
+
/** Words or phrases to treat as subordinating conjunctions. */
|
|
84
|
+
subordinating?: string[];
|
|
85
|
+
/** Words or phrases to ignore when counting. */
|
|
86
|
+
allowList?: string[];
|
|
87
|
+
}
|
|
88
|
+
declare const noOverlyComplexSentences: Rule<NoOverlyComplexSentencesOptions>;
|
|
89
|
+
|
|
90
|
+
interface NoOverusedAdverbsOptions {
|
|
91
|
+
/** Maximum occurrences of a single adverb allowed before later ones are flagged. */
|
|
92
|
+
threshold?: number;
|
|
93
|
+
/** Minimum character length for an adverb to be considered. */
|
|
94
|
+
minLength?: number;
|
|
95
|
+
/** Adverbs that are allowed and do not count toward the threshold. */
|
|
96
|
+
allowedAdverbs?: string[];
|
|
97
|
+
/** If provided, only these adverbs are checked. */
|
|
98
|
+
adverbs?: string[];
|
|
99
|
+
}
|
|
100
|
+
declare const noOverusedAdverbs: Rule<NoOverusedAdverbsOptions>;
|
|
101
|
+
|
|
50
102
|
interface NoPassiveVoiceOptions {
|
|
51
103
|
allowedAuxiliaries?: string[];
|
|
52
104
|
}
|
|
@@ -58,6 +110,14 @@ interface NoPronounLedClaimsOptions {
|
|
|
58
110
|
}
|
|
59
111
|
declare const noPronounLedClaims: Rule<NoPronounLedClaimsOptions>;
|
|
60
112
|
|
|
113
|
+
interface NoQualifierCreepOptions {
|
|
114
|
+
/** Qualifier words that count toward a stacked-qualifier pattern. */
|
|
115
|
+
qualifiers?: string[];
|
|
116
|
+
/** Maximum qualifiers allowed in a row before the excess are flagged. */
|
|
117
|
+
maxQualifiers?: number;
|
|
118
|
+
}
|
|
119
|
+
declare const noQualifierCreep: Rule<NoQualifierCreepOptions>;
|
|
120
|
+
|
|
61
121
|
interface NoRedundantPairsOptions {
|
|
62
122
|
phrases?: string[];
|
|
63
123
|
}
|
|
@@ -73,6 +133,14 @@ interface NoSuperlativeClaimsOptions {
|
|
|
73
133
|
}
|
|
74
134
|
declare const noSuperlativeClaims: Rule<NoSuperlativeClaimsOptions>;
|
|
75
135
|
|
|
136
|
+
interface NoVagueComparativesOptions {
|
|
137
|
+
/** Comparative words or phrases that require a baseline. */
|
|
138
|
+
comparatives?: string[];
|
|
139
|
+
/** Whether to require "than" in the same sentence to avoid flagging. */
|
|
140
|
+
requireThan?: boolean;
|
|
141
|
+
}
|
|
142
|
+
declare const noVagueComparatives: Rule<NoVagueComparativesOptions>;
|
|
143
|
+
|
|
76
144
|
interface NoVagueQuantifiersOptions {
|
|
77
145
|
quantifiers?: string[];
|
|
78
146
|
}
|
|
@@ -84,7 +152,15 @@ interface NoWeakModalsOptions {
|
|
|
84
152
|
}
|
|
85
153
|
declare const noWeakModals: Rule<NoWeakModalsOptions>;
|
|
86
154
|
|
|
155
|
+
interface SentenceComplexityOptions {
|
|
156
|
+
/** Maximum number of words allowed in a single sentence. */
|
|
157
|
+
maxWordCount?: number;
|
|
158
|
+
/** Maximum number of finite-verb clauses allowed in a single sentence. */
|
|
159
|
+
maxClauseCount?: number;
|
|
160
|
+
}
|
|
161
|
+
declare const sentenceComplexity: Rule<SentenceComplexityOptions>;
|
|
162
|
+
|
|
87
163
|
/** All NLP rules keyed by their rule ID. */
|
|
88
164
|
declare const ruleRegistry: Map<string, Rule>;
|
|
89
165
|
|
|
90
|
-
export { type NoBuzzwordStacksOptions, type NoEmptyTransformationClaimsOptions, type NoExpletiveOpenersOptions, type NoFilterWordsOptions, type NoFuturePromisesOptions, type NoHedgeWordsOptions, type NoJargonOptions, type NoMeaninglessModifiersOptions, type NoNominalizedPhrasesOptions, type NoPassiveVoiceOptions, type NoPronounLedClaimsOptions, type NoRedundantPairsOptions, type NoStackedAdjectivesOptions, type NoSuperlativeClaimsOptions, type NoVagueQuantifiersOptions, type NoWeakModalsOptions, noBuzzwordStacks, noEmptyTransformationClaims, noExpletiveOpeners, noFilterWords, noFuturePromises, noHedgeWords, noJargon, noMeaninglessModifiers, noNominalizedPhrases, noPassiveVoice, noPronounLedClaims, noRedundantPairs, noStackedAdjectives, noSuperlativeClaims, noVagueQuantifiers, noWeakModals, ruleRegistry };
|
|
166
|
+
export { type NoAbsoluteIntensifiersOptions, type NoAdverbOveruseOptions, type NoBuzzwordStacksOptions, type NoComplexReadabilityOptions, type NoEmptyTransformationClaimsOptions, type NoExpletiveOpenersOptions, type NoFilterWordsOptions, type NoFuturePromisesOptions, type NoHedgeWordsOptions, type NoJargonOptions, type NoMeaninglessModifiersOptions, type NoNominalizedPhrasesOptions, type NoOverlyComplexSentencesOptions, type NoOverusedAdverbsOptions, type NoPassiveVoiceOptions, type NoPronounLedClaimsOptions, type NoQualifierCreepOptions, type NoRedundantPairsOptions, type NoStackedAdjectivesOptions, type NoSuperlativeClaimsOptions, type NoVagueComparativesOptions, type NoVagueQuantifiersOptions, type NoWeakModalsOptions, type SentenceComplexityOptions, noAbsoluteIntensifiers, noAdverbOveruse, noBuzzwordStacks, noComplexReadability, noEmptyTransformationClaims, noExpletiveOpeners, noFilterWords, noFuturePromises, noHedgeWords, noJargon, noMeaninglessModifiers, noNominalizedPhrases, noOverlyComplexSentences, noOverusedAdverbs, noPassiveVoice, noPronounLedClaims, noQualifierCreep, noRedundantPairs, noStackedAdjectives, noSuperlativeClaims, noVagueComparatives, noVagueQuantifiers, noWeakModals, ruleRegistry, sentenceComplexity };
|