hunspell-reader 5.14.0 → 5.15.3
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/dist/IterableHunspellReader.d.ts +4 -3
- package/dist/IterableHunspellReader.js +2 -2
- package/dist/aff.d.ts +1 -179
- package/dist/aff.js +31 -15
- package/dist/affDef.d.ts +180 -0
- package/dist/affDef.js +7 -0
- package/dist/affReader.d.ts +2 -1
- package/dist/affReader.js +179 -87
- package/dist/app.js +4 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -1
- package/dist/util.d.ts +7 -0
- package/dist/util.js +22 -1
- package/package.json +6 -23
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Aff, AffWord } from './aff';
|
|
2
1
|
import { Sequence } from 'gensequence';
|
|
2
|
+
import { Aff } from './aff';
|
|
3
|
+
import type { AffWord } from './affDef';
|
|
3
4
|
import { WordInfo } from './types';
|
|
4
5
|
export { WordInfo } from './types';
|
|
5
6
|
export interface HunspellSrcData {
|
|
@@ -37,14 +38,14 @@ export declare class IterableHunspellReader implements Iterable<string> {
|
|
|
37
38
|
* @param tapPreApplyRules -- optional function to be called before rules are applied to a word.
|
|
38
39
|
* It is mostly used for monitoring progress in combination with `size`.
|
|
39
40
|
*/
|
|
40
|
-
seqAffWords(tapPreApplyRules?: (dicEntry: string, index: number) =>
|
|
41
|
+
seqAffWords(tapPreApplyRules?: (dicEntry: string, index: number) => void, maxDepth?: number): Sequence<AffWord>;
|
|
41
42
|
/**
|
|
42
43
|
* create an iterable sequence of the words in the dictionary.
|
|
43
44
|
*
|
|
44
45
|
* @param tapPreApplyRules -- optional function to be called before rules are applied to a word.
|
|
45
46
|
* It is mostly used for monitoring progress in combination with `size`.
|
|
46
47
|
*/
|
|
47
|
-
seqTransformDictionaryEntries(tapPreApplyRules?: (dicEntry: string, index: number) =>
|
|
48
|
+
seqTransformDictionaryEntries(tapPreApplyRules?: (dicEntry: string, index: number) => void, maxDepth?: number): Sequence<AffWord[]>;
|
|
48
49
|
/**
|
|
49
50
|
* Iterator for all the words in the dictionary. The words are in the order found in the .dic after the
|
|
50
51
|
* transformations have been applied. Forbidden and CompoundOnly ARE INCLUDED.
|
|
@@ -20,10 +20,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.createMatchingWordsFilter = exports.IterableHunspellReader = void 0;
|
|
23
|
-
const affReader_1 = require("./affReader");
|
|
24
|
-
const gensequence_1 = require("gensequence");
|
|
25
23
|
const fs = __importStar(require("fs-extra"));
|
|
24
|
+
const gensequence_1 = require("gensequence");
|
|
26
25
|
const iconv_lite_1 = require("iconv-lite");
|
|
26
|
+
const affReader_1 = require("./affReader");
|
|
27
27
|
const util_1 = require("./util");
|
|
28
28
|
const defaultEncoding = 'UTF-8';
|
|
29
29
|
class IterableHunspellReader {
|
package/dist/aff.d.ts
CHANGED
|
@@ -1,183 +1,5 @@
|
|
|
1
|
+
import type { AffInfo, AffWord, AffWordFlags, Fx, Rule, Substitution } from './affDef';
|
|
1
2
|
import { Converter } from './converter';
|
|
2
|
-
export interface Fx {
|
|
3
|
-
type: string;
|
|
4
|
-
id: string;
|
|
5
|
-
combinable: boolean;
|
|
6
|
-
substitutionSets: Substitutions;
|
|
7
|
-
count?: string;
|
|
8
|
-
extra?: string[];
|
|
9
|
-
}
|
|
10
|
-
export declare type Substitutions = Map<string, SubstitutionSet>;
|
|
11
|
-
export interface Substitution {
|
|
12
|
-
remove: string;
|
|
13
|
-
attach: string;
|
|
14
|
-
attachRules?: string;
|
|
15
|
-
replace: RegExp;
|
|
16
|
-
extra?: string;
|
|
17
|
-
}
|
|
18
|
-
export interface SubstitutionSet {
|
|
19
|
-
match: RegExp;
|
|
20
|
-
substitutions: Substitution[];
|
|
21
|
-
}
|
|
22
|
-
export interface Rep {
|
|
23
|
-
match: string;
|
|
24
|
-
replaceWith: string;
|
|
25
|
-
}
|
|
26
|
-
export interface Conv {
|
|
27
|
-
from: string;
|
|
28
|
-
to: string;
|
|
29
|
-
}
|
|
30
|
-
export interface AffTransformFlags {
|
|
31
|
-
KEEPCASE?: string;
|
|
32
|
-
WARN?: string;
|
|
33
|
-
NEEDAFFIX?: string;
|
|
34
|
-
FORCEUCASE?: string;
|
|
35
|
-
FORBIDDENWORD?: string;
|
|
36
|
-
NOSUGGEST?: string;
|
|
37
|
-
COMPOUNDBEGIN?: string;
|
|
38
|
-
COMPOUNDEND?: string;
|
|
39
|
-
COMPOUNDFLAG?: string;
|
|
40
|
-
COMPOUNDFORBIDFLAG?: string;
|
|
41
|
-
COMPOUNDMIDDLE?: string;
|
|
42
|
-
COMPOUNDPERMITFLAG?: string;
|
|
43
|
-
ONLYINCOMPOUND?: string;
|
|
44
|
-
}
|
|
45
|
-
export interface AffInfo extends AffTransformFlags {
|
|
46
|
-
SET: string;
|
|
47
|
-
TRY?: string;
|
|
48
|
-
KEY?: string;
|
|
49
|
-
WORDCHARS?: string;
|
|
50
|
-
NOSPLITSUGS?: boolean;
|
|
51
|
-
MAXCPDSUGS?: number;
|
|
52
|
-
ONLYMAXDIFF?: boolean;
|
|
53
|
-
MAXDIFF?: number;
|
|
54
|
-
BREAK?: number;
|
|
55
|
-
FLAG?: string;
|
|
56
|
-
MAP?: string[];
|
|
57
|
-
ICONV?: Conv[];
|
|
58
|
-
OCONV?: Conv[];
|
|
59
|
-
REP?: Rep[];
|
|
60
|
-
AF?: string[];
|
|
61
|
-
COMPOUNDMIN?: number;
|
|
62
|
-
COMPOUNDRULE?: string[];
|
|
63
|
-
CHECKCOMPOUNDCASE?: boolean;
|
|
64
|
-
CHECKCOMPOUNDDUP?: boolean;
|
|
65
|
-
CHECKCOMPOUNDREP?: boolean;
|
|
66
|
-
CHECKCOMPOUNDPATTERN?: string[][];
|
|
67
|
-
PFX?: Map<string, Fx>;
|
|
68
|
-
SFX?: Map<string, Fx>;
|
|
69
|
-
}
|
|
70
|
-
export interface Rule {
|
|
71
|
-
id: string;
|
|
72
|
-
type: string;
|
|
73
|
-
flags?: AffWordFlags;
|
|
74
|
-
pfx?: Fx;
|
|
75
|
-
sfx?: Fx;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* AffWordFlags are the flags applied to a word after the hunspell rules have been applied.
|
|
79
|
-
* They are either `true` or `undefined`.
|
|
80
|
-
*/
|
|
81
|
-
export interface AffWordFlags {
|
|
82
|
-
/**
|
|
83
|
-
* COMPOUNDFLAG flag
|
|
84
|
-
*
|
|
85
|
-
* Words signed with COMPOUNDFLAG may be in compound words (except when word shorter than COMPOUNDMIN).
|
|
86
|
-
* Affixes with COMPOUNDFLAG also permits compounding of affixed words.
|
|
87
|
-
*
|
|
88
|
-
*/
|
|
89
|
-
isCompoundPermitted?: true;
|
|
90
|
-
/**
|
|
91
|
-
* COMPOUNDBEGIN flag
|
|
92
|
-
*
|
|
93
|
-
* Words signed with COMPOUNDBEGIN (or with a signed affix) may be first elements in compound words.
|
|
94
|
-
*
|
|
95
|
-
*/
|
|
96
|
-
canBeCompoundBegin?: true;
|
|
97
|
-
/**
|
|
98
|
-
* COMPOUNDMIDDLE flag
|
|
99
|
-
*
|
|
100
|
-
* Words signed with COMPOUNDMIDDLE (or with a signed affix) may be middle elements in compound words.
|
|
101
|
-
*
|
|
102
|
-
*/
|
|
103
|
-
canBeCompoundMiddle?: true;
|
|
104
|
-
/**
|
|
105
|
-
* COMPOUNDLAST flag
|
|
106
|
-
*
|
|
107
|
-
* Words signed with COMPOUNDLAST (or with a signed affix) may be last elements in compound words.
|
|
108
|
-
*
|
|
109
|
-
*/
|
|
110
|
-
canBeCompoundEnd?: true;
|
|
111
|
-
/**
|
|
112
|
-
* COMPOUNDPERMITFLAG flag
|
|
113
|
-
*
|
|
114
|
-
* Prefixes are allowed at the beginning of compounds, suffixes are allowed at the end of compounds by default.
|
|
115
|
-
* Affixes with COMPOUNDPERMITFLAG may be inside of compounds.
|
|
116
|
-
*
|
|
117
|
-
*/
|
|
118
|
-
isOnlyAllowedInCompound?: true;
|
|
119
|
-
/**
|
|
120
|
-
* COMPOUNDFORBIDFLAG flag
|
|
121
|
-
*
|
|
122
|
-
* Suffixes with this flag forbid compounding of the affixed word.
|
|
123
|
-
*
|
|
124
|
-
*/
|
|
125
|
-
isCompoundForbidden?: true;
|
|
126
|
-
/**
|
|
127
|
-
* WARN flag
|
|
128
|
-
*
|
|
129
|
-
* This flag is for rare words, which are also often spelling mistakes, see option -r of command line Hunspell and FORBIDWARN.
|
|
130
|
-
*/
|
|
131
|
-
isWarning?: true;
|
|
132
|
-
/**
|
|
133
|
-
* KEEPCASE flag
|
|
134
|
-
*
|
|
135
|
-
* Forbid uppercased and capitalized forms of words signed with KEEPCASE flags. Useful for special orthographies (measurements and
|
|
136
|
-
* currency often keep their case in uppercased texts) and writing systems (e.g. keeping lower case of IPA characters). Also valuable
|
|
137
|
-
* for words erroneously written in the wrong case.
|
|
138
|
-
*/
|
|
139
|
-
isKeepCase?: true;
|
|
140
|
-
/**
|
|
141
|
-
* FORCEUCASE flag
|
|
142
|
-
*
|
|
143
|
-
* Last word part of a compound with flag FORCEUCASE forces capitalization of the whole compound word.
|
|
144
|
-
* Eg. Dutch word "straat" (street) with FORCEUCASE flags will allowed only in capitalized compound forms,
|
|
145
|
-
* according to the Dutch spelling rules for proper names.
|
|
146
|
-
*/
|
|
147
|
-
isForceUCase?: true;
|
|
148
|
-
/**
|
|
149
|
-
* FORBIDDENWORD flag
|
|
150
|
-
*
|
|
151
|
-
* This flag signs forbidden word form. Because affixed forms are also forbidden, we can subtract a subset from set of the
|
|
152
|
-
* accepted affixed and compound words. Note: useful to forbid erroneous words, generated by the compounding mechanism.
|
|
153
|
-
*/
|
|
154
|
-
isForbiddenWord?: true;
|
|
155
|
-
/**
|
|
156
|
-
* NOSUGGEST flag
|
|
157
|
-
*
|
|
158
|
-
* Words signed with NOSUGGEST flag are not suggested (but still accepted when typed correctly). Proposed flag for vulgar
|
|
159
|
-
* and obscene words (see also SUBSTANDARD).
|
|
160
|
-
*/
|
|
161
|
-
isNoSuggest?: true;
|
|
162
|
-
/**
|
|
163
|
-
* NEEDAFFIX flag
|
|
164
|
-
*
|
|
165
|
-
* This flag signs virtual stems in the dictionary, words only valid when affixed. Except, if the dictionary word has a homonym
|
|
166
|
-
* or a zero affix. NEEDAFFIX works also with prefixes and prefix + suffix combinations (see tests/pseudoroot5.*).
|
|
167
|
-
*/
|
|
168
|
-
isNeedAffix?: true;
|
|
169
|
-
}
|
|
170
|
-
export interface AffWord {
|
|
171
|
-
word: string;
|
|
172
|
-
rules: string;
|
|
173
|
-
flags: AffWordFlags;
|
|
174
|
-
rulesApplied: string;
|
|
175
|
-
/** prefix + base + suffix == word */
|
|
176
|
-
base: string;
|
|
177
|
-
suffix: string;
|
|
178
|
-
prefix: string;
|
|
179
|
-
dic: string;
|
|
180
|
-
}
|
|
181
3
|
/** The `word` field in a Converted AffWord has been converted using the OCONV mapping */
|
|
182
4
|
export declare type ConvertedAffWord = AffWord;
|
|
183
5
|
export declare class Aff {
|
package/dist/aff.js
CHANGED
|
@@ -20,10 +20,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.debug = exports.filterAff = exports.compareAff = exports.asAffWord = exports.flagsToString = exports.affWordToColoredString = exports.logAffWord = exports.processRules = exports.Aff = void 0;
|
|
23
|
+
const GS = __importStar(require("gensequence"));
|
|
24
|
+
const gensequence_1 = require("gensequence");
|
|
23
25
|
const util = __importStar(require("util"));
|
|
24
26
|
const converter_1 = require("./converter");
|
|
25
|
-
const gensequence_1 = require("gensequence");
|
|
26
|
-
const GS = __importStar(require("gensequence"));
|
|
27
27
|
const util_1 = require("./util");
|
|
28
28
|
const log = false;
|
|
29
29
|
const DefaultMaxDepth = 5;
|
|
@@ -73,7 +73,7 @@ class Aff {
|
|
|
73
73
|
flags: { ...acc.flags, ...rule.flags },
|
|
74
74
|
}), { rulesApplied: affWord.rulesApplied, flags: affWord.flags });
|
|
75
75
|
const rules = this.joinRules(allRules.filter((rule) => !rule.flags).map((rule) => rule.id));
|
|
76
|
-
const affixRules = allRules.map((rule) => rule.sfx || rule.pfx).filter(
|
|
76
|
+
const affixRules = allRules.map((rule) => rule.sfx || rule.pfx).filter(util_1.isDefined);
|
|
77
77
|
const wordWithFlags = { word, flags, rulesApplied, rules: '', base, suffix, prefix, dic };
|
|
78
78
|
return [wordWithFlags, ...this.applyAffixesToWord(affixRules, { ...wordWithFlags, rules }, remainingDepth)]
|
|
79
79
|
.filter(({ flags }) => !flags.isNeedAffix)
|
|
@@ -141,10 +141,11 @@ class Aff {
|
|
|
141
141
|
}
|
|
142
142
|
getMatchingRules(rules) {
|
|
143
143
|
const { AF = [] } = this.affInfo;
|
|
144
|
-
const
|
|
144
|
+
const idx = parseInt(rules, 10);
|
|
145
|
+
const rulesToSplit = AF[idx] || rules;
|
|
145
146
|
return this.separateRules(rulesToSplit)
|
|
146
|
-
.map((key) => this.rules
|
|
147
|
-
.filter(
|
|
147
|
+
.map((key) => this.rules.get(key))
|
|
148
|
+
.filter(util_1.isDefined);
|
|
148
149
|
}
|
|
149
150
|
joinRules(rules) {
|
|
150
151
|
switch (this.affInfo.FLAG) {
|
|
@@ -175,7 +176,7 @@ exports.Aff = Aff;
|
|
|
175
176
|
function signature(aff) {
|
|
176
177
|
const { word, flags } = aff;
|
|
177
178
|
const sig = Object.entries(flags)
|
|
178
|
-
.filter((e) => e[1])
|
|
179
|
+
.filter((e) => !!e[1])
|
|
179
180
|
.map((f) => flagToStringMap[f[0]])
|
|
180
181
|
.sort()
|
|
181
182
|
.join('');
|
|
@@ -190,12 +191,13 @@ function processRules(affInfo) {
|
|
|
190
191
|
.map((pfx) => ({ id: pfx.id, type: 'pfx', pfx }));
|
|
191
192
|
const flagRules = GS.sequenceFromObject(affInfo)
|
|
192
193
|
.filter(([key, value]) => !!affFlag[key] && !!value)
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
193
195
|
.map(([key, value]) => ({ id: value, type: 'flag', flags: affFlag[key] }));
|
|
194
196
|
const rules = sfxRules
|
|
195
197
|
.concat(pfxRules)
|
|
196
198
|
.concat(flagRules)
|
|
197
199
|
.reduce((acc, rule) => {
|
|
198
|
-
acc
|
|
200
|
+
acc.set(rule.id, rule);
|
|
199
201
|
return acc;
|
|
200
202
|
}, new Map());
|
|
201
203
|
return rules;
|
|
@@ -216,7 +218,7 @@ const affFlag = {
|
|
|
216
218
|
COMPOUNDFORBIDFLAG: { isCompoundForbidden: true },
|
|
217
219
|
ONLYINCOMPOUND: { isOnlyAllowedInCompound: true },
|
|
218
220
|
};
|
|
219
|
-
const
|
|
221
|
+
const _FlagToStringMap = {
|
|
220
222
|
isCompoundPermitted: 'C',
|
|
221
223
|
canBeCompoundBegin: 'B',
|
|
222
224
|
canBeCompoundMiddle: 'M',
|
|
@@ -230,6 +232,22 @@ const flagToStringMap = {
|
|
|
230
232
|
isNeedAffix: 'A',
|
|
231
233
|
isCompoundForbidden: '-',
|
|
232
234
|
};
|
|
235
|
+
const _FlagToLongStringMap = {
|
|
236
|
+
isCompoundPermitted: 'CompoundPermitted',
|
|
237
|
+
canBeCompoundBegin: 'CompoundBegin',
|
|
238
|
+
canBeCompoundMiddle: 'CompoundMiddle',
|
|
239
|
+
canBeCompoundEnd: 'CompoundEnd',
|
|
240
|
+
isOnlyAllowedInCompound: 'OnlyInCompound',
|
|
241
|
+
isWarning: 'Warning',
|
|
242
|
+
isKeepCase: 'KeepCase',
|
|
243
|
+
isForceUCase: 'ForceUpperCase',
|
|
244
|
+
isForbiddenWord: 'Forbidden',
|
|
245
|
+
isNoSuggest: 'NoSuggest',
|
|
246
|
+
isNeedAffix: 'NeedAffix',
|
|
247
|
+
isCompoundForbidden: 'CompoundForbidden',
|
|
248
|
+
};
|
|
249
|
+
const flagToStringMap = _FlagToStringMap;
|
|
250
|
+
const flagToLongStringMap = _FlagToLongStringMap;
|
|
233
251
|
function logAffWord(affWord, message) {
|
|
234
252
|
/* istanbul ignore if */
|
|
235
253
|
if (log) {
|
|
@@ -248,13 +266,11 @@ function affWordToColoredString(affWord) {
|
|
|
248
266
|
exports.affWordToColoredString = affWordToColoredString;
|
|
249
267
|
/* istanbul ignore next */
|
|
250
268
|
function flagsToString(flags) {
|
|
251
|
-
return
|
|
269
|
+
return [...Object.entries(flags)]
|
|
252
270
|
.filter(([, v]) => !!v)
|
|
253
|
-
|
|
254
|
-
.map(([k]) => flagToStringMap[k])
|
|
255
|
-
.toArray()
|
|
271
|
+
.map(([k]) => flagToLongStringMap[k])
|
|
256
272
|
.sort()
|
|
257
|
-
.join('
|
|
273
|
+
.join(':');
|
|
258
274
|
}
|
|
259
275
|
exports.flagsToString = flagsToString;
|
|
260
276
|
function asAffWord(word, rules = '', flags = {}) {
|
|
@@ -299,7 +315,7 @@ function adjustCompounding(affWord, minLength) {
|
|
|
299
315
|
if (!affWord.flags.isCompoundPermitted || affWord.word.length >= minLength) {
|
|
300
316
|
return affWord;
|
|
301
317
|
}
|
|
302
|
-
const { isCompoundPermitted, ...flags } = affWord.flags;
|
|
318
|
+
const { isCompoundPermitted: _, ...flags } = affWord.flags;
|
|
303
319
|
affWord.flags = flags;
|
|
304
320
|
return affWord;
|
|
305
321
|
}
|
package/dist/affDef.d.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
export interface Fx {
|
|
2
|
+
type: string;
|
|
3
|
+
id: string;
|
|
4
|
+
combinable: boolean;
|
|
5
|
+
substitutionSets: Substitutions;
|
|
6
|
+
count?: string;
|
|
7
|
+
extra?: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare type Substitutions = Map<string, SubstitutionSet>;
|
|
10
|
+
export interface Substitution {
|
|
11
|
+
remove: string;
|
|
12
|
+
attach: string;
|
|
13
|
+
attachRules?: string;
|
|
14
|
+
replace: RegExp;
|
|
15
|
+
extra?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SubstitutionSet {
|
|
18
|
+
match: RegExp;
|
|
19
|
+
substitutions: Substitution[];
|
|
20
|
+
}
|
|
21
|
+
export interface Rep {
|
|
22
|
+
match: string;
|
|
23
|
+
replaceWith: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Conv {
|
|
26
|
+
from: string;
|
|
27
|
+
to: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AffTransformFlags {
|
|
30
|
+
KEEPCASE?: string;
|
|
31
|
+
WARN?: string;
|
|
32
|
+
NEEDAFFIX?: string;
|
|
33
|
+
FORCEUCASE?: string;
|
|
34
|
+
FORBIDDENWORD?: string;
|
|
35
|
+
NOSUGGEST?: string;
|
|
36
|
+
COMPOUNDBEGIN?: string;
|
|
37
|
+
COMPOUNDEND?: string;
|
|
38
|
+
COMPOUNDFLAG?: string;
|
|
39
|
+
COMPOUNDFORBIDFLAG?: string;
|
|
40
|
+
COMPOUNDMIDDLE?: string;
|
|
41
|
+
COMPOUNDPERMITFLAG?: string;
|
|
42
|
+
ONLYINCOMPOUND?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface AffInfo extends AffTransformFlags {
|
|
45
|
+
SET: string;
|
|
46
|
+
TRY?: string;
|
|
47
|
+
KEY?: string;
|
|
48
|
+
WORDCHARS?: string;
|
|
49
|
+
NOSPLITSUGS?: boolean;
|
|
50
|
+
MAXCPDSUGS?: number;
|
|
51
|
+
ONLYMAXDIFF?: boolean;
|
|
52
|
+
MAXDIFF?: number;
|
|
53
|
+
BREAK?: string[];
|
|
54
|
+
FLAG?: string;
|
|
55
|
+
MAP?: string[];
|
|
56
|
+
ICONV?: Conv[];
|
|
57
|
+
OCONV?: Conv[];
|
|
58
|
+
REP?: Rep[];
|
|
59
|
+
AF?: string[];
|
|
60
|
+
COMPOUNDMIN?: number;
|
|
61
|
+
COMPOUNDRULE?: string[];
|
|
62
|
+
CHECKCOMPOUNDCASE?: boolean;
|
|
63
|
+
CHECKCOMPOUNDDUP?: boolean;
|
|
64
|
+
CHECKCOMPOUNDREP?: boolean;
|
|
65
|
+
CHECKCOMPOUNDPATTERN?: string[][];
|
|
66
|
+
PFX?: Map<string, Fx>;
|
|
67
|
+
SFX?: Map<string, Fx>;
|
|
68
|
+
}
|
|
69
|
+
export interface Rule {
|
|
70
|
+
id: string;
|
|
71
|
+
type: string;
|
|
72
|
+
flags?: AffWordFlags;
|
|
73
|
+
pfx?: Fx;
|
|
74
|
+
sfx?: Fx;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* AffWordFlags are the flags applied to a word after the hunspell rules have been applied.
|
|
78
|
+
* They are either `true` or `undefined`.
|
|
79
|
+
*/
|
|
80
|
+
export interface AffWordFlags {
|
|
81
|
+
/**
|
|
82
|
+
* COMPOUNDFLAG flag
|
|
83
|
+
*
|
|
84
|
+
* Words signed with COMPOUNDFLAG may be in compound words (except when word shorter than COMPOUNDMIN).
|
|
85
|
+
* Affixes with COMPOUNDFLAG also permits compounding of affixed words.
|
|
86
|
+
*
|
|
87
|
+
*/
|
|
88
|
+
isCompoundPermitted?: true;
|
|
89
|
+
/**
|
|
90
|
+
* COMPOUNDBEGIN flag
|
|
91
|
+
*
|
|
92
|
+
* Words signed with COMPOUNDBEGIN (or with a signed affix) may be first elements in compound words.
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
canBeCompoundBegin?: true;
|
|
96
|
+
/**
|
|
97
|
+
* COMPOUNDMIDDLE flag
|
|
98
|
+
*
|
|
99
|
+
* Words signed with COMPOUNDMIDDLE (or with a signed affix) may be middle elements in compound words.
|
|
100
|
+
*
|
|
101
|
+
*/
|
|
102
|
+
canBeCompoundMiddle?: true;
|
|
103
|
+
/**
|
|
104
|
+
* COMPOUNDLAST flag
|
|
105
|
+
*
|
|
106
|
+
* Words signed with COMPOUNDLAST (or with a signed affix) may be last elements in compound words.
|
|
107
|
+
*
|
|
108
|
+
*/
|
|
109
|
+
canBeCompoundEnd?: true;
|
|
110
|
+
/**
|
|
111
|
+
* COMPOUNDPERMITFLAG flag
|
|
112
|
+
*
|
|
113
|
+
* Prefixes are allowed at the beginning of compounds, suffixes are allowed at the end of compounds by default.
|
|
114
|
+
* Affixes with COMPOUNDPERMITFLAG may be inside of compounds.
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
isOnlyAllowedInCompound?: true;
|
|
118
|
+
/**
|
|
119
|
+
* COMPOUNDFORBIDFLAG flag
|
|
120
|
+
*
|
|
121
|
+
* Suffixes with this flag forbid compounding of the affixed word.
|
|
122
|
+
*
|
|
123
|
+
*/
|
|
124
|
+
isCompoundForbidden?: true;
|
|
125
|
+
/**
|
|
126
|
+
* WARN flag
|
|
127
|
+
*
|
|
128
|
+
* This flag is for rare words, which are also often spelling mistakes, see option -r of command line Hunspell and FORBIDWARN.
|
|
129
|
+
*/
|
|
130
|
+
isWarning?: true;
|
|
131
|
+
/**
|
|
132
|
+
* KEEPCASE flag
|
|
133
|
+
*
|
|
134
|
+
* Forbid uppercased and capitalized forms of words signed with KEEPCASE flags. Useful for special orthographies (measurements and
|
|
135
|
+
* currency often keep their case in uppercased texts) and writing systems (e.g. keeping lower case of IPA characters). Also valuable
|
|
136
|
+
* for words erroneously written in the wrong case.
|
|
137
|
+
*/
|
|
138
|
+
isKeepCase?: true;
|
|
139
|
+
/**
|
|
140
|
+
* FORCEUCASE flag
|
|
141
|
+
*
|
|
142
|
+
* Last word part of a compound with flag FORCEUCASE forces capitalization of the whole compound word.
|
|
143
|
+
* Eg. Dutch word "straat" (street) with FORCEUCASE flags will allowed only in capitalized compound forms,
|
|
144
|
+
* according to the Dutch spelling rules for proper names.
|
|
145
|
+
*/
|
|
146
|
+
isForceUCase?: true;
|
|
147
|
+
/**
|
|
148
|
+
* FORBIDDENWORD flag
|
|
149
|
+
*
|
|
150
|
+
* This flag signs forbidden word form. Because affixed forms are also forbidden, we can subtract a subset from set of the
|
|
151
|
+
* accepted affixed and compound words. Note: useful to forbid erroneous words, generated by the compounding mechanism.
|
|
152
|
+
*/
|
|
153
|
+
isForbiddenWord?: true;
|
|
154
|
+
/**
|
|
155
|
+
* NOSUGGEST flag
|
|
156
|
+
*
|
|
157
|
+
* Words signed with NOSUGGEST flag are not suggested (but still accepted when typed correctly). Proposed flag for vulgar
|
|
158
|
+
* and obscene words (see also SUBSTANDARD).
|
|
159
|
+
*/
|
|
160
|
+
isNoSuggest?: true;
|
|
161
|
+
/**
|
|
162
|
+
* NEEDAFFIX flag
|
|
163
|
+
*
|
|
164
|
+
* This flag signs virtual stems in the dictionary, words only valid when affixed. Except, if the dictionary word has a homonym
|
|
165
|
+
* or a zero affix. NEEDAFFIX works also with prefixes and prefix + suffix combinations (see tests/pseudoroot5.*).
|
|
166
|
+
*/
|
|
167
|
+
isNeedAffix?: true;
|
|
168
|
+
}
|
|
169
|
+
export interface AffWord {
|
|
170
|
+
word: string;
|
|
171
|
+
rules: string;
|
|
172
|
+
flags: AffWordFlags;
|
|
173
|
+
rulesApplied: string;
|
|
174
|
+
/** prefix + base + suffix == word */
|
|
175
|
+
base: string;
|
|
176
|
+
suffix: string;
|
|
177
|
+
prefix: string;
|
|
178
|
+
dic: string;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=affDef.d.ts.map
|
package/dist/affDef.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// cspell:words uppercased
|
|
3
|
+
// cspell:words KEEPCASE WARN NEEDAFFIX FORCEUCASE FORBIDDENWORD NOSUGGEST WORDCHARS
|
|
4
|
+
// cspell:words COMPOUNDBEGIN COMPOUNDMIDDLE COMPOUNDEND COMPOUNDPERMITFLAG COMPOUNDFORBIDFLAG
|
|
5
|
+
// cspell:words MAXDIFF COMPOUNDMIN COMPOUNDRULE COMPOUNDFLAG COMPOUNDLAST FORBIDWARN
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
//# sourceMappingURL=affDef.js.map
|
package/dist/affReader.d.ts
CHANGED
package/dist/affReader.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.testing = exports.parseAffFileToAff = exports.parseAff = exports.parseAffFile = void 0;
|
|
4
|
-
const
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
5
8
|
const fs_extra_1 = require("fs-extra");
|
|
6
9
|
const iconv_lite_1 = require("iconv-lite");
|
|
10
|
+
const aff_1 = require("./aff");
|
|
11
|
+
const util_1 = require("./util");
|
|
7
12
|
const fixRegex = {
|
|
8
13
|
SFX: { m: /$/, r: '$' },
|
|
9
14
|
PFX: { m: /^/, r: '^' },
|
|
@@ -13,32 +18,55 @@ const spaceRegex = /\s+/;
|
|
|
13
18
|
const commentRegex = /(?:^\s*#.*)|(?:\s+#.*)/;
|
|
14
19
|
const affixLine = /^\s*([^\s]+)\s+(.*)?$/;
|
|
15
20
|
const UTF8 = 'UTF-8';
|
|
16
|
-
function convEntry(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function convEntry() {
|
|
22
|
+
let fieldValue;
|
|
23
|
+
return {
|
|
24
|
+
addLine: (line) => {
|
|
25
|
+
if (fieldValue === undefined) {
|
|
26
|
+
fieldValue = [];
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const args = (line.value || '').split(spaceRegex);
|
|
30
|
+
fieldValue.push({ from: args[0], to: args[1] });
|
|
31
|
+
},
|
|
32
|
+
getValue: () => fieldValue,
|
|
33
|
+
};
|
|
23
34
|
}
|
|
24
|
-
function afEntry(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
function afEntry() {
|
|
36
|
+
let fieldValue;
|
|
37
|
+
return {
|
|
38
|
+
addLine: (line) => {
|
|
39
|
+
if (fieldValue === undefined) {
|
|
40
|
+
// Add empty entry because rules start at 1
|
|
41
|
+
fieldValue = [''];
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (line.value) {
|
|
45
|
+
fieldValue.push(line.value);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
getValue: () => fieldValue,
|
|
49
|
+
};
|
|
32
50
|
}
|
|
33
|
-
function simpleTable(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return
|
|
51
|
+
function simpleTable(map) {
|
|
52
|
+
let data;
|
|
53
|
+
function getValue() {
|
|
54
|
+
if (data === null || data === void 0 ? void 0 : data.values)
|
|
55
|
+
return map(data.values);
|
|
56
|
+
return undefined;
|
|
39
57
|
}
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
function addLine(line) {
|
|
59
|
+
const args = (line.value || '').split(spaceRegex);
|
|
60
|
+
if (data === undefined) {
|
|
61
|
+
const [count, ...extraValues] = args;
|
|
62
|
+
const extra = extraValues.length ? extraValues : undefined;
|
|
63
|
+
const values = [];
|
|
64
|
+
data = { count, extra, values };
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
data.values.push(args);
|
|
68
|
+
}
|
|
69
|
+
return { addLine, getValue };
|
|
42
70
|
}
|
|
43
71
|
function tablePfxOrSfx(fieldValue, line) {
|
|
44
72
|
/*
|
|
@@ -69,6 +97,7 @@ function tablePfxOrSfx(fieldValue, line) {
|
|
|
69
97
|
return fieldValue;
|
|
70
98
|
}
|
|
71
99
|
const fixRuleSet = fieldValue.get(subField);
|
|
100
|
+
(0, assert_1.default)(fixRuleSet);
|
|
72
101
|
const substitutionSets = fixRuleSet.substitutionSets;
|
|
73
102
|
const ruleAsString = rule.condition.source;
|
|
74
103
|
if (!substitutionSets.has(ruleAsString)) {
|
|
@@ -78,6 +107,7 @@ function tablePfxOrSfx(fieldValue, line) {
|
|
|
78
107
|
});
|
|
79
108
|
}
|
|
80
109
|
const substitutionSet = substitutionSets.get(ruleAsString);
|
|
110
|
+
(0, assert_1.default)(substitutionSet);
|
|
81
111
|
const [attachText, attachRules] = rule.affix.split('/', 2);
|
|
82
112
|
substitutionSet.substitutions.push({
|
|
83
113
|
remove: rule.stripping,
|
|
@@ -143,23 +173,46 @@ function affixMatchToRegExpString(match) {
|
|
|
143
173
|
return '';
|
|
144
174
|
return match.replace(/([\\\-?*])/g, '\\$1');
|
|
145
175
|
}
|
|
146
|
-
function
|
|
147
|
-
|
|
176
|
+
function collectFx() {
|
|
177
|
+
let value;
|
|
178
|
+
function addLine(line) {
|
|
179
|
+
value = tablePfxOrSfx(value, line);
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
addLine,
|
|
183
|
+
getValue: () => value,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const asPfx = collectFx;
|
|
187
|
+
const asSfx = collectFx;
|
|
188
|
+
const asString = () => collectPrimitive((v) => v, '');
|
|
189
|
+
const asBoolean = () => collectPrimitive((v) => !!parseInt(v), '1');
|
|
190
|
+
const asNumber = () => collectPrimitive(parseInt, '0');
|
|
191
|
+
function collectPrimitive(map, defaultValue = '') {
|
|
192
|
+
let primitive;
|
|
193
|
+
function getValue() {
|
|
194
|
+
return primitive;
|
|
195
|
+
}
|
|
196
|
+
function addLine(line) {
|
|
197
|
+
const { value = defaultValue } = line;
|
|
198
|
+
primitive = map(value);
|
|
199
|
+
}
|
|
200
|
+
return { addLine, getValue };
|
|
201
|
+
}
|
|
202
|
+
function toRep(values) {
|
|
203
|
+
return values.map((v) => ({ match: v[0], replaceWith: v[1] }));
|
|
148
204
|
}
|
|
149
|
-
function
|
|
150
|
-
return
|
|
205
|
+
function toSingleStrings(values) {
|
|
206
|
+
return values.map((v) => v[0]).filter(util_1.isDefined);
|
|
151
207
|
}
|
|
152
|
-
function
|
|
153
|
-
return
|
|
208
|
+
function toAffMap(values) {
|
|
209
|
+
return toSingleStrings(values);
|
|
154
210
|
}
|
|
155
|
-
function
|
|
156
|
-
|
|
157
|
-
const iValue = parseInt(value);
|
|
158
|
-
return !!iValue;
|
|
211
|
+
function toCompoundRule(values) {
|
|
212
|
+
return toSingleStrings(values);
|
|
159
213
|
}
|
|
160
|
-
function
|
|
161
|
-
|
|
162
|
-
return parseInt(value);
|
|
214
|
+
function toCheckCompoundPattern(values) {
|
|
215
|
+
return values;
|
|
163
216
|
}
|
|
164
217
|
/*
|
|
165
218
|
cspell:ignore COMPOUNDBEGIN COMPOUNDEND COMPOUNDMIDDLE COMPOUNDMIN COMPOUNDPERMITFLAG COMPOUNDRULE COMPOUNDFORBIDFLAG COMPOUNDFLAG
|
|
@@ -167,44 +220,86 @@ cspell:ignore FORBIDDENWORD KEEPCASE
|
|
|
167
220
|
cspell:ignore MAXDIFF NEEDAFFIX WORDCHARS
|
|
168
221
|
*/
|
|
169
222
|
// prettier-ignore
|
|
170
|
-
const
|
|
171
|
-
AF: afEntry,
|
|
172
|
-
BREAK:
|
|
173
|
-
CHECKCOMPOUNDCASE: asBoolean,
|
|
174
|
-
CHECKCOMPOUNDDUP: asBoolean,
|
|
175
|
-
CHECKCOMPOUNDPATTERN: simpleTable,
|
|
176
|
-
CHECKCOMPOUNDREP: asBoolean,
|
|
177
|
-
COMPOUNDBEGIN: asString,
|
|
178
|
-
COMPOUNDEND: asString,
|
|
179
|
-
COMPOUNDMIDDLE: asString,
|
|
180
|
-
COMPOUNDMIN: asNumber,
|
|
181
|
-
COMPOUNDFLAG: asString,
|
|
182
|
-
COMPOUNDPERMITFLAG: asString,
|
|
183
|
-
COMPOUNDFORBIDFLAG: asString,
|
|
184
|
-
COMPOUNDRULE: simpleTable,
|
|
185
|
-
FLAG: asString,
|
|
186
|
-
FORBIDDENWORD: asString,
|
|
187
|
-
FORCEUCASE: asString,
|
|
188
|
-
ICONV: convEntry,
|
|
189
|
-
KEEPCASE: asString,
|
|
190
|
-
KEY: asString,
|
|
191
|
-
MAP: simpleTable,
|
|
192
|
-
MAXCPDSUGS: asNumber,
|
|
193
|
-
MAXDIFF: asNumber,
|
|
194
|
-
NEEDAFFIX: asString,
|
|
195
|
-
NOSPLITSUGS: asBoolean,
|
|
196
|
-
NOSUGGEST: asString,
|
|
197
|
-
OCONV: convEntry,
|
|
198
|
-
ONLYINCOMPOUND: asString,
|
|
199
|
-
ONLYMAXDIFF: asBoolean,
|
|
200
|
-
PFX: asPfx,
|
|
201
|
-
REP: simpleTable,
|
|
202
|
-
SET: asString,
|
|
203
|
-
SFX: asSfx,
|
|
204
|
-
TRY: asString,
|
|
205
|
-
WARN: asString,
|
|
206
|
-
WORDCHARS: asString,
|
|
207
|
-
};
|
|
223
|
+
const createAffFieldTable = () => ({
|
|
224
|
+
AF: afEntry(),
|
|
225
|
+
BREAK: simpleTable(toSingleStrings),
|
|
226
|
+
CHECKCOMPOUNDCASE: asBoolean(),
|
|
227
|
+
CHECKCOMPOUNDDUP: asBoolean(),
|
|
228
|
+
CHECKCOMPOUNDPATTERN: simpleTable(toCheckCompoundPattern),
|
|
229
|
+
CHECKCOMPOUNDREP: asBoolean(),
|
|
230
|
+
COMPOUNDBEGIN: asString(),
|
|
231
|
+
COMPOUNDEND: asString(),
|
|
232
|
+
COMPOUNDMIDDLE: asString(),
|
|
233
|
+
COMPOUNDMIN: asNumber(),
|
|
234
|
+
COMPOUNDFLAG: asString(),
|
|
235
|
+
COMPOUNDPERMITFLAG: asString(),
|
|
236
|
+
COMPOUNDFORBIDFLAG: asString(),
|
|
237
|
+
COMPOUNDRULE: simpleTable(toCompoundRule),
|
|
238
|
+
FLAG: asString(),
|
|
239
|
+
FORBIDDENWORD: asString(),
|
|
240
|
+
FORCEUCASE: asString(),
|
|
241
|
+
ICONV: convEntry(),
|
|
242
|
+
KEEPCASE: asString(),
|
|
243
|
+
KEY: asString(),
|
|
244
|
+
MAP: simpleTable(toAffMap),
|
|
245
|
+
MAXCPDSUGS: asNumber(),
|
|
246
|
+
MAXDIFF: asNumber(),
|
|
247
|
+
NEEDAFFIX: asString(),
|
|
248
|
+
NOSPLITSUGS: asBoolean(),
|
|
249
|
+
NOSUGGEST: asString(),
|
|
250
|
+
OCONV: convEntry(),
|
|
251
|
+
ONLYINCOMPOUND: asString(),
|
|
252
|
+
ONLYMAXDIFF: asBoolean(),
|
|
253
|
+
PFX: asPfx(),
|
|
254
|
+
REP: simpleTable(toRep),
|
|
255
|
+
SET: asString(),
|
|
256
|
+
SFX: asSfx(),
|
|
257
|
+
TRY: asString(),
|
|
258
|
+
WARN: asString(),
|
|
259
|
+
WORDCHARS: asString(),
|
|
260
|
+
});
|
|
261
|
+
function collectionToAffInfo(affFieldCollectionTable, encoding) {
|
|
262
|
+
// prettier-ignore
|
|
263
|
+
const result = {
|
|
264
|
+
AF: affFieldCollectionTable.AF.getValue(),
|
|
265
|
+
BREAK: affFieldCollectionTable.BREAK.getValue(),
|
|
266
|
+
CHECKCOMPOUNDCASE: affFieldCollectionTable.CHECKCOMPOUNDCASE.getValue(),
|
|
267
|
+
CHECKCOMPOUNDDUP: affFieldCollectionTable.CHECKCOMPOUNDDUP.getValue(),
|
|
268
|
+
CHECKCOMPOUNDPATTERN: affFieldCollectionTable.CHECKCOMPOUNDPATTERN.getValue(),
|
|
269
|
+
CHECKCOMPOUNDREP: affFieldCollectionTable.CHECKCOMPOUNDREP.getValue(),
|
|
270
|
+
COMPOUNDBEGIN: affFieldCollectionTable.COMPOUNDBEGIN.getValue(),
|
|
271
|
+
COMPOUNDEND: affFieldCollectionTable.COMPOUNDEND.getValue(),
|
|
272
|
+
COMPOUNDMIDDLE: affFieldCollectionTable.COMPOUNDMIDDLE.getValue(),
|
|
273
|
+
COMPOUNDMIN: affFieldCollectionTable.COMPOUNDMIN.getValue(),
|
|
274
|
+
COMPOUNDFLAG: affFieldCollectionTable.COMPOUNDFLAG.getValue(),
|
|
275
|
+
COMPOUNDPERMITFLAG: affFieldCollectionTable.COMPOUNDPERMITFLAG.getValue(),
|
|
276
|
+
COMPOUNDFORBIDFLAG: affFieldCollectionTable.COMPOUNDFORBIDFLAG.getValue(),
|
|
277
|
+
COMPOUNDRULE: affFieldCollectionTable.COMPOUNDRULE.getValue(),
|
|
278
|
+
FLAG: affFieldCollectionTable.FLAG.getValue(),
|
|
279
|
+
FORBIDDENWORD: affFieldCollectionTable.FORBIDDENWORD.getValue(),
|
|
280
|
+
FORCEUCASE: affFieldCollectionTable.FORCEUCASE.getValue(),
|
|
281
|
+
ICONV: affFieldCollectionTable.ICONV.getValue(),
|
|
282
|
+
KEEPCASE: affFieldCollectionTable.KEEPCASE.getValue(),
|
|
283
|
+
KEY: affFieldCollectionTable.KEY.getValue(),
|
|
284
|
+
MAP: affFieldCollectionTable.MAP.getValue(),
|
|
285
|
+
MAXCPDSUGS: affFieldCollectionTable.MAXCPDSUGS.getValue(),
|
|
286
|
+
MAXDIFF: affFieldCollectionTable.MAXDIFF.getValue(),
|
|
287
|
+
NEEDAFFIX: affFieldCollectionTable.NEEDAFFIX.getValue(),
|
|
288
|
+
NOSPLITSUGS: affFieldCollectionTable.NOSPLITSUGS.getValue(),
|
|
289
|
+
NOSUGGEST: affFieldCollectionTable.NOSUGGEST.getValue(),
|
|
290
|
+
OCONV: affFieldCollectionTable.OCONV.getValue(),
|
|
291
|
+
ONLYINCOMPOUND: affFieldCollectionTable.ONLYINCOMPOUND.getValue(),
|
|
292
|
+
ONLYMAXDIFF: affFieldCollectionTable.ONLYMAXDIFF.getValue(),
|
|
293
|
+
PFX: affFieldCollectionTable.PFX.getValue(),
|
|
294
|
+
REP: affFieldCollectionTable.REP.getValue(),
|
|
295
|
+
SET: affFieldCollectionTable.SET.getValue() || encoding,
|
|
296
|
+
SFX: affFieldCollectionTable.SFX.getValue(),
|
|
297
|
+
TRY: affFieldCollectionTable.TRY.getValue(),
|
|
298
|
+
WARN: affFieldCollectionTable.WARN.getValue(),
|
|
299
|
+
WORDCHARS: affFieldCollectionTable.WORDCHARS.getValue(),
|
|
300
|
+
};
|
|
301
|
+
return (0, util_1.cleanObject)(result);
|
|
302
|
+
}
|
|
208
303
|
async function parseAffFile(filename, encoding = UTF8) {
|
|
209
304
|
const buffer = await (0, fs_extra_1.readFile)(filename);
|
|
210
305
|
const file = (0, iconv_lite_1.decode)(buffer, encoding);
|
|
@@ -217,22 +312,19 @@ async function parseAffFile(filename, encoding = UTF8) {
|
|
|
217
312
|
exports.parseAffFile = parseAffFile;
|
|
218
313
|
function parseAff(affFileContent, encoding = UTF8) {
|
|
219
314
|
const lines = affFileContent.split(/\r?\n/g);
|
|
220
|
-
|
|
221
|
-
|
|
315
|
+
const affFieldCollectionTable = createAffFieldTable();
|
|
316
|
+
affFieldCollectionTable.SET.addLine({ option: 'SET', value: encoding });
|
|
317
|
+
lines
|
|
318
|
+
.map((line) => line.trimStart())
|
|
222
319
|
.map((line) => line.replace(commentRegex, ''))
|
|
223
320
|
.filter((line) => line.trim() !== '')
|
|
224
321
|
.map(parseLine)
|
|
225
|
-
.
|
|
322
|
+
.forEach((line) => {
|
|
323
|
+
var _a;
|
|
226
324
|
const field = line.option;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
aff[field] = line.value;
|
|
233
|
-
}
|
|
234
|
-
return aff;
|
|
235
|
-
}, { SET: encoding });
|
|
325
|
+
(_a = affFieldCollectionTable[field]) === null || _a === void 0 ? void 0 : _a.addLine(line);
|
|
326
|
+
});
|
|
327
|
+
return collectionToAffInfo(affFieldCollectionTable, encoding);
|
|
236
328
|
}
|
|
237
329
|
exports.parseAff = parseAff;
|
|
238
330
|
function parseAffFileToAff(filename, encoding) {
|
package/dist/app.js
CHANGED
|
@@ -28,6 +28,7 @@ const gensequence_1 = require("gensequence");
|
|
|
28
28
|
const aff_1 = require("./aff");
|
|
29
29
|
const iterableToStream_1 = require("./iterableToStream");
|
|
30
30
|
const uniqueHistorySize = 500000;
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
31
32
|
const packageInfo = require('../package.json');
|
|
32
33
|
const version = packageInfo['version'];
|
|
33
34
|
let displayHelp = true;
|
|
@@ -159,7 +160,9 @@ async function actionPrime(hunspellDicFilename, options) {
|
|
|
159
160
|
current++;
|
|
160
161
|
!(current % reportProgressRate) && process.stderr.write(calcProgress(), 'utf-8');
|
|
161
162
|
}
|
|
162
|
-
: () => {
|
|
163
|
+
: () => {
|
|
164
|
+
/* void */
|
|
165
|
+
};
|
|
163
166
|
const seqWords = transform ? reader.seqAffWords(callback) : reader.seqRootWords().map(aff_1.asAffWord);
|
|
164
167
|
const filterUnique = unique ? (0, util_1.uniqueFilter)(uniqueHistorySize) : (_) => true;
|
|
165
168
|
const applyTransformers = (aff) => transformers.reduce((aff, fn) => fn(aff), aff);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export * from './IterableHunspellReader';
|
|
2
2
|
export { IterableHunspellReader as HunspellReader } from './IterableHunspellReader';
|
|
3
|
+
export { parseAffFile as readAffFile, parseAff } from './affReader';
|
|
4
|
+
export type { AffInfo, AffWord } from './affDef';
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
10
10
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.HunspellReader = void 0;
|
|
13
|
+
exports.parseAff = exports.readAffFile = exports.HunspellReader = void 0;
|
|
14
14
|
__exportStar(require("./IterableHunspellReader"), exports);
|
|
15
15
|
var IterableHunspellReader_1 = require("./IterableHunspellReader");
|
|
16
16
|
Object.defineProperty(exports, "HunspellReader", { enumerable: true, get: function () { return IterableHunspellReader_1.IterableHunspellReader; } });
|
|
17
|
+
var affReader_1 = require("./affReader");
|
|
18
|
+
Object.defineProperty(exports, "readAffFile", { enumerable: true, get: function () { return affReader_1.parseAffFile; } });
|
|
19
|
+
Object.defineProperty(exports, "parseAff", { enumerable: true, get: function () { return affReader_1.parseAff; } });
|
|
17
20
|
//# sourceMappingURL=index.js.map
|
package/dist/util.d.ts
CHANGED
|
@@ -7,4 +7,11 @@ export declare function batch<T>(i: Iterable<T>, size: number): Iterable<T[]>;
|
|
|
7
7
|
* @param compare function to evaluate if two values are considered the same.
|
|
8
8
|
*/
|
|
9
9
|
export declare function filterOrderedList<T>(compare: (a: T, b: T) => boolean | number): (t: T) => boolean;
|
|
10
|
+
export declare function isDefined<T>(v: T | undefined): v is T;
|
|
11
|
+
/**
|
|
12
|
+
* Remove all `undefined` values from an Object.
|
|
13
|
+
* @param obj
|
|
14
|
+
* @returns the same object.
|
|
15
|
+
*/
|
|
16
|
+
export declare function cleanObject<T>(obj: T): T;
|
|
10
17
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filterOrderedList = exports.batch = exports.uniqueFilter = exports.hrTimeToSeconds = void 0;
|
|
3
|
+
exports.cleanObject = exports.isDefined = exports.filterOrderedList = exports.batch = exports.uniqueFilter = exports.hrTimeToSeconds = void 0;
|
|
4
4
|
function hrTimeToSeconds([seconds, nanoseconds]) {
|
|
5
5
|
return seconds + nanoseconds / 1000000000;
|
|
6
6
|
}
|
|
@@ -53,4 +53,25 @@ function filterOrderedList(compare) {
|
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
exports.filterOrderedList = filterOrderedList;
|
|
56
|
+
function isDefined(v) {
|
|
57
|
+
return v !== undefined;
|
|
58
|
+
}
|
|
59
|
+
exports.isDefined = isDefined;
|
|
60
|
+
/**
|
|
61
|
+
* Remove all `undefined` values from an Object.
|
|
62
|
+
* @param obj
|
|
63
|
+
* @returns the same object.
|
|
64
|
+
*/
|
|
65
|
+
function cleanObject(obj) {
|
|
66
|
+
if (typeof obj != 'object')
|
|
67
|
+
return obj;
|
|
68
|
+
const r = obj;
|
|
69
|
+
for (const [k, v] of Object.entries(r)) {
|
|
70
|
+
if (v === undefined) {
|
|
71
|
+
delete r[k];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return obj;
|
|
75
|
+
}
|
|
76
|
+
exports.cleanObject = cleanObject;
|
|
56
77
|
//# sourceMappingURL=util.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hunspell-reader",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.15.3",
|
|
4
4
|
"description": "A library for reading Hunspell Dictionary Files",
|
|
5
5
|
"bin": "bin.js",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -39,12 +39,11 @@
|
|
|
39
39
|
"homepage": "https://github.com/Jason-Rev/hunspell-reader#readme",
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/fs-extra": "^9.0.13",
|
|
42
|
-
"@types/jest": "^27.0
|
|
43
|
-
"@types/node": "^17.0.
|
|
44
|
-
"jest": "^27.4.
|
|
45
|
-
"prettier": "^2.5.1",
|
|
42
|
+
"@types/jest": "^27.4.0",
|
|
43
|
+
"@types/node": "^17.0.10",
|
|
44
|
+
"jest": "^27.4.7",
|
|
46
45
|
"rimraf": "^3.0.2",
|
|
47
|
-
"ts-jest": "^27.1.
|
|
46
|
+
"ts-jest": "^27.1.3",
|
|
48
47
|
"typescript": "^4.5.4"
|
|
49
48
|
},
|
|
50
49
|
"dependencies": {
|
|
@@ -53,24 +52,8 @@
|
|
|
53
52
|
"gensequence": "^3.1.1",
|
|
54
53
|
"iconv-lite": "^0.6.3"
|
|
55
54
|
},
|
|
56
|
-
"eslintConfig": {
|
|
57
|
-
"root": true,
|
|
58
|
-
"parserOptions": {
|
|
59
|
-
"ecmaVersion": 6,
|
|
60
|
-
"sourceType": "module"
|
|
61
|
-
},
|
|
62
|
-
"env": {
|
|
63
|
-
"node": true,
|
|
64
|
-
"mocha": true
|
|
65
|
-
},
|
|
66
|
-
"ignorePatterns": [
|
|
67
|
-
"dist/**",
|
|
68
|
-
"node_modules/**"
|
|
69
|
-
],
|
|
70
|
-
"rules": {}
|
|
71
|
-
},
|
|
72
55
|
"engines": {
|
|
73
56
|
"node": ">=12.13.0"
|
|
74
57
|
},
|
|
75
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "8a7c55b7d0b340d3c4e964ba91390a405f2cda2d"
|
|
76
59
|
}
|