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,33 @@
1
+
2
+ //sweep-through all prefixes
3
+ const prefixLoop = function (str = '', prefixes = []) {
4
+ const len = str.length
5
+ let max = 10
6
+ if (max > len - 3) {
7
+ max = len - 3
8
+ }
9
+ for (let i = max; i > 2; i -= 1) {
10
+ let prefix = str.substring(0, i)
11
+ if (prefixes[prefix.length].hasOwnProperty(prefix) === true) {
12
+ let tag = prefixes[prefix.length][prefix]
13
+ return tag
14
+ }
15
+ }
16
+ return null
17
+ }
18
+
19
+ // give 'overwork' the same tag as 'work'
20
+ const checkPrefix = function (terms, i, world) {
21
+ let setTag = world.methods.one.setTag
22
+ let term = terms[i]
23
+ if (term.tags.size === 0) {
24
+ let tag = prefixLoop(term.normal, world.model.two.prefixPatterns)
25
+ if (tag !== null) {
26
+ setTag([term], tag, world, false, '2-prefix')
27
+ term.confidence = 0.5
28
+ return true
29
+ }
30
+ }
31
+ return null
32
+ }
33
+ export default checkPrefix
@@ -0,0 +1,44 @@
1
+
2
+ //sweep-through all suffixes
3
+ const suffixLoop = function (str = '', suffixes = []) {
4
+ const len = str.length
5
+ let max = 10
6
+ if (len <= max) {
7
+ max = len - 1
8
+ }
9
+ for (let i = max; i > 1; i -= 1) {
10
+ let suffix = str.substr(len - i, len)
11
+ if (suffixes[suffix.length].hasOwnProperty(suffix) === true) {
12
+ // console.log(suffix)
13
+ let tag = suffixes[suffix.length][suffix]
14
+ return tag
15
+ }
16
+ }
17
+ return null
18
+ }
19
+
20
+ // decide tag from the ending of the word
21
+ const suffixCheck = function (terms, i, world) {
22
+ let setTag = world.methods.one.setTag
23
+ let suffixes = world.model.two.suffixPatterns
24
+ let term = terms[i]
25
+ if (term.tags.size === 0) {
26
+ let tag = suffixLoop(term.normal, suffixes)
27
+ if (tag !== null) {
28
+ setTag([term], tag, world, false, '2-suffix')
29
+ term.confidence = 0.7
30
+ return true
31
+ }
32
+ // try implicit form of word, too
33
+ if (term.implicit) {
34
+ tag = suffixLoop(term.implicit, suffixes)
35
+ if (tag !== null) {
36
+ setTag([term], tag, world, false, '2-implicit-suffix')
37
+ term.confidence = 0.7
38
+ return true
39
+ }
40
+ }
41
+ }
42
+ return null
43
+ }
44
+ export default suffixCheck
@@ -0,0 +1,42 @@
1
+ // 1st pass
2
+ import checkRegex from './1st-pass/regex.js'
3
+ import titleCase from './1st-pass/titlecase.js'
4
+ import checkYear from './1st-pass/year.js'
5
+ // 2nd pass
6
+ import acronym from './2nd-pass/acronym.js'
7
+ // import neighbours from './2nd-pass/neighbours.js'
8
+ import fallback from './2nd-pass/fallback.js'
9
+ import suffixCheck from './2nd-pass/suffix-lookup.js'
10
+ import prefixCheck from './2nd-pass/prefix-lookup.js'
11
+
12
+ // these methods don't care about word-neighbours
13
+ const firstPass = function (terms, world) {
14
+ for (let i = 0; i < terms.length; i += 1) {
15
+ // is it titlecased?
16
+ let found = titleCase(terms, i, world)
17
+ // try look-like rules
18
+ found = found || checkRegex(terms, i, world)
19
+ // turn '1993' into a year
20
+ checkYear(terms, i, world)
21
+ }
22
+ }
23
+ const secondPass = function (terms, world) {
24
+ for (let i = 0; i < terms.length; i += 1) {
25
+ let found = acronym(terms, i, world)
26
+ found = found || suffixCheck(terms, i, world)
27
+ found = found || prefixCheck(terms, i, world)
28
+ // found = found || neighbours(terms, i, world)
29
+ found = found || fallback(terms, i, world)
30
+ }
31
+ }
32
+
33
+
34
+ const tagger = function (view) {
35
+ let world = view.world
36
+ view.docs.forEach(terms => {
37
+ firstPass(terms, world)
38
+ secondPass(terms, world)
39
+ })
40
+ return view
41
+ }
42
+ export default tagger
@@ -0,0 +1,14 @@
1
+ import regexNormal from './regex/regex-normal.js'
2
+ import regexNumbers from './regex/regex-numbers.js'
3
+ import regexText from './regex/regex-text.js'
4
+ import suffixPatterns from './suffixes.js'
5
+ import prefixPatterns from './prefixes.js'
6
+
7
+
8
+ export default {
9
+ regexNormal,
10
+ regexNumbers,
11
+ regexText,
12
+ suffixPatterns,
13
+ prefixPatterns
14
+ }
@@ -0,0 +1,46 @@
1
+ const val = 'TextValue'
2
+
3
+ export default [
4
+ null,
5
+ {
6
+ // one-letter prefixes
7
+ },
8
+ {
9
+ // two-letter prefixes
10
+ },
11
+ {
12
+ // three-letter prefixes
13
+ },
14
+ {
15
+ // four-letter prefixes
16
+ "eins": val,
17
+ "zwei": val,
18
+ "drei": val,
19
+ "vier": val,
20
+ "fünf": val,
21
+ "acht": val,
22
+ "neun": val,
23
+ },
24
+ {
25
+ // five-letter prefixes
26
+ "sechs": val,
27
+ "sieben": val,
28
+ },
29
+ {
30
+ // six-letter prefixes
31
+ },
32
+ {
33
+ // seven-letter prefixes
34
+ },
35
+ {
36
+ // eight-letter prefixes
37
+ },
38
+ {
39
+ // nine-letter prefixes
40
+ einhunder: val
41
+ },
42
+ {
43
+ // ten-letter prefixes
44
+ zweihunder: val
45
+ },
46
+ ]
@@ -0,0 +1,25 @@
1
+ export default [
2
+ //web tags
3
+ [/^[\w.]+@[\w.]+\.[a-z]{2,3}$/, 'Email'],
4
+ [/^(https?:\/\/|www\.)+\w+\.[a-z]{2,3}/, 'Url', 'http..'],
5
+ [/^[a-z0-9./].+\.(com|net|gov|org|ly|edu|info|biz|dev|ru|jp|de|in|uk|br|io|ai)/, 'Url', '.com'],
6
+
7
+ // timezones
8
+ [/^[PMCE]ST$/, 'Timezone', 'EST'],
9
+
10
+ //names
11
+ [/^ma?c'.*/, 'LastName', "mc'neil"],
12
+ [/^o'[drlkn].*/, 'LastName', "o'connor"],
13
+ [/^ma?cd[aeiou]/, 'LastName', 'mcdonald'],
14
+
15
+ //slang things
16
+ [/^(lol)+[sz]$/, 'Expression', 'lol'],
17
+ [/^wo{2,}a*h?$/, 'Expression', 'wooah'],
18
+ [/^(hee?){2,}h?$/, 'Expression', 'hehe'],
19
+ [/^(un|de|re)\\-[a-z\u00C0-\u00FF]{2}/, 'Verb', 'un-vite'],
20
+
21
+ // m/h
22
+ [/^(m|k|cm|km)\/(s|h|hr)$/, 'Unit', '5 k/m'],
23
+ // μg/g
24
+ [/^(ug|ng|mg)\/(l|m3|ft3)$/, 'Unit', 'ug/L'],
25
+ ]
@@ -0,0 +1,62 @@
1
+ export default [
2
+
3
+ [/^@1?[0-9](am|pm)$/i, 'Time', '3pm'],
4
+ [/^[0-9]{2}[:.][0-9]{2}(am|pm)?$/i, 'Time', '13.30pm'],
5
+ [/^'[0-9]{2}$/, 'Year'],
6
+ // times
7
+ [/^[012]?[0-9](:[0-5][0-9])(:[0-5][0-9])$/, 'Time', '3:12:31'],
8
+ [/^[012]?[0-9](:[0-5][0-9])?(:[0-5][0-9])? ?(am|pm)$/i, 'Time', '1:12pm'],
9
+ [/^[012]?[0-9](:[0-5][0-9])(:[0-5][0-9])? ?(am|pm)?$/i, 'Time', '1:12:31pm'], //can remove?
10
+
11
+ // iso-dates
12
+ [/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}/i, 'Date', 'iso-date'],
13
+ [/^[0-9]{1,4}-[0-9]{1,2}-[0-9]{1,4}$/, 'Date', 'iso-dash'],
14
+ [/^[0-9]{1,4}\/[0-9]{1,2}\/[0-9]{1,4}$/, 'Date', 'iso-slash'],
15
+ [/^[0-9]{1,4}\.[0-9]{1,2}\.[0-9]{1,4}$/, 'Date', 'iso-dot'],
16
+ [/^[0-9]{1,4}-[a-z]{2,9}-[0-9]{1,4}$/i, 'Date', '12-dec-2019'],
17
+
18
+ // timezones
19
+ [/^utc ?[+-]?[0-9]+$/, 'Timezone', 'utc-9'],
20
+ [/^(gmt|utc)[+-][0-9]{1,2}$/i, 'Timezone', 'gmt-3'],
21
+
22
+ //phone numbers
23
+ [/^[0-9]{3}-[0-9]{4}$/, 'PhoneNumber', '421-0029'],
24
+ [/^(\+?[0-9][ -])?[0-9]{3}[ -]?[0-9]{3}-[0-9]{4}$/, 'PhoneNumber', '1-800-'],
25
+
26
+
27
+ //money
28
+ //like $5.30
29
+ [
30
+ /^[-+]?[$\xA2-\xA5\u058F\u060B\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u17DB\u20A0-\u20BD\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6][-+]?[0-9]+(,[0-9]{3})*(\.[0-9]+)?([kmb]|bn)?\+?$/,
31
+ ['Money', 'Value'],
32
+ '$5.30',
33
+ ],
34
+ //like 5.30$
35
+ [
36
+ /^[-+]?[0-9]+(,[0-9]{3})*(\.[0-9]+)?[$\xA2-\xA5\u058F\u060B\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u17DB\u20A0-\u20BD\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6]\+?$/,
37
+ ['Money', 'Value'],
38
+ '5.30£',
39
+ ],
40
+ //like
41
+ [/^[-+]?[$£]?[0-9]([0-9,.])+(usd|eur|jpy|gbp|cad|aud|chf|cny|hkd|nzd|kr|rub)$/i, ['Money', 'Value'], '$400usd'],
42
+
43
+ //numbers
44
+ // german-format - '.' groups thousands
45
+ [/^[-+]?[0-9]{1,3}(\.[0-9]{3})+(,[0-9]+)?$/, ['Cardinal', 'NumericValue'], '1.234.567'],
46
+ // 50 | -50 | 3.23 | 5,999.0 | 10+
47
+ [/^[-+]?[0-9]+(,[0-9]{3})*(\.[0-9]+)?\+?$/, ['Cardinal', 'NumericValue'], '5,999'],
48
+ [/^[-+]?[0-9]+(,[0-9]{3})*(\.[0-9]+)?(st|nd|rd|r?th)$/, ['Ordinal', 'NumericValue'], '53rd'],
49
+ // .73th
50
+ [/^\.[0-9]+\+?$/, ['Cardinal', 'NumericValue'], '.73th'],
51
+ //percent
52
+ [/^[-+]?[0-9]+(,[0-9]{3})*(\.[0-9]+)?%\+?$/, ['Percent', 'Cardinal', 'NumericValue'], '-4%'],
53
+ [/^\.[0-9]+%$/, ['Percent', 'Cardinal', 'NumericValue'], '.3%'],
54
+ //fraction
55
+ [/^[0-9]{1,4}\/[0-9]{1,4}(st|nd|rd|th)?s?$/, ['Fraction', 'NumericValue'], '2/3rds'],
56
+ //range
57
+ [/^[0-9.]{1,3}[a-z]{0,2}[-–—][0-9]{1,3}[a-z]{0,2}$/, ['Value', 'NumberRange'], '3-4'],
58
+ //time-range
59
+ [/^[0-9]{1,2}(:[0-9][0-9])?(am|pm)? ?[-–—] ?[0-9]{1,2}(:[0-9][0-9])?(am|pm)$/, ['Time', 'NumberRange'], '3-4pm'],
60
+ //with unit
61
+ [/^[0-9.]+([a-z]{1,4})$/, 'Value', '9km'],
62
+ ]
@@ -0,0 +1,17 @@
1
+ export default [
2
+ // #coolguy
3
+ [/^#[a-z0-9_\u00C0-\u00FF]{2,}$/i, 'HashTag'],
4
+
5
+ // @spencermountain
6
+ [/^@\w{2,}$/, 'AtMention'],
7
+
8
+ // period-ones acronyms - f.b.i.
9
+ [/^([A-ZÄÖÜ]\.){2}[A-ZÄÖÜ]?/i, ['Acronym', 'Noun'], 'F.B.I'], //ascii-only
10
+
11
+ // ending-apostrophes
12
+ [/.{3}[lkmnp]in['‘’‛‵′`´]$/, 'Gerund', "chillin'"],
13
+ [/.{4}s['‘’‛‵′`´]$/, 'Possessive', "flanders'"],
14
+
15
+ // german ordinals '4.'
16
+ // [/^[0-9]+\.$/, 'Ordinal'],
17
+ ]
@@ -0,0 +1,171 @@
1
+ const rb = 'Adverb'
2
+ const nn = 'Noun'
3
+ const vb = 'Verb'
4
+ const jj = 'Adjective'
5
+ const ord = 'TextOrdinal'
6
+ const card = 'TextCardinal'
7
+
8
+
9
+ export default [
10
+ null,
11
+ {
12
+ // one-letter suffixes
13
+ s: nn,
14
+ l: nn,
15
+ a: nn,
16
+ k: nn,
17
+ d: nn,
18
+ z: nn,
19
+ },
20
+ {
21
+ // two-letter suffixes
22
+ ig: jj,
23
+ ls: rb,
24
+ // er: nn,
25
+ el: nn,
26
+ et: vb,
27
+ gt: vb,
28
+ lt: vb,
29
+ // en: vb,
30
+ ns: nn,
31
+ ts: nn,
32
+ // ht: vb,
33
+ 'ßt': vb
34
+ },
35
+ {
36
+ // three-letter suffixes
37
+ che: jj,
38
+ ige: jj,
39
+ // ger: jj,
40
+ tig: jj,
41
+ end: jj,
42
+ // mal: rb,
43
+ hin: rb,
44
+ ung: nn,
45
+ ion: nn,
46
+ ter: nn,
47
+ ert: vb,
48
+ tet: vb,
49
+ ten: vb,
50
+ eln: vb,
51
+ ern: vb,
52
+ gen: vb,
53
+ fen: vb,
54
+ // ben: vb,
55
+ // ren: vb,
56
+ // fen: vb,
57
+ // men: vb,
58
+ igt: vb,
59
+ tzt: vb,
60
+ det: vb,
61
+ elt: vb,
62
+ ete: vb,
63
+ elf: card,//eleven
64
+ },
65
+ {
66
+ // four-letter suffixes
67
+ chen: jj,
68
+ lich: jj,
69
+ igen: jj,
70
+ cher: jj,
71
+ ende: jj,
72
+ isch: jj,
73
+ enen: jj,
74
+ tige: jj,
75
+ tens: rb,
76
+ mals: rb,
77
+ rung: nn,
78
+ iert: vb,
79
+ eben: vb,
80
+ ehen: vb,
81
+ mmen: vb,
82
+ llen: vb,
83
+ ngen: vb,
84
+ tzen: vb,
85
+ hren: vb,
86
+ cken: vb,
87
+ ssen: vb,
88
+ eßen: vb,
89
+ hnen: vb,
90
+ ufen: vb,
91
+ lten: vb,
92
+ hten: vb,
93
+ zehn: card,//10s
94
+ eins: card,
95
+ zwei: card,
96
+ drei: card,
97
+ vier: card,
98
+ fünf: card,
99
+ acht: card,
100
+ neun: card,
101
+ // zehn: card,
102
+ // lten: vb,
103
+ // ssen: vb
104
+ },
105
+ {
106
+ // five-letter suffixes
107
+ ische: jj,
108
+ zwölf: card,
109
+ sechs: card,
110
+ liche: jj,
111
+ // enden: jj,
112
+ tlich: jj,
113
+ // tigen: jj,
114
+ stens: rb,
115
+ falls: rb,
116
+ weise: rb,
117
+ seits: rb,
118
+ ungen: nn,
119
+ erung: nn,
120
+ ieren: vb,
121
+ },
122
+ {
123
+ // six-letter suffixes
124
+ igsten: jj,
125
+ ischen: jj,
126
+ sieben: card,
127
+ lichen: jj,
128
+ tische: jj,
129
+ nische: jj,
130
+ zehnte: ord,
131
+ zigste: ord,
132
+ ßigste: ord,
133
+ },
134
+ {
135
+ // seven-letter suffixes
136
+ zigsten: ord,
137
+ tischen: jj,
138
+ tlichen: jj,
139
+ nischen: jj,
140
+ zwanzig: card,//20
141
+ dreißig: card,//30
142
+ vierzig: card,//40
143
+ fünfzig: card,//50
144
+ sechzig: card, //60
145
+ siebzig: card, //70
146
+ achtzig: card, //80
147
+ neunzig: card, //90
148
+ hundert: card,//100
149
+ tausend: card,//1,000
150
+ },
151
+ // eight-letter suffixes
152
+ {
153
+ dreizehn: card,
154
+ vierzehn: card,
155
+ fünfzehn: card,
156
+ sechzehn: card,
157
+ siebzehn: card,
158
+ achtzehn: card,
159
+ neunzehn: card,
160
+
161
+ },
162
+ // nine-letter suffixes
163
+ {
164
+ },
165
+ // ten-letter suffixes
166
+ {
167
+ hundertste: ord,
168
+ tausendste: ord,
169
+ millionste: ord
170
+ },
171
+ ]
@@ -0,0 +1,12 @@
1
+ import tagger from './compute/index.js'
2
+ import model from './model/index.js'
3
+
4
+ export default {
5
+ compute: {
6
+ tagger
7
+ },
8
+ model: {
9
+ two: model
10
+ },
11
+ hooks: ['tagger']
12
+ }
@@ -0,0 +1,34 @@
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
+ m = m.eq(0).compute('root')
6
+ return m.text('root')
7
+ }
8
+
9
+ const api = function (View) {
10
+ class Adjectives extends View {
11
+ constructor(document, pointer, groups) {
12
+ super(document, pointer, groups)
13
+ this.viewType = 'Adjectives'
14
+ }
15
+ conjugate(n) {
16
+ const methods = this.methods.two.transform.adjective
17
+ const { inflect, toRoot } = methods
18
+ return getNth(this, n).map(m => {
19
+ let str = getRoot(m, methods)
20
+ let root = toRoot(str) || str
21
+ let res = inflect(root)
22
+ res.infinitive = root
23
+ return res
24
+ }, [])
25
+ }
26
+ }
27
+
28
+ View.prototype.adjectives = function (n) {
29
+ let m = this.match('#Adjective')
30
+ m = getNth(m, n)
31
+ return new Adjectives(this.document, m.pointer)
32
+ }
33
+ }
34
+ export default api
@@ -0,0 +1,5 @@
1
+ import api from './api.js'
2
+
3
+ export default {
4
+ api,
5
+ }
@@ -0,0 +1,74 @@
1
+ export const getNth = (doc, n) => (typeof n === 'number' ? doc.eq(n) : doc)
2
+
3
+ // get (lower-cased) singular form of noun
4
+ const getRoot = function (m) {
5
+ m = m.eq(0).compute('root')
6
+ return m.text('root')
7
+ }
8
+
9
+ // german nouns are capitalized - keep the casing of the original word
10
+ const matchCase = function (m, str) {
11
+ if (/^[A-ZÄÖÜ]/.test(m.text().trim())) {
12
+ return str.charAt(0).toUpperCase() + str.substring(1)
13
+ }
14
+ return str
15
+ }
16
+
17
+ // 'hunde' → 'hund' → 'hunde' round-trips, so it is already a plural,
18
+ // even when the tagger could not tell - 'die Hunde' vs 'der Kunde'
19
+ const isPluralForm = function (methods, str) {
20
+ let single = methods.toSingular(str)
21
+ return single !== str && methods.toPlural(single).one === str
22
+ }
23
+
24
+ const api = function (View) {
25
+ class Nouns extends View {
26
+ constructor(document, pointer, groups) {
27
+ super(document, pointer, groups)
28
+ this.viewType = 'Nouns'
29
+ }
30
+ conjugate(n) {
31
+ const methods = this.methods.two.transform.noun
32
+ return getNth(this, n).map(m => {
33
+ let root = getRoot(m)
34
+ return {
35
+ singular: root,
36
+ plural: methods.toPlural(root).one,
37
+ }
38
+ }, [])
39
+ }
40
+
41
+ isPlural(n) {
42
+ return getNth(this, n).if('#Plural')
43
+ }
44
+ toPlural(n) {
45
+ const methods = this.methods.two.transform.noun
46
+ return getNth(this, n).not('#Plural').map(m => {
47
+ if (isPluralForm(methods, m.text('normal'))) {
48
+ return m
49
+ }
50
+ let str = getRoot(m)
51
+ let plural = methods.toPlural(str).one
52
+ return m.replaceWith(matchCase(m, plural))
53
+ })
54
+ }
55
+ toSingular(n) {
56
+ const methods = this.methods.two.transform.noun
57
+ return getNth(this, n).not('#Singular').map(m => {
58
+ let str = m.text('normal')
59
+ if (!m.has('#Plural') && !isPluralForm(methods, str)) {
60
+ return m
61
+ }
62
+ let singular = methods.toSingular(str)
63
+ return m.replaceWith(matchCase(m, singular))
64
+ })
65
+ }
66
+ }
67
+
68
+ View.prototype.nouns = function (n) {
69
+ let m = this.match('#Noun+')
70
+ m = getNth(m, n)
71
+ return new Nouns(this.document, m.pointer)
72
+ }
73
+ }
74
+ export default api
@@ -0,0 +1,5 @@
1
+ import api from './api.js'
2
+
3
+ export default {
4
+ api,
5
+ }