@fpw/en-wiktionary-la-modules 0.2.2 → 0.3.2

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 (63) hide show
  1. package/LICENSE +75 -75
  2. package/README.md +19 -15
  3. package/dist/LaEngine.d.ts +23 -23
  4. package/dist/LaEngine.js +64 -66
  5. package/dist/index.d.ts +12 -11
  6. package/dist/index.js +12 -28
  7. package/dist/modules/common.d.ts +67 -66
  8. package/dist/modules/common.js +145 -157
  9. package/dist/modules/conjugation/LaVerb.d.ts +118 -109
  10. package/dist/modules/conjugation/LaVerb.js +2861 -2295
  11. package/dist/modules/conjugation/VerbAffix.d.ts +18 -18
  12. package/dist/modules/conjugation/VerbAffix.js +19 -23
  13. package/dist/modules/conjugation/VerbForm.d.ts +204 -182
  14. package/dist/modules/conjugation/VerbForm.js +215 -199
  15. package/dist/modules/conjugation/VerbType.d.ts +54 -40
  16. package/dist/modules/conjugation/VerbType.js +66 -58
  17. package/dist/modules/declination/LaAdjData.d.ts +16 -16
  18. package/dist/modules/declination/LaAdjData.js +1474 -908
  19. package/dist/modules/declination/LaNominal.d.ts +136 -130
  20. package/dist/modules/declination/LaNominal.js +1884 -1804
  21. package/dist/modules/declination/LaNounData.d.ts +16 -2
  22. package/dist/modules/declination/LaNounData.js +935 -855
  23. package/dist/modules/declination/LaPersonalPronoun.d.ts +12 -12
  24. package/dist/modules/declination/LaPersonalPronoun.js +80 -85
  25. package/dist/modules/declination/NominalForm.d.ts +85 -69
  26. package/dist/modules/declination/NominalForm.js +101 -91
  27. package/dist/modules/declination/NominalType.d.ts +191 -120
  28. package/dist/modules/declination/NominalType.js +211 -146
  29. package/dist/modules/headword/HeadWord.d.ts +107 -107
  30. package/dist/modules/headword/HeadWord.js +28 -32
  31. package/dist/modules/headword/HeadwordParser.d.ts +29 -29
  32. package/dist/modules/headword/HeadwordParser.js +456 -452
  33. package/package.json +23 -15
  34. package/dist/LaEngine.js.map +0 -1
  35. package/dist/index.js.map +0 -1
  36. package/dist/modules/common.js.map +0 -1
  37. package/dist/modules/conjugation/LaVerb.js.map +0 -1
  38. package/dist/modules/conjugation/VerbAffix.js.map +0 -1
  39. package/dist/modules/conjugation/VerbForm.js.map +0 -1
  40. package/dist/modules/conjugation/VerbType.js.map +0 -1
  41. package/dist/modules/declination/LaAdjData.js.map +0 -1
  42. package/dist/modules/declination/LaNominal.js.map +0 -1
  43. package/dist/modules/declination/LaNounData.js.map +0 -1
  44. package/dist/modules/declination/LaPersonalPronoun.js.map +0 -1
  45. package/dist/modules/declination/NominalForm.js.map +0 -1
  46. package/dist/modules/declination/NominalType.js.map +0 -1
  47. package/dist/modules/headword/HeadWord.js.map +0 -1
  48. package/dist/modules/headword/HeadwordParser.js.map +0 -1
  49. package/src/LaEngine.ts +0 -86
  50. package/src/index.ts +0 -16
  51. package/src/modules/common.ts +0 -164
  52. package/src/modules/conjugation/LaVerb.ts +0 -2669
  53. package/src/modules/conjugation/VerbAffix.ts +0 -18
  54. package/src/modules/conjugation/VerbForm.ts +0 -223
  55. package/src/modules/conjugation/VerbType.ts +0 -55
  56. package/src/modules/declination/LaAdjData.ts +0 -1036
  57. package/src/modules/declination/LaNominal.ts +0 -2025
  58. package/src/modules/declination/LaNounData.ts +0 -897
  59. package/src/modules/declination/LaPersonalPronoun.ts +0 -92
  60. package/src/modules/declination/NominalForm.ts +0 -89
  61. package/src/modules/declination/NominalType.ts +0 -157
  62. package/src/modules/headword/HeadWord.ts +0 -132
  63. package/src/modules/headword/HeadwordParser.ts +0 -515
@@ -1,452 +1,456 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HeadwordParser = void 0;
4
- /**
5
- * This is based on https://en.wiktionary.org/wiki/Module:la-headword developed by Benwing2.
6
- * It was converted from Lua to TypeScript by Folke Will <folko@solhost.org>.
7
- *
8
- * Original source: https://en.wiktionary.org/wiki/Module:la-headword
9
- *
10
- * Lua idioms, function and variable names kept as in the original in order to easily
11
- * backport later changes to this implementation.
12
- *
13
- * For that reason, it's suggested to add a type-aware wrapper around this class and leave
14
- * this code unchanged instead of improving the types and use of idioms in this class.
15
- *
16
- */
17
- const common_1 = require("../common");
18
- const LaVerb_1 = require("../conjugation/LaVerb");
19
- const VerbForm_1 = require("../conjugation/VerbForm");
20
- const NominalForm_1 = require("../declination/NominalForm");
21
- const HeadWord_1 = require("./HeadWord");
22
- class HeadwordParser {
23
- constructor(nominal, conj, logger) {
24
- this.templateParsers = new Map([
25
- // these are parsed by la-ndecl
26
- ["la-noun", args => this.parseNominalHead(args, HeadWord_1.NominalType.Noun)],
27
- ["la-num-noun", args => this.parseNominalHead(args, HeadWord_1.NominalType.Numeral)],
28
- ["la-suffix-noun", args => this.parseNominalHead(args, HeadWord_1.NominalType.Suffix)],
29
- ["la-proper noun", args => this.parseNominalHead(args, HeadWord_1.NominalType.ProperNoun)],
30
- ["la-prop", args => this.parseNominalHead(args, HeadWord_1.NominalType.ProperNoun)],
31
- // these are parsed by la-adecl
32
- ["la-adj", args => this.parseAdjectivalHead(args, HeadWord_1.AdjectivalType.Adjective)],
33
- ["la-num-adj", args => this.parseAdjectivalHead(args, HeadWord_1.AdjectivalType.Numeral)],
34
- ["la-suffix-adj", args => this.parseAdjectivalHead(args, HeadWord_1.AdjectivalType.Suffix)],
35
- ["la-pronoun", args => this.parseAdjectivalHead(args, HeadWord_1.AdjectivalType.Pronoun)],
36
- ["la-det", args => this.parseAdjectivalHead(args, HeadWord_1.AdjectivalType.Determiner)],
37
- ["la-part", args => this.parseAdjectivalHead(args, HeadWord_1.AdjectivalType.Participle)],
38
- // these are parsed by la-verb
39
- ["la-verb", args => this.parseVerbalHead(args, HeadWord_1.VerbalType.Verb)],
40
- ["la-suffix-verb", args => this.parseVerbalHead(args, HeadWord_1.VerbalType.Suffix)],
41
- // these are all custom
42
- ["la-gerund", (args, lemma) => this.parseGerund(args)],
43
- ["la-adj-comp", (args, lemma) => this.parseComparativeAdj(args, lemma)],
44
- ["la-adj-sup", (args, lemma) => this.parseSuperlativeAdj(args, lemma)],
45
- ["la-adv", (args, lemma) => this.parseAdverb(args, HeadWord_1.AdverbType.Adverb)],
46
- ["la-adv-comp", (args, lemma) => this.parseAdverbCompSup(args, HeadWord_1.AdverbType.Comparative)],
47
- ["la-adv-sup", (args, lemma) => this.parseAdverbCompSup(args, HeadWord_1.AdverbType.Superlative)],
48
- ["la-suffix-adv", (args, lemma) => this.parseAdverb(args, HeadWord_1.AdverbType.Suffix)],
49
- ["la-num-adv", (args, lemma) => this.parseAdverbNumeral(args)],
50
- ["la-prep", (args, lemma) => this.parsePreposition(args, lemma)],
51
- ["la-letter", (args, lemma) => this.parseLetter(args, lemma)],
52
- ["la-interj", (args, lemma) => this.parseInterjection(args, lemma)],
53
- ["la-phrase", (args, lemma) => this.parsePhrase(args, lemma)],
54
- ["head", (args, lemma) => this.parseHead(args, lemma)],
55
- // forms only
56
- ["la-adj-form", (args, lemma) => this.parseForm(args, lemma, "adjectives")],
57
- ["la-noun-form", (args, lemma) => this.parseForm(args, lemma, "nouns")],
58
- ["la-proper noun-form", (args, lemma) => this.parseForm(args, lemma, "proper nouns")],
59
- ["la-num-form", (args, lemma) => this.parseForm(args, lemma, "numerals")],
60
- ["la-pronoun-form", (args, lemma) => this.parseForm(args, lemma, "pronouns")],
61
- ["la-part-form", (args, lemma) => this.parseForm(args, lemma, "participles")],
62
- ["la-verb-form", (args, lemma) => this.parseForm(args, lemma, "verbs")],
63
- ["la-gerund-form", (args, lemma) => this.parseForm(args, lemma, "gerunds")],
64
- ["la-suffix-form", (args, lemma) => this.parseForm(args, lemma, "suffixes")],
65
- ["la-det-form", (args, lemma) => this.parseForm(args, lemma, "determiners")],
66
- ]);
67
- this.nominal = nominal;
68
- this.conj = conj;
69
- this.logger = logger;
70
- }
71
- isHeadwordTemplate(template) {
72
- const args = (0, common_1.parse_template)(template);
73
- const templateName = args.get("0");
74
- if (!templateName) {
75
- throw Error(`Invalid template string: ${template}`);
76
- }
77
- return this.templateParsers.has(templateName);
78
- }
79
- parse(template, lemma) {
80
- const args = (0, common_1.parse_template)(template);
81
- const templateName = args.get("0") || "nil";
82
- const parseFunc = this.templateParsers.get(templateName);
83
- if (!parseFunc) {
84
- throw Error(`Not a headword template: ${template}`);
85
- }
86
- const data = parseFunc(args, lemma);
87
- if (data.heads.length == 0) {
88
- throw Error(`No heads for ${template} in ${lemma}`);
89
- }
90
- return data;
91
- }
92
- log(msg) {
93
- if (this.logger) {
94
- this.logger(msg);
95
- }
96
- }
97
- parseNominalHead(args, pos) {
98
- const overridePos = args.get("pos") || pos;
99
- const decl = this.nominal.do_generate_noun_forms(args, overridePos, true, args.get("lemma"));
100
- const isNum = (pos == "numerals");
101
- let lemmata = decl.overriding_lemma;
102
- const lemmaNum = (decl.num == "pl" ? "pl" : "sg");
103
- if (lemmata.length == 0) {
104
- lemmata = (0, NominalForm_1.getNominalForm)(decl.forms, `linked_nom_${lemmaNum}`) || [];
105
- }
106
- let genders = decl.overriding_genders || [];
107
- if (genders.length == 0) {
108
- if (decl.gender) {
109
- genders = [decl.gender.toLowerCase()];
110
- }
111
- else if (!isNum) {
112
- throw Error("Couldn't infer gender");
113
- }
114
- }
115
- return {
116
- templateType: "headword",
117
- headType: "nominal",
118
- partOfSpeech: pos,
119
- indeclinable: args.has("indecl"),
120
- data: decl,
121
- heads: lemmata,
122
- genders: genders,
123
- };
124
- }
125
- parseAdjectivalHead(args, pos) {
126
- const overridePos = args.get("pos") || pos;
127
- const decl = this.nominal.do_generate_adj_forms(args, overridePos, true);
128
- let lemmata = decl.overriding_lemma;
129
- const lemmaNum = (decl.num == "pl" ? "pl" : "sg");
130
- if (lemmata.length == 0) {
131
- lemmata = (0, NominalForm_1.getNominalForm)(decl.forms, `linked_nom_${lemmaNum}_m`) || [];
132
- }
133
- return {
134
- templateType: "headword",
135
- headType: "adjectival",
136
- partOfSpeech: pos,
137
- indeclinable: args.has("indecl"),
138
- data: decl,
139
- heads: lemmata,
140
- comparatives: decl.comp,
141
- superlatives: decl.sup,
142
- adverbs: decl.adv,
143
- };
144
- }
145
- parseVerbalHead(args, pos) {
146
- const conj = this.conj.make_data(args);
147
- let lemma_forms = conj.data.overriding_lemma;
148
- if (lemma_forms.length == 0) {
149
- lemma_forms = LaVerb_1.LaVerb.get_lemma_forms(conj.data, true);
150
- }
151
- const infinitives = (0, VerbForm_1.getVerbForm)(conj.data.forms, "pres_actv_inf") || [];
152
- return {
153
- templateType: "headword",
154
- headType: "verbal",
155
- data: conj,
156
- partOfSpeech: pos,
157
- heads: lemma_forms,
158
- infinitives: infinitives,
159
- };
160
- }
161
- parseGerund(args) {
162
- const gerund = args.get("1") || "";
163
- const match = gerund.match(/^(.*)um$/);
164
- if (!match) {
165
- throw Error(`Unrecognized gerund ending in: ${gerund}`);
166
- }
167
- const stem = match[1];
168
- const a2 = args.get("2") || "";
169
- let gerundive;
170
- if (a2 == "-") {
171
- gerundive = undefined;
172
- }
173
- else {
174
- gerundive = a2 || (stem + "us");
175
- }
176
- return {
177
- templateType: "headword",
178
- headType: "gerund",
179
- heads: [gerund],
180
- gerundive: gerundive,
181
- };
182
- }
183
- parseComparativeAdj(args, lemma) {
184
- const a1 = args.get("1");
185
- const a2 = args.get("2");
186
- const is_lemma = args.get("is_lemma");
187
- const heads = (0, common_1.read_list)(args, "head");
188
- const positive = (0, common_1.read_list)(args, "pos");
189
- if (heads.length == 0) {
190
- if (a1) {
191
- heads.push(a1);
192
- }
193
- else {
194
- heads.push(lemma);
195
- }
196
- }
197
- if (positive.length == 0) {
198
- if (a2) {
199
- positive.push(a2);
200
- }
201
- }
202
- const n = [];
203
- for (const head of heads) {
204
- if (!head.endsWith("or")) {
205
- this.log(`Strange comparative head ${head} in ${lemma}`);
206
- }
207
- const neuter = head.replace(/or$/, "us");
208
- n.push(neuter);
209
- }
210
- return {
211
- templateType: "headword",
212
- headType: "comparative",
213
- isLemma: is_lemma ? true : false,
214
- heads: heads,
215
- neuter: n,
216
- positive: positive,
217
- };
218
- }
219
- parseSuperlativeAdj(args, lemma) {
220
- const a1 = args.get("1");
221
- const a2 = args.get("2");
222
- const is_lemma = args.get("is_lemma");
223
- const heads = (0, common_1.read_list)(args, "head");
224
- const positive = (0, common_1.read_list)(args, "pos");
225
- if (heads.length == 0) {
226
- if (a1) {
227
- heads.push(a1);
228
- }
229
- else {
230
- heads.push(lemma);
231
- }
232
- }
233
- if (positive.length == 0) {
234
- if (a2) {
235
- positive.push(a2);
236
- }
237
- }
238
- const n = [];
239
- const f = [];
240
- for (const head of heads) {
241
- if (!head.endsWith("us")) {
242
- this.log(`Skpping invalid superlative head ${head} in ${lemma}`);
243
- continue;
244
- }
245
- const stem = head.replace(/us$/, "");
246
- f.push(stem + "a");
247
- n.push(stem + "um");
248
- }
249
- return {
250
- templateType: "headword",
251
- headType: "superlative",
252
- isLemma: is_lemma ? true : false,
253
- heads: heads,
254
- neuter: n,
255
- feminine: f,
256
- positive: positive,
257
- };
258
- }
259
- parseAdverb(args, pos) {
260
- const a1 = args.get("1");
261
- const a2 = args.get("2");
262
- const a3 = args.get("3");
263
- const heads = (0, common_1.read_list)(args, "head");
264
- let comp = (0, common_1.read_list)(args, "comp");
265
- let sup = (0, common_1.read_list)(args, "sup");
266
- if (a1) {
267
- heads.push(a1);
268
- }
269
- if (a2) {
270
- comp.push(a2);
271
- }
272
- if (a3) {
273
- sup.push(a3);
274
- }
275
- if (comp.length > 0 && comp[0] == "-") {
276
- sup = ["-"];
277
- }
278
- if (comp.length == 0 || sup.length == 0) {
279
- const default_comp = [];
280
- const default_sup = [];
281
- for (const head of heads) {
282
- let stem;
283
- for (let suff of ["iter", "nter", "ter", "er", "iē", "ē", "im", "ō"]) {
284
- const match = head.match(new RegExp(`(.*)${suff}$`));
285
- if (match) {
286
- stem = match[1];
287
- if (suff == "nter") {
288
- stem = stem + "nt";
289
- suff = "er";
290
- }
291
- default_comp.push(stem + "ius");
292
- default_sup.push(stem + "issimē");
293
- break;
294
- }
295
- }
296
- if (!stem) {
297
- throw Error("Unrecognized adverb type");
298
- }
299
- }
300
- if (comp.length == 0) {
301
- comp = default_comp;
302
- }
303
- if (sup.length == 0) {
304
- sup = default_sup;
305
- }
306
- }
307
- if (comp.length > 0 && comp[0] == "-") {
308
- comp = [];
309
- }
310
- if (sup.length > 0 && sup[0] == "-") {
311
- sup = [];
312
- }
313
- return {
314
- templateType: "headword",
315
- headType: "adverb",
316
- partOfSpeech: pos,
317
- heads: heads,
318
- comparatives: comp,
319
- superlatives: sup,
320
- };
321
- }
322
- parseAdverbNumeral(args) {
323
- const a1 = args.get("1") || "";
324
- const numType = args.get("type") || "";
325
- return {
326
- templateType: "headword",
327
- headType: "numeral_adverb",
328
- heads: [a1],
329
- numType: numType,
330
- };
331
- }
332
- parseAdverbCompSup(args, pos) {
333
- const head = args.get("1");
334
- let heads;
335
- if (head) {
336
- heads = [head];
337
- }
338
- return {
339
- templateType: "headword",
340
- headType: "adverb",
341
- partOfSpeech: pos,
342
- heads: heads || [],
343
- comparatives: [],
344
- superlatives: [],
345
- };
346
- }
347
- parseLetter(args, lemma) {
348
- const upper = (0, common_1.read_list)(args, "upper");
349
- const lower = (0, common_1.read_list)(args, "lower");
350
- const mixed = (0, common_1.read_list)(args, "mixed");
351
- const sc = args.get("sc") || "";
352
- if (upper.length == 0 && lower.length == 0 && mixed.length == 0) {
353
- this.log(`No parameters for letter ${lemma}`);
354
- upper.push(lemma);
355
- }
356
- return {
357
- templateType: "headword",
358
- headType: "letter",
359
- heads: upper.concat(lower).concat(mixed),
360
- upper: upper,
361
- lower: lower,
362
- mixed: mixed,
363
- scriptCode: sc,
364
- };
365
- }
366
- parsePreposition(args, lemma) {
367
- let genitive = false;
368
- let ablative = false;
369
- let accusative = false;
370
- const heads = (0, common_1.read_list)(args, "head");
371
- for (const [key, value] of args) {
372
- if (value == "genitive") {
373
- genitive = true;
374
- }
375
- else if (value == "ablative") {
376
- ablative = true;
377
- }
378
- else if (value == "accusative") {
379
- accusative = true;
380
- }
381
- else {
382
- if (key != "0") {
383
- heads.push(value);
384
- }
385
- }
386
- }
387
- if (heads.length == 0) {
388
- heads.push(lemma);
389
- }
390
- return {
391
- templateType: "headword",
392
- headType: "preposition",
393
- heads: heads,
394
- genitive: genitive,
395
- accusative: accusative,
396
- ablative: ablative,
397
- };
398
- }
399
- parseInterjection(args, lemma) {
400
- const head = args.get("head");
401
- let interj = head || args.get("1");
402
- if (!interj) {
403
- interj = lemma;
404
- }
405
- return {
406
- templateType: "headword",
407
- headType: "interjection",
408
- heads: [interj],
409
- };
410
- }
411
- parsePhrase(args, lemma) {
412
- let phrase = args.get("1");
413
- if (!phrase) {
414
- phrase = lemma;
415
- }
416
- return {
417
- templateType: "headword",
418
- headType: "phrase",
419
- heads: [phrase],
420
- };
421
- }
422
- parseHead(args, lemma) {
423
- const pos = args.get("2");
424
- const heads = (0, common_1.read_list)(args, "head");
425
- if (!pos) {
426
- throw Error(`la-head without pos: ${lemma}`);
427
- }
428
- if (heads.length == 0) {
429
- heads.push(lemma);
430
- }
431
- return {
432
- templateType: "headword",
433
- headType: "particle",
434
- partOfSpeech: pos,
435
- heads: heads,
436
- };
437
- }
438
- parseForm(args, lemma, pos) {
439
- let form = args.get("1");
440
- if (!form) {
441
- form = lemma;
442
- }
443
- return {
444
- templateType: "headword",
445
- headType: "form",
446
- partOfSpeech: pos,
447
- heads: [form],
448
- };
449
- }
450
- }
451
- exports.HeadwordParser = HeadwordParser;
452
- //# sourceMappingURL=HeadwordParser.js.map
1
+ /**
2
+ * This is based on https://en.wiktionary.org/wiki/Module:la-headword developed by Benwing2.
3
+ * It was converted from Lua to TypeScript by Folke Will <folko@solhost.org>.
4
+ *
5
+ * Original source: https://en.wiktionary.org/wiki/Module:la-headword
6
+ *
7
+ * Lua idioms, function and variable names kept as in the original in order to easily
8
+ * backport later changes to this implementation.
9
+ *
10
+ * For that reason, it's suggested to add a type-aware wrapper around this class and leave
11
+ * this code unchanged instead of improving the types and use of idioms in this class.
12
+ *
13
+ */
14
+ import { parse_template, read_list } from "../common.js";
15
+ import { LaVerb } from "../conjugation/LaVerb.js";
16
+ import { getVerbForm } from "../conjugation/VerbForm.js";
17
+ import { getNominalForm } from "../declination/NominalForm.js";
18
+ import { AdjectivalType, AdverbType, NominalPosType, VerbalType } from "./HeadWord.js";
19
+ export class HeadwordParser {
20
+ templateParsers = new Map([
21
+ // these are parsed by la-ndecl
22
+ ["la-noun", args => this.parseNominalHead(args, NominalPosType.Noun)],
23
+ ["la-num-noun", args => this.parseNominalHead(args, NominalPosType.Numeral)],
24
+ ["la-suffix-noun", args => this.parseNominalHead(args, NominalPosType.Suffix)],
25
+ ["la-proper noun", args => this.parseNominalHead(args, NominalPosType.ProperNoun)],
26
+ ["la-prop", args => this.parseNominalHead(args, NominalPosType.ProperNoun)],
27
+ // these are parsed by la-adecl
28
+ ["la-adj", args => this.parseAdjectivalHead(args, AdjectivalType.Adjective)],
29
+ ["la-num-adj", args => this.parseAdjectivalHead(args, AdjectivalType.Numeral)],
30
+ ["la-suffix-adj", args => this.parseAdjectivalHead(args, AdjectivalType.Suffix)],
31
+ ["la-pronoun", args => this.parseAdjectivalHead(args, AdjectivalType.Pronoun)],
32
+ ["la-det", args => this.parseAdjectivalHead(args, AdjectivalType.Determiner)],
33
+ ["la-part", args => this.parseAdjectivalHead(args, AdjectivalType.Participle)],
34
+ // these are parsed by la-verb
35
+ ["la-verb", args => this.parseVerbalHead(args, VerbalType.Verb)],
36
+ ["la-suffix-verb", args => this.parseVerbalHead(args, VerbalType.Suffix)],
37
+ // these are all custom
38
+ ["la-gerund", (args, lemma) => this.parseGerund(args)],
39
+ ["la-adj-comp", (args, lemma) => this.parseComparativeAdj(args, lemma)],
40
+ ["la-adj-sup", (args, lemma) => this.parseSuperlativeAdj(args, lemma)],
41
+ ["la-adv", (args, lemma) => this.parseAdverb(args, AdverbType.Adverb)],
42
+ ["la-adv-comp", (args, lemma) => this.parseAdverbCompSup(args, AdverbType.Comparative)],
43
+ ["la-adv-sup", (args, lemma) => this.parseAdverbCompSup(args, AdverbType.Superlative)],
44
+ ["la-suffix-adv", (args, lemma) => this.parseAdverb(args, AdverbType.Suffix)],
45
+ ["la-num-adv", (args, lemma) => this.parseAdverbNumeral(args)],
46
+ ["la-prep", (args, lemma) => this.parsePreposition(args, lemma)],
47
+ ["la-letter", (args, lemma) => this.parseLetter(args, lemma)],
48
+ ["la-interj", (args, lemma) => this.parseInterjection(args, lemma)],
49
+ ["la-phrase", (args, lemma) => this.parsePhrase(args, lemma)],
50
+ ["head", (args, lemma) => this.parseHead(args, lemma)],
51
+ // forms only
52
+ ["la-adj-form", (args, lemma) => this.parseForm(args, lemma, "adjectives")],
53
+ ["la-noun-form", (args, lemma) => this.parseForm(args, lemma, "nouns")],
54
+ ["la-proper noun-form", (args, lemma) => this.parseForm(args, lemma, "proper nouns")],
55
+ ["la-num-form", (args, lemma) => this.parseForm(args, lemma, "numerals")],
56
+ ["la-pronoun-form", (args, lemma) => this.parseForm(args, lemma, "pronouns")],
57
+ ["la-part-form", (args, lemma) => this.parseForm(args, lemma, "participles")],
58
+ ["la-verb-form", (args, lemma) => this.parseForm(args, lemma, "verbs")],
59
+ ["la-gerund-form", (args, lemma) => this.parseForm(args, lemma, "gerunds")],
60
+ ["la-suffix-form", (args, lemma) => this.parseForm(args, lemma, "suffixes")],
61
+ ["la-det-form", (args, lemma) => this.parseForm(args, lemma, "determiners")],
62
+ ]);
63
+ nominal;
64
+ conj;
65
+ logger;
66
+ constructor(nominal, conj, logger) {
67
+ this.nominal = nominal;
68
+ this.conj = conj;
69
+ this.logger = logger;
70
+ }
71
+ isHeadwordTemplate(template) {
72
+ const args = parse_template(template);
73
+ const templateName = args.get("0");
74
+ if (!templateName) {
75
+ throw Error(`Invalid template string: ${template}`);
76
+ }
77
+ return this.templateParsers.has(templateName);
78
+ }
79
+ parse(template, lemma) {
80
+ const args = parse_template(template);
81
+ const templateName = args.get("0") || "nil";
82
+ const parseFunc = this.templateParsers.get(templateName);
83
+ if (!parseFunc) {
84
+ throw Error(`Not a headword template: ${template}`);
85
+ }
86
+ const data = parseFunc(args, lemma);
87
+ if (data.heads.length == 0) {
88
+ throw Error(`No heads for ${template} in ${lemma}`);
89
+ }
90
+ return data;
91
+ }
92
+ log(msg) {
93
+ if (this.logger) {
94
+ this.logger(msg);
95
+ }
96
+ }
97
+ parseNominalHead(args, pos) {
98
+ const overridePos = args.get("pos") || pos;
99
+ const decl = this.nominal.do_generate_noun_forms(args, overridePos, true, args.get("lemma"));
100
+ const isNum = (pos == "numerals");
101
+ let lemmata = decl.overriding_lemma;
102
+ const lemmaNum = (decl.num == "pl" ? "pl" : "sg");
103
+ if (lemmata.length == 0) {
104
+ lemmata = getNominalForm(decl.forms, `linked_nom_${lemmaNum}`) || [];
105
+ }
106
+ let genders = decl.overriding_genders || [];
107
+ if (genders.length == 0) {
108
+ if (decl.gender) {
109
+ genders = [decl.gender.toLowerCase()];
110
+ }
111
+ else if (!isNum) {
112
+ throw Error("Couldn't infer gender");
113
+ }
114
+ }
115
+ return {
116
+ templateType: "headword",
117
+ headType: "nominal",
118
+ partOfSpeech: pos,
119
+ indeclinable: args.has("indecl"),
120
+ data: decl,
121
+ heads: lemmata,
122
+ genders: genders,
123
+ };
124
+ }
125
+ parseAdjectivalHead(args, pos) {
126
+ const overridePos = args.get("pos") || pos;
127
+ const decl = this.nominal.do_generate_adj_forms(args, overridePos, true);
128
+ let lemmata = decl.overriding_lemma;
129
+ const lemmaNum = (decl.num == "pl" ? "pl" : "sg");
130
+ if (lemmata.length == 0) {
131
+ lemmata = getNominalForm(decl.forms, `linked_nom_${lemmaNum}_m`) || [];
132
+ if (lemmata.length == 0) {
133
+ lemmata = getNominalForm(decl.forms, `linked_nom_${lemmaNum}_n`) || [];
134
+ }
135
+ if (lemmata.length == 0) {
136
+ lemmata = getNominalForm(decl.forms, `linked_nom_${lemmaNum}_f`) || [];
137
+ }
138
+ }
139
+ return {
140
+ templateType: "headword",
141
+ headType: "adjectival",
142
+ partOfSpeech: pos,
143
+ indeclinable: args.has("indecl"),
144
+ data: decl,
145
+ heads: lemmata,
146
+ comparatives: decl.comp,
147
+ superlatives: decl.sup,
148
+ adverbs: decl.adv,
149
+ };
150
+ }
151
+ parseVerbalHead(args, pos) {
152
+ const conj = this.conj.make_data(args);
153
+ let lemma_forms = conj.data.overriding_lemma;
154
+ if (lemma_forms.length == 0) {
155
+ lemma_forms = LaVerb.get_lemma_forms(conj.data, true);
156
+ }
157
+ const infinitives = getVerbForm(conj.data.forms, "pres_actv_inf") || [];
158
+ return {
159
+ templateType: "headword",
160
+ headType: "verbal",
161
+ data: conj,
162
+ partOfSpeech: pos,
163
+ heads: lemma_forms,
164
+ infinitives: infinitives,
165
+ };
166
+ }
167
+ parseGerund(args) {
168
+ const gerund = args.get("1") || "";
169
+ const match = gerund.match(/^(.*)um$/);
170
+ if (!match) {
171
+ throw Error(`Unrecognized gerund ending in: ${gerund}`);
172
+ }
173
+ const stem = match[1];
174
+ const a2 = args.get("2") || "";
175
+ let gerundive;
176
+ if (a2 == "-") {
177
+ gerundive = undefined;
178
+ }
179
+ else {
180
+ gerundive = a2 || (stem + "us");
181
+ }
182
+ return {
183
+ templateType: "headword",
184
+ headType: "gerund",
185
+ heads: [gerund],
186
+ gerundive: gerundive,
187
+ };
188
+ }
189
+ parseComparativeAdj(args, lemma) {
190
+ const a1 = args.get("1");
191
+ const a2 = args.get("2");
192
+ const is_lemma = args.get("is_lemma");
193
+ const heads = read_list(args, "head");
194
+ const positive = read_list(args, "pos");
195
+ if (heads.length == 0) {
196
+ if (a1) {
197
+ heads.push(a1);
198
+ }
199
+ else {
200
+ heads.push(lemma);
201
+ }
202
+ }
203
+ if (positive.length == 0) {
204
+ if (a2) {
205
+ positive.push(a2);
206
+ }
207
+ }
208
+ const n = [];
209
+ for (const head of heads) {
210
+ if (!head.endsWith("or")) {
211
+ this.log(`Strange comparative head ${head} in ${lemma}`);
212
+ }
213
+ const neuter = head.replace(/or$/, "us");
214
+ n.push(neuter);
215
+ }
216
+ return {
217
+ templateType: "headword",
218
+ headType: "comparative",
219
+ isLemma: is_lemma ? true : false,
220
+ heads: heads,
221
+ neuter: n,
222
+ positive: positive,
223
+ };
224
+ }
225
+ parseSuperlativeAdj(args, lemma) {
226
+ const a1 = args.get("1");
227
+ const a2 = args.get("2");
228
+ const is_lemma = args.get("is_lemma");
229
+ const heads = read_list(args, "head");
230
+ const positive = read_list(args, "pos");
231
+ if (heads.length == 0) {
232
+ if (a1) {
233
+ heads.push(a1);
234
+ }
235
+ else {
236
+ heads.push(lemma);
237
+ }
238
+ }
239
+ if (positive.length == 0) {
240
+ if (a2) {
241
+ positive.push(a2);
242
+ }
243
+ }
244
+ const n = [];
245
+ const f = [];
246
+ for (const head of heads) {
247
+ if (!head.endsWith("us")) {
248
+ this.log(`Skpping invalid superlative head ${head} in ${lemma}`);
249
+ continue;
250
+ }
251
+ const stem = head.replace(/us$/, "");
252
+ f.push(stem + "a");
253
+ n.push(stem + "um");
254
+ }
255
+ return {
256
+ templateType: "headword",
257
+ headType: "superlative",
258
+ isLemma: is_lemma ? true : false,
259
+ heads: heads,
260
+ neuter: n,
261
+ feminine: f,
262
+ positive: positive,
263
+ };
264
+ }
265
+ parseAdverb(args, pos) {
266
+ const a1 = args.get("1");
267
+ const a2 = args.get("2");
268
+ const a3 = args.get("3");
269
+ const heads = read_list(args, "head");
270
+ let comp = read_list(args, "comp");
271
+ let sup = read_list(args, "sup");
272
+ if (a1) {
273
+ heads.push(a1);
274
+ }
275
+ if (a2) {
276
+ comp.push(a2);
277
+ }
278
+ if (a3) {
279
+ sup.push(a3);
280
+ }
281
+ if (comp.length > 0 && comp[0] == "-") {
282
+ sup = ["-"];
283
+ }
284
+ if (comp.length == 0 || sup.length == 0) {
285
+ const default_comp = [];
286
+ const default_sup = [];
287
+ for (const head of heads) {
288
+ let stem;
289
+ for (let suff of ["iter", "nter", "ter", "er", "iē", "ē", "im", "ō"]) {
290
+ const match = head.match(new RegExp(`(.*)${suff}$`));
291
+ if (match) {
292
+ stem = match[1];
293
+ if (suff == "nter") {
294
+ stem = stem + "nt";
295
+ suff = "er";
296
+ }
297
+ default_comp.push(stem + "ius");
298
+ default_sup.push(stem + "issimē");
299
+ break;
300
+ }
301
+ }
302
+ if (!stem) {
303
+ throw Error("Unrecognized adverb type");
304
+ }
305
+ }
306
+ if (comp.length == 0) {
307
+ comp = default_comp;
308
+ }
309
+ if (sup.length == 0) {
310
+ sup = default_sup;
311
+ }
312
+ }
313
+ if (comp.length > 0 && comp[0] == "-") {
314
+ comp = [];
315
+ }
316
+ if (sup.length > 0 && sup[0] == "-") {
317
+ sup = [];
318
+ }
319
+ return {
320
+ templateType: "headword",
321
+ headType: "adverb",
322
+ partOfSpeech: pos,
323
+ heads: heads,
324
+ comparatives: comp,
325
+ superlatives: sup,
326
+ };
327
+ }
328
+ parseAdverbNumeral(args) {
329
+ const a1 = args.get("1") || "";
330
+ const numType = args.get("type") || "";
331
+ return {
332
+ templateType: "headword",
333
+ headType: "numeral_adverb",
334
+ heads: [a1],
335
+ numType: numType,
336
+ };
337
+ }
338
+ parseAdverbCompSup(args, pos) {
339
+ const head = args.get("1");
340
+ let heads;
341
+ if (head) {
342
+ heads = [head];
343
+ }
344
+ return {
345
+ templateType: "headword",
346
+ headType: "adverb",
347
+ partOfSpeech: pos,
348
+ heads: heads || [],
349
+ comparatives: [],
350
+ superlatives: [],
351
+ };
352
+ }
353
+ parseLetter(args, lemma) {
354
+ const upper = read_list(args, "upper");
355
+ const lower = read_list(args, "lower");
356
+ const mixed = read_list(args, "mixed");
357
+ const sc = args.get("sc") || "";
358
+ if (upper.length == 0 && lower.length == 0 && mixed.length == 0) {
359
+ this.log(`No parameters for letter ${lemma}`);
360
+ upper.push(lemma);
361
+ }
362
+ return {
363
+ templateType: "headword",
364
+ headType: "letter",
365
+ heads: upper.concat(lower).concat(mixed),
366
+ upper: upper,
367
+ lower: lower,
368
+ mixed: mixed,
369
+ scriptCode: sc,
370
+ };
371
+ }
372
+ parsePreposition(args, lemma) {
373
+ let genitive = false;
374
+ let ablative = false;
375
+ let accusative = false;
376
+ const heads = read_list(args, "head");
377
+ for (const [key, value] of args) {
378
+ if (value == "genitive") {
379
+ genitive = true;
380
+ }
381
+ else if (value == "ablative") {
382
+ ablative = true;
383
+ }
384
+ else if (value == "accusative") {
385
+ accusative = true;
386
+ }
387
+ else {
388
+ if (key != "0") {
389
+ heads.push(value);
390
+ }
391
+ }
392
+ }
393
+ if (heads.length == 0) {
394
+ heads.push(lemma);
395
+ }
396
+ return {
397
+ templateType: "headword",
398
+ headType: "preposition",
399
+ heads: heads,
400
+ genitive: genitive,
401
+ accusative: accusative,
402
+ ablative: ablative,
403
+ };
404
+ }
405
+ parseInterjection(args, lemma) {
406
+ const head = args.get("head");
407
+ let interj = head || args.get("1");
408
+ if (!interj) {
409
+ interj = lemma;
410
+ }
411
+ return {
412
+ templateType: "headword",
413
+ headType: "interjection",
414
+ heads: [interj],
415
+ };
416
+ }
417
+ parsePhrase(args, lemma) {
418
+ let phrase = args.get("1");
419
+ if (!phrase) {
420
+ phrase = lemma;
421
+ }
422
+ return {
423
+ templateType: "headword",
424
+ headType: "phrase",
425
+ heads: [phrase],
426
+ };
427
+ }
428
+ parseHead(args, lemma) {
429
+ const pos = args.get("2");
430
+ const heads = read_list(args, "head");
431
+ if (!pos) {
432
+ throw Error(`la-head without pos: ${lemma}`);
433
+ }
434
+ if (heads.length == 0) {
435
+ heads.push(lemma);
436
+ }
437
+ return {
438
+ templateType: "headword",
439
+ headType: "particle",
440
+ partOfSpeech: pos,
441
+ heads: heads,
442
+ };
443
+ }
444
+ parseForm(args, lemma, pos) {
445
+ let form = args.get("1");
446
+ if (!form) {
447
+ form = lemma;
448
+ }
449
+ return {
450
+ templateType: "headword",
451
+ headType: "form",
452
+ partOfSpeech: pos,
453
+ heads: [form],
454
+ };
455
+ }
456
+ }