@ingglish/phonemes 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,698 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ARPABET_CONSONANTS: () => ARPABET_CONSONANTS,
24
+ ARPABET_TO_INGGLISH_MAP: () => ARPABET_TO_INGGLISH_MAP,
25
+ ARPABET_VOWELS: () => ARPABET_VOWELS,
26
+ R_COLORED_FORWARD: () => R_COLORED_FORWARD,
27
+ STRESS_MARKER_REGEX: () => STRESS_MARKER_REGEX,
28
+ arpabetPhonemeToIngglish: () => arpabetPhonemeToIngglish,
29
+ arpabetToFormat: () => arpabetToFormat,
30
+ arpabetToIngglish: () => arpabetToIngglish,
31
+ createCustomConverter: () => createCustomConverter,
32
+ expandArpabetAlternatives: () => expandArpabetAlternatives,
33
+ findOnsetStart: () => findOnsetStart,
34
+ getFormatHandler: () => getFormatHandler,
35
+ getFormatIsLatinScript: () => getFormatIsLatinScript,
36
+ getFormatJoinSeparator: () => getFormatJoinSeparator,
37
+ getFormatLabel: () => getFormatLabel,
38
+ getFormatNativeLabel: () => getFormatNativeLabel,
39
+ getFormatPreservesCase: () => getFormatPreservesCase,
40
+ getStress: () => getStress,
41
+ ingglishToArpabet: () => ingglishToArpabet,
42
+ isVowel: () => isVowel,
43
+ registerFormat: () => registerFormat,
44
+ registerPronunciation: () => registerPronunciation,
45
+ stripStress: () => stripStress
46
+ });
47
+ module.exports = __toCommonJS(index_exports);
48
+
49
+ // src/arpabet.ts
50
+ var ARPABET_VOWELS = [
51
+ "AA",
52
+ // father, hot
53
+ "AE",
54
+ // cat, bat
55
+ "AH",
56
+ // but, cup (stressed) / schwa (unstressed)
57
+ "AO",
58
+ // thought, law
59
+ "AW",
60
+ // cow, how
61
+ "AY",
62
+ // my, time
63
+ "EH",
64
+ // bed, red
65
+ "ER",
66
+ // bird, her
67
+ "EY",
68
+ // say, day
69
+ "IH",
70
+ // bit, sit
71
+ "IY",
72
+ // bee, see
73
+ "OW",
74
+ // go, show
75
+ "OY",
76
+ // boy, toy
77
+ "UH",
78
+ // book, put
79
+ "UW"
80
+ // too, blue
81
+ ];
82
+ var ARPABET_CONSONANTS = [
83
+ // Stops
84
+ "B",
85
+ "D",
86
+ "G",
87
+ "K",
88
+ "P",
89
+ "T",
90
+ // Fricatives
91
+ "DH",
92
+ // the, this
93
+ "F",
94
+ "HH",
95
+ // hat
96
+ "S",
97
+ "SH",
98
+ // ship
99
+ "TH",
100
+ // think
101
+ "V",
102
+ "Z",
103
+ "ZH",
104
+ // measure
105
+ // Affricates
106
+ "CH",
107
+ // chat
108
+ "JH",
109
+ // just
110
+ // Nasals
111
+ "M",
112
+ "N",
113
+ "NG",
114
+ // sing
115
+ // Liquids
116
+ "L",
117
+ "R",
118
+ // Glides
119
+ "W",
120
+ "Y"
121
+ ];
122
+ var VOWELS_SET = new Set(ARPABET_VOWELS);
123
+ var CONSONANTS_SET = new Set(ARPABET_CONSONANTS);
124
+ var STRESS_MARKER_REGEX = /[012]$/;
125
+ function getStress(phoneme) {
126
+ const lastChar = phoneme.codePointAt(phoneme.length - 1);
127
+ if (lastChar >= 48 && lastChar <= 50) {
128
+ return lastChar - 48;
129
+ }
130
+ return null;
131
+ }
132
+ function isVowel(phoneme) {
133
+ const base = stripStress(phoneme);
134
+ return VOWELS_SET.has(base);
135
+ }
136
+ function stripStress(phoneme) {
137
+ const lastChar = phoneme.codePointAt(phoneme.length - 1);
138
+ if (lastChar >= 48 && lastChar <= 50) {
139
+ return phoneme.slice(0, -1);
140
+ }
141
+ return phoneme;
142
+ }
143
+
144
+ // src/phonotactics.ts
145
+ var VALID_ONSETS = /* @__PURE__ */ new Set([
146
+ // Single consonants (all are valid onsets except NG)
147
+ "B",
148
+ // Two-consonant clusters: consonant + liquid (L, R)
149
+ "B L",
150
+ "B R",
151
+ // Two-consonant clusters: consonant + glide (W, Y)
152
+ "B Y",
153
+ "CH",
154
+ "D",
155
+ "DH",
156
+ "D R",
157
+ "D W",
158
+ "D Y",
159
+ "F",
160
+ "F L",
161
+ "F R",
162
+ "F Y",
163
+ "G",
164
+ "G L",
165
+ "G R",
166
+ "G W",
167
+ "G Y",
168
+ "HH",
169
+ "HH W",
170
+ "HH Y",
171
+ "JH",
172
+ "K",
173
+ "K L",
174
+ "K R",
175
+ "K W",
176
+ "K Y",
177
+ "L",
178
+ "L Y",
179
+ "M",
180
+ "M Y",
181
+ "N",
182
+ "N Y",
183
+ "P",
184
+ "P L",
185
+ "P R",
186
+ "P Y",
187
+ "R",
188
+ "S",
189
+ "SH",
190
+ "SH R",
191
+ // Two-consonant clusters: s + consonant
192
+ "S K",
193
+ // Three-consonant clusters: s + stop + liquid/glide
194
+ "S K R",
195
+ "S K W",
196
+ "S K Y",
197
+ "S L",
198
+ "S M",
199
+ "S N",
200
+ "S P",
201
+ "S P L",
202
+ "S P R",
203
+ "S P Y",
204
+ "S T",
205
+ "S T R",
206
+ "S T Y",
207
+ "S W",
208
+ "S Y",
209
+ "T",
210
+ "TH",
211
+ "TH R",
212
+ "TH W",
213
+ "T R",
214
+ "T W",
215
+ "T Y",
216
+ "V",
217
+ "V Y",
218
+ "W",
219
+ "Y",
220
+ "Z",
221
+ "ZH"
222
+ ]);
223
+ function findOnsetStart(consonants) {
224
+ if (consonants.length === 0) {
225
+ return 0;
226
+ }
227
+ for (let start = 0; start < consonants.length; start++) {
228
+ const candidate = consonants.slice(start);
229
+ if (isValidOnset(candidate)) {
230
+ return start;
231
+ }
232
+ }
233
+ return consonants.length - 1;
234
+ }
235
+ function isValidOnset(consonants) {
236
+ if (consonants.length === 0) {
237
+ return true;
238
+ }
239
+ const key = consonants.join(" ");
240
+ return VALID_ONSETS.has(key);
241
+ }
242
+
243
+ // src/format-registry.ts
244
+ var registry = /* @__PURE__ */ new Map();
245
+ var isLatinScriptCache = /* @__PURE__ */ new Map();
246
+ var preservesCaseCache = /* @__PURE__ */ new Map();
247
+ function getFormatHandler(name) {
248
+ return registry.get(name);
249
+ }
250
+ function getFormatIsLatinScript(name) {
251
+ return isLatinScriptCache.get(name) ?? true;
252
+ }
253
+ function getFormatJoinSeparator(name) {
254
+ return registry.get(name)?.joinSeparator ?? "";
255
+ }
256
+ function getFormatLabel(name) {
257
+ return registry.get(name)?.label ?? name;
258
+ }
259
+ function getFormatNativeLabel(name) {
260
+ const handler = registry.get(name);
261
+ return handler?.nativeLabel ?? handler?.label ?? name;
262
+ }
263
+ function getFormatPreservesCase(name) {
264
+ return preservesCaseCache.get(name) ?? true;
265
+ }
266
+ function registerFormat(name, handler) {
267
+ const existing = registry.get(name);
268
+ const merged = { ...existing, ...handler };
269
+ registry.set(name, merged);
270
+ isLatinScriptCache.set(name, merged.isLatinScript ?? true);
271
+ preservesCaseCache.set(name, merged.preservesCase ?? merged.isLatinScript ?? true);
272
+ }
273
+
274
+ // src/ingglish-maps.ts
275
+ var INGGLISH_VOWEL_MAP = {
276
+ // Monophthongs
277
+ AA: "o",
278
+ // father, hot, rock (but AA+R → 'ar' in star, car)
279
+ AE: "a",
280
+ // cat, bat, had (but AE+R → 'arr' in arrow, barrow)
281
+ AH: "uh",
282
+ // but, cup, son (stressed /ʌ/; unstressed /ə/ AH0 → 'a' in conversion)
283
+ AO: "aw",
284
+ // thought, caught, law (but AO+R → 'or' in store, more)
285
+ // Diphthongs
286
+ AW: "ou",
287
+ // cow, how, out
288
+ AY: "ai",
289
+ // my, eye, time
290
+ EH: "e",
291
+ // bed, red, said (but EH+R → 'air' in air, care, there)
292
+ ER: "er",
293
+ // bird, her, nurse
294
+ EY: "ay",
295
+ // say, day, make
296
+ IH: "i",
297
+ // bit, sit, gym
298
+ IY: "ee",
299
+ // bee, see, machine
300
+ OW: "oh",
301
+ // go, show, coat
302
+ OY: "oi",
303
+ // boy, toy, coin
304
+ UH: "u",
305
+ // book, put, could
306
+ UW: "oo"
307
+ // too, blue, food
308
+ };
309
+ var INGGLISH_CONSONANT_MAP = {
310
+ // Stops (plosives)
311
+ B: "b",
312
+ // bat, cab
313
+ // Affricates
314
+ CH: "ch",
315
+ // chat, batch
316
+ D: "d",
317
+ // dog, bed
318
+ // Fricatives
319
+ DH: "dh",
320
+ // the, this (voiced) - distinguishes from TH
321
+ F: "f",
322
+ // fat, laugh
323
+ G: "g",
324
+ // go, big
325
+ // Aspirate
326
+ HH: "h",
327
+ // hat, ahead
328
+ JH: "j",
329
+ // just, edge
330
+ K: "k",
331
+ // cat, back
332
+ // Liquids
333
+ L: "l",
334
+ // let, well
335
+ // Nasals
336
+ M: "m",
337
+ // man, come
338
+ N: "n",
339
+ // no, pen
340
+ NG: "ng",
341
+ // sing, thing
342
+ P: "p",
343
+ // pat, cup
344
+ R: "r",
345
+ // run, car
346
+ S: "s",
347
+ // sat, miss
348
+ SH: "sh",
349
+ // she, push
350
+ T: "t",
351
+ // top, cat
352
+ TH: "th",
353
+ // think, bath (voiceless)
354
+ V: "v",
355
+ // van, love
356
+ // Semivowels (glides)
357
+ W: "w",
358
+ // wet, away
359
+ Y: "y",
360
+ // yes, you
361
+ Z: "z",
362
+ // zoo, is
363
+ ZH: "zh"
364
+ // measure, beige
365
+ };
366
+ var ARPABET_TO_INGGLISH_MAP = {
367
+ ...INGGLISH_VOWEL_MAP,
368
+ ...INGGLISH_CONSONANT_MAP
369
+ };
370
+ var INGGLISH_TO_ARPABET_MAP = Object.fromEntries(
371
+ Object.entries(ARPABET_TO_INGGLISH_MAP).map(([arpabet, ingglish]) => [ingglish, arpabet])
372
+ );
373
+ var R_COLORED_VOWELS = [
374
+ { arpabet: "AA", prefix: "a" },
375
+ // star, car, far → 'ar'
376
+ { arpabet: "AO", prefix: "o" },
377
+ // store, more, for → 'or'
378
+ { arpabet: "EH", prefix: "ai" },
379
+ // air, care, there → 'air'
380
+ { arpabet: "AE", prefix: "ar" },
381
+ // arrow, barrow, carrot → 'arr'
382
+ { arpabet: "IH", prefix: "ee" },
383
+ // beer, beard, fear → 'eer'
384
+ { arpabet: "UH", prefix: "u" },
385
+ // tour, cure, pure → 'ur' (CURE vowel, experimentable)
386
+ { arpabet: "AH", prefix: "uh" }
387
+ // curry, burroughs → 'uhr' (AH=uh, prevents AH0+R collision with 'ar')
388
+ ];
389
+ var R_COLORED_FORWARD = new Map(
390
+ R_COLORED_VOWELS.map(({ arpabet, prefix }) => [arpabet, prefix])
391
+ );
392
+ var R_COLORED_REVERSE_3CHAR = Object.fromEntries(
393
+ R_COLORED_VOWELS.filter(({ prefix }) => prefix.length === 2).map(({ arpabet, prefix }) => [
394
+ prefix + "r",
395
+ [arpabet, "R"]
396
+ ])
397
+ );
398
+ var R_COLORED_REVERSE_2CHAR = Object.fromEntries(
399
+ R_COLORED_VOWELS.filter(({ prefix }) => prefix.length === 1).map(({ arpabet, prefix }) => [
400
+ prefix + "r",
401
+ [arpabet, "R"]
402
+ ])
403
+ );
404
+
405
+ // src/to-ingglish.ts
406
+ function arpabetPhonemeToIngglish(phoneme) {
407
+ if (phoneme === "AH0") {
408
+ return "a";
409
+ }
410
+ const base = stripStress(phoneme);
411
+ return ARPABET_TO_INGGLISH_MAP[base] ?? phoneme.toLowerCase();
412
+ }
413
+ function convertArpabet(arpabet, phonemeMap, rColoredMap, stressOverrides) {
414
+ let result = "";
415
+ const len = arpabet.length;
416
+ for (let i = 0; i < len; i++) {
417
+ const phoneme = arpabet[i];
418
+ const base = stripStress(phoneme);
419
+ if (i + 1 < len && arpabet[i + 1] === "R") {
420
+ const rPrefix = rColoredMap.get(base);
421
+ if (rPrefix !== void 0) {
422
+ result += rPrefix;
423
+ continue;
424
+ }
425
+ }
426
+ const stressOverride = stressOverrides.get(phoneme);
427
+ if (stressOverride !== void 0) {
428
+ result += stressOverride;
429
+ continue;
430
+ }
431
+ result += phonemeMap[base] ?? phoneme.toLowerCase();
432
+ }
433
+ return result;
434
+ }
435
+ var INGGLISH_FULL_MAP = {};
436
+ for (const [base, spelling] of Object.entries(ARPABET_TO_INGGLISH_MAP)) {
437
+ INGGLISH_FULL_MAP[base] = spelling;
438
+ INGGLISH_FULL_MAP[base + "0"] = spelling;
439
+ INGGLISH_FULL_MAP[base + "1"] = spelling;
440
+ INGGLISH_FULL_MAP[base + "2"] = spelling;
441
+ }
442
+ INGGLISH_FULL_MAP.AH0 = "a";
443
+ function arpabetToIngglish(arpabet) {
444
+ let result = "";
445
+ const len = arpabet.length;
446
+ for (let i = 0; i < len; i++) {
447
+ const phoneme = arpabet[i];
448
+ if (i + 1 < len && arpabet[i + 1] === "R") {
449
+ const base = stripStress(phoneme);
450
+ const rPrefix = R_COLORED_FORWARD.get(base);
451
+ if (rPrefix !== void 0) {
452
+ result += rPrefix;
453
+ continue;
454
+ }
455
+ }
456
+ result += INGGLISH_FULL_MAP[phoneme] ?? phoneme.toLowerCase();
457
+ }
458
+ return result;
459
+ }
460
+ registerFormat("ingglish", {
461
+ forward: arpabetToIngglish,
462
+ isLatinScript: true,
463
+ label: "Ingglish",
464
+ preservesCase: true
465
+ });
466
+ var EMPTY_R_COLORED = /* @__PURE__ */ new Map();
467
+ var INGGLISH_STRESS_OVERRIDES = /* @__PURE__ */ new Map([["AH0", "a"]]);
468
+ function arpabetToFormat(arpabet, format = "ingglish", options) {
469
+ if (format === "ingglish") {
470
+ if (options?.disableRColoring === true) {
471
+ return convertArpabet(
472
+ arpabet,
473
+ ARPABET_TO_INGGLISH_MAP,
474
+ EMPTY_R_COLORED,
475
+ INGGLISH_STRESS_OVERRIDES
476
+ );
477
+ }
478
+ return arpabetToIngglish(arpabet);
479
+ }
480
+ const handler = getFormatHandler(format);
481
+ if (handler?.forward) {
482
+ return handler.forward(arpabet, options);
483
+ }
484
+ return arpabetToIngglish(arpabet);
485
+ }
486
+
487
+ // src/to-pronunciation.ts
488
+ var GUIDE_MAP = {};
489
+ for (const [base, spelling] of Object.entries(ARPABET_TO_INGGLISH_MAP)) {
490
+ GUIDE_MAP[base] = spelling;
491
+ GUIDE_MAP[base + "0"] = spelling;
492
+ GUIDE_MAP[base + "1"] = spelling;
493
+ GUIDE_MAP[base + "2"] = spelling;
494
+ }
495
+ GUIDE_MAP.AH0 = "a";
496
+ function arpabetToPronunciation(arpabet) {
497
+ const syllables = syllabify(arpabet);
498
+ return syllables.map(({ phonemes, stress }) => {
499
+ const spelling = syllableToSpelling(phonemes);
500
+ return stress >= 1 ? spelling.toUpperCase() : spelling;
501
+ }).join("-");
502
+ }
503
+ function registerPronunciation() {
504
+ registerFormat("pronunciation", {
505
+ forward: arpabetToPronunciation,
506
+ isLatinScript: true,
507
+ label: "Guide",
508
+ preservesCase: false
509
+ });
510
+ }
511
+ function syllabify(arpabet) {
512
+ const vowelIndices = [];
513
+ for (const [i, phoneme] of arpabet.entries()) {
514
+ if (isVowel(phoneme)) {
515
+ vowelIndices.push(i);
516
+ }
517
+ }
518
+ if (vowelIndices.length === 0) {
519
+ return [{ phonemes: arpabet, stress: 0 }];
520
+ }
521
+ const syllables = [];
522
+ let start = 0;
523
+ for (let vi = 0; vi < vowelIndices.length; vi++) {
524
+ const vowelIdx = vowelIndices[vi];
525
+ const stress = getStress(arpabet[vowelIdx]) ?? 0;
526
+ if (vi < vowelIndices.length - 1) {
527
+ const nextVowelIdx = vowelIndices[vi + 1];
528
+ const consonantStart = vowelIdx + 1;
529
+ const consonants = [];
530
+ for (let j = consonantStart; j < nextVowelIdx; j++) {
531
+ consonants.push(stripStress(arpabet[j]));
532
+ }
533
+ if (consonants.length === 0) {
534
+ syllables.push({ phonemes: arpabet.slice(start, consonantStart), stress });
535
+ start = consonantStart;
536
+ } else {
537
+ const onsetIdx = findOnsetStart(consonants);
538
+ const boundary = consonantStart + onsetIdx;
539
+ syllables.push({ phonemes: arpabet.slice(start, boundary), stress });
540
+ start = boundary;
541
+ }
542
+ } else {
543
+ syllables.push({ phonemes: arpabet.slice(start), stress });
544
+ }
545
+ }
546
+ return syllables;
547
+ }
548
+ function syllableToSpelling(phonemes) {
549
+ let result = "";
550
+ for (let i = 0; i < phonemes.length; i++) {
551
+ const phoneme = phonemes[i];
552
+ if (i + 1 < phonemes.length && phonemes[i + 1] === "R") {
553
+ const base = stripStress(phoneme);
554
+ const rPrefix = R_COLORED_FORWARD.get(base);
555
+ if (rPrefix !== void 0) {
556
+ result += rPrefix;
557
+ continue;
558
+ }
559
+ }
560
+ result += GUIDE_MAP[phoneme] ?? phoneme.toLowerCase();
561
+ }
562
+ return result;
563
+ }
564
+
565
+ // src/from-ingglish.ts
566
+ var ARPABET_ALTERNATIVES = {
567
+ AE: [["AH"]],
568
+ // "a" could be AE (cat) or AH (schwa: about, the)
569
+ ER: [["EH", "R"]],
570
+ SH: [["S", "HH"]]
571
+ // "sh" could be SH (ship) or S+HH (exhume)
572
+ };
573
+ var ARPABET_ALTERNATIVES_ENTRIES = Object.entries(ARPABET_ALTERNATIVES);
574
+ function expandArpabetAlternatives(arpabet) {
575
+ const results = [arpabet];
576
+ for (let i = 0; i < arpabet.length; i++) {
577
+ const alternatives = ARPABET_ALTERNATIVES[arpabet[i]];
578
+ if (alternatives !== void 0) {
579
+ for (const alt of alternatives) {
580
+ const expanded = [...arpabet.slice(0, i), ...alt, ...arpabet.slice(i + 1)];
581
+ results.push(expanded);
582
+ }
583
+ }
584
+ }
585
+ for (const [phoneme, alts] of ARPABET_ALTERNATIVES_ENTRIES) {
586
+ for (const alt of alts) {
587
+ if (alt.length === 1) {
588
+ let count = 0;
589
+ for (const p of arpabet) {
590
+ if (p === phoneme) {
591
+ count++;
592
+ }
593
+ }
594
+ if (count >= 2) {
595
+ results.push(arpabet.map((p) => p === phoneme ? alt[0] : p));
596
+ }
597
+ }
598
+ }
599
+ }
600
+ return results;
601
+ }
602
+ var TWO_CHAR_SPELLINGS = new Set(
603
+ Object.keys(INGGLISH_TO_ARPABET_MAP).filter((s) => s.length === 2)
604
+ );
605
+ var ONE_CHAR_SPELLINGS = new Set(
606
+ Object.keys(INGGLISH_TO_ARPABET_MAP).filter((s) => s.length === 1)
607
+ );
608
+ function ingglishToArpabet(ingglish) {
609
+ const result = [];
610
+ const str = ingglish.toLowerCase();
611
+ const len = str.length;
612
+ let pos = 0;
613
+ while (pos < len) {
614
+ if (pos + 3 <= len) {
615
+ const threeChar = str.slice(pos, pos + 3);
616
+ if (threeChar in R_COLORED_REVERSE_3CHAR) {
617
+ result.push(...R_COLORED_REVERSE_3CHAR[threeChar]);
618
+ pos += 3;
619
+ continue;
620
+ }
621
+ }
622
+ if (pos + 2 <= len) {
623
+ const twoChar = str.slice(pos, pos + 2);
624
+ if (twoChar in R_COLORED_REVERSE_2CHAR) {
625
+ result.push(...R_COLORED_REVERSE_2CHAR[twoChar]);
626
+ pos += 2;
627
+ continue;
628
+ }
629
+ if (TWO_CHAR_SPELLINGS.has(twoChar)) {
630
+ result.push(INGGLISH_TO_ARPABET_MAP[twoChar]);
631
+ pos += 2;
632
+ continue;
633
+ }
634
+ }
635
+ const oneChar = str[pos];
636
+ if (ONE_CHAR_SPELLINGS.has(oneChar)) {
637
+ result.push(INGGLISH_TO_ARPABET_MAP[oneChar]);
638
+ pos += 1;
639
+ continue;
640
+ }
641
+ pos += 1;
642
+ }
643
+ return result.length > 0 ? result : null;
644
+ }
645
+
646
+ // src/custom-format.ts
647
+ function createCustomConverter(config) {
648
+ const mergedMap = { ...ARPABET_TO_INGGLISH_MAP, ...config.phonemeMap };
649
+ const mergedRColored = new Map(R_COLORED_FORWARD);
650
+ for (const [vowel] of R_COLORED_FORWARD) {
651
+ if (vowel in config.phonemeMap && !(vowel in config.rColoredPrefixes)) {
652
+ mergedRColored.set(vowel, config.phonemeMap[vowel]);
653
+ }
654
+ }
655
+ for (const [key, value] of Object.entries(config.rColoredPrefixes)) {
656
+ mergedRColored.set(key, value);
657
+ }
658
+ const stressOverrides = /* @__PURE__ */ new Map([["AH0", "a"]]);
659
+ for (const [key, value] of Object.entries(config.phonemeMap)) {
660
+ const lastChar = key.codePointAt(key.length - 1);
661
+ if (lastChar >= 48 && lastChar <= 50) {
662
+ stressOverrides.set(key, value);
663
+ }
664
+ }
665
+ const emptyRColored = /* @__PURE__ */ new Map();
666
+ return (arpabet, options) => convertArpabet(
667
+ arpabet,
668
+ mergedMap,
669
+ options?.disableRColoring === true ? emptyRColored : mergedRColored,
670
+ stressOverrides
671
+ );
672
+ }
673
+ // Annotate the CommonJS export names for ESM import in node:
674
+ 0 && (module.exports = {
675
+ ARPABET_CONSONANTS,
676
+ ARPABET_TO_INGGLISH_MAP,
677
+ ARPABET_VOWELS,
678
+ R_COLORED_FORWARD,
679
+ STRESS_MARKER_REGEX,
680
+ arpabetPhonemeToIngglish,
681
+ arpabetToFormat,
682
+ arpabetToIngglish,
683
+ createCustomConverter,
684
+ expandArpabetAlternatives,
685
+ findOnsetStart,
686
+ getFormatHandler,
687
+ getFormatIsLatinScript,
688
+ getFormatJoinSeparator,
689
+ getFormatLabel,
690
+ getFormatNativeLabel,
691
+ getFormatPreservesCase,
692
+ getStress,
693
+ ingglishToArpabet,
694
+ isVowel,
695
+ registerFormat,
696
+ registerPronunciation,
697
+ stripStress
698
+ });