@kensio/pinyinjs 1.7.5 → 1.7.7

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 (163) hide show
  1. package/README.md +128 -123
  2. package/data/full.entries +2637 -2637
  3. package/data/manifest.json +9 -9
  4. package/data/script.map +168 -3
  5. package/data/standard.entries +8 -8
  6. package/dist/decode/chang-complement.d.ts +19 -0
  7. package/dist/decode/chang-complement.d.ts.map +1 -0
  8. package/dist/decode/chang-complement.js +113 -0
  9. package/dist/decode/chang-complement.js.map +1 -0
  10. package/dist/decode/chang-context.d.ts +29 -0
  11. package/dist/decode/chang-context.d.ts.map +1 -0
  12. package/dist/decode/chang-context.js +99 -0
  13. package/dist/decode/chang-context.js.map +1 -0
  14. package/dist/decode/chang-rule.d.ts +47 -0
  15. package/dist/decode/chang-rule.d.ts.map +1 -0
  16. package/dist/decode/chang-rule.js +188 -0
  17. package/dist/decode/chang-rule.js.map +1 -0
  18. package/dist/decode/confidence.d.ts +11 -3
  19. package/dist/decode/confidence.d.ts.map +1 -1
  20. package/dist/decode/confidence.js +11 -3
  21. package/dist/decode/confidence.js.map +1 -1
  22. package/dist/decode/convert-pipeline.d.ts.map +1 -1
  23. package/dist/decode/convert-pipeline.js +5 -4
  24. package/dist/decode/convert-pipeline.js.map +1 -1
  25. package/dist/decode/de-rule.d.ts +74 -0
  26. package/dist/decode/de-rule.d.ts.map +1 -0
  27. package/dist/decode/de-rule.js +199 -0
  28. package/dist/decode/de-rule.js.map +1 -0
  29. package/dist/decode/decode.d.ts +12 -25
  30. package/dist/decode/decode.d.ts.map +1 -1
  31. package/dist/decode/decode.js +10 -47
  32. package/dist/decode/decode.js.map +1 -1
  33. package/dist/decode/decoders.d.ts +9 -4
  34. package/dist/decode/decoders.d.ts.map +1 -1
  35. package/dist/decode/decoders.js +7 -7
  36. package/dist/decode/decoders.js.map +1 -1
  37. package/dist/decode/edge-context.d.ts +19 -0
  38. package/dist/decode/edge-context.d.ts.map +1 -1
  39. package/dist/decode/edge-context.js +41 -0
  40. package/dist/decode/edge-context.js.map +1 -1
  41. package/dist/decode/hint-lattice.d.ts.map +1 -1
  42. package/dist/decode/hint-lattice.js +17 -3
  43. package/dist/decode/hint-lattice.js.map +1 -1
  44. package/dist/decode/jiao-rule.d.ts +9 -3
  45. package/dist/decode/jiao-rule.d.ts.map +1 -1
  46. package/dist/decode/jiao-rule.js +44 -5
  47. package/dist/decode/jiao-rule.js.map +1 -1
  48. package/dist/decode/lattice-decode.d.ts +28 -0
  49. package/dist/decode/lattice-decode.d.ts.map +1 -0
  50. package/dist/decode/lattice-decode.js +48 -0
  51. package/dist/decode/lattice-decode.js.map +1 -0
  52. package/dist/decode/lattice-slice.d.ts +22 -6
  53. package/dist/decode/lattice-slice.d.ts.map +1 -1
  54. package/dist/decode/lattice-slice.js +24 -18
  55. package/dist/decode/lattice-slice.js.map +1 -1
  56. package/dist/decode/lattice-types.d.ts +27 -8
  57. package/dist/decode/lattice-types.d.ts.map +1 -1
  58. package/dist/decode/lattice-types.js +27 -8
  59. package/dist/decode/lattice-types.js.map +1 -1
  60. package/dist/decode/numbers.d.ts +0 -8
  61. package/dist/decode/numbers.d.ts.map +1 -1
  62. package/dist/decode/numbers.js +0 -10
  63. package/dist/decode/numbers.js.map +1 -1
  64. package/dist/decode/polyphone-rules.d.ts +7 -27
  65. package/dist/decode/polyphone-rules.d.ts.map +1 -1
  66. package/dist/decode/polyphone-rules.js +7 -155
  67. package/dist/decode/polyphone-rules.js.map +1 -1
  68. package/dist/decode/reading-rules.d.ts +1 -29
  69. package/dist/decode/reading-rules.d.ts.map +1 -1
  70. package/dist/decode/reading-rules.js +5 -69
  71. package/dist/decode/reading-rules.js.map +1 -1
  72. package/dist/decode/rules.d.ts +1 -1
  73. package/dist/decode/rules.d.ts.map +1 -1
  74. package/dist/decode/rules.js +1 -1
  75. package/dist/decode/rules.js.map +1 -1
  76. package/dist/decode/run-context.d.ts +33 -0
  77. package/dist/decode/run-context.d.ts.map +1 -0
  78. package/dist/decode/run-context.js +47 -0
  79. package/dist/decode/run-context.js.map +1 -0
  80. package/dist/decode/run-lattice.d.ts +13 -10
  81. package/dist/decode/run-lattice.d.ts.map +1 -1
  82. package/dist/decode/run-lattice.js +15 -12
  83. package/dist/decode/run-lattice.js.map +1 -1
  84. package/dist/decode/run-words.d.ts +17 -0
  85. package/dist/decode/run-words.d.ts.map +1 -0
  86. package/dist/decode/run-words.js +29 -0
  87. package/dist/decode/run-words.js.map +1 -0
  88. package/dist/decode/sandhi-input.d.ts +30 -0
  89. package/dist/decode/sandhi-input.d.ts.map +1 -0
  90. package/dist/decode/sandhi-input.js +35 -0
  91. package/dist/decode/sandhi-input.js.map +1 -0
  92. package/dist/decode/sandhi-tones.d.ts +33 -5
  93. package/dist/decode/sandhi-tones.d.ts.map +1 -1
  94. package/dist/decode/sandhi-tones.js +59 -8
  95. package/dist/decode/sandhi-tones.js.map +1 -1
  96. package/dist/decode/sandhi.d.ts +9 -6
  97. package/dist/decode/sandhi.d.ts.map +1 -1
  98. package/dist/decode/sandhi.js +10 -7
  99. package/dist/decode/sandhi.js.map +1 -1
  100. package/dist/decode/script-region.d.ts +15 -0
  101. package/dist/decode/script-region.d.ts.map +1 -0
  102. package/dist/decode/script-region.js +61 -0
  103. package/dist/decode/script-region.js.map +1 -0
  104. package/dist/decode/script-types.d.ts +11 -2
  105. package/dist/decode/script-types.d.ts.map +1 -1
  106. package/dist/decode/script-types.js +2 -1
  107. package/dist/decode/script-types.js.map +1 -1
  108. package/dist/decode/script-words.d.ts +7 -5
  109. package/dist/decode/script-words.d.ts.map +1 -1
  110. package/dist/decode/script-words.js +18 -25
  111. package/dist/decode/script-words.js.map +1 -1
  112. package/dist/decode/script.d.ts.map +1 -1
  113. package/dist/decode/script.js +2 -1
  114. package/dist/decode/script.js.map +1 -1
  115. package/dist/decode/write-run.d.ts +0 -7
  116. package/dist/decode/write-run.d.ts.map +1 -1
  117. package/dist/decode/write-run.js +4 -39
  118. package/dist/decode/write-run.js.map +1 -1
  119. package/dist/dictionary/cedict-senses.d.ts +7 -0
  120. package/dist/dictionary/cedict-senses.d.ts.map +1 -1
  121. package/dist/dictionary/cedict-senses.js +12 -0
  122. package/dist/dictionary/cedict-senses.js.map +1 -1
  123. package/dist/dictionary/constituent-repair.d.ts +36 -0
  124. package/dist/dictionary/constituent-repair.d.ts.map +1 -0
  125. package/dist/dictionary/constituent-repair.js +117 -0
  126. package/dist/dictionary/constituent-repair.js.map +1 -0
  127. package/dist/dictionary/measure-tone.d.ts +36 -0
  128. package/dist/dictionary/measure-tone.d.ts.map +1 -0
  129. package/dist/dictionary/measure-tone.js +139 -0
  130. package/dist/dictionary/measure-tone.js.map +1 -0
  131. package/dist/dictionary/merge-types.d.ts +13 -2
  132. package/dist/dictionary/merge-types.d.ts.map +1 -1
  133. package/dist/dictionary/merge-types.js.map +1 -1
  134. package/dist/dictionary/merge-walk.d.ts +27 -0
  135. package/dist/dictionary/merge-walk.d.ts.map +1 -0
  136. package/dist/dictionary/merge-walk.js +49 -0
  137. package/dist/dictionary/merge-walk.js.map +1 -0
  138. package/dist/dictionary/merge.d.ts +3 -3
  139. package/dist/dictionary/merge.d.ts.map +1 -1
  140. package/dist/dictionary/merge.js +24 -28
  141. package/dist/dictionary/merge.js.map +1 -1
  142. package/dist/dictionary/overrides.d.ts +5 -0
  143. package/dist/dictionary/overrides.d.ts.map +1 -1
  144. package/dist/dictionary/overrides.js +5 -5
  145. package/dist/dictionary/overrides.js.map +1 -1
  146. package/dist/dictionary/script-tables.js +91 -13
  147. package/dist/dictionary/script-tables.js.map +1 -1
  148. package/dist/dictionary/word-readings.d.ts.map +1 -1
  149. package/dist/dictionary/word-readings.js +6 -0
  150. package/dist/dictionary/word-readings.js.map +1 -1
  151. package/dist/index.d.ts +1 -1
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +1 -1
  154. package/dist/index.js.map +1 -1
  155. package/dist/script/glyphs.d.ts +9 -8
  156. package/dist/script/glyphs.d.ts.map +1 -1
  157. package/dist/script/glyphs.js +21 -48
  158. package/dist/script/glyphs.js.map +1 -1
  159. package/dist/script/reading-splits.d.ts +41 -0
  160. package/dist/script/reading-splits.d.ts.map +1 -0
  161. package/dist/script/reading-splits.js +98 -0
  162. package/dist/script/reading-splits.js.map +1 -0
  163. package/package.json +2 -2
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Recutting a run's words for 分词连写.
3
+ *
4
+ * Grouping rewrites word boundaries and never the readings behind them, so the
5
+ * syllables — and the confidence beside them — survive it in order, and are
6
+ * simply cut in different places.
7
+ */
8
+ import type { Dictionary } from "../dictionary/dictionary.js";
9
+ import type { ScoredWord } from "./word.js";
10
+ /**
11
+ * The words a Han run decodes to, with 分词连写 applied.
12
+ *
13
+ * Grouping rewrites word boundaries and never the readings behind them, so the
14
+ * syllables — and the confidence beside them — survive it in order.
15
+ */
16
+ export declare function wordsOf(decoded: readonly ScoredWord[], dictionary: Dictionary, isGrouped: boolean): readonly ScoredWord[];
17
+ //# sourceMappingURL=run-words.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-words.d.ts","sourceRoot":"","sources":["../../src/decode/run-words.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,WAAW,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,OAAO,GACjB,SAAS,UAAU,EAAE,CAUvB"}
@@ -0,0 +1,29 @@
1
+ import { applyGrouping } from "../orthography/grouping.js";
2
+ /**
3
+ * The words a Han run decodes to, with 分词连写 applied.
4
+ *
5
+ * Grouping rewrites word boundaries and never the readings behind them, so the
6
+ * syllables — and the confidence beside them — survive it in order.
7
+ */
8
+ export function wordsOf(decoded, dictionary, isGrouped) {
9
+ return isGrouped
10
+ ? regroup(decoded, applyGrouping(decoded.map((scored) => scored.word), dictionary))
11
+ : decoded;
12
+ }
13
+ /**
14
+ * Redistribute the decode's per-syllable confidence over regrouped words.
15
+ *
16
+ * 分词连写 moves word boundaries — 看 and 了 become 看了 — without touching a
17
+ * reading, so the run's syllables are the same syllables in the same order and
18
+ * are simply cut in different places.
19
+ */
20
+ function regroup(decoded, grouped) {
21
+ const confidence = decoded.flatMap((scored) => [...scored.confidence]);
22
+ let at = 0;
23
+ return grouped.map((word) => {
24
+ const held = confidence.slice(at, at + word.reading.length);
25
+ at += word.reading.length;
26
+ return { word, confidence: held };
27
+ });
28
+ }
29
+ //# sourceMappingURL=run-words.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-words.js","sourceRoot":"","sources":["../../src/decode/run-words.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CACrB,OAA8B,EAC9B,UAAsB,EACtB,SAAkB;IAElB,OAAO,SAAS;QACd,CAAC,CAAC,OAAO,CACL,OAAO,EACP,aAAa,CACX,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EACpC,UAAU,CACX,CACF;QACH,CAAC,CAAC,OAAO,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAS,OAAO,CACd,OAA8B,EAC9B,OAA+B;IAE/B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IACvE,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5D,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * What the sandhi pass needs from a decoded run, beyond the syllables.
3
+ *
4
+ * Two questions sandhi cannot answer from a reading alone. Third-tone sandhi
5
+ * applies inside a prosodic foot, so it has to be told where the words and
6
+ * their parts are. 一 sandhi asks what stands in front of the 一, and the answer
7
+ * is a character rather than a spelling. Both are things the decode knows and
8
+ * the syllable array does not.
9
+ */
10
+ import type { Dictionary } from "../dictionary/dictionary.js";
11
+ import type { Syllable } from "../syllable/syllable.js";
12
+ import type { SandhiGrouping } from "./sandhi.js";
13
+ import type { ScoredWord } from "./word.js";
14
+ /**
15
+ * Where the words and their constituents fall, for third-tone sandhi.
16
+ *
17
+ * Undefined unless third-tone sandhi was asked for, since dividing a word costs
18
+ * dictionary lookups and nothing else reads the answer.
19
+ */
20
+ export declare function groupingOf(dictionary: Dictionary, words: readonly ScoredWord[], readings: readonly (readonly Syllable[])[], isThirdTone: boolean): SandhiGrouping | undefined;
21
+ /**
22
+ * One 汉字 per syllable, where a word offers one.
23
+ *
24
+ * A word whose reading is a different length from its text — 玩儿 as `wánr` —
25
+ * has no character to give any one of its syllables, so its syllables get none
26
+ * and the pass falls back to their spellings. See
27
+ * {@link import("./sandhi-tones.js").isCounting}.
28
+ */
29
+ export declare function charactersPerSyllable(words: readonly ScoredWord[], readings: readonly (readonly Syllable[])[]): readonly (string | undefined)[];
30
+ //# sourceMappingURL=sandhi-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandhi-input.d.ts","sourceRoot":"","sources":["../../src/decode/sandhi-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,QAAQ,EAAE,SAAS,CAAC,SAAS,QAAQ,EAAE,CAAC,EAAE,EAC1C,WAAW,EAAE,OAAO,GACnB,cAAc,GAAG,SAAS,CAQ5B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,QAAQ,EAAE,SAAS,CAAC,SAAS,QAAQ,EAAE,CAAC,EAAE,GACzC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAQjC"}
@@ -0,0 +1,35 @@
1
+ import { toCharacters } from "../script/characters.js";
2
+ import { divisionOf } from "./constituents.js";
3
+ /**
4
+ * Where the words and their constituents fall, for third-tone sandhi.
5
+ *
6
+ * Undefined unless third-tone sandhi was asked for, since dividing a word costs
7
+ * dictionary lookups and nothing else reads the answer.
8
+ */
9
+ export function groupingOf(dictionary, words, readings, isThirdTone) {
10
+ if (!isThirdTone) {
11
+ return undefined;
12
+ }
13
+ return words.map((scored, index) => {
14
+ const reading = readings[index] ?? [];
15
+ return divisionOf(dictionary, scored.word.text, reading) ?? reading.length;
16
+ });
17
+ }
18
+ /**
19
+ * One 汉字 per syllable, where a word offers one.
20
+ *
21
+ * A word whose reading is a different length from its text — 玩儿 as `wánr` —
22
+ * has no character to give any one of its syllables, so its syllables get none
23
+ * and the pass falls back to their spellings. See
24
+ * {@link import("./sandhi-tones.js").isCounting}.
25
+ */
26
+ export function charactersPerSyllable(words, readings) {
27
+ return words.flatMap((scored, index) => {
28
+ const reading = readings[index] ?? [];
29
+ const held = toCharacters(scored.word.text);
30
+ return held.length === reading.length
31
+ ? held
32
+ : Array.from({ length: reading.length });
33
+ });
34
+ }
35
+ //# sourceMappingURL=sandhi-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandhi-input.js","sourceRoot":"","sources":["../../src/decode/sandhi-input.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/C;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,UAAsB,EACtB,KAA4B,EAC5B,QAA0C,EAC1C,WAAoB;IAEpB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA4B,EAC5B,QAA0C;IAE1C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAmC,EAAE;QACtE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;YACnC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,KAAK,CAAC,IAAI,CAAqB,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -47,6 +47,28 @@ export declare const CONTINUES_NUMBER: Set<string>;
47
47
  * The ordinal prefix 第.
48
48
  */
49
49
  export declare const ORDINAL_PREFIX = "di";
50
+ /**
51
+ * The 汉字 {@link NUMERAL_WORDS} names, for a caller that has them.
52
+ *
53
+ * The spellings are ambiguous and the characters are not, which is the whole
54
+ * point of carrying both. 是 is spelt `shi` and stands in front of a 一 in
55
+ * 那是一条狗, 这是一个好主意 and several hundred sentences like them, and every
56
+ * one of them lost its sandhi to a 十 that was never there. 时, 事, 使 and 试 do
57
+ * the same.
58
+ *
59
+ * The 繁體 forms are here because a 繁體 text reaches this pass with 繁體
60
+ * characters. 拾, 佰 and 仟 are the 大写 banking forms, which appear on cheques
61
+ * and in contracts and count exactly as their everyday spellings do.
62
+ */
63
+ export declare const NUMERAL_CHARACTERS: Set<string>;
64
+ /**
65
+ * The 汉字 {@link CONTINUES_NUMBER} names.
66
+ */
67
+ export declare const CONTINUES_NUMBER_CHARACTERS: Set<string>;
68
+ /**
69
+ * The ordinal prefix as it is written.
70
+ */
71
+ export declare const ORDINAL_CHARACTER = "\u7B2C";
50
72
  /**
51
73
  * Whether a 一 is counting something, which is the only time it takes sandhi.
52
74
  *
@@ -60,10 +82,16 @@ export declare const ORDINAL_PREFIX = "di";
60
82
  * is counting the ten.
61
83
  * - **An ordinal.** 第一个 is `dìyī gè`.
62
84
  *
63
- * **Read off the syllables rather than the characters**, because that is all
64
- * this pass has: `pinyinjs sandhi shíyī gè` never sees a hanzi. So it cannot
65
- * tell 十 from 时 or 第 from 地, and `docs/sandhi/` carries what that costs —
66
- * measured, not estimated.
85
+ * **Answered from the characters wherever the caller has them**, and from the
86
+ * spellings where it does not. `pinyinjs sandhi shíyī gè` is handed nothing but
87
+ * pinyin, so there the pass still cannot tell 十 from 时 or 第 from 地 and
88
+ * `docs/sandhi/` carries what that costs. A conversion knows which 汉字 it read,
89
+ * and passing them along is what stops 那是一条狗 losing its sandhi to the 是 in
90
+ * front of the 一.
91
+ *
92
+ * The two sides are decided separately, because a run can know one and not the
93
+ * other: a word whose reading has a different syllable count from its character
94
+ * count has no character to offer for any one syllable.
67
95
  */
68
- export declare function isCounting(syllables: readonly Syllable[], at: number): boolean;
96
+ export declare function isCounting(syllables: readonly Syllable[], at: number, characters?: readonly (string | undefined)[]): boolean;
69
97
  //# sourceMappingURL=sandhi-tones.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandhi-tones.d.ts","sourceRoot":"","sources":["../../src/decode/sandhi-tones.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAgB,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;GAEG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI,CAK9D;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,aAAyC,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,aAAsC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,EAAE,EAAE,MAAM,GACT,OAAO,CAUT"}
1
+ {"version":3,"file":"sandhi-tones.d.ts","sourceRoot":"","sources":["../../src/decode/sandhi-tones.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAgB,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;GAEG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI,CAK9D;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,aAAyC,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,aAAsC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,aAS7B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,2BAA2B,aAItC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,WAAM,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,EAAE,EAAE,MAAM,EACV,UAAU,GAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAO,GAC/C,OAAO,CAwBT"}
@@ -56,6 +56,41 @@ export const CONTINUES_NUMBER = new Set([...NUMERAL_WORDS, "ling"]);
56
56
  * The ordinal prefix 第.
57
57
  */
58
58
  export const ORDINAL_PREFIX = "di";
59
+ /**
60
+ * The 汉字 {@link NUMERAL_WORDS} names, for a caller that has them.
61
+ *
62
+ * The spellings are ambiguous and the characters are not, which is the whole
63
+ * point of carrying both. 是 is spelt `shi` and stands in front of a 一 in
64
+ * 那是一条狗, 这是一个好主意 and several hundred sentences like them, and every
65
+ * one of them lost its sandhi to a 十 that was never there. 时, 事, 使 and 试 do
66
+ * the same.
67
+ *
68
+ * The 繁體 forms are here because a 繁體 text reaches this pass with 繁體
69
+ * characters. 拾, 佰 and 仟 are the 大写 banking forms, which appear on cheques
70
+ * and in contracts and count exactly as their everyday spellings do.
71
+ */
72
+ export const NUMERAL_CHARACTERS = new Set([
73
+ "十",
74
+ "百",
75
+ "千",
76
+ "万",
77
+ "萬",
78
+ "拾",
79
+ "佰",
80
+ "仟",
81
+ ]);
82
+ /**
83
+ * The 汉字 {@link CONTINUES_NUMBER} names.
84
+ */
85
+ export const CONTINUES_NUMBER_CHARACTERS = new Set([
86
+ ...NUMERAL_CHARACTERS,
87
+ "零",
88
+ "〇",
89
+ ]);
90
+ /**
91
+ * The ordinal prefix as it is written.
92
+ */
93
+ export const ORDINAL_CHARACTER = "第";
59
94
  /**
60
95
  * Whether a 一 is counting something, which is the only time it takes sandhi.
61
96
  *
@@ -69,20 +104,36 @@ export const ORDINAL_PREFIX = "di";
69
104
  * is counting the ten.
70
105
  * - **An ordinal.** 第一个 is `dìyī gè`.
71
106
  *
72
- * **Read off the syllables rather than the characters**, because that is all
73
- * this pass has: `pinyinjs sandhi shíyī gè` never sees a hanzi. So it cannot
74
- * tell 十 from 时 or 第 from 地, and `docs/sandhi/` carries what that costs —
75
- * measured, not estimated.
107
+ * **Answered from the characters wherever the caller has them**, and from the
108
+ * spellings where it does not. `pinyinjs sandhi shíyī gè` is handed nothing but
109
+ * pinyin, so there the pass still cannot tell 十 from 时 or 第 from 地 and
110
+ * `docs/sandhi/` carries what that costs. A conversion knows which 汉字 it read,
111
+ * and passing them along is what stops 那是一条狗 losing its sandhi to the 是 in
112
+ * front of the 一.
113
+ *
114
+ * The two sides are decided separately, because a run can know one and not the
115
+ * other: a word whose reading has a different syllable count from its character
116
+ * count has no character to offer for any one syllable.
76
117
  */
77
- export function isCounting(syllables, at) {
118
+ export function isCounting(syllables, at, characters = []) {
78
119
  const spelt = (index) => {
79
120
  const syllable = syllables[index];
80
121
  return syllable === undefined ? "" : writeSyllableSpelling(syllable);
81
122
  };
82
- const before = spelt(at - 1);
83
- if (before === ORDINAL_PREFIX) {
123
+ const before = characters[at - 1];
124
+ if (before === undefined
125
+ ? spelt(at - 1) === ORDINAL_PREFIX
126
+ : before === ORDINAL_CHARACTER) {
84
127
  return false;
85
128
  }
86
- return !NUMERAL_WORDS.has(before) || CONTINUES_NUMBER.has(spelt(at + 1));
129
+ if (before === undefined
130
+ ? !NUMERAL_WORDS.has(spelt(at - 1))
131
+ : !NUMERAL_CHARACTERS.has(before)) {
132
+ return true;
133
+ }
134
+ const after = characters[at + 1];
135
+ return after === undefined
136
+ ? CONTINUES_NUMBER.has(spelt(at + 1))
137
+ : CONTINUES_NUMBER_CHARACTERS.has(after);
87
138
  }
88
139
  //# sourceMappingURL=sandhi-tones.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandhi-tones.js","sourceRoot":"","sources":["../../src/decode/sandhi-tones.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAiB,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAa,MAAM,iBAAiB,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,QAAkB;IACrC,OAAO,QAAQ,CAAC,OAAO,KAAK,EAAE,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,QAAkB;IACrC,OAAO,QAAQ,CAAC,OAAO,KAAK,GAAG,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,SAA2B;IACtD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC1D,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CACxB,SAA8B,EAC9B,EAAU;IAEV,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE;QACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"sandhi-tones.js","sourceRoot":"","sources":["../../src/decode/sandhi-tones.ts"],"names":[],"mappings":"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"}
@@ -39,14 +39,17 @@ export type SandhiGrouping = readonly (number | readonly number[])[];
39
39
  * contextual tone is put back, over the whole syllable array rather than within
40
40
  * a word, which is what lets 不 in one word assimilate to a tone in the next.
41
41
  *
42
- * 一 and 不 assimilate to whatever follows them and need nothing but the
43
- * syllables. Third-tone sandhi is not like that — its domain is the foot rather
44
- * than the syllable string — so `grouping` says where the words and their parts
45
- * are. Without one the whole array is taken for a single word, which is what a
46
- * caller holding nothing but a reading has.
42
+ * 不 assimilates to whatever follows it and needs nothing but the syllables.
43
+ * Third-tone sandhi is not like that — its domain is the foot rather than the
44
+ * syllable string — so `grouping` says where the words and their parts are.
45
+ * Without one the whole array is taken for a single word, which is what a
46
+ * caller holding nothing but a reading has. 一 sits between the two: the tone it
47
+ * takes is settled by the syllables, and whether it takes one at all is a
48
+ * question about the 汉字, so `characters` carries them where the caller has
49
+ * them. See {@link isCounting}.
47
50
  *
48
51
  * Never operates on a string. The old project patched output text with regexes,
49
52
  * which is what made its rules order-dependent and untestable.
50
53
  */
51
- export declare function applySandhi(syllables: readonly Syllable[], options?: SandhiOptions, grouping?: SandhiGrouping): readonly Syllable[];
54
+ export declare function applySandhi(syllables: readonly Syllable[], options?: SandhiOptions, grouping?: SandhiGrouping, characters?: readonly (string | undefined)[]): readonly Syllable[];
52
55
  //# sourceMappingURL=sandhi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandhi.d.ts","sourceRoot":"","sources":["../../src/decode/sandhi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;AA6HrE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,GAAE,aAAkB,EAC3B,QAAQ,CAAC,EAAE,cAAc,GACxB,SAAS,QAAQ,EAAE,CA6BrB"}
1
+ {"version":3,"file":"sandhi.d.ts","sourceRoot":"","sources":["../../src/decode/sandhi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;AA6HrE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,GAAE,aAAkB,EAC3B,QAAQ,CAAC,EAAE,cAAc,EACzB,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAC3C,SAAS,QAAQ,EAAE,CA6BrB"}
@@ -103,16 +103,19 @@ function applyThirdTone(syllables, grouping) {
103
103
  * contextual tone is put back, over the whole syllable array rather than within
104
104
  * a word, which is what lets 不 in one word assimilate to a tone in the next.
105
105
  *
106
- * 一 and 不 assimilate to whatever follows them and need nothing but the
107
- * syllables. Third-tone sandhi is not like that — its domain is the foot rather
108
- * than the syllable string — so `grouping` says where the words and their parts
109
- * are. Without one the whole array is taken for a single word, which is what a
110
- * caller holding nothing but a reading has.
106
+ * 不 assimilates to whatever follows it and needs nothing but the syllables.
107
+ * Third-tone sandhi is not like that — its domain is the foot rather than the
108
+ * syllable string — so `grouping` says where the words and their parts are.
109
+ * Without one the whole array is taken for a single word, which is what a
110
+ * caller holding nothing but a reading has. 一 sits between the two: the tone it
111
+ * takes is settled by the syllables, and whether it takes one at all is a
112
+ * question about the 汉字, so `characters` carries them where the caller has
113
+ * them. See {@link isCounting}.
111
114
  *
112
115
  * Never operates on a string. The old project patched output text with regexes,
113
116
  * which is what made its rules order-dependent and untestable.
114
117
  */
115
- export function applySandhi(syllables, options = {}, grouping) {
118
+ export function applySandhi(syllables, options = {}, grouping, characters) {
116
119
  const { yiBu = true, thirdTone = false } = options;
117
120
  const applied = thirdTone
118
121
  ? applyThirdTone(syllables, grouping)
@@ -122,7 +125,7 @@ export function applySandhi(syllables, options = {}, grouping) {
122
125
  if (yiBu && isYi(syllable) && syllable.tone === 1) {
123
126
  // A 一 that is not counting keeps its citation tone, so it is left
124
127
  // exactly as the dictionary stored it.
125
- if (isCounting(applied, at)) {
128
+ if (isCounting(applied, at, characters)) {
126
129
  applied[at] = { ...syllable, tone: yiToneBefore(following?.tone) };
127
130
  }
128
131
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"sandhi.js","sourceRoot":"","sources":["../../src/decode/sandhi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandhi.js","sourceRoot":"","sources":["../../src/decode/sandhi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Writing a converted word in a region's own 繁體 orthography.
3
+ *
4
+ * The last pass over a word's choices. Taiwan and Hong Kong disagree about the
5
+ * standard form of 58 characters and about nothing else, so this rewrites forms
6
+ * and never a reading.
7
+ */
8
+ import { type Region } from "../script/glyphs.js";
9
+ import type { Syllable } from "../syllable/syllable.js";
10
+ import type { ScriptChoice } from "./script-types.js";
11
+ /**
12
+ * Apply the regional 繁體 forms, which never change a reading.
13
+ */
14
+ export declare function applyRegion(choices: readonly ScriptChoice[], reading: readonly Syllable[], region: Region, isAligned: boolean): readonly ScriptChoice[];
15
+ //# sourceMappingURL=script-region.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-region.d.ts","sourceRoot":"","sources":["../../src/decode/script-region.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAGL,KAAK,MAAM,EAGZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAEtE;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GACjB,SAAS,YAAY,EAAE,CAsBzB"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Writing a converted word in a region's own 繁體 orthography.
3
+ *
4
+ * The last pass over a word's choices. Taiwan and Hong Kong disagree about the
5
+ * standard form of 58 characters and about nothing else, so this rewrites forms
6
+ * and never a reading.
7
+ */
8
+ import { DEFAULT_REGION, isReadingSensitive, regionalGlyphsOf, toRegionalGlyph, } from "../script/glyphs.js";
9
+ /**
10
+ * Apply the regional 繁體 forms, which never change a reading.
11
+ */
12
+ export function applyRegion(choices, reading, region, isAligned) {
13
+ if (region === DEFAULT_REGION) {
14
+ return choices;
15
+ }
16
+ return choices.map((choice, at) => {
17
+ const syllable = isAligned ? reading[at] : undefined;
18
+ // A regional form that needs the reading and has none is a guess, whatever
19
+ // settled the script conversion before it: 著 is 着 or 著 in Hong Kong.
20
+ const isGuess = isReadingSensitive(choice.to) && syllable === undefined;
21
+ const to = toRegionalGlyph(choice.to, region, syllable);
22
+ const alternatives = regionalAlternatives(choice, region, to, isGuess);
23
+ return {
24
+ ...choice,
25
+ to,
26
+ // A region can leave a character one form where the script left it two:
27
+ // Hong Kong writes 台 for both 台 and 臺, and 泄 for both 泄 and 洩. There
28
+ // was nothing to decide once the region is applied, whatever the script
29
+ // conversion thought it was deciding.
30
+ evidence: evidenceAfter(choice, alternatives, isGuess),
31
+ alternatives,
32
+ };
33
+ });
34
+ }
35
+ /**
36
+ * What settled a choice once the region has had its say.
37
+ */
38
+ function evidenceAfter(choice, alternatives, isGuess) {
39
+ if (alternatives.length === 0) {
40
+ return "locked";
41
+ }
42
+ return isGuess ? "default" : choice.evidence;
43
+ }
44
+ /**
45
+ * The forms a choice was written against, in the region's own orthography.
46
+ *
47
+ * Two things happen here. The rivals the script tables named are rewritten,
48
+ * since a choice reporting 面 settled for Hong Kong beside a Taiwan 麵 would be
49
+ * writing two orthographies at once — 3,163 of the 39,430 alternatives over
50
+ * 88,866 lines were doing that, mostly 裡 for 裏 and 麵 for 麪. And a guess the
51
+ * region itself created gains the form the reading would have kept, which is
52
+ * the only thing 著 and 參 were ever choosing between.
53
+ */
54
+ function regionalAlternatives(choice, region, to, isGuess) {
55
+ const forms = [
56
+ ...choice.alternatives.map((form) => toRegionalGlyph(form, region)),
57
+ ...(isGuess ? regionalGlyphsOf(choice.to, region) : []),
58
+ ];
59
+ return [...new Set(forms)].filter((form) => form !== to);
60
+ }
61
+ //# sourceMappingURL=script-region.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-region.js","sourceRoot":"","sources":["../../src/decode/script-region.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,cAAc,EACd,kBAAkB,EAElB,gBAAgB,EAChB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAI7B;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,OAAgC,EAChC,OAA4B,EAC5B,MAAc,EACd,SAAkB;IAElB,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE;QAChC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrD,2EAA2E;QAC3E,qEAAqE;QACrE,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,KAAK,SAAS,CAAC;QACxE,MAAM,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QACvE,OAAO;YACL,GAAG,MAAM;YACT,EAAE;YACF,wEAAwE;YACxE,qEAAqE;YACrE,wEAAwE;YACxE,sCAAsC;YACtC,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC;YACtD,YAAY;SACb,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,MAAoB,EACpB,YAA+B,EAC/B,OAAgB;IAEhB,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC/C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAC3B,MAAoB,EACpB,MAAc,EACd,EAAU,EACV,OAAgB;IAEhB,MAAM,KAAK,GAAG;QACZ,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC;IACF,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;AAC3D,CAAC"}
@@ -35,7 +35,8 @@ export interface ScriptOptions {
35
35
  *
36
36
  * - `locked` — the character has one form and there was nothing to decide.
37
37
  * True of the great majority: simplification changed a minority of
38
- * characters, and most of those are one-to-one.
38
+ * characters, and most of those are one-to-one. The one evidence that comes
39
+ * with no {@link ScriptChoice.alternatives}, and the only one.
39
40
  * - `word` — a word some source wrote in both scripts settled it. The strongest
40
41
  * real evidence, because it was written rather than inferred.
41
42
  * - `reading` — the character had rival forms and the syllable it was decoded
@@ -63,7 +64,15 @@ export interface ScriptChoice {
63
64
  /** The character as it was converted. */
64
65
  readonly to: string;
65
66
  readonly evidence: ScriptEvidence;
66
- /** The forms this character could also have taken. */
67
+ /**
68
+ * The forms this character could also have taken.
69
+ *
70
+ * Empty exactly when the evidence is `locked`, so a caller reading one of
71
+ * them never has to check the other. The character's own form counts: 万 is
72
+ * 萬 counting and 万 in the surname 万俟, and a conversion that took 萬 was
73
+ * choosing between the two. So does the region's: Hong Kong writes 麪 where
74
+ * Taiwan writes 麵, and a Hong Kong conversion says 麪.
75
+ */
67
76
  readonly alternatives: readonly string[];
68
77
  }
69
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"script-types.d.ts","sourceRoot":"","sources":["../../src/decode/script-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,YACzB,SAAS,EACT,SAAS,EACT,YAAY,EACZ,YAAY,CACJ,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,YAC1B,QAAQ,EACR,MAAM,EACN,SAAS,EACT,SAAS,CACD,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,sDAAsD;IACtD,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C"}
1
+ {"version":3,"file":"script-types.d.ts","sourceRoot":"","sources":["../../src/decode/script-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,YACzB,SAAS,EACT,SAAS,EACT,YAAY,EACZ,YAAY,CACJ,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,YAC1B,QAAQ,EACR,MAAM,EACN,SAAS,EACT,SAAS,CACD,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C"}
@@ -17,7 +17,8 @@ export const SCRIPT_TARGETS = [
17
17
  *
18
18
  * - `locked` — the character has one form and there was nothing to decide.
19
19
  * True of the great majority: simplification changed a minority of
20
- * characters, and most of those are one-to-one.
20
+ * characters, and most of those are one-to-one. The one evidence that comes
21
+ * with no {@link ScriptChoice.alternatives}, and the only one.
21
22
  * - `word` — a word some source wrote in both scripts settled it. The strongest
22
23
  * real evidence, because it was written rather than inferred.
23
24
  * - `reading` — the character had rival forms and the syllable it was decoded
@@ -1 +1 @@
1
- {"version":3,"file":"script-types.js","sourceRoot":"","sources":["../../src/decode/script-types.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS;IACT,SAAS;IACT,YAAY;IACZ,YAAY;CACJ,CAAC;AAuBX;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ;IACR,MAAM;IACN,SAAS;IACT,SAAS;CACD,CAAC"}
1
+ {"version":3,"file":"script-types.js","sourceRoot":"","sources":["../../src/decode/script-types.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS;IACT,SAAS;IACT,YAAY;IACZ,YAAY;CACJ,CAAC;AAuBX;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ;IACR,MAAM;IACN,SAAS;IACT,SAAS;CACD,CAAC"}
@@ -23,10 +23,12 @@ export declare function targetOf(target: ScriptTarget): {
23
23
  export declare function convertWord(table: ReadonlyMap<string, CharacterConversion>, words: ReadonlyMap<string, string>, word: string, reading: readonly Syllable[]): readonly ScriptChoice[];
24
24
  /**
25
25
  * Rank what settled a character, strongest evidence first.
26
+ *
27
+ * `locked` is keyed on whether a rival form survived rather than on
28
+ * {@link import("../script/conversion.js").isAmbiguousCharacter}, and the two part company where a word overrides
29
+ * the character table. 钟 has one 繁體 form by the characters and 一见钟情 is
30
+ * 一見鍾情, so the choice named 鐘 as the road not taken while calling itself
31
+ * locked. A word settled that one, which is what `word` is for.
26
32
  */
27
- export declare function evidenceFor(isAttested: boolean, isAtReading: boolean, isAmbiguous: boolean): ScriptEvidence;
28
- /**
29
- * Apply the regional 繁體 forms, which never change a reading.
30
- */
31
- export declare function applyRegion(choices: readonly ScriptChoice[], reading: readonly Syllable[], region: Region, isAligned: boolean): readonly ScriptChoice[];
33
+ export declare function evidenceFor(isAttested: boolean, isAtReading: boolean, hasRival: boolean): ScriptEvidence;
32
34
  //# sourceMappingURL=script-words.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"script-words.d.ts","sourceRoot":"","sources":["../../src/decode/script-words.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,mBAAmB,EAKzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,MAAM,EAEZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAQA;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC/C,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,QAAQ,EAAE,GAC3B,SAAS,YAAY,EAAE,CAmCzB;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,OAAO,EACnB,WAAW,EAAE,OAAO,EACpB,WAAW,EAAE,OAAO,GACnB,cAAc,CAQhB;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GACjB,SAAS,YAAY,EAAE,CAezB"}
1
+ {"version":3,"file":"script-words.d.ts","sourceRoot":"","sources":["../../src/decode/script-words.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,mBAAmB,EAIzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAQA;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC/C,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,QAAQ,EAAE,GAC3B,SAAS,YAAY,EAAE,CAuCzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,OAAO,EACnB,WAAW,EAAE,OAAO,EACpB,QAAQ,EAAE,OAAO,GAChB,cAAc,CAQhB"}
@@ -1,6 +1,6 @@
1
1
  import { toCharacters } from "../script/characters.js";
2
- import { conversionKey, convertCharacter, formsOf, isAmbiguousCharacter, } from "../script/conversion.js";
3
- import { DEFAULT_REGION, isReadingSensitive, toRegionalGlyph, } from "../script/glyphs.js";
2
+ import { conversionKey, convertCharacter, formsOf, } from "../script/conversion.js";
3
+ import { DEFAULT_REGION } from "../script/glyphs.js";
4
4
  /**
5
5
  * The script and region a target names.
6
6
  */
@@ -35,19 +35,31 @@ export function convertWord(table, words, word, reading) {
35
35
  ? /* c8 ignore next -- the lengths were just checked */
36
36
  (attestedCharacters[at] ?? character)
37
37
  : convertCharacter(table, character, syllable);
38
+ // Every form the table names but the one taken. The character's own form
39
+ // belongs among them: 万 is 萬 counting and 万 in the surname 万俟, 准 is
40
+ // 準 and 准 in 准將, 著 is 着 and 著 at `zhù`. Excluding it left 42 简→繁
41
+ // characters and 3,160 繁→简 ones reporting a guess with nothing to have
42
+ // guessed between.
43
+ const alternatives = formsOf(conversion).filter((form) => form !== to);
38
44
  return {
39
45
  from: character,
40
46
  to,
41
- evidence: evidenceFor(isAttested, atReading !== undefined, isAmbiguousCharacter(table, character)),
42
- alternatives: formsOf(conversion).filter((form) => form !== character && form !== to),
47
+ evidence: evidenceFor(isAttested, atReading !== undefined, alternatives.length > 0),
48
+ alternatives,
43
49
  };
44
50
  });
45
51
  }
46
52
  /**
47
53
  * Rank what settled a character, strongest evidence first.
54
+ *
55
+ * `locked` is keyed on whether a rival form survived rather than on
56
+ * {@link import("../script/conversion.js").isAmbiguousCharacter}, and the two part company where a word overrides
57
+ * the character table. 钟 has one 繁體 form by the characters and 一见钟情 is
58
+ * 一見鍾情, so the choice named 鐘 as the road not taken while calling itself
59
+ * locked. A word settled that one, which is what `word` is for.
48
60
  */
49
- export function evidenceFor(isAttested, isAtReading, isAmbiguous) {
50
- if (!isAmbiguous) {
61
+ export function evidenceFor(isAttested, isAtReading, hasRival) {
62
+ if (!hasRival) {
51
63
  return "locked";
52
64
  }
53
65
  if (isAttested) {
@@ -55,23 +67,4 @@ export function evidenceFor(isAttested, isAtReading, isAmbiguous) {
55
67
  }
56
68
  return isAtReading ? "reading" : "default";
57
69
  }
58
- /**
59
- * Apply the regional 繁體 forms, which never change a reading.
60
- */
61
- export function applyRegion(choices, reading, region, isAligned) {
62
- if (region === DEFAULT_REGION) {
63
- return choices;
64
- }
65
- return choices.map((choice, at) => {
66
- const syllable = isAligned ? reading[at] : undefined;
67
- // A regional form that needs the reading and has none is a guess, whatever
68
- // settled the script conversion before it: 著 is 着 or 著 in Hong Kong.
69
- const isGuess = isReadingSensitive(choice.to) && syllable === undefined;
70
- return {
71
- ...choice,
72
- to: toRegionalGlyph(choice.to, region, syllable),
73
- evidence: isGuess ? "default" : choice.evidence,
74
- };
75
- });
76
- }
77
70
  //# sourceMappingURL=script-words.js.map