de-compromise 0.0.10 → 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 +1 -1
- package/builds/de-compromise.cjs +2354 -1687
- package/builds/de-compromise.min.js +1 -1
- package/builds/de-compromise.mjs +1 -1
- package/package.json +21 -14
- package/src/01-one/lexicon/_data.js +32 -0
- package/src/01-one/lexicon/compute/root.js +55 -0
- package/src/01-one/lexicon/lexicon.js +95 -0
- package/src/01-one/lexicon/methods/_data.js +193 -0
- package/src/01-one/lexicon/methods/adjectives/_test-back.js +29 -0
- package/src/01-one/lexicon/methods/adjectives/_test.js +49 -0
- package/src/01-one/lexicon/methods/adjectives/inflect.js +27 -0
- package/src/01-one/lexicon/methods/adjectives/model.js +126 -0
- package/src/01-one/lexicon/methods/adjectives/new/adjective.js +8 -0
- package/src/01-one/lexicon/methods/adjectives/new/comparative.js +7 -0
- package/src/01-one/lexicon/methods/adjectives/new/superlative.js +159 -0
- package/src/01-one/lexicon/methods/adjectives/toRoot.js +47 -0
- package/src/01-one/lexicon/methods/index.js +56 -0
- package/src/01-one/lexicon/methods/models.js +10 -0
- package/src/01-one/lexicon/methods/nouns/_test-back.js +45 -0
- package/src/01-one/lexicon/methods/nouns/new.js +56 -0
- package/src/01-one/lexicon/methods/nouns/toPlural.js +49 -0
- package/src/01-one/lexicon/methods/nouns/toSingular.js +46 -0
- package/src/01-one/lexicon/methods/verbs/conjugate.js +87 -0
- package/src/01-one/lexicon/methods/verbs/custom/_test-from.js +53 -0
- package/src/01-one/lexicon/methods/verbs/custom/_test-to.js +50 -0
- package/src/01-one/lexicon/methods/verbs/custom/fromPastParticiple.js +37 -0
- package/src/01-one/lexicon/methods/verbs/custom/rules.js +182 -0
- package/src/01-one/lexicon/methods/verbs/custom/toPastParticiple.js +54 -0
- package/src/01-one/lexicon/methods/verbs/irregulars.js +202 -0
- package/src/01-one/lexicon/methods/verbs/toRoot.js +55 -0
- package/src/01-one/lexicon/misc.js +78 -0
- package/src/01-one/lexicon/plugin.js +14 -0
- package/src/01-one/splitter/build.js +20 -0
- package/src/01-one/splitter/compute/splitter.js +54 -0
- package/src/01-one/splitter/model/index.js +20 -0
- package/src/01-one/splitter/plugin.js +10 -0
- package/src/01-one/splitter/trie.js +40 -0
- package/src/01-one/tagset/plugin.js +11 -0
- package/src/01-one/tagset/tags/dates.js +45 -0
- package/src/01-one/tagset/tags/misc.js +70 -0
- package/src/01-one/tagset/tags/nouns.js +116 -0
- package/src/01-one/tagset/tags/values.js +47 -0
- package/src/01-one/tagset/tags/verbs.js +64 -0
- package/src/01-one/tokenizer/contractions.js +40 -0
- package/src/01-one/tokenizer/is-sentence.js +37 -0
- package/src/01-one/tokenizer/plugin.js +11 -0
- package/src/01-one/tokenizer/unicode.js +55 -0
- package/src/02-two/postTagger/matches.js +47 -0
- package/src/02-two/postTagger/plugin.js +8 -0
- package/src/02-two/preTagger/compute/1st-pass/regex.js +43 -0
- package/src/02-two/preTagger/compute/1st-pass/titlecase.js +21 -0
- package/src/02-two/preTagger/compute/1st-pass/year.js +54 -0
- package/src/02-two/preTagger/compute/2nd-pass/acronym.js +82 -0
- package/src/02-two/preTagger/compute/2nd-pass/fallback.js +27 -0
- package/src/02-two/preTagger/compute/2nd-pass/prefix-lookup.js +33 -0
- package/src/02-two/preTagger/compute/2nd-pass/suffix-lookup.js +44 -0
- package/src/02-two/preTagger/compute/index.js +42 -0
- package/src/02-two/preTagger/model/index.js +14 -0
- package/src/02-two/preTagger/model/prefixes.js +46 -0
- package/src/02-two/preTagger/model/regex/regex-normal.js +25 -0
- package/src/02-two/preTagger/model/regex/regex-numbers.js +62 -0
- package/src/02-two/preTagger/model/regex/regex-text.js +17 -0
- package/src/02-two/preTagger/model/suffixes.js +171 -0
- package/src/02-two/preTagger/plugin.js +12 -0
- package/src/03-three/adjectives/api.js +34 -0
- package/src/03-three/adjectives/plugin.js +5 -0
- package/src/03-three/nouns/api.js +74 -0
- package/src/03-three/nouns/plugin.js +5 -0
- package/src/03-three/numbers/api.js +259 -0
- package/src/03-three/numbers/data.js +77 -0
- package/src/03-three/numbers/format/index.js +27 -0
- package/src/03-three/numbers/format/toText.js +118 -0
- package/src/03-three/numbers/parse/fromText.js +52 -0
- package/src/03-three/numbers/parse/index.js +63 -0
- package/src/03-three/numbers/plugin.js +5 -0
- package/src/03-three/verbs/api.js +41 -0
- package/src/03-three/verbs/plugin.js +5 -0
- package/src/_lib.js +4 -0
- package/src/_version.js +1 -0
- package/src/index.js +53 -0
- package/types/index.d.ts +46 -0
- package/types/misc.ts +92 -0
- package/types/view/de.ts +61 -0
- package/types/view/one.ts +235 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { prefixes } from './custom/rules.js'
|
|
2
|
+
|
|
3
|
+
// hand-curated conjugations for the highest-frequency irregular verbs.
|
|
4
|
+
// the trained models lose some of these to compression, and they are
|
|
5
|
+
// too important to get wrong.
|
|
6
|
+
// person order: [ich, du, er/sie/es, wir, ihr, sie]
|
|
7
|
+
const irregulars = {
|
|
8
|
+
sein: {
|
|
9
|
+
present: ['bin', 'bist', 'ist', 'sind', 'seid', 'sind'],
|
|
10
|
+
past: ['war', 'warst', 'war', 'waren', 'wart', 'waren'],
|
|
11
|
+
subj1: ['sei', 'seist', 'sei', 'seien', 'seiet', 'seien'],
|
|
12
|
+
subj2: ['wäre', 'wärst', 'wäre', 'wären', 'wärt', 'wären'],
|
|
13
|
+
imperative: ['sei', 'seid'],
|
|
14
|
+
pastParticiple: 'gewesen',
|
|
15
|
+
presentParticiple: 'seiend',
|
|
16
|
+
},
|
|
17
|
+
haben: {
|
|
18
|
+
present: ['habe', 'hast', 'hat', 'haben', 'habt', 'haben'],
|
|
19
|
+
past: ['hatte', 'hattest', 'hatte', 'hatten', 'hattet', 'hatten'],
|
|
20
|
+
subj2: ['hätte', 'hättest', 'hätte', 'hätten', 'hättet', 'hätten'],
|
|
21
|
+
imperative: ['hab', 'habt'],
|
|
22
|
+
pastParticiple: 'gehabt',
|
|
23
|
+
},
|
|
24
|
+
werden: {
|
|
25
|
+
present: ['werde', 'wirst', 'wird', 'werden', 'werdet', 'werden'],
|
|
26
|
+
past: ['wurde', 'wurdest', 'wurde', 'wurden', 'wurdet', 'wurden'],
|
|
27
|
+
subj2: ['würde', 'würdest', 'würde', 'würden', 'würdet', 'würden'],
|
|
28
|
+
imperative: ['werde', 'werdet'],
|
|
29
|
+
pastParticiple: 'geworden',
|
|
30
|
+
},
|
|
31
|
+
tun: {
|
|
32
|
+
present: ['tue', 'tust', 'tut', 'tun', 'tut', 'tun'],
|
|
33
|
+
past: ['tat', 'tatest', 'tat', 'taten', 'tatet', 'taten'],
|
|
34
|
+
subj2: ['täte', 'tätest', 'täte', 'täten', 'tätet', 'täten'],
|
|
35
|
+
pastParticiple: 'getan',
|
|
36
|
+
presentParticiple: 'tuend',
|
|
37
|
+
},
|
|
38
|
+
wissen: {
|
|
39
|
+
present: ['weiß', 'weißt', 'weiß', 'wissen', 'wisst', 'wissen'],
|
|
40
|
+
past: ['wusste', 'wusstest', 'wusste', 'wussten', 'wusstet', 'wussten'],
|
|
41
|
+
subj2: ['wüsste', 'wüsstest', 'wüsste', 'wüssten', 'wüsstet', 'wüssten'],
|
|
42
|
+
pastParticiple: 'gewusst',
|
|
43
|
+
},
|
|
44
|
+
essen: {
|
|
45
|
+
present: ['esse', 'isst', 'isst', 'essen', 'esst', 'essen'],
|
|
46
|
+
past: ['aß', 'aßest', 'aß', 'aßen', 'aßt', 'aßen'],
|
|
47
|
+
subj2: ['äße', 'äßest', 'äße', 'äßen', 'äßet', 'äßen'],
|
|
48
|
+
imperative: ['iss', 'esst'],
|
|
49
|
+
pastParticiple: 'gegessen',
|
|
50
|
+
},
|
|
51
|
+
lesen: {
|
|
52
|
+
present: ['lese', 'liest', 'liest', 'lesen', 'lest', 'lesen'],
|
|
53
|
+
past: ['las', 'lasest', 'las', 'lasen', 'last', 'lasen'],
|
|
54
|
+
imperative: ['lies', 'lest'],
|
|
55
|
+
pastParticiple: 'gelesen',
|
|
56
|
+
},
|
|
57
|
+
geben: {
|
|
58
|
+
present: ['gebe', 'gibst', 'gibt', 'geben', 'gebt', 'geben'],
|
|
59
|
+
past: ['gab', 'gabst', 'gab', 'gaben', 'gabt', 'gaben'],
|
|
60
|
+
subj2: ['gäbe', 'gäbest', 'gäbe', 'gäben', 'gäbet', 'gäben'],
|
|
61
|
+
imperative: ['gib', 'gebt'],
|
|
62
|
+
pastParticiple: 'gegeben',
|
|
63
|
+
},
|
|
64
|
+
kommen: {
|
|
65
|
+
present: ['komme', 'kommst', 'kommt', 'kommen', 'kommt', 'kommen'],
|
|
66
|
+
past: ['kam', 'kamst', 'kam', 'kamen', 'kamt', 'kamen'],
|
|
67
|
+
subj2: ['käme', 'kämest', 'käme', 'kämen', 'kämet', 'kämen'],
|
|
68
|
+
imperative: ['komm', 'kommt'],
|
|
69
|
+
pastParticiple: 'gekommen',
|
|
70
|
+
},
|
|
71
|
+
heißen: {
|
|
72
|
+
pastParticiple: 'geheißen',
|
|
73
|
+
},
|
|
74
|
+
// modal verbs
|
|
75
|
+
können: {
|
|
76
|
+
present: ['kann', 'kannst', 'kann', 'können', 'könnt', 'können'],
|
|
77
|
+
past: ['konnte', 'konntest', 'konnte', 'konnten', 'konntet', 'konnten'],
|
|
78
|
+
subj2: ['könnte', 'könntest', 'könnte', 'könnten', 'könntet', 'könnten'],
|
|
79
|
+
pastParticiple: 'gekonnt',
|
|
80
|
+
},
|
|
81
|
+
müssen: {
|
|
82
|
+
present: ['muss', 'musst', 'muss', 'müssen', 'müsst', 'müssen'],
|
|
83
|
+
past: ['musste', 'musstest', 'musste', 'mussten', 'musstet', 'mussten'],
|
|
84
|
+
subj2: ['müsste', 'müsstest', 'müsste', 'müssten', 'müsstet', 'müssten'],
|
|
85
|
+
pastParticiple: 'gemusst',
|
|
86
|
+
},
|
|
87
|
+
dürfen: {
|
|
88
|
+
present: ['darf', 'darfst', 'darf', 'dürfen', 'dürft', 'dürfen'],
|
|
89
|
+
past: ['durfte', 'durftest', 'durfte', 'durften', 'durftet', 'durften'],
|
|
90
|
+
subj2: ['dürfte', 'dürftest', 'dürfte', 'dürften', 'dürftet', 'dürften'],
|
|
91
|
+
pastParticiple: 'gedurft',
|
|
92
|
+
},
|
|
93
|
+
mögen: {
|
|
94
|
+
present: ['mag', 'magst', 'mag', 'mögen', 'mögt', 'mögen'],
|
|
95
|
+
past: ['mochte', 'mochtest', 'mochte', 'mochten', 'mochtet', 'mochten'],
|
|
96
|
+
subj2: ['möchte', 'möchtest', 'möchte', 'möchten', 'möchtet', 'möchten'],
|
|
97
|
+
pastParticiple: 'gemocht',
|
|
98
|
+
},
|
|
99
|
+
wollen: {
|
|
100
|
+
present: ['will', 'willst', 'will', 'wollen', 'wollt', 'wollen'],
|
|
101
|
+
past: ['wollte', 'wolltest', 'wollte', 'wollten', 'wolltet', 'wollten'],
|
|
102
|
+
subj2: ['wollte', 'wolltest', 'wollte', 'wollten', 'wolltet', 'wollten'],
|
|
103
|
+
pastParticiple: 'gewollt',
|
|
104
|
+
},
|
|
105
|
+
sollen: {
|
|
106
|
+
present: ['soll', 'sollst', 'soll', 'sollen', 'sollt', 'sollen'],
|
|
107
|
+
past: ['sollte', 'solltest', 'sollte', 'sollten', 'solltet', 'sollten'],
|
|
108
|
+
subj2: ['sollte', 'solltest', 'sollte', 'sollten', 'solltet', 'sollten'],
|
|
109
|
+
pastParticiple: 'gesollt',
|
|
110
|
+
},
|
|
111
|
+
// mixed verbs — weak endings, strong vowel change
|
|
112
|
+
denken: {
|
|
113
|
+
past: ['dachte', 'dachtest', 'dachte', 'dachten', 'dachtet', 'dachten'],
|
|
114
|
+
subj2: ['dächte', 'dächtest', 'dächte', 'dächten', 'dächtet', 'dächten'],
|
|
115
|
+
pastParticiple: 'gedacht',
|
|
116
|
+
},
|
|
117
|
+
bringen: {
|
|
118
|
+
past: ['brachte', 'brachtest', 'brachte', 'brachten', 'brachtet', 'brachten'],
|
|
119
|
+
subj2: ['brächte', 'brächtest', 'brächte', 'brächten', 'brächtet', 'brächten'],
|
|
120
|
+
pastParticiple: 'gebracht',
|
|
121
|
+
},
|
|
122
|
+
kennen: {
|
|
123
|
+
past: ['kannte', 'kanntest', 'kannte', 'kannten', 'kanntet', 'kannten'],
|
|
124
|
+
pastParticiple: 'gekannt',
|
|
125
|
+
},
|
|
126
|
+
nennen: {
|
|
127
|
+
past: ['nannte', 'nanntest', 'nannte', 'nannten', 'nanntet', 'nannten'],
|
|
128
|
+
pastParticiple: 'genannt',
|
|
129
|
+
},
|
|
130
|
+
rennen: {
|
|
131
|
+
past: ['rannte', 'ranntest', 'rannte', 'rannten', 'ranntet', 'rannten'],
|
|
132
|
+
pastParticiple: 'gerannt',
|
|
133
|
+
},
|
|
134
|
+
brennen: {
|
|
135
|
+
past: ['brannte', 'branntest', 'brannte', 'brannten', 'branntet', 'brannten'],
|
|
136
|
+
pastParticiple: 'gebrannt',
|
|
137
|
+
},
|
|
138
|
+
senden: {
|
|
139
|
+
past: ['sandte', 'sandtest', 'sandte', 'sandten', 'sandtet', 'sandten'],
|
|
140
|
+
pastParticiple: 'gesandt',
|
|
141
|
+
},
|
|
142
|
+
wenden: {
|
|
143
|
+
past: ['wandte', 'wandtest', 'wandte', 'wandten', 'wandtet', 'wandten'],
|
|
144
|
+
pastParticiple: 'gewandt',
|
|
145
|
+
},
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const inseparable = /^(be|emp|ent|er|ge|miss|ver|zer|wiederer)/
|
|
149
|
+
|
|
150
|
+
// 'verstehen' → ver + stehen, 'aufstehen' → auf + stehen
|
|
151
|
+
const find = function (str) {
|
|
152
|
+
if (irregulars.hasOwnProperty(str)) {
|
|
153
|
+
return { base: irregulars[str], prefix: '', separable: false }
|
|
154
|
+
}
|
|
155
|
+
let m = str.match(inseparable)
|
|
156
|
+
if (m && irregulars.hasOwnProperty(str.substring(m[0].length))) {
|
|
157
|
+
return { base: irregulars[str.substring(m[0].length)], prefix: m[0], separable: false }
|
|
158
|
+
}
|
|
159
|
+
for (let i = 0; i < prefixes.length; i += 1) {
|
|
160
|
+
let p = prefixes[i]
|
|
161
|
+
if (str.startsWith(p) && irregulars.hasOwnProperty(str.substring(p.length))) {
|
|
162
|
+
return { base: irregulars[str.substring(p.length)], prefix: p, separable: true }
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return null
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// returns conjugated forms for one tense, or null.
|
|
169
|
+
// tense: present | past | subj1 | subj2 | imperative | pastParticiple | presentParticiple
|
|
170
|
+
const getIrregular = function (str, tense) {
|
|
171
|
+
let found = find(str)
|
|
172
|
+
if (!found || !found.base[tense]) {
|
|
173
|
+
return null
|
|
174
|
+
}
|
|
175
|
+
let { base, prefix, separable } = found
|
|
176
|
+
let forms = base[tense]
|
|
177
|
+
if (typeof forms === 'string') {
|
|
178
|
+
// participles - 'auf' + 'gestanden', but 'ver' + 'standen'
|
|
179
|
+
if (tense === 'pastParticiple' && separable === false && prefix) {
|
|
180
|
+
return prefix + forms.replace(/^ge/, '')
|
|
181
|
+
}
|
|
182
|
+
return prefix + forms
|
|
183
|
+
}
|
|
184
|
+
return forms.map(f => prefix + f)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// form → infinitive, for root-recovery
|
|
188
|
+
let toInfinitive = {}
|
|
189
|
+
Object.keys(irregulars).forEach(inf => {
|
|
190
|
+
Object.keys(irregulars[inf]).forEach(tense => {
|
|
191
|
+
let forms = irregulars[inf][tense]
|
|
192
|
+
forms = typeof forms === 'string' ? [forms] : forms
|
|
193
|
+
forms.forEach(w => {
|
|
194
|
+
if (!toInfinitive.hasOwnProperty(w)) {
|
|
195
|
+
toInfinitive[w] = inf
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
export default getIrregular
|
|
202
|
+
export { toInfinitive }
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { convert, reverse } from 'suffix-thumb'
|
|
2
|
+
import model from '../models.js'
|
|
3
|
+
import { toInfinitive } from './irregulars.js'
|
|
4
|
+
import ppRules from './custom/fromPastParticiple.js'
|
|
5
|
+
let { presentTense, pastTense, subjunctive1, subjunctive2, imperative, presentParticiple, pastParticiple } = model
|
|
6
|
+
|
|
7
|
+
// =-=-
|
|
8
|
+
const revAll = function (m) {
|
|
9
|
+
return Object.keys(m).reduce((h, k) => {
|
|
10
|
+
h[k] = reverse(m[k])
|
|
11
|
+
return h
|
|
12
|
+
}, {})
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let presentRev = revAll(presentTense)
|
|
16
|
+
let pastRev = revAll(pastTense)
|
|
17
|
+
let subjRev1 = revAll(subjunctive1)
|
|
18
|
+
let subjRev2 = revAll(subjunctive2)
|
|
19
|
+
let impRev = revAll(imperative)
|
|
20
|
+
let presentPartRev = reverse(presentParticiple.presentParticiple)
|
|
21
|
+
let pastPartRev = pastParticiple ? reverse(pastParticiple.pastParticiple) : null
|
|
22
|
+
|
|
23
|
+
const allForms = function (str, form, m) {
|
|
24
|
+
if (toInfinitive.hasOwnProperty(str)) {
|
|
25
|
+
return toInfinitive[str]
|
|
26
|
+
}
|
|
27
|
+
if (m.hasOwnProperty(form)) {
|
|
28
|
+
return convert(str, m[form])
|
|
29
|
+
}
|
|
30
|
+
return str
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const fromPresent = (str, form) => allForms(str, form, presentRev)
|
|
34
|
+
const fromPast = (str, form) => allForms(str, form, pastRev)
|
|
35
|
+
const fromSubjunctive1 = (str, form) => allForms(str, form, subjRev1)
|
|
36
|
+
const fromSubjunctive2 = (str, form) => allForms(str, form, subjRev2)
|
|
37
|
+
const fromImperative = (str, form) => allForms(str, form, impRev)
|
|
38
|
+
const fromPresentParticiple = (str) => {
|
|
39
|
+
return toInfinitive[str] || convert(str, presentPartRev)
|
|
40
|
+
}
|
|
41
|
+
const fromPastParticiple = (str) => {
|
|
42
|
+
if (toInfinitive.hasOwnProperty(str)) {
|
|
43
|
+
return toInfinitive[str]
|
|
44
|
+
}
|
|
45
|
+
if (pastPartRev) {
|
|
46
|
+
return convert(str, pastPartRev)
|
|
47
|
+
}
|
|
48
|
+
return ppRules(str)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
fromPresent, fromPast, fromSubjunctive1, fromSubjunctive2, fromImperative, fromPresentParticiple, fromPastParticiple
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// console.log(fromPresent('tanzt', 'secondPlural'))
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// hand-set tags for core function words.
|
|
2
|
+
// these win over the packed lexicon and the conjugation expansion.
|
|
3
|
+
export default {
|
|
4
|
+
// question words
|
|
5
|
+
'wo': 'QuestionWord',// where
|
|
6
|
+
'woher': 'QuestionWord',//where from
|
|
7
|
+
'wohin': 'QuestionWord',//where to
|
|
8
|
+
'wann': 'QuestionWord',// when
|
|
9
|
+
'was': 'QuestionWord',// what
|
|
10
|
+
'wer': 'QuestionWord',// who
|
|
11
|
+
'wie': 'QuestionWord',// how
|
|
12
|
+
'warum': 'QuestionWord',// why
|
|
13
|
+
'achte': 'TextOrdinal',
|
|
14
|
+
|
|
15
|
+
// negation
|
|
16
|
+
'nicht': ['Adverb', 'Negative'],
|
|
17
|
+
'nein': ['Negative', 'Expression'],
|
|
18
|
+
'kein': ['Determiner', 'Negative'],
|
|
19
|
+
'keine': ['Determiner', 'Negative'],
|
|
20
|
+
'keinem': ['Determiner', 'Negative'],
|
|
21
|
+
'keinen': ['Determiner', 'Negative'],
|
|
22
|
+
'keiner': ['Determiner', 'Negative'],
|
|
23
|
+
'keines': ['Determiner', 'Negative'],
|
|
24
|
+
|
|
25
|
+
// demonstrative determiners
|
|
26
|
+
'dieser': 'Determiner',
|
|
27
|
+
'diese': 'Determiner',
|
|
28
|
+
'dieses': 'Determiner',
|
|
29
|
+
'diesem': 'Determiner',
|
|
30
|
+
'diesen': 'Determiner',
|
|
31
|
+
'jener': 'Determiner',
|
|
32
|
+
'jene': 'Determiner',
|
|
33
|
+
'jenes': 'Determiner',
|
|
34
|
+
'jenem': 'Determiner',
|
|
35
|
+
'jenen': 'Determiner',
|
|
36
|
+
|
|
37
|
+
// quantifier determiners
|
|
38
|
+
'jeder': 'Determiner',
|
|
39
|
+
'jede': 'Determiner',
|
|
40
|
+
'jedes': 'Determiner',
|
|
41
|
+
'jedem': 'Determiner',
|
|
42
|
+
'jeden': 'Determiner',
|
|
43
|
+
'mancher': 'Determiner',
|
|
44
|
+
'manche': 'Determiner',
|
|
45
|
+
'manches': 'Determiner',
|
|
46
|
+
'manchem': 'Determiner',
|
|
47
|
+
'manchen': 'Determiner',
|
|
48
|
+
'solcher': 'Determiner',
|
|
49
|
+
'solche': 'Determiner',
|
|
50
|
+
'solches': 'Determiner',
|
|
51
|
+
'solchem': 'Determiner',
|
|
52
|
+
'solchen': 'Determiner',
|
|
53
|
+
'welcher': 'Determiner',
|
|
54
|
+
'welche': 'Determiner',
|
|
55
|
+
'welches': 'Determiner',
|
|
56
|
+
'welchem': 'Determiner',
|
|
57
|
+
'welchen': 'Determiner',
|
|
58
|
+
'alle': 'Determiner',
|
|
59
|
+
'allen': 'Determiner',
|
|
60
|
+
'aller': 'Determiner',
|
|
61
|
+
'beide': 'Determiner',
|
|
62
|
+
'beiden': 'Determiner',
|
|
63
|
+
'viele': 'Determiner',
|
|
64
|
+
'vielen': 'Determiner',
|
|
65
|
+
'vieler': 'Determiner',
|
|
66
|
+
'mehrere': 'Determiner',
|
|
67
|
+
'mehreren': 'Determiner',
|
|
68
|
+
'wenige': 'Determiner',
|
|
69
|
+
'wenigen': 'Determiner',
|
|
70
|
+
'einige': 'Determiner',
|
|
71
|
+
'einigen': 'Determiner',
|
|
72
|
+
'einiger': 'Determiner',
|
|
73
|
+
|
|
74
|
+
// common adverbs/particles the lexicon mis-tags
|
|
75
|
+
'morgen': 'Adverb',// tomorrow — 'Morgen' (morning) is caught by the titlecase pass
|
|
76
|
+
'bitte': 'Adverb',// please — far more common than 'ich bitte'
|
|
77
|
+
'etwas': 'Pronoun',// something
|
|
78
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import methods from './methods/index.js'
|
|
2
|
+
import lexicon from './lexicon.js'
|
|
3
|
+
import root from './compute/root.js'
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
compute: { root: root },
|
|
7
|
+
methods: {
|
|
8
|
+
two: {
|
|
9
|
+
transform: methods
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
words: lexicon,
|
|
13
|
+
hooks: ['lexicon']
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { addWord } from './trie.js'
|
|
2
|
+
|
|
3
|
+
const buildIndex = function (world) {
|
|
4
|
+
let words = Object.entries(world.model.one.lexicon)
|
|
5
|
+
let { nouns, values } = world.model.one.splitter
|
|
6
|
+
words.forEach((a) => {
|
|
7
|
+
let [w, tag] = a
|
|
8
|
+
if (tag === 'TextOrdinal' || tag === 'TextCardinal') {
|
|
9
|
+
addWord(w, values)
|
|
10
|
+
}
|
|
11
|
+
if (tag === 'Noun' || tag === 'FemaleNoun' || tag === 'MaleNoun' || tag === 'NeuterNoun') {
|
|
12
|
+
addWord(w, nouns)
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
// misc words
|
|
16
|
+
addWord('und', values) //'and'
|
|
17
|
+
addWord('ein', values) //'one'
|
|
18
|
+
addWord('hunderttausend', values)
|
|
19
|
+
}
|
|
20
|
+
export default buildIndex
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// links between words
|
|
2
|
+
// https://digital.lib.washington.edu/researchworks/bitstream/handle/1773/44691/Callow_washington_0250O_20779.pdf
|
|
3
|
+
// 'er|en|es|s|e|n
|
|
4
|
+
const hasLink = /^(e[rns]|s|n)/
|
|
5
|
+
import { findMatch } from '../trie.js'
|
|
6
|
+
|
|
7
|
+
const findSplits = function (str, root) {
|
|
8
|
+
let found = []
|
|
9
|
+
while (str.length > 0) {
|
|
10
|
+
let match = findMatch(str, root)
|
|
11
|
+
if (!match) {
|
|
12
|
+
//we done
|
|
13
|
+
// allow a connector - [foo, en, bar]
|
|
14
|
+
if (found.length > 0 && hasLink.test(str)) {
|
|
15
|
+
let tmp = str.replace(hasLink, '')
|
|
16
|
+
match = findMatch(tmp, root)
|
|
17
|
+
if (match) {
|
|
18
|
+
let link = str.match(hasLink)[0]
|
|
19
|
+
found.push(link)
|
|
20
|
+
str = str.substr(link.length)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!match) {
|
|
25
|
+
found.push(str)
|
|
26
|
+
break
|
|
27
|
+
}
|
|
28
|
+
// found a prefix
|
|
29
|
+
found.push(match)
|
|
30
|
+
str = str.substr(match.length)
|
|
31
|
+
}
|
|
32
|
+
return found
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const splitter = function (view) {
|
|
36
|
+
let { values } = view.model.one.splitter
|
|
37
|
+
view.docs.forEach((terms) => {
|
|
38
|
+
terms.forEach((term) => {
|
|
39
|
+
// split numbers
|
|
40
|
+
if (term.tags.has('Value')) {
|
|
41
|
+
term.splits = findSplits(term.normal, values)
|
|
42
|
+
}
|
|
43
|
+
// split nouns
|
|
44
|
+
// if (term.tags.has('Noun')) {
|
|
45
|
+
// term.splits = findSplits(term.normal, nouns)
|
|
46
|
+
// }
|
|
47
|
+
// split adjectives
|
|
48
|
+
// if (term.tags.has('Adjective')) {
|
|
49
|
+
// term.byChar = findbyChar(term, adjectives)
|
|
50
|
+
// }
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
export default { splitter }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// import values from './splitter/values.js'
|
|
2
|
+
// import nouns from './splitter/nouns.js'
|
|
3
|
+
// import verbs from './splitter/verbs.js'
|
|
4
|
+
// import adjectives from './splitter/adjectives.js'
|
|
5
|
+
|
|
6
|
+
let values = { more: [] }
|
|
7
|
+
let nouns = { more: [] }
|
|
8
|
+
let verbs = { more: [] }
|
|
9
|
+
let adjectives = { more: [] }
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
one: {
|
|
13
|
+
splitter: {
|
|
14
|
+
values,
|
|
15
|
+
nouns,
|
|
16
|
+
verbs,
|
|
17
|
+
adjectives
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const addWord = function (str, root) {
|
|
2
|
+
let chars = str.split('')
|
|
3
|
+
let node = root
|
|
4
|
+
chars.forEach(c => {
|
|
5
|
+
node.more[c] = node.more[c] || { more: {} }
|
|
6
|
+
node = node.more[c]
|
|
7
|
+
})
|
|
8
|
+
node.end = true
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const makeTrie = function (arr) {
|
|
12
|
+
let root = {
|
|
13
|
+
more: {}
|
|
14
|
+
}
|
|
15
|
+
arr.forEach(str => addWord(str, root))
|
|
16
|
+
return root
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const findMatch = function (str, root) {
|
|
20
|
+
let match = null
|
|
21
|
+
let chars = str.split('')
|
|
22
|
+
let node = root
|
|
23
|
+
for (let i = 0; i < chars.length; i += 1) {
|
|
24
|
+
if (!node.more[chars[i]]) {
|
|
25
|
+
// dead end
|
|
26
|
+
return match
|
|
27
|
+
}
|
|
28
|
+
node = node.more[chars[i]]
|
|
29
|
+
if (node.end === true) {
|
|
30
|
+
match = chars.slice(0, i + 1).join('')
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return match
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { makeTrie, findMatch, addWord }
|
|
37
|
+
|
|
38
|
+
// let trie = makeTrie(['car', 'cab', 'stab', 'carbon'])
|
|
39
|
+
// console.dir(trie, { depth: 15 })
|
|
40
|
+
// console.log(findMatch('carbon', trie))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import nouns from './tags/nouns.js'
|
|
2
|
+
import verbs from './tags/verbs.js'
|
|
3
|
+
import values from './tags/values.js'
|
|
4
|
+
import dates from './tags/dates.js'
|
|
5
|
+
import misc from './tags/misc.js'
|
|
6
|
+
|
|
7
|
+
let tags = Object.assign({}, nouns, verbs, values, dates, misc)
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
tags
|
|
11
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
Date: {
|
|
3
|
+
not: ['Verb', 'Adverb', 'Adjective'],
|
|
4
|
+
},
|
|
5
|
+
Month: {
|
|
6
|
+
is: 'Singular',
|
|
7
|
+
also: ['Date'],
|
|
8
|
+
not: ['Year', 'WeekDay', 'Time'],
|
|
9
|
+
},
|
|
10
|
+
WeekDay: {
|
|
11
|
+
is: 'Noun',
|
|
12
|
+
also: ['Date'],
|
|
13
|
+
},
|
|
14
|
+
Year: {
|
|
15
|
+
is: 'Date',
|
|
16
|
+
not: ['RomanNumeral'],
|
|
17
|
+
},
|
|
18
|
+
FinancialQuarter: {
|
|
19
|
+
is: 'Date',
|
|
20
|
+
not: 'Fraction',
|
|
21
|
+
},
|
|
22
|
+
// 'easter'
|
|
23
|
+
Holiday: {
|
|
24
|
+
is: 'Date',
|
|
25
|
+
also: ['Noun'],
|
|
26
|
+
},
|
|
27
|
+
// 'summer'
|
|
28
|
+
Season: {
|
|
29
|
+
is: 'Date',
|
|
30
|
+
},
|
|
31
|
+
Timezone: {
|
|
32
|
+
is: 'Noun',
|
|
33
|
+
also: ['Date'],
|
|
34
|
+
not: ['ProperNoun'],
|
|
35
|
+
},
|
|
36
|
+
Time: {
|
|
37
|
+
is: 'Date',
|
|
38
|
+
not: ['AtMention'],
|
|
39
|
+
},
|
|
40
|
+
// 'months'
|
|
41
|
+
Duration: {
|
|
42
|
+
is: 'Noun',
|
|
43
|
+
also: ['Date'],
|
|
44
|
+
},
|
|
45
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const anything = ['Noun', 'Verb', 'Adjective', 'Adverb', 'Value', 'QuestionWord']
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
Adjective: {
|
|
5
|
+
not: ['Noun', 'Verb', 'Adverb', 'Value'],
|
|
6
|
+
},
|
|
7
|
+
Comparable: {
|
|
8
|
+
is: 'Adjective',
|
|
9
|
+
},
|
|
10
|
+
Comparative: {
|
|
11
|
+
is: 'Adjective',
|
|
12
|
+
},
|
|
13
|
+
Superlative: {
|
|
14
|
+
is: 'Adjective',
|
|
15
|
+
not: ['Comparative'],
|
|
16
|
+
},
|
|
17
|
+
NumberRange: {},
|
|
18
|
+
Adverb: {
|
|
19
|
+
not: ['Noun', 'Verb', 'Adjective', 'Value'],
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
Determiner: {
|
|
23
|
+
not: ['Noun', 'Verb', 'Adjective', 'Adverb', 'QuestionWord', 'Conjunction'], //allow 'a' to be a Determiner/Value
|
|
24
|
+
},
|
|
25
|
+
Conjunction: {
|
|
26
|
+
not: anything,
|
|
27
|
+
},
|
|
28
|
+
Preposition: {
|
|
29
|
+
not: ['Noun', 'Verb', 'Adjective', 'Adverb', 'QuestionWord'],
|
|
30
|
+
},
|
|
31
|
+
QuestionWord: {
|
|
32
|
+
not: ['Determiner'],
|
|
33
|
+
},
|
|
34
|
+
Currency: {
|
|
35
|
+
is: 'Noun',
|
|
36
|
+
},
|
|
37
|
+
Expression: {
|
|
38
|
+
not: ['Noun', 'Adjective', 'Verb', 'Adverb'],
|
|
39
|
+
},
|
|
40
|
+
Abbreviation: {},
|
|
41
|
+
Url: {
|
|
42
|
+
not: ['HashTag', 'PhoneNumber', 'Verb', 'Adjective', 'Value', 'AtMention', 'Email'],
|
|
43
|
+
},
|
|
44
|
+
PhoneNumber: {
|
|
45
|
+
not: ['HashTag', 'Verb', 'Adjective', 'Value', 'AtMention', 'Email'],
|
|
46
|
+
},
|
|
47
|
+
HashTag: {},
|
|
48
|
+
AtMention: {
|
|
49
|
+
is: 'Noun',
|
|
50
|
+
not: ['HashTag', 'Email'],
|
|
51
|
+
},
|
|
52
|
+
Emoji: {
|
|
53
|
+
not: ['HashTag', 'Verb', 'Adjective', 'Value', 'AtMention'],
|
|
54
|
+
},
|
|
55
|
+
Emoticon: {
|
|
56
|
+
not: ['HashTag', 'Verb', 'Adjective', 'Value', 'AtMention'],
|
|
57
|
+
},
|
|
58
|
+
Email: {
|
|
59
|
+
not: ['HashTag', 'Verb', 'Adjective', 'Value', 'AtMention'],
|
|
60
|
+
},
|
|
61
|
+
Acronym: {
|
|
62
|
+
not: ['Plural', 'RomanNumeral'],
|
|
63
|
+
},
|
|
64
|
+
Negative: {
|
|
65
|
+
not: ['Noun', 'Adjective', 'Value'],
|
|
66
|
+
},
|
|
67
|
+
Condition: {
|
|
68
|
+
not: ['Verb', 'Adjective', 'Noun', 'Value'],
|
|
69
|
+
},
|
|
70
|
+
}
|