@kensio/pinyinjs 0.1.0-beta.0 → 1.0.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 (145) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/NOTICE +7 -0
  3. package/README.md +144 -19
  4. package/data/full.entries +13400 -13400
  5. package/data/manifest.json +4 -4
  6. package/data/standard.entries +2492 -2492
  7. package/dist/cli/arguments.d.ts +67 -0
  8. package/dist/cli/arguments.d.ts.map +1 -1
  9. package/dist/cli/arguments.js +79 -0
  10. package/dist/cli/arguments.js.map +1 -1
  11. package/dist/cli/colour.d.ts +77 -0
  12. package/dist/cli/colour.d.ts.map +1 -0
  13. package/dist/cli/colour.js +117 -0
  14. package/dist/cli/colour.js.map +1 -0
  15. package/dist/cli/commands.d.ts +49 -1
  16. package/dist/cli/commands.d.ts.map +1 -1
  17. package/dist/cli/commands.js +404 -42
  18. package/dist/cli/commands.js.map +1 -1
  19. package/dist/cli/environment.d.ts.map +1 -1
  20. package/dist/cli/environment.js +20 -0
  21. package/dist/cli/environment.js.map +1 -1
  22. package/dist/cli/help.d.ts.map +1 -1
  23. package/dist/cli/help.js +43 -16
  24. package/dist/cli/help.js.map +1 -1
  25. package/dist/cli/run.d.ts +11 -0
  26. package/dist/cli/run.d.ts.map +1 -1
  27. package/dist/cli/run.js +4 -2
  28. package/dist/cli/run.js.map +1 -1
  29. package/dist/decode/convert.d.ts +20 -0
  30. package/dist/decode/convert.d.ts.map +1 -1
  31. package/dist/decode/convert.js +170 -12
  32. package/dist/decode/convert.js.map +1 -1
  33. package/dist/decode/decode.d.ts +3 -2
  34. package/dist/decode/decode.d.ts.map +1 -1
  35. package/dist/decode/decode.js +17 -4
  36. package/dist/decode/decode.js.map +1 -1
  37. package/dist/decode/reading-rules.d.ts +56 -0
  38. package/dist/decode/reading-rules.d.ts.map +1 -0
  39. package/dist/decode/reading-rules.js +107 -0
  40. package/dist/decode/reading-rules.js.map +1 -0
  41. package/dist/decode/rules.d.ts +66 -0
  42. package/dist/decode/rules.d.ts.map +1 -0
  43. package/dist/decode/rules.js +138 -0
  44. package/dist/decode/rules.js.map +1 -0
  45. package/dist/decode/sandhi.d.ts +1 -1
  46. package/dist/decode/sandhi.d.ts.map +1 -1
  47. package/dist/decode/sandhi.js +60 -1
  48. package/dist/decode/sandhi.js.map +1 -1
  49. package/dist/decode/word.d.ts +18 -0
  50. package/dist/decode/word.d.ts.map +1 -1
  51. package/dist/dictionary/artifact.d.ts.map +1 -1
  52. package/dist/dictionary/artifact.js +28 -1
  53. package/dist/dictionary/artifact.js.map +1 -1
  54. package/dist/dictionary/dictionary.d.ts +9 -0
  55. package/dist/dictionary/dictionary.d.ts.map +1 -1
  56. package/dist/dictionary/dictionary.js +7 -0
  57. package/dist/dictionary/dictionary.js.map +1 -1
  58. package/dist/dictionary/entry.d.ts +12 -0
  59. package/dist/dictionary/entry.d.ts.map +1 -1
  60. package/dist/dictionary/entry.js.map +1 -1
  61. package/dist/dictionary/merge.d.ts +3 -1
  62. package/dist/dictionary/merge.d.ts.map +1 -1
  63. package/dist/dictionary/merge.js +19 -1
  64. package/dist/dictionary/merge.js.map +1 -1
  65. package/dist/format/transcription.d.ts +52 -0
  66. package/dist/format/transcription.d.ts.map +1 -0
  67. package/dist/format/transcription.js +88 -0
  68. package/dist/format/transcription.js.map +1 -0
  69. package/dist/index.d.ts +24 -3
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +15 -1
  72. package/dist/index.js.map +1 -1
  73. package/dist/numerals/cardinal.d.ts +39 -0
  74. package/dist/numerals/cardinal.d.ts.map +1 -0
  75. package/dist/numerals/cardinal.js +111 -0
  76. package/dist/numerals/cardinal.js.map +1 -0
  77. package/dist/numerals/characters.d.ts +31 -0
  78. package/dist/numerals/characters.d.ts.map +1 -0
  79. package/dist/numerals/characters.js +80 -0
  80. package/dist/numerals/characters.js.map +1 -0
  81. package/dist/numerals/numerals.d.ts +76 -0
  82. package/dist/numerals/numerals.d.ts.map +1 -0
  83. package/dist/numerals/numerals.js +119 -0
  84. package/dist/numerals/numerals.js.map +1 -0
  85. package/dist/numerals/text.d.ts +52 -0
  86. package/dist/numerals/text.d.ts.map +1 -0
  87. package/dist/numerals/text.js +248 -0
  88. package/dist/numerals/text.js.map +1 -0
  89. package/dist/orthography/grouping.d.ts +56 -11
  90. package/dist/orthography/grouping.d.ts.map +1 -1
  91. package/dist/orthography/grouping.js +109 -35
  92. package/dist/orthography/grouping.js.map +1 -1
  93. package/dist/orthography/idiom-list.d.ts +56 -0
  94. package/dist/orthography/idiom-list.d.ts.map +1 -0
  95. package/dist/orthography/idiom-list.js +296 -0
  96. package/dist/orthography/idiom-list.js.map +1 -0
  97. package/dist/orthography/idioms.d.ts +18 -0
  98. package/dist/orthography/idioms.d.ts.map +1 -0
  99. package/dist/orthography/idioms.js +22 -0
  100. package/dist/orthography/idioms.js.map +1 -0
  101. package/dist/orthography/reduplication.d.ts +52 -0
  102. package/dist/orthography/reduplication.d.ts.map +1 -0
  103. package/dist/orthography/reduplication.js +99 -0
  104. package/dist/orthography/reduplication.js.map +1 -0
  105. package/dist/orthography/rule.d.ts +50 -0
  106. package/dist/orthography/rule.d.ts.map +1 -0
  107. package/dist/orthography/rule.js +101 -0
  108. package/dist/orthography/rule.js.map +1 -0
  109. package/dist/sources/cedict.d.ts +23 -0
  110. package/dist/sources/cedict.d.ts.map +1 -1
  111. package/dist/sources/cedict.js +28 -0
  112. package/dist/sources/cedict.js.map +1 -1
  113. package/dist/syllable/syllable.d.ts +1 -1
  114. package/dist/syllable/syllable.d.ts.map +1 -1
  115. package/dist/syllable/syllable.js +2 -37
  116. package/dist/syllable/syllable.js.map +1 -1
  117. package/dist/tone/tone-mark.d.ts +23 -0
  118. package/dist/tone/tone-mark.d.ts.map +1 -1
  119. package/dist/tone/tone-mark.js +49 -0
  120. package/dist/tone/tone-mark.js.map +1 -1
  121. package/dist/transcription/bopomofo.d.ts +46 -0
  122. package/dist/transcription/bopomofo.d.ts.map +1 -0
  123. package/dist/transcription/bopomofo.js +371 -0
  124. package/dist/transcription/bopomofo.js.map +1 -0
  125. package/dist/transcription/gwoyeu.d.ts +32 -0
  126. package/dist/transcription/gwoyeu.d.ts.map +1 -0
  127. package/dist/transcription/gwoyeu.js +491 -0
  128. package/dist/transcription/gwoyeu.js.map +1 -0
  129. package/dist/transcription/ipa.d.ts +40 -0
  130. package/dist/transcription/ipa.d.ts.map +1 -0
  131. package/dist/transcription/ipa.js +221 -0
  132. package/dist/transcription/ipa.js.map +1 -0
  133. package/dist/transcription/spelling-index.d.ts +23 -0
  134. package/dist/transcription/spelling-index.d.ts.map +1 -0
  135. package/dist/transcription/spelling-index.js +61 -0
  136. package/dist/transcription/spelling-index.js.map +1 -0
  137. package/dist/transcription/wade-giles.d.ts +108 -0
  138. package/dist/transcription/wade-giles.d.ts.map +1 -0
  139. package/dist/transcription/wade-giles.js +656 -0
  140. package/dist/transcription/wade-giles.js.map +1 -0
  141. package/dist/transcription/yale.d.ts +43 -0
  142. package/dist/transcription/yale.d.ts.map +1 -0
  143. package/dist/transcription/yale.js +242 -0
  144. package/dist/transcription/yale.js.map +1 -0
  145. package/package.json +9 -5
@@ -0,0 +1,656 @@
1
+ /**
2
+ * Wade-Giles, in both directions.
3
+ *
4
+ * Writing it is a table, in the same way bopomofo is: an underlying initial and
5
+ * final go in and a spelling comes out, with a handful of context rules for the
6
+ * places Wade-Giles respells a final after particular initials (歌 gē is `ko`,
7
+ * 作 zuò is `tso`, 貴 guì is `kuei`).
8
+ *
9
+ * Reading it is not a table, and that asymmetry is the whole of this file.
10
+ * Three things stand in the way:
11
+ *
12
+ * - The spelling is not injective even when written correctly: `lo` is both
13
+ * luō and lo, and `o` is both ē and ō.
14
+ * - The aspiration apostrophe is routinely dropped, and it carries a phonemic
15
+ * distinction: `ch'i` is qī and `chi` is jī, so a dropped mark makes one
16
+ * spelling stand for both. Written `chu`, with the diaeresis gone too, it
17
+ * stands for four syllables.
18
+ * - The diacritics are routinely dropped as well — ê, ŭ and ü — which merges
19
+ * `hsü` into `hsu` and `tzŭ` into `tzu`.
20
+ *
21
+ * So reading returns *every* syllable a spelling could be, and does it against
22
+ * the attested inventory rather than by rule: a rule would happily read `shung`
23
+ * or `ki`, which are not syllables of Mandarin at all.
24
+ * {@link readWadeGiles} takes the spelling as written, and
25
+ * {@link readWadeGilesLoosely} allows for the marks that fell off. How much
26
+ * that costs is measured — see `docs/romanization/`.
27
+ */
28
+ import { DICTIONARY_SYLLABLES } from "../syllable/inventory.js";
29
+ import { readSyllable } from "../syllable/syllable.js";
30
+ import { normaliseSuperscript, SUPERSCRIPT_TONES } from "../tone/tone-mark.js";
31
+ import { toneFromNotation } from "../tone/tone.js";
32
+ /**
33
+ * The mark Wade-Giles writes aspiration with.
34
+ *
35
+ * ASCII, because that is what a keyboard produces and what nearly all text
36
+ * carries; the turned comma ʻ of the original and of library cataloguing is
37
+ * read back but not written. Every shape a text might use is accepted on input,
38
+ * which matters more here than in most places — this mark is the one carrying
39
+ * the p/pʻ distinction.
40
+ */
41
+ const APOSTROPHE = "'";
42
+ /**
43
+ * Every shape the aspiration mark is written with in the wild.
44
+ */
45
+ const APOSTROPHES = /['ʻʼ‘’`´ʹ]/gu;
46
+ /**
47
+ * How each initial is spelled.
48
+ *
49
+ * The unvoiced/aspirated pairing is what makes this look wrong to a reader who
50
+ * only knows pinyin: Wade-Giles writes the *unaspirated* stop with the plain
51
+ * letter, so pinyin b is `p` and pinyin p is `pʻ`. Nothing is missing from the
52
+ * table; the whole series is shifted.
53
+ */
54
+ const INITIAL_SPELLINGS = new Map([
55
+ ["b", "p"],
56
+ ["p", `p${APOSTROPHE}`],
57
+ ["m", "m"],
58
+ ["f", "f"],
59
+ ["d", "t"],
60
+ ["t", `t${APOSTROPHE}`],
61
+ ["n", "n"],
62
+ ["l", "l"],
63
+ ["g", "k"],
64
+ ["k", `k${APOSTROPHE}`],
65
+ ["h", "h"],
66
+ ["j", "ch"],
67
+ ["q", `ch${APOSTROPHE}`],
68
+ ["x", "hs"],
69
+ ["zh", "ch"],
70
+ ["ch", `ch${APOSTROPHE}`],
71
+ ["sh", "sh"],
72
+ ["r", "j"],
73
+ ["z", "ts"],
74
+ ["c", `ts${APOSTROPHE}`],
75
+ ["s", "s"],
76
+ ]);
77
+ /**
78
+ * How z, c and s are spelled before the empty rhyme.
79
+ *
80
+ * 資 zī is `tzŭ` rather than `tsŭ`, and 私 sī is `ssŭ` rather than `sŭ`: the
81
+ * three sibilants take a different shape in front of the vowel that is not
82
+ * really one.
83
+ */
84
+ const SIBILANT_SPELLINGS = new Map([
85
+ ["z", "tz"],
86
+ ["c", `tz${APOSTROPHE}`],
87
+ ["s", "ss"],
88
+ ]);
89
+ /**
90
+ * How each final is spelled after an initial.
91
+ *
92
+ * `ueng` never occurs after one — 翁 wēng is the only syllable that has it —
93
+ * and is written with the form the pattern would give it rather than being made
94
+ * a special case.
95
+ */
96
+ const FINAL_SPELLINGS = {
97
+ a: "a",
98
+ o: "o",
99
+ e: "ê",
100
+ ê: "eh",
101
+ er: "êrh",
102
+ ai: "ai",
103
+ ei: "ei",
104
+ ao: "ao",
105
+ ou: "ou",
106
+ an: "an",
107
+ en: "ên",
108
+ ang: "ang",
109
+ eng: "êng",
110
+ ong: "ung",
111
+ i: "i",
112
+ ia: "ia",
113
+ io: "io",
114
+ ie: "ieh",
115
+ iao: "iao",
116
+ iou: "iu",
117
+ ian: "ien",
118
+ in: "in",
119
+ iang: "iang",
120
+ ing: "ing",
121
+ iong: "iung",
122
+ u: "u",
123
+ ua: "ua",
124
+ uo: "uo",
125
+ uai: "uai",
126
+ uei: "ui",
127
+ uan: "uan",
128
+ uen: "un",
129
+ uang: "uang",
130
+ ueng: "uêng",
131
+ ü: "ü",
132
+ üe: "üeh",
133
+ üan: "üan",
134
+ ün: "ün",
135
+ m: "m",
136
+ n: "n",
137
+ ng: "ng",
138
+ };
139
+ /**
140
+ * How each final is spelled with no initial in front of it.
141
+ *
142
+ * The i, u and ü groups take a y or w onset as they do in pinyin, but not the
143
+ * same one in the same places: 一 yī is `i` and 有 yǒu is `yu`, which is also
144
+ * where 魚 yú's `yü` loses its diaeresis and collides. Finals that cannot stand
145
+ * alone keep their after-initial spelling.
146
+ */
147
+ const ZERO_INITIAL_SPELLINGS = {
148
+ ...FINAL_SPELLINGS,
149
+ i: "i",
150
+ ia: "ya",
151
+ io: "yo",
152
+ ie: "yeh",
153
+ iao: "yao",
154
+ iou: "yu",
155
+ ian: "yen",
156
+ in: "yin",
157
+ iang: "yang",
158
+ ing: "ying",
159
+ iong: "yung",
160
+ u: "wu",
161
+ ua: "wa",
162
+ uo: "wo",
163
+ uai: "wai",
164
+ uei: "wei",
165
+ uan: "wan",
166
+ uen: "wên",
167
+ uang: "wang",
168
+ ueng: "wêng",
169
+ ü: "yü",
170
+ üe: "yüeh",
171
+ üan: "yüan",
172
+ ün: "yün",
173
+ };
174
+ /**
175
+ * The initials after which the i final is the empty rhyme written `ih`.
176
+ */
177
+ const RETROFLEX_INITIALS = new Set(["zh", "ch", "sh", "r"]);
178
+ /**
179
+ * The initials after which it is the empty rhyme written `ŭ`.
180
+ */
181
+ const SIBILANT_INITIALS = new Set(["z", "c", "s"]);
182
+ /**
183
+ * The initials after which the e final is written `o` rather than `ê`.
184
+ */
185
+ const O_FOR_E_INITIALS = new Set(["g", "k", "h"]);
186
+ /**
187
+ * The initials after which `uo` loses its u: 作 zuò is `tso`, 若 ruò is `jo`.
188
+ *
189
+ * sh is the exception that has to be listed by its absence — 說 shuō stays
190
+ * `shuo` while 桌 zhuō is `cho` — and it is an exception in the source rather
191
+ * than an error here.
192
+ */
193
+ const O_FOR_UO_INITIALS = new Set([
194
+ "d",
195
+ "t",
196
+ "n",
197
+ "l",
198
+ "z",
199
+ "c",
200
+ "s",
201
+ "zh",
202
+ "ch",
203
+ "r",
204
+ ]);
205
+ /**
206
+ * The initials after which `uei` keeps its middle vowel: 貴 guì is `kuei`.
207
+ */
208
+ const UEI_INITIALS = new Set(["g", "k"]);
209
+ /**
210
+ * How an initial is spelled in front of a given final.
211
+ */
212
+ function initialSpelling(initial, final) {
213
+ const sibilant = final === "i" ? SIBILANT_SPELLINGS.get(initial) : undefined;
214
+ return sibilant ?? INITIAL_SPELLINGS.get(initial) ?? "";
215
+ }
216
+ /**
217
+ * How a final is spelled after a given initial.
218
+ */
219
+ function finalSpelling(initial, final) {
220
+ if (initial === "") {
221
+ return ZERO_INITIAL_SPELLINGS[final];
222
+ }
223
+ if (final === "i") {
224
+ if (RETROFLEX_INITIALS.has(initial)) {
225
+ return "ih";
226
+ }
227
+ if (SIBILANT_INITIALS.has(initial)) {
228
+ return "ŭ";
229
+ }
230
+ }
231
+ if (final === "e" && O_FOR_E_INITIALS.has(initial)) {
232
+ return "o";
233
+ }
234
+ if (final === "uo" && O_FOR_UO_INITIALS.has(initial)) {
235
+ return "o";
236
+ }
237
+ if (final === "uei" && UEI_INITIALS.has(initial)) {
238
+ return "uei";
239
+ }
240
+ return FINAL_SPELLINGS[final];
241
+ }
242
+ /**
243
+ * The 儿化 suffix, which Wade-Giles writes as the syllable 兒 rather than as a
244
+ * letter on the end of the one before it.
245
+ *
246
+ * So this is the one place a syllable is written with a hyphen in it: 花儿 huār
247
+ * is `hua-êrh`. Pinyin's `r` suffix is the later convention and the two are not
248
+ * interchangeable.
249
+ */
250
+ const ERHUA_SUFFIX = "-êrh";
251
+ /**
252
+ * Spell a syllable in Wade-Giles without its tone.
253
+ */
254
+ export function writeWadeGilesSpelling(syllable) {
255
+ const { initial, final } = syllable;
256
+ const suffix = syllable.erhua === true ? ERHUA_SUFFIX : "";
257
+ return `${initialSpelling(initial, final)}${finalSpelling(initial, final)}${suffix}`;
258
+ }
259
+ /**
260
+ * Write a syllable in Wade-Giles: 就 jiù becomes `chiu⁴`.
261
+ *
262
+ * Total over well-formed syllables, as the bopomofo writer is. An unwritten
263
+ * tone stays unwritten rather than being invented as a first tone, which is
264
+ * what lets the round trip come back exactly.
265
+ */
266
+ export function writeWadeGiles(syllable, options = {}) {
267
+ const spelling = writeWadeGilesSpelling(syllable);
268
+ const { tone } = syllable;
269
+ const { tones = "superscript" } = options;
270
+ if (tone === undefined || tones === "none") {
271
+ return spelling;
272
+ }
273
+ return tones === "numbers"
274
+ ? `${spelling}${String(tone)}`
275
+ : /* c8 ignore next -- every tone has a raised digit */
276
+ `${spelling}${SUPERSCRIPT_TONES.get(tone) ?? ""}`;
277
+ }
278
+ /**
279
+ * Write a word in Wade-Giles, hyphenating between its syllables.
280
+ *
281
+ * The hyphen is Wade's own convention and it is not decoration: `Tse-tung`
282
+ * written solid could be read as two syllables or as three, and the system has
283
+ * no 隔音符号 to fall back on. Pinyin writes the word solid and reaches for an
284
+ * apostrophe only where the boundary is genuinely ambiguous, which is the
285
+ * opposite default.
286
+ */
287
+ export function writeWadeGilesWord(syllables, options = {}) {
288
+ return syllables
289
+ .map((syllable) => writeWadeGiles(syllable, options))
290
+ .join("-");
291
+ }
292
+ /**
293
+ * Spellings that are correct Wade-Giles but are not the ones written here.
294
+ *
295
+ * Each is a place the sources give two forms for one syllable. Writing picks
296
+ * one — the form that keeps the system as close to injective as it can be — and
297
+ * reading takes either, since a text using the other is not wrong.
298
+ */
299
+ const VARIANT_SPELLINGS = [
300
+ // 一 yī: `i` is the older and commoner form, `yi` follows pinyin.
301
+ ["yi", "yi"],
302
+ // 俄 é: `o` is attested (O-kuo for 俄國) but collides with 哦 ō, so `ê` is
303
+ // written and `o` is only read.
304
+ ["o", "e"],
305
+ // 戳 chuō: regular in the series with 桌 `cho`, but `chʻuo` is also written.
306
+ [`ch${APOSTROPHE}uo`, "chuo"],
307
+ ];
308
+ /**
309
+ * How each mark is written once it has been dropped.
310
+ */
311
+ const DROPPED_MARKS = new Map([
312
+ [APOSTROPHE, ""],
313
+ ["ê", "e"],
314
+ ["ŭ", "u"],
315
+ ["ü", "u"],
316
+ ]);
317
+ /**
318
+ * Every mark that can fall off.
319
+ */
320
+ const MARKS = /['êŭü]/gu;
321
+ /**
322
+ * Strip the marks that fall off Wade-Giles in the wild.
323
+ *
324
+ * The aspiration apostrophe and the three diacritics, all at once, because in
325
+ * practice they go together: a text that writes `Tsingtao` for 青島 has dropped
326
+ * both. ü becomes u rather than being spelled out, since that is what the
327
+ * dropped form looks like.
328
+ */
329
+ function withoutMarks(spelling) {
330
+ return spelling.replaceAll(MARKS,
331
+ /* c8 ignore next -- the pattern only matches what the map holds */
332
+ (mark) => DROPPED_MARKS.get(mark) ?? "");
333
+ }
334
+ /**
335
+ * Every syllable each Wade-Giles spelling can stand for.
336
+ *
337
+ * Built from the attested inventory rather than from a reverse rule, so that
338
+ * nothing outside the syllabary can be read: `shung` is a perfectly regular
339
+ * Wade-Giles spelling of a syllable Mandarin does not have, and a rule would
340
+ * hand it back.
341
+ *
342
+ * The loose index is the same thing keyed by the spelling with its marks taken
343
+ * off, which is what makes reading sloppy Wade-Giles a lookup rather than a
344
+ * search.
345
+ */
346
+ function buildIndex() {
347
+ const exact = new Map();
348
+ const loose = new Map();
349
+ // A spelling of undefined means "whatever this module would write"; the
350
+ // variants carry theirs, since they are the forms it would not have written.
351
+ const sources = [
352
+ ...[...DICTIONARY_SYLLABLES].map((pinyin) => [undefined, pinyin]),
353
+ ...VARIANT_SPELLINGS,
354
+ ];
355
+ const spelt = [];
356
+ for (const [spelling, pinyin] of sources) {
357
+ const syllable = readSyllable(pinyin);
358
+ /* c8 ignore next 3 -- inventory.test.ts holds the parser to the inventory */
359
+ if (syllable === undefined) {
360
+ continue;
361
+ }
362
+ spelt.push({
363
+ spelling: spelling ?? writeWadeGilesSpelling(syllable),
364
+ syllable,
365
+ });
366
+ }
367
+ for (const one of spelt) {
368
+ for (const [index, key] of [
369
+ [exact, one.spelling],
370
+ [loose, withoutMarks(one.spelling)],
371
+ ]) {
372
+ const found = index.get(key);
373
+ if (found === undefined) {
374
+ index.set(key, [one]);
375
+ }
376
+ else if (found.every((other) => !isSameSyllable(other.syllable, one.syllable))) {
377
+ found.push(one);
378
+ }
379
+ }
380
+ }
381
+ return { exact, loose };
382
+ }
383
+ /**
384
+ * Whether two syllables differ only in their tone, which none of the indexed
385
+ * ones carry.
386
+ */
387
+ function isSameSyllable(one, other) {
388
+ return one.initial === other.initial && one.final === other.final;
389
+ }
390
+ const INDEX = buildIndex();
391
+ /**
392
+ * Take a trailing tone digit off, raised or on the line.
393
+ */
394
+ function splitTone(text) {
395
+ const found = /^(.*?)([0-5])$/u.exec(normaliseSuperscript(text));
396
+ const digit = found?.[2];
397
+ if (found === null || digit === undefined) {
398
+ return [text, undefined];
399
+ }
400
+ return [found[1] ?? "", toneFromNotation(Number(digit))];
401
+ }
402
+ /**
403
+ * Normalise a written syllable to the shape the exact index is keyed by.
404
+ */
405
+ function normalise(text) {
406
+ return text
407
+ .trim()
408
+ .normalize("NFC")
409
+ .toLowerCase()
410
+ .replaceAll(APOSTROPHES, () => APOSTROPHE);
411
+ }
412
+ /**
413
+ * Whether `written` is `spelling` with some of its marks dropped.
414
+ *
415
+ * Dropped, and never added: a text that wrote `chʻu` did not mean `chü`, and
416
+ * only a text that wrote `chu` could have meant either. Allowing for a mark
417
+ * that should not be there would double the candidate lists to catch a mistake
418
+ * nobody makes, since the marks are dropped by not being typed rather than by
419
+ * being typed wrongly.
420
+ *
421
+ * Per mark rather than all or nothing, because that is how they come off:
422
+ * `chʻu` has kept its apostrophe and lost a diaeresis it may or may not have
423
+ * had, so it is 出 chū or 去 qù but not 朱 zhū.
424
+ */
425
+ function isMarksDropped(spelling, written) {
426
+ let at = 0;
427
+ for (const character of spelling) {
428
+ const dropped = DROPPED_MARKS.get(character);
429
+ if (written[at] === character) {
430
+ at += 1;
431
+ }
432
+ else if (dropped !== undefined && written.startsWith(dropped, at)) {
433
+ at += dropped.length;
434
+ }
435
+ else {
436
+ return false;
437
+ }
438
+ }
439
+ return at === written.length;
440
+ }
441
+ /**
442
+ * Read a normalised spelling out of one of the two indexes.
443
+ *
444
+ * `toKey` is how the spelling is turned into that index's key, and it has to be
445
+ * applied to the 儿化 suffix as well: read loosely, `hua-êrh` arrives as
446
+ * `hua-erh`.
447
+ */
448
+ function readFrom(index, toKey, spelling, tone) {
449
+ const found = (written, isErhua) => (index.get(toKey(written)) ?? [])
450
+ .filter((one) => isMarksDropped(one.spelling, written))
451
+ .map((one) => ({
452
+ ...one.syllable,
453
+ tone,
454
+ ...(isErhua && { erhua: true }),
455
+ }));
456
+ const suffix = toKey(ERHUA_SUFFIX);
457
+ const base = spelling.endsWith(suffix)
458
+ ? spelling.slice(0, -suffix.length)
459
+ : "";
460
+ return [...found(spelling, false), ...(base === "" ? [] : found(base, true))];
461
+ }
462
+ /**
463
+ * Read a Wade-Giles syllable exactly as it is written: `chiu⁴` becomes 就 jiù.
464
+ *
465
+ * Returns every syllable the spelling stands for, which is one for all but a
466
+ * handful of them — `lo` is both 羅 luó and 咯 lo, and `o` is both 俄 é and
467
+ * 哦 ó. Empty for anything that is not Wade-Giles at all.
468
+ */
469
+ export function readWadeGiles(text) {
470
+ const [spelling, tone] = splitTone(normalise(text));
471
+ return readFrom(INDEX.exact, (key) => key, spelling, tone);
472
+ }
473
+ /**
474
+ * The same, allowing for the marks real-world Wade-Giles drops.
475
+ *
476
+ * `chi` read exactly is 機 jī; read loosely it is jī or 七 qī, because a text
477
+ * that meant `chʻi` may simply never have typed the apostrophe. The exact
478
+ * readings come first, so a caller that wants to believe what was written can
479
+ * take the head of the list and one that wants every possibility can take the
480
+ * lot.
481
+ */
482
+ export function readWadeGilesLoosely(text) {
483
+ const exact = readWadeGiles(text);
484
+ const [spelling, tone] = splitTone(normalise(text));
485
+ const loose = readFrom(INDEX.loose, withoutMarks, spelling, tone);
486
+ return [
487
+ ...exact,
488
+ ...loose.filter((syllable) => exact.every((other) => !isSameSyllable(other, syllable) || other.erhua !== syllable.erhua)),
489
+ ];
490
+ }
491
+ /**
492
+ * The longest a Wade-Giles head can be: the longest spelling, plus the 儿化
493
+ * suffix and a tone digit.
494
+ *
495
+ * Derived rather than written down, because a fixed width is a number that goes
496
+ * stale silently.
497
+ */
498
+ const LONGEST_SPELLING = Math.max(...[...INDEX.exact.keys()].map((spelling) => spelling.length)) + 1;
499
+ /**
500
+ * The syllables Wade-Giles writes with no vowel in them at all.
501
+ *
502
+ * 嗯 `ng`, 呣 `m`, 唔 `n`, 噷 `hm` and 哼 `hng` — the syllabic nasals, every one
503
+ * of them an interjection. They are syllables and read as such on their own,
504
+ * but a *piece* of a longer run is never one of them: over the 411,956
505
+ * multi-syllable words of the phrase corpus, **not one** has a syllabic nasal
506
+ * anywhere in it, first or otherwise.
507
+ *
508
+ * That matters because `ng` would otherwise let any run ending in -ng come
509
+ * apart: `shung` is a regular Wade-Giles spelling of a syllable Mandarin does
510
+ * not have, and {@link readWadeGiles} refuses it precisely so that a rule
511
+ * cannot invent it — but `shu` + `ng` would hand it back through the side door.
512
+ * Barring them from a split costs nothing that can be measured and closes it.
513
+ */
514
+ const SYLLABIC_NASALS = new Set([...INDEX.loose.keys()].filter((spelling) => !/[aeiouêŭü]/u.test(spelling)));
515
+ /**
516
+ * Whether a normalised run reads as exactly one Wade-Giles syllable.
517
+ *
518
+ * Asked of the loose reader, so that a splitter accepts the same spellings the
519
+ * reader does: a splitter that emitted a piece the reader then refused would be
520
+ * the two halves disagreeing about what Wade-Giles is.
521
+ */
522
+ function isOneSyllable(run, memo) {
523
+ const found = memo.get(run);
524
+ if (found !== undefined) {
525
+ return found;
526
+ }
527
+ const isReads = readWadeGilesLoosely(run).length > 0;
528
+ memo.set(run, isReads);
529
+ return isReads;
530
+ }
531
+ /**
532
+ * Split a run of Wade-Giles with no hyphens in it, longest-first.
533
+ *
534
+ * Memoised on the suffix, as `splitSyllables` is, since a run of ambiguous
535
+ * syllables would otherwise backtrack exponentially.
536
+ */
537
+ function segmentWadeGiles(run, reads, memo) {
538
+ if (run === "") {
539
+ return [];
540
+ }
541
+ const found = memo.get(run);
542
+ if (found !== undefined || memo.has(run)) {
543
+ return found;
544
+ }
545
+ memo.set(run, undefined);
546
+ for (let length = Math.min(LONGEST_SPELLING, run.length); length > 0; length--) {
547
+ const head = run.slice(0, length);
548
+ if (!isOneSyllable(head, reads) || SYLLABIC_NASALS.has(head)) {
549
+ continue;
550
+ }
551
+ const rest = segmentWadeGiles(run.slice(length), reads, memo);
552
+ if (rest !== undefined) {
553
+ const split = [head, ...rest];
554
+ memo.set(run, split);
555
+ return split;
556
+ }
557
+ }
558
+ return undefined;
559
+ }
560
+ /**
561
+ * Split written Wade-Giles into syllables: `maotsetung` becomes three.
562
+ *
563
+ * **The hyphen is Wade's own boundary and is honoured where it is there.** What
564
+ * this is for is the text that dropped it, which is most of the Wade-Giles
565
+ * anybody meets — and there the system has nothing to fall back on, since its
566
+ * apostrophe marks aspiration rather than separation. Pinyin's 隔音符号 has no
567
+ * counterpart here.
568
+ *
569
+ * Longest-first, as `splitSyllables` is for pinyin, and measured on the same
570
+ * vocabulary the 52.07% ambiguity figure comes from — 411,956 multi-syllable
571
+ * words of the phrase corpus, written in Wade-Giles and run together:
572
+ *
573
+ * | | marks kept | marks dropped |
574
+ * | --- | ---: | ---: |
575
+ * | the boundary is found | 99.19% | 99.04% |
576
+ * | the word comes back | **99.45%** | **56.04%** |
577
+ *
578
+ * **Finding the boundary is not the hard part; saying which syllable it was
579
+ * is.** The boundary is found either way; what collapses is the reading, and
580
+ * only when the marks are gone, because 52.07% of written syllables then no
581
+ * longer say which syllable they were. See {@link readWadeGilesLoosely}.
582
+ *
583
+ * The true split is among the candidates 100.00% of the time and is the only
584
+ * candidate 17.08% of the time, at a mean of 5.23 candidates per word — so
585
+ * longest-first is a choice among real rivals rather than the only reading
586
+ * available. It comes back whole slightly *more* often than it finds the
587
+ * boundary, because two of the variant spellings read the same either way.
588
+ *
589
+ * The 0.81% of boundaries that are missed are one mechanism: Wade-Giles ends
590
+ * syllables in -n and -ng and begins them with vowels and n-, so `i-ti-hu-na`
591
+ * runs together as `itihuna` and comes back `i-ti-hun-a`. Of 3,317 misses,
592
+ * 53.39% swallow a syllable beginning with n- and 36.72% one beginning with a
593
+ * vowel. Pinyin is spared most of this by spelling a zero-initial i- as `yi-`;
594
+ * Wade-Giles writes 一 as `i`, and 960 of the misses — 28.94% — are a
595
+ * swallowed 一.
596
+ *
597
+ * Returns undefined for a run that does not split into Wade-Giles at all —
598
+ * which includes `Chungking` and `Tsingtao`, because those are Postal
599
+ * Romanisation rather than Wade-Giles and `king`, `tsing` and `pe` are not
600
+ * Wade-Giles syllables.
601
+ */
602
+ export function splitWadeGiles(text) {
603
+ const run = normalise(text);
604
+ if (run === "") {
605
+ return undefined;
606
+ }
607
+ const reads = new Map();
608
+ // One syllable is one syllable, which is what lets the syllabic nasals be
609
+ // read on their own while never being a piece of anything longer.
610
+ if (isOneSyllable(run, reads)) {
611
+ return [run];
612
+ }
613
+ const memo = new Map();
614
+ // A hyphen is a boundary except in `-êrh`, which is part of a spelling — so
615
+ // the segmenter is given the hyphens and takes the longer head where one
616
+ // reads, rather than the run being cut on them first.
617
+ const split = segmentWadeGiles(run, reads, memo);
618
+ if (split !== undefined) {
619
+ return split;
620
+ }
621
+ // Nothing read across the hyphens, so treat every one of them as a boundary.
622
+ const parts = run.split("-").filter((part) => part !== "");
623
+ if (parts.length < 2) {
624
+ return undefined;
625
+ }
626
+ const segments = parts.map((part) => segmentWadeGiles(part, reads, memo));
627
+ return segments.includes(undefined)
628
+ ? undefined
629
+ : segments.flatMap((segment) => segment ?? []);
630
+ }
631
+ /**
632
+ * Read a whole Wade-Giles word, splitting it first: `maotsetung` is 毛澤東.
633
+ *
634
+ * Takes the first candidate for each syllable rather than every combination,
635
+ * which is the same choice {@link readWadeGilesLoosely}'s ordering offers and
636
+ * for the same reason: a caller looking at a word cannot be handed the 5.23
637
+ * splits and the candidates under each of them and be said to have an answer.
638
+ * Measured over the phrase corpus, that recovers 99.45% of words written with
639
+ * their marks and 56.04% of words written without them.
640
+ *
641
+ * Undefined where the run does not split at all.
642
+ */
643
+ export function readWadeGilesWord(text) {
644
+ const split = splitWadeGiles(text);
645
+ if (split === undefined) {
646
+ return undefined;
647
+ }
648
+ const syllables = split.flatMap((spelling) => {
649
+ const [first] = readWadeGilesLoosely(spelling);
650
+ /* c8 ignore next -- the splitter only emits spellings that read */
651
+ return first === undefined ? [] : [first];
652
+ });
653
+ /* c8 ignore next -- for the same reason */
654
+ return syllables.length === split.length ? syllables : undefined;
655
+ }
656
+ //# sourceMappingURL=wade-giles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wade-giles.js","sourceRoot":"","sources":["../../src/transcription/wade-giles.ts"],"names":[],"mappings":"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"}