opengrammar-server 2.0.644277
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.npm.md +95 -0
- package/bin/opengrammar-server.js +111 -0
- package/dist/server.js +48639 -0
- package/package.json +80 -0
- package/server-node.ts +159 -0
- package/server.ts +15 -0
- package/src/analyzer.ts +542 -0
- package/src/dictionary.ts +1973 -0
- package/src/index.ts +978 -0
- package/src/nlp/nlp-engine.ts +17 -0
- package/src/nlp/tone-analyzer.ts +269 -0
- package/src/rephraser.ts +146 -0
- package/src/rules/categories/academic-writing.ts +182 -0
- package/src/rules/categories/adjectives-adverbs.ts +152 -0
- package/src/rules/categories/articles.ts +160 -0
- package/src/rules/categories/business-writing.ts +250 -0
- package/src/rules/categories/capitalization.ts +79 -0
- package/src/rules/categories/clarity.ts +117 -0
- package/src/rules/categories/common-errors.ts +601 -0
- package/src/rules/categories/confused-words.ts +219 -0
- package/src/rules/categories/conjunctions.ts +176 -0
- package/src/rules/categories/dangling-modifiers.ts +123 -0
- package/src/rules/categories/formality.ts +274 -0
- package/src/rules/categories/formatting-idioms.ts +323 -0
- package/src/rules/categories/gerund-infinitive.ts +274 -0
- package/src/rules/categories/grammar-advanced.ts +294 -0
- package/src/rules/categories/grammar.ts +286 -0
- package/src/rules/categories/inclusive-language.ts +280 -0
- package/src/rules/categories/nouns-pronouns.ts +233 -0
- package/src/rules/categories/prepositions-extended.ts +217 -0
- package/src/rules/categories/prepositions.ts +159 -0
- package/src/rules/categories/punctuation.ts +347 -0
- package/src/rules/categories/quantity-agreement.ts +200 -0
- package/src/rules/categories/readability.ts +293 -0
- package/src/rules/categories/sentence-structure.ts +100 -0
- package/src/rules/categories/spelling-advanced.ts +164 -0
- package/src/rules/categories/spelling.ts +119 -0
- package/src/rules/categories/style-tone.ts +511 -0
- package/src/rules/categories/style.ts +78 -0
- package/src/rules/categories/subject-verb-agreement.ts +201 -0
- package/src/rules/categories/tone-rules.ts +206 -0
- package/src/rules/categories/verb-tense.ts +582 -0
- package/src/rules/context-filter.ts +446 -0
- package/src/rules/index.ts +96 -0
- package/src/rules/ruleset-part1-cj-pu-sp.json +657 -0
- package/src/rules/ruleset-part1-np-ad-aa-pr.json +831 -0
- package/src/rules/ruleset-part1-ss-vt.json +907 -0
- package/src/rules/ruleset-part2-cw-st-nf.json +318 -0
- package/src/rules/ruleset-part3-aw-bw-il-rd.json +161 -0
- package/src/rules/types.ts +79 -0
- package/src/shared-types.ts +152 -0
- package/src/spellchecker.ts +418 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { Issue } from '../../shared-types.js';
|
|
2
|
+
import { createRegexRule, type Rule } from '../types.js';
|
|
3
|
+
|
|
4
|
+
export const clarityRules: Rule[] = [
|
|
5
|
+
// Repetition
|
|
6
|
+
createRegexRule({
|
|
7
|
+
id: 'repetition',
|
|
8
|
+
category: 'clarity',
|
|
9
|
+
pattern: /\b(\w+)\s+\1\b/i,
|
|
10
|
+
suggestion: (match) => match[1] || '',
|
|
11
|
+
reason: 'Repeated word detected.',
|
|
12
|
+
}),
|
|
13
|
+
|
|
14
|
+
// Redundant Phrases
|
|
15
|
+
...Object.entries({
|
|
16
|
+
'absolutely essential': 'essential',
|
|
17
|
+
'advance planning': 'planning',
|
|
18
|
+
'basic fundamentals': 'fundamentals',
|
|
19
|
+
'close proximity': 'proximity',
|
|
20
|
+
'completely eliminate': 'eliminate',
|
|
21
|
+
'end result': 'result',
|
|
22
|
+
'exact same': 'same',
|
|
23
|
+
'final outcome': 'outcome',
|
|
24
|
+
'free gift': 'gift',
|
|
25
|
+
'future plans': 'plans',
|
|
26
|
+
'past history': 'history',
|
|
27
|
+
'personal opinion': 'opinion',
|
|
28
|
+
'true fact': 'fact',
|
|
29
|
+
'unexpected surprise': 'surprise',
|
|
30
|
+
}).map(([phrase, replacement]) =>
|
|
31
|
+
createRegexRule({
|
|
32
|
+
id: `redundant-${phrase.replace(' ', '-')}`,
|
|
33
|
+
category: 'clarity',
|
|
34
|
+
pattern: new RegExp(`\\b${phrase}\\b`, 'i'),
|
|
35
|
+
suggestion: replacement,
|
|
36
|
+
reason: `Redundant phrase. Use "${replacement}" instead.`,
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
|
|
40
|
+
// Cliches
|
|
41
|
+
...[
|
|
42
|
+
'at the end of the day',
|
|
43
|
+
'back to the drawing board',
|
|
44
|
+
'beat around the bush',
|
|
45
|
+
'best of both worlds',
|
|
46
|
+
'bite the bullet',
|
|
47
|
+
'cut corners',
|
|
48
|
+
'hit the nail on the head',
|
|
49
|
+
'in the nick of time',
|
|
50
|
+
'piece of cake',
|
|
51
|
+
'spill the beans',
|
|
52
|
+
'under the weather',
|
|
53
|
+
'when pigs fly',
|
|
54
|
+
].map((cliche) =>
|
|
55
|
+
createRegexRule({
|
|
56
|
+
id: `cliche-${cliche.replace(/\s/g, '-')}`,
|
|
57
|
+
category: 'style',
|
|
58
|
+
pattern: new RegExp(`\\b${cliche}\\b`, 'i'),
|
|
59
|
+
suggestion: 'Consider using more original language',
|
|
60
|
+
reason: 'This is a cliché. Consider using more original language.',
|
|
61
|
+
}),
|
|
62
|
+
),
|
|
63
|
+
|
|
64
|
+
// Weak Words
|
|
65
|
+
...Object.entries({
|
|
66
|
+
'very good': 'excellent',
|
|
67
|
+
'very bad': 'terrible',
|
|
68
|
+
'very big': 'enormous',
|
|
69
|
+
'very small': 'tiny',
|
|
70
|
+
'very important': 'crucial',
|
|
71
|
+
'very interesting': 'fascinating',
|
|
72
|
+
'kind of': 'somewhat',
|
|
73
|
+
'sort of': 'somewhat',
|
|
74
|
+
'a lot': 'much',
|
|
75
|
+
stuff: 'things',
|
|
76
|
+
nice: 'pleasant',
|
|
77
|
+
}).map(([weak, strong]) =>
|
|
78
|
+
createRegexRule({
|
|
79
|
+
id: `weak-word-${weak.replace(' ', '-')}`,
|
|
80
|
+
category: 'style',
|
|
81
|
+
pattern: new RegExp(`\\b${weak}\\b`, 'i'),
|
|
82
|
+
suggestion: strong,
|
|
83
|
+
reason: `Consider a stronger word: "${strong}".`,
|
|
84
|
+
}),
|
|
85
|
+
),
|
|
86
|
+
|
|
87
|
+
// Long Sentences (Custom logic because JS Regex doesn't count words easily)
|
|
88
|
+
{
|
|
89
|
+
id: 'long-sentences',
|
|
90
|
+
type: 'regex',
|
|
91
|
+
category: 'clarity',
|
|
92
|
+
reason: 'Sentence is too long and hard to read.',
|
|
93
|
+
pattern: /[^.!?]+[.!?]+/g, // Not used strictly, but required by interface
|
|
94
|
+
suggestion: 'Consider splitting into shorter sentences',
|
|
95
|
+
check: (text: string): Issue[] => {
|
|
96
|
+
const issues: Issue[] = [];
|
|
97
|
+
const sentences = text.match(/[^.!?]+[.!?]+/g) || [];
|
|
98
|
+
let currentIndex = 0;
|
|
99
|
+
sentences.forEach((sentence) => {
|
|
100
|
+
const words = sentence.trim().split(/\s+/).length;
|
|
101
|
+
if (words > 35) {
|
|
102
|
+
issues.push({
|
|
103
|
+
id: `long-sentence-${currentIndex}`,
|
|
104
|
+
type: 'clarity',
|
|
105
|
+
original: sentence.substring(0, 30) + '...',
|
|
106
|
+
suggestion: 'Consider splitting into shorter sentences',
|
|
107
|
+
reason: `This sentence has ${words} words. Shorter sentences are easier to read.`,
|
|
108
|
+
offset: currentIndex,
|
|
109
|
+
length: sentence.length,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
currentIndex += sentence.length;
|
|
113
|
+
});
|
|
114
|
+
return issues;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
];
|