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,259 @@
1
+ import parse from './parse/index.js'
2
+ import format from './format/index.js'
3
+
4
+ // return the nth elem of a doc
5
+ export const getNth = (doc, n) => (typeof n === 'number' ? doc.eq(n) : doc)
6
+
7
+ const api = function (View) {
8
+ /** */
9
+ class Numbers extends View {
10
+ constructor(document, pointer, groups) {
11
+ super(document, pointer, groups)
12
+ this.viewType = 'Numbers'
13
+ }
14
+ parse(n) {
15
+ return getNth(this, n).map(parse)
16
+ }
17
+ get(n) {
18
+ return getNth(this, n).map(parse).map(o => o.num)
19
+ }
20
+ json(n) {
21
+ let doc = getNth(this, n)
22
+ return doc.map(p => {
23
+ let json = p.toView().json(n)[0]
24
+ let parsed = parse(p)
25
+ json.number = {
26
+ prefix: parsed.prefix,
27
+ num: parsed.num,
28
+ suffix: parsed.suffix,
29
+ hasComma: parsed.hasComma,
30
+ }
31
+ return json
32
+ }, [])
33
+ }
34
+ /** any known measurement unit, for the number */
35
+ units() {
36
+ return this.growRight('#Unit').match('#Unit$')
37
+ }
38
+ /** return only ordinal numbers */
39
+ isOrdinal() {
40
+ return this.if('#Ordinal')
41
+ }
42
+ /** return only cardinal numbers*/
43
+ isCardinal() {
44
+ return this.if('#Cardinal')
45
+ }
46
+
47
+ /** convert to numeric form like '8' or '8th' */
48
+ toNumber() {
49
+ let m = this.if('#TextValue')
50
+ let res = m.map(val => {
51
+ let obj = parse(val)
52
+ if (obj.num === null) {
53
+ return val
54
+ }
55
+ let fmt = val.has('#Ordinal') ? 'Ordinal' : 'Cardinal'
56
+ let str = format(obj, fmt)
57
+ if (str) {
58
+ val.replaceWith(str, { tags: true })
59
+ val.tag('NumericValue')
60
+ }
61
+ return val
62
+ })
63
+ return new Numbers(res.document, res.pointer)
64
+ }
65
+ /** convert to numeric form like 'eight' or 'eighth' */
66
+ toText() {
67
+ let m = this
68
+ let res = m.map(val => {
69
+ if (val.has('#TextValue')) {
70
+ return val
71
+ }
72
+ let obj = parse(val)
73
+ if (obj.num === null) {
74
+ return val
75
+ }
76
+ let fmt = val.has('#Ordinal') ? 'TextOrdinal' : 'TextCardinal'
77
+ let str = format(obj, fmt)
78
+ if (str) {
79
+ val.replaceWith(str, { tags: true })
80
+ val.tag('TextValue')
81
+ }
82
+ return val
83
+ })
84
+ return new Numbers(res.document, res.pointer)
85
+ }
86
+ /** convert ordinal to cardinal form, like 'eight', or '8' */
87
+ toCardinal() {
88
+ let m = this
89
+ let res = m.map(val => {
90
+ if (!val.has('#Ordinal')) {
91
+ return val
92
+ }
93
+ let obj = parse(val)
94
+ if (obj.num === null) {
95
+ return val
96
+ }
97
+ let fmt = val.has('#TextValue') ? 'TextCardinal' : 'Cardinal'
98
+ let str = format(obj, fmt)
99
+ if (str) {
100
+ val.replaceWith(str, { tags: true })
101
+ val.tag('Cardinal')
102
+ }
103
+ return val
104
+ })
105
+ return new Numbers(res.document, res.pointer)
106
+ }
107
+ /** convert cardinal to ordinal form, like 'eighth', or '8th' */
108
+ toOrdinal() {
109
+ let m = this
110
+ let res = m.map(val => {
111
+ if (val.has('#Ordinal')) {
112
+ return val
113
+ }
114
+ let obj = parse(val)
115
+ if (obj.num === null) {
116
+ return val
117
+ }
118
+ let fmt = val.has('#TextValue') ? 'TextOrdinal' : 'Ordinal'
119
+ let str = format(obj, fmt)
120
+ if (str) {
121
+ val.replaceWith(str, { tags: true })
122
+ val.tag('Ordinal')
123
+ }
124
+ return val
125
+ })
126
+ return new Numbers(res.document, res.pointer)
127
+ }
128
+
129
+ /** return only numbers that are == n */
130
+ isEqual(n) {
131
+ return this.filter((val) => {
132
+ let num = parse(val).num
133
+ return num === n
134
+ })
135
+ }
136
+ /** return only numbers that are > n*/
137
+ greaterThan(n) {
138
+ return this.filter((val) => {
139
+ let num = parse(val).num
140
+ return num > n
141
+ })
142
+ }
143
+ /** return only numbers that are < n*/
144
+ lessThan(n) {
145
+ return this.filter((val) => {
146
+ let num = parse(val).num
147
+ return num < n
148
+ })
149
+ }
150
+ /** return only numbers > min and < max */
151
+ between(min, max) {
152
+ return this.filter((val) => {
153
+ let num = parse(val).num
154
+ return num > min && num < max
155
+ })
156
+ }
157
+ /** set these number to n */
158
+ set(n) {
159
+ if (n === undefined) {
160
+ return this // don't bother
161
+ }
162
+ if (typeof n === 'string') {
163
+ n = parse(n).num
164
+ }
165
+ let m = this
166
+ let res = m.map((val) => {
167
+ let obj = parse(val)
168
+ obj.num = n
169
+ if (obj.num === null) {
170
+ return val
171
+ }
172
+ let fmt = val.has('#Ordinal') ? 'Ordinal' : 'Cardinal'
173
+ if (val.has('#TextValue')) {
174
+ fmt = val.has('#Ordinal') ? 'TextOrdinal' : 'TextCardinal'
175
+ }
176
+ let str = format(obj, fmt)
177
+ // re-group thousands - '1.234.567'
178
+ if (obj.hasComma && fmt === 'Cardinal') {
179
+ str = obj.num.toLocaleString('de-DE')
180
+ }
181
+ if (str) {
182
+ val = val.not('#Currency')
183
+ val.replaceWith(str, { tags: true })
184
+ // handle plural/singular unit
185
+ // agreeUnits(agree, val, obj)
186
+ }
187
+ return val
188
+ })
189
+ return new Numbers(res.document, res.pointer)
190
+ }
191
+ add(n) {
192
+ if (!n) {
193
+ return this // don't bother
194
+ }
195
+ if (typeof n === 'string') {
196
+ n = parse(n).num
197
+ }
198
+ let m = this
199
+ let res = m.map((val) => {
200
+ let obj = parse(val)
201
+ if (obj.num === null) {
202
+ return val
203
+ }
204
+ obj.num += n
205
+ let fmt = val.has('#Ordinal') ? 'Ordinal' : 'Cardinal'
206
+ if (obj.isText) {
207
+ fmt = val.has('#Ordinal') ? 'TextOrdinal' : 'TextCardinal'
208
+ }
209
+ let str = format(obj, fmt)
210
+ if (str) {
211
+ val.replaceWith(str, { tags: true })
212
+ // handle plural/singular unit
213
+ // agreeUnits(agree, val, obj)
214
+ }
215
+ return val
216
+ })
217
+ return new Numbers(res.document, res.pointer)
218
+ }
219
+ /** decrease each number by n*/
220
+ subtract(n, agree) {
221
+ return this.add(n * -1, agree)
222
+ }
223
+ /** increase each number by 1 */
224
+ increment(agree) {
225
+ return this.add(1, agree)
226
+ }
227
+ /** decrease each number by 1 */
228
+ decrement(agree) {
229
+ return this.add(-1, agree)
230
+ }
231
+ // overloaded - keep Numbers class
232
+ update(pointer) {
233
+ let m = new Numbers(this.document, pointer)
234
+ m._cache = this._cache // share this full thing
235
+ return m
236
+ }
237
+ }
238
+ // aliases
239
+ Numbers.prototype.isBetween = Numbers.prototype.between
240
+ Numbers.prototype.minus = Numbers.prototype.subtract
241
+ Numbers.prototype.plus = Numbers.prototype.add
242
+ Numbers.prototype.equals = Numbers.prototype.isEqual
243
+
244
+ View.prototype.numbers = function (n) {
245
+ let m = this.match('#Value+')
246
+ // most numbers are 1-term
247
+ // but very-large numbers get broken up 'zwei Millionen eins'
248
+ if (!m.has('(million|millionen|milliarde)')) {
249
+ m = m.terms()
250
+ }
251
+ // make sure splitter has run
252
+ m.compute('splitter')
253
+ m = getNth(m, n)
254
+ return new Numbers(this.document, m.pointer)
255
+ }
256
+ // alias
257
+ View.prototype.values = View.prototype.numbers
258
+ }
259
+ export default api
@@ -0,0 +1,77 @@
1
+ let data = {
2
+ ones: [
3
+ [1, 'eins', 'erste'],
4
+ [2, 'zwei', 'zweite'],
5
+ [3, 'drei', 'dritte'],
6
+ [4, 'vier', 'vierte'],
7
+ [5, 'fünf', 'fünfte'],
8
+ [6, 'sechs', 'sechste'],
9
+ [7, 'sieben', 'siebente'], //siebte
10
+ [8, 'acht', 'achte'],
11
+ [9, 'neun', 'neunte'],
12
+ ],
13
+ teens: [
14
+ [10, 'zehn', 'zehnte'],
15
+ [11, 'elf', 'elfte'],
16
+ [12, 'zwölf', 'zwölfte'],
17
+ [13, 'dreizehn', 'dreizehnte'],
18
+ [14, 'vierzehn', 'vierzehnte'],
19
+ [15, 'fünfzehn', 'fünfzehnte'],
20
+ [16, 'sechzehn', 'sechzehnte'],
21
+ [17, 'siebzehn', 'siebzehnte'],
22
+ [18, 'achtzehn', 'achtzehnte'],
23
+ [19, 'neunzehn', 'neunzehnte'],
24
+ ],
25
+ tens: [
26
+ [20, 'zwanzig', 'zwanzigste'],
27
+ [30, 'dreißig', 'dreißigste'],
28
+ [40, 'vierzig', 'vierzigste'],
29
+ [50, 'fünfzig', 'fünfzigste'],
30
+ [60, 'sechzig', 'sechzigste'],
31
+ [70, 'siebzig', 'siebzigste'],
32
+ [80, 'achtzig', 'achtzigste'],
33
+ [90, 'neunzig', 'neunzigste'],
34
+ ],
35
+ hundreds: [
36
+ [100, 'einhundert', 'hundertste'],
37
+ // [101, 'einhunderteins', 'hunderterste'],
38
+ [200, 'zweihundert', 'zweihundertste'],
39
+ [300, 'dreihundert', 'dreihundertste'],
40
+ [400, 'vierhundert', 'vierhundertste'],
41
+ [500, 'fünfhundert', 'fünfhundertste'],
42
+ [600, 'sechshundert', 'sechshundertste'],
43
+ [700, 'siebenhundert', 'siebenhundertste'],
44
+ [800, 'achthundert', 'achthundertste'],
45
+ [900, 'neunhundert', 'neunhundertste'],
46
+ ],
47
+ multiples: [
48
+ [100, 'hundert', 'hundertste'],
49
+ [1000, 'tausend', 'tausendste'],
50
+ [100000, 'hunderttausend', 'hunderttausendste'],
51
+ [1000000, 'million', 'millionste'],
52
+ ]
53
+ }
54
+ const toCardinal = {}
55
+ const toOrdinal = {}
56
+ const toNumber = {}
57
+
58
+ Object.keys(data).forEach(k => {
59
+ data[k].forEach(a => {
60
+ let [num, w, ord] = a
61
+ toCardinal[ord] = w
62
+ toOrdinal[w] = ord
63
+ toNumber[w] = num
64
+ })
65
+ })
66
+
67
+ const isMultiple = new Set(data.multiples.map(a => a[1]))
68
+
69
+ // misc
70
+ toNumber.ein = 1 // eins - ein
71
+ toNumber.hunderteins = 101
72
+ toCardinal.siebte = 'sieben'
73
+ toCardinal.hunderterste = 'hunderteins'
74
+ toOrdinal.hunderteins = 'hunderterste'
75
+
76
+
77
+ export { data, toCardinal, toOrdinal, toNumber, isMultiple }
@@ -0,0 +1,27 @@
1
+ import toText from './toText.js'
2
+ import { toOrdinal } from '../data.js'
3
+
4
+
5
+ const formatNumber = function (parsed, fmt) {
6
+ if (fmt === 'TextOrdinal') {
7
+ let words = toText(parsed.num)
8
+ let last = words[words.length - 1]
9
+ words[words.length - 1] = toOrdinal[last]
10
+ return words.join('')
11
+ }
12
+ if (fmt === 'TextCardinal') {
13
+ return toText(parsed.num).join('')
14
+ }
15
+ // numeric formats
16
+ // '55e'
17
+ if (fmt === 'Ordinal') {
18
+ let str = String(parsed.num)
19
+ return str += '.'
20
+ }
21
+ if (fmt === 'Cardinal') {
22
+ // german decimals use a comma - '12,5'
23
+ return String(parsed.num).replace('.', ',')
24
+ }
25
+ return String(parsed.num || '').replace('.', ',')
26
+ }
27
+ export default formatNumber
@@ -0,0 +1,118 @@
1
+ import { data } from '../data.js'
2
+ let tens = data.tens.reverse()
3
+ let teens = data.teens.reverse()
4
+ let ones = data.ones.reverse()
5
+ let hundreds = data.hundreds.reverse()
6
+
7
+
8
+ const doThousands = function (num) {
9
+ let words = []
10
+ // hunderttausend
11
+ if (num >= 100000) {
12
+ for (let i = 0; i < ones.length; i += 1) {
13
+ if (num >= ones[i][0] * 100000) {
14
+ let found = ones[i][0] === 1 ? 'ein' : ones[i][1]
15
+ words.push(found)
16
+ words.push('hunderttausend')
17
+ num -= teens[i][0] * 100000
18
+ }
19
+ }
20
+ }
21
+ // eleven-thousand...
22
+ if (num >= 10000) {
23
+ for (let i = 0; i < teens.length; i += 1) {
24
+ if (num >= teens[i][0] * 1000) {
25
+ words.push(teens[i][1])
26
+ words.push('tausend')
27
+ num -= teens[i][0] * 1000
28
+ }
29
+ }
30
+ }
31
+ // dreitausend, viertausend...
32
+ for (let i = 0; i < ones.length; i += 1) {
33
+ if (num >= ones[i][0] * 1000) {
34
+ let found = ones[i][0] === 1 ? 'ein' : ones[i][1]
35
+ return [found, 'tausend']
36
+ }
37
+ }
38
+ return words
39
+ }
40
+
41
+ const doHundreds = function (num) {
42
+ let words = []
43
+ for (let i = 0; i < hundreds.length; i += 1) {
44
+ if (num >= hundreds[i][0]) {
45
+ words.push(hundreds[i][1])
46
+ num -= hundreds[i][0]
47
+ break
48
+ }
49
+ }
50
+ return words
51
+ }
52
+
53
+ // 23 -> '[drei][und][zwanzig]'
54
+ const twoDigit = function (num) {
55
+ let words = []
56
+ // ninety, eighty ...
57
+ for (let i = 0; i < tens.length; i += 1) {
58
+ if (num >= tens[i][0]) {
59
+ words.push(tens[i][1])
60
+ num -= tens[i][0]
61
+ }
62
+ }
63
+ // found nothing? look for teens
64
+ if (words.length === 0) {
65
+ for (let i = 0; i < teens.length; i += 1) {
66
+ if (num === teens[i][0]) {
67
+ return [teens[i][1]] //these don't combine
68
+ }
69
+ }
70
+ }
71
+ // look for ones to add on
72
+ for (let i = 0; i < ones.length; i += 1) {
73
+ if (num === ones[i][0]) {
74
+ // drei und zwanzig
75
+ if (words.length === 1) {
76
+ // use '[ein][und][zwanzig]', not 'eins..'
77
+ let found = ones[i][0] === 1 ? 'ein' : ones[i][1]
78
+ return [found, 'und', words[0]]
79
+ }
80
+ // just 'drei'
81
+ if (words.length === 0) {
82
+ return [ones[i][1]]
83
+ }
84
+ }
85
+ }
86
+ return words
87
+ }
88
+
89
+
90
+ // turn 130 into '[ein][hundert][dreißig]'
91
+ const toText = function (num) {
92
+ let words = []
93
+ if (num === 0) {
94
+ return ['null']
95
+ }
96
+ if (num < 0) {
97
+ words.push('moins')
98
+ num = Math.abs(num)
99
+ }
100
+ // do '[sieben][tausend]'
101
+ if (num >= 1000) {
102
+ let res = doThousands(num)
103
+ words = words.concat(res)
104
+ num %= 1000
105
+ }
106
+ // do '[zwei][hundert]'
107
+ if (num >= 100) {
108
+ let res = doHundreds(num)
109
+ words = words.concat(res)
110
+ num %= 100
111
+ }
112
+ // do '[drei][und][zwanzig]'
113
+ if (num > 0) {
114
+ words = words.concat(twoDigit(num))
115
+ }
116
+ return words
117
+ }
118
+ export default toText
@@ -0,0 +1,52 @@
1
+ import { toCardinal, toNumber, isMultiple } from '../data.js'
2
+
3
+ const parseNumbers = function (terms = []) {
4
+ let sum = 0
5
+ let carry = 0
6
+ let minus = false
7
+
8
+ let words = terms[0].splits || []
9
+ // console.log(words)
10
+ let tags = terms[0].tags
11
+ for (let i = 0; i < words.length; i += 1) {
12
+ let w = words[i]
13
+
14
+ if (w === 'minus') {
15
+ minus = true
16
+ continue
17
+ }
18
+ // ... [ein][und][zwanzig]
19
+ if (w === 'und') {
20
+ continue
21
+ }
22
+ // 'huitieme'
23
+ if (tags.has('Ordinal')) {
24
+ w = toCardinal[w] || w
25
+ }
26
+ // 'hundert'
27
+ if (isMultiple.has(w)) {
28
+ let mult = toNumber[w] || 1
29
+ if (carry === 0) {
30
+ carry = 1
31
+ }
32
+ sum += mult * carry
33
+ carry = 0
34
+ continue
35
+ }
36
+ // 'fünf'
37
+ if (toNumber.hasOwnProperty(w)) {
38
+ carry += toNumber[w]
39
+ // console.log(w, carry)
40
+ }
41
+ }
42
+ // include any remaining
43
+ if (carry !== 0) {
44
+ sum += carry
45
+ }
46
+ // make it all negative
47
+ if (minus === true) {
48
+ sum *= -1
49
+ }
50
+ return sum
51
+ }
52
+ export default parseNumbers
@@ -0,0 +1,63 @@
1
+ import fromText from './fromText.js'
2
+
3
+ const fromNumber = function (m) {
4
+ // use the raw text - normalization strips the german decimal-comma
5
+ let str = (m.text() || m.text('normal')).toLowerCase().trim()
6
+ str = str.replace(/(e|er)$/, '')
7
+ // get prefix/suffix
8
+ let arr = str.split(/([0-9.,]*)/)
9
+ let [prefix, num] = arr
10
+ let suffix = arr.slice(2).join('')
11
+ // german format - '.' groups thousands, ',' marks the decimal
12
+ num = num.replace(/[.,]$/, '')
13
+ let hasComma = /\d\.\d/.test(num)
14
+ num = num.replace(/\./g, '').replace(/,/, '.')
15
+ if (num !== '' && m.length < 2) {
16
+ num = Number(num)
17
+ //ensure that num is an actual number
18
+ if (typeof num !== 'number' || isNaN(num)) {
19
+ num = null
20
+ } else if (/-$/.test(prefix)) {
21
+ num = num * -1
22
+ }
23
+ // strip an ordinal off the suffix
24
+ if (suffix === 'e' || suffix === 'er') {
25
+ suffix = ''
26
+ }
27
+ }
28
+ return {
29
+ hasComma,
30
+ prefix,
31
+ num,
32
+ suffix,
33
+ }
34
+ }
35
+
36
+ const parseNumber = function (m) {
37
+ let terms = m.docs[0]
38
+ let num = null
39
+ let prefix = ''
40
+ let suffix = ''
41
+ let hasComma = false
42
+ let isText = m.has('#TextValue')
43
+ if (isText) {
44
+ num = fromText(terms)
45
+ } else {
46
+ let res = fromNumber(m)
47
+ prefix = res.prefix
48
+ suffix = res.suffix
49
+ num = res.num
50
+ hasComma = res.hasComma
51
+ }
52
+ return {
53
+ hasComma,
54
+ prefix,
55
+ num,
56
+ suffix,
57
+ isText,
58
+ isOrdinal: m.has('#Ordinal'),
59
+ isFraction: m.has('#Fraction'),
60
+ isMoney: m.has('#Money'),
61
+ }
62
+ }
63
+ export default parseNumber
@@ -0,0 +1,5 @@
1
+ import api from './api.js'
2
+
3
+ export default {
4
+ api
5
+ }
@@ -0,0 +1,41 @@
1
+ export const getNth = (doc, n) => (typeof n === 'number' ? doc.eq(n) : doc)
2
+
3
+ // get root form of adjective
4
+ const getRoot = function (m) {
5
+ let r = m.not('(#Adverb|#Auxiliary|#Modal)')
6
+ r = r.eq(0).compute('root')
7
+ return r.text('root')
8
+ }
9
+
10
+ const api = function (View) {
11
+ class Verbs extends View {
12
+ constructor(document, pointer, groups) {
13
+ super(document, pointer, groups)
14
+ this.viewType = 'Verbs'
15
+ }
16
+ conjugate(n) {
17
+ const methods = this.methods.two.transform.verb
18
+ const { toPresent, toPast, toSubjunctive1, toSubjunctive2, toImperative, toPastParticiple, toPresentParticiple } = methods
19
+ return getNth(this, n).map(m => {
20
+ let str = getRoot(m, methods)
21
+ return {
22
+ infinitive: str,
23
+ presentTense: toPresent(str),
24
+ pastTense: toPast(str),
25
+ subjunctive1: toSubjunctive1(str),
26
+ subjunctive2: toSubjunctive2(str),
27
+ imperative: toImperative(str),
28
+ pastParticiple: toPastParticiple(str),
29
+ presentParticiple: toPresentParticiple(str)
30
+ }
31
+ }, [])
32
+ }
33
+ }
34
+
35
+ View.prototype.verbs = function (n) {
36
+ let m = this.match('#Verb+')
37
+ m = getNth(m, n)
38
+ return new Verbs(this.document, m.pointer)
39
+ }
40
+ }
41
+ export default api
@@ -0,0 +1,5 @@
1
+ import api from './api.js'
2
+
3
+ export default {
4
+ api,
5
+ }
package/src/_lib.js ADDED
@@ -0,0 +1,4 @@
1
+ // console.log('local-path')
2
+ // import nlp from '/Users/spencer/mountain/compromise/src/one.js'
3
+ import nlp from 'compromise/one'
4
+ export default nlp
@@ -0,0 +1 @@
1
+ export default '0.1.0'