@faircopy/rules-default 0.1.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 ADDED
@@ -0,0 +1,88 @@
1
+ # @faircopy/rules-default
2
+
3
+ Default ruleset for faircopy. Ships three rules targeting the most common landing-page copy patterns.
4
+
5
+ ## Install
6
+
7
+ Included automatically when you install `faircopy`. To use standalone:
8
+
9
+ ```sh
10
+ npm i @faircopy/rules-default
11
+ ```
12
+
13
+ ## Rules
14
+
15
+ ### `no-em-dash`
16
+
17
+ Bans the em-dash character (`—`, U+2014) in marketing copy.
18
+
19
+ ```
20
+ error[no-em-dash]: use a sentence break instead of an em-dash
21
+ ```
22
+
23
+ **Options:**
24
+
25
+ ```ts
26
+ {
27
+ flagEnDash?: boolean // Also flag en-dashes (–). Default false.
28
+ flagDoubleHyphen?: boolean // Also flag --. Default false.
29
+ }
30
+ ```
31
+
32
+ **Config example:**
33
+
34
+ ```ts
35
+ rules: {
36
+ 'no-em-dash': ['error', { flagDoubleHyphen: true }],
37
+ }
38
+ ```
39
+
40
+ ---
41
+
42
+ ### `no-weasel-words`
43
+
44
+ Bans reinforcement adverbs that weaken claims.
45
+
46
+ ```
47
+ error[no-weasel-words]: remove "actually" — it weakens the claim
48
+ ```
49
+
50
+ **Options:**
51
+
52
+ ```ts
53
+ {
54
+ words: string[] // Default: ['actually', 'truly', 'really', 'literally']
55
+ }
56
+ ```
57
+
58
+ **Config example:**
59
+
60
+ ```ts
61
+ rules: {
62
+ 'no-weasel-words': ['error', { words: ['actually', 'truly', 'really', 'literally', 'just', 'simply'] }],
63
+ }
64
+ ```
65
+
66
+ ---
67
+
68
+ ### `no-rhetorical-scaffolding`
69
+
70
+ Bans two formulaic patterns:
71
+
72
+ 1. `X is Y, not Z` constructions
73
+ 2. `Without X... With X...` sentence pairs
74
+
75
+ ```
76
+ error[no-rhetorical-scaffolding]: avoid "X is Y, not Z" — state the claim directly
77
+ error[no-rhetorical-scaffolding]: avoid "Without X / With X" — drop the setup and make the claim
78
+ ```
79
+
80
+ **Options:**
81
+
82
+ ```ts
83
+ {
84
+ allowIsNotConstruction?: boolean // Disable pattern 1. Default false.
85
+ allowWithoutWithConstruction?: boolean // Disable pattern 2. Default false.
86
+ extraPatterns?: string[] // Additional regex patterns to ban.
87
+ }
88
+ ```
@@ -0,0 +1,29 @@
1
+ import { Rule } from '@faircopy/core';
2
+
3
+ interface NoEmDashOptions {
4
+ /** Additionally flag en-dashes (U+2013). Default false. */
5
+ flagEnDash?: boolean;
6
+ /** Additionally flag ASCII double-hyphen --. Default false. */
7
+ flagDoubleHyphen?: boolean;
8
+ }
9
+ declare const noEmDash: Rule<NoEmDashOptions>;
10
+
11
+ interface NoWeaselWordsOptions {
12
+ words: string[];
13
+ }
14
+ declare const noWeaselWords: Rule<NoWeaselWordsOptions>;
15
+
16
+ interface NoRhetoricalScaffoldingOptions {
17
+ /** Disable "X is Y, not Z" detection. Default false. */
18
+ allowIsNotConstruction?: boolean;
19
+ /** Disable "Without X / With X" detection. Default false. */
20
+ allowWithoutWithConstruction?: boolean;
21
+ /** Additional banned patterns as regex strings. */
22
+ extraPatterns?: string[];
23
+ }
24
+ declare const noRhetoricalScaffolding: Rule<NoRhetoricalScaffoldingOptions>;
25
+
26
+ /** All built-in rules keyed by their rule ID. */
27
+ declare const ruleRegistry: Map<string, Rule>;
28
+
29
+ export { type NoEmDashOptions, type NoRhetoricalScaffoldingOptions, type NoWeaselWordsOptions, noEmDash, noRhetoricalScaffolding, noWeaselWords, ruleRegistry };
package/dist/index.js ADDED
@@ -0,0 +1,125 @@
1
+ // src/no-em-dash.ts
2
+ var noEmDash = {
3
+ id: "no-em-dash",
4
+ description: "Ban the em-dash character in marketing copy",
5
+ defaults: { flagEnDash: false, flagDoubleHyphen: false },
6
+ help: "Em-dashes are a stylistic tell. Split the sentence at the break. Use a period, a semicolon, parentheses, or a new sentence. If the clauses genuinely belong together and a comma reads worse, write shorter sentences.",
7
+ check({ text, sourceMap, options }) {
8
+ const diagnostics = [];
9
+ const opts = { ...noEmDash.defaults, ...options };
10
+ const flag = (re, message) => {
11
+ let m;
12
+ while ((m = re.exec(text)) !== null) {
13
+ const start = sourceMap[m.index];
14
+ const end = sourceMap[m.index + m[0].length - 1] + 1;
15
+ diagnostics.push({ ruleId: "no-em-dash", severity: "error", message, range: { start, end }, help: noEmDash.help });
16
+ }
17
+ };
18
+ flag(/—/g, "use a sentence break instead of an em-dash");
19
+ if (opts.flagEnDash) flag(/–/g, "use a hyphen instead of an en-dash");
20
+ if (opts.flagDoubleHyphen) flag(/--/g, "use a sentence break instead of --");
21
+ return diagnostics;
22
+ }
23
+ };
24
+
25
+ // src/no-weasel-words.ts
26
+ var DEFAULT_WORDS = ["actually", "truly", "really", "literally"];
27
+ var noWeaselWords = {
28
+ id: "no-weasel-words",
29
+ description: "Ban reinforcement adverbs that protest too much",
30
+ defaults: { words: DEFAULT_WORDS },
31
+ help: "Reinforcement adverbs defend a claim instead of making it. Delete the word. If the sentence no longer reads right, the original claim was the problem \u2014 rewrite it, don't prop it up.",
32
+ check({ text, sourceMap, options }) {
33
+ const diagnostics = [];
34
+ const words = options.words?.length ? options.words : DEFAULT_WORDS;
35
+ for (const word of words) {
36
+ const re = new RegExp(`\\b${word}\\b`, "gi");
37
+ let m;
38
+ while ((m = re.exec(text)) !== null) {
39
+ const start = sourceMap[m.index];
40
+ const end = sourceMap[m.index + m[0].length - 1] + 1;
41
+ diagnostics.push({
42
+ ruleId: "no-weasel-words",
43
+ severity: "error",
44
+ message: `remove "${m[0].toLowerCase()}" \u2014 it weakens the claim`,
45
+ range: { start, end },
46
+ help: noWeaselWords.help
47
+ });
48
+ }
49
+ }
50
+ return diagnostics;
51
+ }
52
+ };
53
+
54
+ // src/no-rhetorical-scaffolding.ts
55
+ var IS_NOT_RE = /\b(is|are|was|were)\s+[^.!?]{1,80},\s+not\s+(a|an|the|just|only|merely|simply)\b/gi;
56
+ var WITHOUT_WITH_RE = /\bWithout\b[^.!?]{1,200}[.!?]\s*(?:[^.!?]{1,200}[.!?]\s*){0,2}With\b/gs;
57
+ var noRhetoricalScaffolding = {
58
+ id: "no-rhetorical-scaffolding",
59
+ description: 'Ban formulaic "X is Y, not Z" and "Without X / With X" patterns',
60
+ defaults: { allowIsNotConstruction: false, allowWithoutWithConstruction: false, extraPatterns: [] },
61
+ help: "These patterns spend a clause denying a straw man or performing a reveal instead of making a claim. Delete the setup and keep the claim.",
62
+ check({ text, sourceMap, options }) {
63
+ const diagnostics = [];
64
+ const opts = { ...noRhetoricalScaffolding.defaults, ...options };
65
+ if (!opts.allowIsNotConstruction) {
66
+ const re = new RegExp(IS_NOT_RE.source, IS_NOT_RE.flags);
67
+ let m;
68
+ while ((m = re.exec(text)) !== null) {
69
+ const start = sourceMap[m.index];
70
+ const end = sourceMap[m.index + m[0].length - 1] + 1;
71
+ diagnostics.push({
72
+ ruleId: "no-rhetorical-scaffolding",
73
+ severity: "error",
74
+ message: 'avoid "X is Y, not Z" \u2014 state the claim directly',
75
+ range: { start, end },
76
+ help: noRhetoricalScaffolding.help
77
+ });
78
+ }
79
+ }
80
+ if (!opts.allowWithoutWithConstruction) {
81
+ const re = new RegExp(WITHOUT_WITH_RE.source, WITHOUT_WITH_RE.flags);
82
+ let m;
83
+ while ((m = re.exec(text)) !== null) {
84
+ const start = sourceMap[m.index];
85
+ const end = sourceMap[m.index + m[0].length - 1] + 1;
86
+ diagnostics.push({
87
+ ruleId: "no-rhetorical-scaffolding",
88
+ severity: "error",
89
+ message: 'avoid "Without X / With X" \u2014 drop the setup and make the claim',
90
+ range: { start, end },
91
+ help: noRhetoricalScaffolding.help
92
+ });
93
+ }
94
+ }
95
+ for (const pattern of opts.extraPatterns ?? []) {
96
+ const re = new RegExp(pattern, "gi");
97
+ let m;
98
+ while ((m = re.exec(text)) !== null) {
99
+ const start = sourceMap[m.index];
100
+ const end = sourceMap[m.index + m[0].length - 1] + 1;
101
+ diagnostics.push({
102
+ ruleId: "no-rhetorical-scaffolding",
103
+ severity: "error",
104
+ message: "banned rhetorical pattern",
105
+ range: { start, end }
106
+ });
107
+ }
108
+ }
109
+ return diagnostics;
110
+ }
111
+ };
112
+
113
+ // src/index.ts
114
+ var ruleRegistry = /* @__PURE__ */ new Map([
115
+ ["no-em-dash", noEmDash],
116
+ ["no-weasel-words", noWeaselWords],
117
+ ["no-rhetorical-scaffolding", noRhetoricalScaffolding]
118
+ ]);
119
+ export {
120
+ noEmDash,
121
+ noRhetoricalScaffolding,
122
+ noWeaselWords,
123
+ ruleRegistry
124
+ };
125
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/no-em-dash.ts","../src/no-weasel-words.ts","../src/no-rhetorical-scaffolding.ts","../src/index.ts"],"sourcesContent":["import type { Rule, RuleInput, Diagnostic } from '@faircopy/core'\n\nexport interface NoEmDashOptions {\n /** Additionally flag en-dashes (U+2013). Default false. */\n flagEnDash?: boolean\n /** Additionally flag ASCII double-hyphen --. Default false. */\n flagDoubleHyphen?: boolean\n}\n\nexport const noEmDash: Rule<NoEmDashOptions> = {\n id: 'no-em-dash',\n description: 'Ban the em-dash character in marketing copy',\n defaults: { flagEnDash: false, flagDoubleHyphen: false },\n help: 'Em-dashes are a stylistic tell. Split the sentence at the break. ' +\n 'Use a period, a semicolon, parentheses, or a new sentence. ' +\n 'If the clauses genuinely belong together and a comma reads worse, write shorter sentences.',\n\n check({ text, sourceMap, options }: RuleInput<NoEmDashOptions>): Diagnostic[] {\n const diagnostics: Diagnostic[] = []\n const opts = { ...noEmDash.defaults, ...options }\n\n const flag = (re: RegExp, message: string) => {\n let m: RegExpExecArray | null\n while ((m = re.exec(text)) !== null) {\n const start = sourceMap[m.index]!\n const end = sourceMap[m.index + m[0].length - 1]! + 1\n diagnostics.push({ ruleId: 'no-em-dash', severity: 'error', message, range: { start, end }, help: noEmDash.help })\n }\n }\n\n flag(/—/g, 'use a sentence break instead of an em-dash')\n if (opts.flagEnDash) flag(/–/g, 'use a hyphen instead of an en-dash')\n if (opts.flagDoubleHyphen) flag(/--/g, 'use a sentence break instead of --')\n\n return diagnostics\n },\n}\n","import type { Rule, RuleInput, Diagnostic } from '@faircopy/core'\n\nexport interface NoWeaselWordsOptions {\n words: string[]\n}\n\nconst DEFAULT_WORDS = ['actually', 'truly', 'really', 'literally']\n\nexport const noWeaselWords: Rule<NoWeaselWordsOptions> = {\n id: 'no-weasel-words',\n description: 'Ban reinforcement adverbs that protest too much',\n defaults: { words: DEFAULT_WORDS },\n help: 'Reinforcement adverbs defend a claim instead of making it. ' +\n 'Delete the word. If the sentence no longer reads right, ' +\n 'the original claim was the problem — rewrite it, don\\'t prop it up.',\n\n check({ text, sourceMap, options }: RuleInput<NoWeaselWordsOptions>): Diagnostic[] {\n const diagnostics: Diagnostic[] = []\n const words = options.words?.length ? options.words : DEFAULT_WORDS\n\n for (const word of words) {\n const re = new RegExp(`\\\\b${word}\\\\b`, 'gi')\n let m: RegExpExecArray | null\n while ((m = re.exec(text)) !== null) {\n const start = sourceMap[m.index]!\n const end = sourceMap[m.index + m[0].length - 1]! + 1\n diagnostics.push({\n ruleId: 'no-weasel-words',\n severity: 'error',\n message: `remove \"${m[0].toLowerCase()}\" — it weakens the claim`,\n range: { start, end },\n help: noWeaselWords.help,\n })\n }\n }\n\n return diagnostics\n },\n}\n","import type { Rule, RuleInput, Diagnostic } from '@faircopy/core'\n\nexport interface NoRhetoricalScaffoldingOptions {\n /** Disable \"X is Y, not Z\" detection. Default false. */\n allowIsNotConstruction?: boolean\n /** Disable \"Without X / With X\" detection. Default false. */\n allowWithoutWithConstruction?: boolean\n /** Additional banned patterns as regex strings. */\n extraPatterns?: string[]\n}\n\n// \"X is Y, not a/an/the/just/only/merely/simply...\"\nconst IS_NOT_RE = /\\b(is|are|was|were)\\s+[^.!?]{1,80},\\s+not\\s+(a|an|the|just|only|merely|simply)\\b/gi\n\n// \"Without ... [sentences] ... With ...\"\nconst WITHOUT_WITH_RE = /\\bWithout\\b[^.!?]{1,200}[.!?]\\s*(?:[^.!?]{1,200}[.!?]\\s*){0,2}With\\b/gs\n\nexport const noRhetoricalScaffolding: Rule<NoRhetoricalScaffoldingOptions> = {\n id: 'no-rhetorical-scaffolding',\n description: 'Ban formulaic \"X is Y, not Z\" and \"Without X / With X\" patterns',\n defaults: { allowIsNotConstruction: false, allowWithoutWithConstruction: false, extraPatterns: [] },\n help: 'These patterns spend a clause denying a straw man or performing a reveal instead of making a claim. ' +\n 'Delete the setup and keep the claim.',\n\n check({ text, sourceMap, options }: RuleInput<NoRhetoricalScaffoldingOptions>): Diagnostic[] {\n const diagnostics: Diagnostic[] = []\n const opts = { ...noRhetoricalScaffolding.defaults, ...options }\n\n if (!opts.allowIsNotConstruction) {\n const re = new RegExp(IS_NOT_RE.source, IS_NOT_RE.flags)\n let m: RegExpExecArray | null\n while ((m = re.exec(text)) !== null) {\n const start = sourceMap[m.index]!\n const end = sourceMap[m.index + m[0].length - 1]! + 1\n diagnostics.push({\n ruleId: 'no-rhetorical-scaffolding',\n severity: 'error',\n message: 'avoid \"X is Y, not Z\" — state the claim directly',\n range: { start, end },\n help: noRhetoricalScaffolding.help,\n })\n }\n }\n\n if (!opts.allowWithoutWithConstruction) {\n const re = new RegExp(WITHOUT_WITH_RE.source, WITHOUT_WITH_RE.flags)\n let m: RegExpExecArray | null\n while ((m = re.exec(text)) !== null) {\n const start = sourceMap[m.index]!\n const end = sourceMap[m.index + m[0].length - 1]! + 1\n diagnostics.push({\n ruleId: 'no-rhetorical-scaffolding',\n severity: 'error',\n message: 'avoid \"Without X / With X\" — drop the setup and make the claim',\n range: { start, end },\n help: noRhetoricalScaffolding.help,\n })\n }\n }\n\n for (const pattern of opts.extraPatterns ?? []) {\n const re = new RegExp(pattern, 'gi')\n let m: RegExpExecArray | null\n while ((m = re.exec(text)) !== null) {\n const start = sourceMap[m.index]!\n const end = sourceMap[m.index + m[0].length - 1]! + 1\n diagnostics.push({\n ruleId: 'no-rhetorical-scaffolding',\n severity: 'error',\n message: 'banned rhetorical pattern',\n range: { start, end },\n })\n }\n }\n\n return diagnostics\n },\n}\n","import type { Rule } from '@faircopy/core'\nimport { noEmDash } from './no-em-dash.js'\nimport { noWeaselWords } from './no-weasel-words.js'\nimport { noRhetoricalScaffolding } from './no-rhetorical-scaffolding.js'\n\nexport { noEmDash } from './no-em-dash.js'\nexport { noWeaselWords } from './no-weasel-words.js'\nexport { noRhetoricalScaffolding } from './no-rhetorical-scaffolding.js'\nexport type { NoEmDashOptions } from './no-em-dash.js'\nexport type { NoWeaselWordsOptions } from './no-weasel-words.js'\nexport type { NoRhetoricalScaffoldingOptions } from './no-rhetorical-scaffolding.js'\n\n/** All built-in rules keyed by their rule ID. */\nexport const ruleRegistry: Map<string, Rule> = new Map([\n ['no-em-dash', noEmDash as Rule],\n ['no-weasel-words', noWeaselWords as Rule],\n ['no-rhetorical-scaffolding', noRhetoricalScaffolding as Rule],\n])\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@faircopy/rules-default",
3
+ "version": "0.1.0",
4
+ "description": "Default ruleset for faircopy: no-em-dash, no-weasel-words, no-rhetorical-scaffolding",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md"
15
+ ],
16
+ "dependencies": {
17
+ "@faircopy/core": "0.1.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/bun": "latest",
21
+ "tsup": "^8.4.0",
22
+ "typescript": "^5.8.0"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "license": "MIT",
28
+ "author": "omniaura",
29
+ "scripts": {
30
+ "build": "tsup",
31
+ "typecheck": "tsc --noEmit",
32
+ "test": "bun test"
33
+ }
34
+ }