de-compromise 0.0.9 → 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.
Files changed (85) hide show
  1. package/README.md +1 -1
  2. package/builds/de-compromise.cjs +2357 -1687
  3. package/builds/de-compromise.min.js +1 -1
  4. package/builds/de-compromise.mjs +1 -1
  5. package/package.json +21 -14
  6. package/src/01-one/lexicon/_data.js +32 -0
  7. package/src/01-one/lexicon/compute/root.js +55 -0
  8. package/src/01-one/lexicon/lexicon.js +95 -0
  9. package/src/01-one/lexicon/methods/_data.js +193 -0
  10. package/src/01-one/lexicon/methods/adjectives/_test-back.js +29 -0
  11. package/src/01-one/lexicon/methods/adjectives/_test.js +49 -0
  12. package/src/01-one/lexicon/methods/adjectives/inflect.js +27 -0
  13. package/src/01-one/lexicon/methods/adjectives/model.js +126 -0
  14. package/src/01-one/lexicon/methods/adjectives/new/adjective.js +8 -0
  15. package/src/01-one/lexicon/methods/adjectives/new/comparative.js +7 -0
  16. package/src/01-one/lexicon/methods/adjectives/new/superlative.js +159 -0
  17. package/src/01-one/lexicon/methods/adjectives/toRoot.js +47 -0
  18. package/src/01-one/lexicon/methods/index.js +56 -0
  19. package/src/01-one/lexicon/methods/models.js +10 -0
  20. package/src/01-one/lexicon/methods/nouns/_test-back.js +45 -0
  21. package/src/01-one/lexicon/methods/nouns/new.js +56 -0
  22. package/src/01-one/lexicon/methods/nouns/toPlural.js +49 -0
  23. package/src/01-one/lexicon/methods/nouns/toSingular.js +46 -0
  24. package/src/01-one/lexicon/methods/verbs/conjugate.js +87 -0
  25. package/src/01-one/lexicon/methods/verbs/custom/_test-from.js +53 -0
  26. package/src/01-one/lexicon/methods/verbs/custom/_test-to.js +50 -0
  27. package/src/01-one/lexicon/methods/verbs/custom/fromPastParticiple.js +37 -0
  28. package/src/01-one/lexicon/methods/verbs/custom/rules.js +182 -0
  29. package/src/01-one/lexicon/methods/verbs/custom/toPastParticiple.js +54 -0
  30. package/src/01-one/lexicon/methods/verbs/irregulars.js +202 -0
  31. package/src/01-one/lexicon/methods/verbs/toRoot.js +55 -0
  32. package/src/01-one/lexicon/misc.js +78 -0
  33. package/src/01-one/lexicon/plugin.js +14 -0
  34. package/src/01-one/splitter/build.js +20 -0
  35. package/src/01-one/splitter/compute/splitter.js +54 -0
  36. package/src/01-one/splitter/model/index.js +20 -0
  37. package/src/01-one/splitter/plugin.js +10 -0
  38. package/src/01-one/splitter/trie.js +40 -0
  39. package/src/01-one/tagset/plugin.js +11 -0
  40. package/src/01-one/tagset/tags/dates.js +45 -0
  41. package/src/01-one/tagset/tags/misc.js +70 -0
  42. package/src/01-one/tagset/tags/nouns.js +116 -0
  43. package/src/01-one/tagset/tags/values.js +47 -0
  44. package/src/01-one/tagset/tags/verbs.js +64 -0
  45. package/src/01-one/tokenizer/contractions.js +40 -0
  46. package/src/01-one/tokenizer/is-sentence.js +37 -0
  47. package/src/01-one/tokenizer/plugin.js +11 -0
  48. package/src/01-one/tokenizer/unicode.js +55 -0
  49. package/src/02-two/postTagger/matches.js +47 -0
  50. package/src/02-two/postTagger/plugin.js +8 -0
  51. package/src/02-two/preTagger/compute/1st-pass/regex.js +43 -0
  52. package/src/02-two/preTagger/compute/1st-pass/titlecase.js +21 -0
  53. package/src/02-two/preTagger/compute/1st-pass/year.js +54 -0
  54. package/src/02-two/preTagger/compute/2nd-pass/acronym.js +82 -0
  55. package/src/02-two/preTagger/compute/2nd-pass/fallback.js +27 -0
  56. package/src/02-two/preTagger/compute/2nd-pass/prefix-lookup.js +33 -0
  57. package/src/02-two/preTagger/compute/2nd-pass/suffix-lookup.js +44 -0
  58. package/src/02-two/preTagger/compute/index.js +42 -0
  59. package/src/02-two/preTagger/model/index.js +14 -0
  60. package/src/02-two/preTagger/model/prefixes.js +46 -0
  61. package/src/02-two/preTagger/model/regex/regex-normal.js +25 -0
  62. package/src/02-two/preTagger/model/regex/regex-numbers.js +62 -0
  63. package/src/02-two/preTagger/model/regex/regex-text.js +17 -0
  64. package/src/02-two/preTagger/model/suffixes.js +171 -0
  65. package/src/02-two/preTagger/plugin.js +12 -0
  66. package/src/03-three/adjectives/api.js +34 -0
  67. package/src/03-three/adjectives/plugin.js +5 -0
  68. package/src/03-three/nouns/api.js +74 -0
  69. package/src/03-three/nouns/plugin.js +5 -0
  70. package/src/03-three/numbers/api.js +259 -0
  71. package/src/03-three/numbers/data.js +77 -0
  72. package/src/03-three/numbers/format/index.js +27 -0
  73. package/src/03-three/numbers/format/toText.js +118 -0
  74. package/src/03-three/numbers/parse/fromText.js +52 -0
  75. package/src/03-three/numbers/parse/index.js +63 -0
  76. package/src/03-three/numbers/plugin.js +5 -0
  77. package/src/03-three/verbs/api.js +41 -0
  78. package/src/03-three/verbs/plugin.js +5 -0
  79. package/src/_lib.js +4 -0
  80. package/src/_version.js +1 -0
  81. package/src/index.js +53 -0
  82. package/types/index.d.ts +46 -0
  83. package/types/misc.ts +92 -0
  84. package/types/view/de.ts +61 -0
  85. 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,10 @@
1
+ import model from '../splitter/model/index.js'
2
+ import compute from '../splitter/compute/splitter.js'
3
+ import mutate from './build.js'
4
+
5
+ export default {
6
+ mutate,
7
+ model,
8
+ compute,
9
+ // hooks: ['splitter'],
10
+ }
@@ -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
+ }