@kensio/pinyinjs 1.7.6 → 1.7.8

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 (127) hide show
  1. package/README.md +2 -2
  2. package/data/full.counts +0 -0
  3. package/data/full.entries +46 -46
  4. package/data/manifest.json +15 -8
  5. package/data/script.map +102 -0
  6. package/data/standard.entries +8 -8
  7. package/dist/decode/chang-complement.d.ts +19 -0
  8. package/dist/decode/chang-complement.d.ts.map +1 -0
  9. package/dist/decode/chang-complement.js +113 -0
  10. package/dist/decode/chang-complement.js.map +1 -0
  11. package/dist/decode/chang-context.d.ts +9 -7
  12. package/dist/decode/chang-context.d.ts.map +1 -1
  13. package/dist/decode/chang-context.js +36 -3
  14. package/dist/decode/chang-context.js.map +1 -1
  15. package/dist/decode/chang-rule.d.ts +25 -15
  16. package/dist/decode/chang-rule.d.ts.map +1 -1
  17. package/dist/decode/chang-rule.js +38 -19
  18. package/dist/decode/chang-rule.js.map +1 -1
  19. package/dist/decode/convert-pipeline.d.ts.map +1 -1
  20. package/dist/decode/convert-pipeline.js +3 -3
  21. package/dist/decode/convert-pipeline.js.map +1 -1
  22. package/dist/decode/de-rule.d.ts +20 -0
  23. package/dist/decode/de-rule.d.ts.map +1 -1
  24. package/dist/decode/de-rule.js +87 -1
  25. package/dist/decode/de-rule.js.map +1 -1
  26. package/dist/decode/decode.d.ts +12 -25
  27. package/dist/decode/decode.d.ts.map +1 -1
  28. package/dist/decode/decode.js +10 -47
  29. package/dist/decode/decode.js.map +1 -1
  30. package/dist/decode/decoders.d.ts +9 -4
  31. package/dist/decode/decoders.d.ts.map +1 -1
  32. package/dist/decode/decoders.js +7 -7
  33. package/dist/decode/decoders.js.map +1 -1
  34. package/dist/decode/edge-context.d.ts +19 -0
  35. package/dist/decode/edge-context.d.ts.map +1 -1
  36. package/dist/decode/edge-context.js +41 -0
  37. package/dist/decode/edge-context.js.map +1 -1
  38. package/dist/decode/lattice-decode.d.ts +28 -0
  39. package/dist/decode/lattice-decode.d.ts.map +1 -0
  40. package/dist/decode/lattice-decode.js +48 -0
  41. package/dist/decode/lattice-decode.js.map +1 -0
  42. package/dist/decode/lattice-slice.d.ts +22 -6
  43. package/dist/decode/lattice-slice.d.ts.map +1 -1
  44. package/dist/decode/lattice-slice.js +24 -18
  45. package/dist/decode/lattice-slice.js.map +1 -1
  46. package/dist/decode/numbers.d.ts +0 -8
  47. package/dist/decode/numbers.d.ts.map +1 -1
  48. package/dist/decode/numbers.js +0 -10
  49. package/dist/decode/numbers.js.map +1 -1
  50. package/dist/decode/reading-rules.d.ts +1 -1
  51. package/dist/decode/reading-rules.d.ts.map +1 -1
  52. package/dist/decode/reading-rules.js +3 -2
  53. package/dist/decode/reading-rules.js.map +1 -1
  54. package/dist/decode/rules.d.ts +1 -1
  55. package/dist/decode/rules.d.ts.map +1 -1
  56. package/dist/decode/rules.js +1 -1
  57. package/dist/decode/rules.js.map +1 -1
  58. package/dist/decode/run-context.d.ts +33 -0
  59. package/dist/decode/run-context.d.ts.map +1 -0
  60. package/dist/decode/run-context.js +47 -0
  61. package/dist/decode/run-context.js.map +1 -0
  62. package/dist/decode/run-lattice.d.ts +13 -10
  63. package/dist/decode/run-lattice.d.ts.map +1 -1
  64. package/dist/decode/run-lattice.js +15 -12
  65. package/dist/decode/run-lattice.js.map +1 -1
  66. package/dist/decode/script-region.d.ts +15 -0
  67. package/dist/decode/script-region.d.ts.map +1 -0
  68. package/dist/decode/script-region.js +61 -0
  69. package/dist/decode/script-region.js.map +1 -0
  70. package/dist/decode/script-types.d.ts +11 -2
  71. package/dist/decode/script-types.d.ts.map +1 -1
  72. package/dist/decode/script-types.js +2 -1
  73. package/dist/decode/script-types.js.map +1 -1
  74. package/dist/decode/script-words.d.ts +7 -5
  75. package/dist/decode/script-words.d.ts.map +1 -1
  76. package/dist/decode/script-words.js +18 -25
  77. package/dist/decode/script-words.js.map +1 -1
  78. package/dist/decode/script.d.ts.map +1 -1
  79. package/dist/decode/script.js +2 -1
  80. package/dist/decode/script.js.map +1 -1
  81. package/dist/dictionary/artifact-claims.d.ts +8 -0
  82. package/dist/dictionary/artifact-claims.d.ts.map +1 -1
  83. package/dist/dictionary/artifact-claims.js +11 -1
  84. package/dist/dictionary/artifact-claims.js.map +1 -1
  85. package/dist/dictionary/artifact.d.ts.map +1 -1
  86. package/dist/dictionary/artifact.js +3 -5
  87. package/dist/dictionary/artifact.js.map +1 -1
  88. package/dist/dictionary/measure-tone.d.ts +36 -0
  89. package/dist/dictionary/measure-tone.d.ts.map +1 -0
  90. package/dist/dictionary/measure-tone.js +139 -0
  91. package/dist/dictionary/measure-tone.js.map +1 -0
  92. package/dist/dictionary/merge-types.d.ts +8 -3
  93. package/dist/dictionary/merge-types.d.ts.map +1 -1
  94. package/dist/dictionary/merge-types.js.map +1 -1
  95. package/dist/dictionary/merge.d.ts.map +1 -1
  96. package/dist/dictionary/merge.js +7 -1
  97. package/dist/dictionary/merge.js.map +1 -1
  98. package/dist/dictionary/overrides.d.ts +5 -0
  99. package/dist/dictionary/overrides.d.ts.map +1 -1
  100. package/dist/dictionary/overrides.js +5 -5
  101. package/dist/dictionary/overrides.js.map +1 -1
  102. package/dist/dictionary/script-tables.js +91 -13
  103. package/dist/dictionary/script-tables.js.map +1 -1
  104. package/dist/dictionary/source.d.ts +22 -0
  105. package/dist/dictionary/source.d.ts.map +1 -1
  106. package/dist/dictionary/source.js +24 -0
  107. package/dist/dictionary/source.js.map +1 -1
  108. package/dist/dictionary/word-counts.d.ts +74 -0
  109. package/dist/dictionary/word-counts.d.ts.map +1 -0
  110. package/dist/dictionary/word-counts.js +142 -0
  111. package/dist/dictionary/word-counts.js.map +1 -0
  112. package/dist/dictionary/word-readings.d.ts.map +1 -1
  113. package/dist/dictionary/word-readings.js +3 -0
  114. package/dist/dictionary/word-readings.js.map +1 -1
  115. package/dist/index.d.ts +3 -2
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +3 -2
  118. package/dist/index.js.map +1 -1
  119. package/dist/script/glyphs.d.ts +9 -8
  120. package/dist/script/glyphs.d.ts.map +1 -1
  121. package/dist/script/glyphs.js +21 -48
  122. package/dist/script/glyphs.js.map +1 -1
  123. package/dist/script/reading-splits.d.ts +41 -0
  124. package/dist/script/reading-splits.d.ts.map +1 -0
  125. package/dist/script/reading-splits.js +98 -0
  126. package/dist/script/reading-splits.js.map +1 -0
  127. package/package.json +1 -1
@@ -0,0 +1,113 @@
1
+ /**
2
+ * What can follow a 长 that is a length and cannot follow one that is growing.
3
+ *
4
+ * The near-side contexts are in `chang-context.ts`, and each of them has to
5
+ * check this side as well. These two do the opposite: they settle a 长 from what
6
+ * comes after it and ask nothing at all about what comes before.
7
+ */
8
+ import { toCharacters } from "../script/characters.js";
9
+ import { tagOf, wordsStartingAt } from "./rules.js";
10
+ /**
11
+ * What can only follow a 长 that is a length.
12
+ *
13
+ * A quality can be compared and intensified, and a growing cannot: 长一点 is
14
+ * longer by a bit, 长极了 is extremely long, and 长而美丽 conjoins two
15
+ * adjectives. None of them is something a verb governs, so the near side needs
16
+ * no test at all and these settle a 长 on their own.
17
+ *
18
+ * 得 is pointedly absent even though 长得很 looks like the same shape, because
19
+ * 长得很快 is the growing with its complement and 得 is where that complement
20
+ * hangs. {@link GROWING} in `chang-rule.ts` guards it from the other side.
21
+ */
22
+ const COMPARED = new Set([
23
+ "而",
24
+ "一点",
25
+ "一點",
26
+ "点",
27
+ "點",
28
+ "一些",
29
+ "些",
30
+ "极了",
31
+ "極了",
32
+ "得多",
33
+ ]);
34
+ /**
35
+ * Whether what follows a 长 is a comparison or an intensifier.
36
+ */
37
+ export function isCompared(context) {
38
+ const { characters, edge } = context;
39
+ for (let length = 1; length <= 2; length++) {
40
+ const after = characters.slice(edge.to, edge.to + length).join("");
41
+ if (COMPARED.has(after)) {
42
+ return true;
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ /**
48
+ * The tag jieba gives a numeral.
49
+ */
50
+ const NUMERAL = "m";
51
+ /**
52
+ * The units a length or a duration is given in.
53
+ *
54
+ * Written out rather than taken from the 量词 tag, and the corpus says why: a
55
+ * numeral after a 长 is far more often counting something else. 学校现有通榆和新
56
+ * 长两个校区 counts campuses and 竞争马华总会长一职 counts posts, and both read
57
+ * `zhǎng`. What a 长 can be measured in is a distance or a stretch of time, and
58
+ * that is a closed set.
59
+ */
60
+ const MEASURED_IN = new Set([
61
+ "米",
62
+ "公里",
63
+ "千米",
64
+ "厘米",
65
+ "毫米",
66
+ "公分",
67
+ "英里",
68
+ "英尺",
69
+ "英寸",
70
+ "尺",
71
+ "寸",
72
+ "里",
73
+ "码",
74
+ "秒",
75
+ "分钟",
76
+ "分鐘",
77
+ "小时",
78
+ "小時",
79
+ "天",
80
+ "周",
81
+ "週",
82
+ "年",
83
+ "世纪",
84
+ "世紀",
85
+ ]);
86
+ /**
87
+ * Whether a 长 is being given a measurement.
88
+ *
89
+ * 那条河长三百公里, 隧道长五公里. A quantity after a 长 is how long the thing is,
90
+ * and a growing takes an aspect marker before it can take one — 长了三厘米 —
91
+ * which is the 了 this never sees.
92
+ *
93
+ * A number written in digits reads the same, though nothing here knows the
94
+ * difference. 那条河长300公里 is four runs and the 长 ends the first of them, so
95
+ * the numeral and the 公里 are one run and two runs away; the decode is handed
96
+ * the 汉字 they stand for before this is ever asked. See `convert-pipeline.ts`.
97
+ */
98
+ export function isMeasured(context) {
99
+ const { characters, edge } = context;
100
+ for (const number of wordsStartingAt(context, edge.to)) {
101
+ if (!tagOf(context, number).startsWith(NUMERAL)) {
102
+ continue;
103
+ }
104
+ const at = edge.to + toCharacters(number).length;
105
+ for (let length = 1; length <= 2; length++) {
106
+ if (MEASURED_IN.has(characters.slice(at, at + length).join(""))) {
107
+ return true;
108
+ }
109
+ }
110
+ }
111
+ return false;
112
+ }
113
+ //# sourceMappingURL=chang-complement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chang-complement.js","sourceRoot":"","sources":["../../src/decode/chang-complement.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAoB,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,GAAG;IACH,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;CACL,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;CACL,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,KAAK,MAAM,MAAM,IAAI,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACjD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBAChE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,10 +1,3 @@
1
- /**
2
- * The two 长 contexts a degree adverb does not cover.
3
- *
4
- * 很 or 太 in front of a 长 settles it on its own, and `chang-rule.ts` says why.
5
- * These two do not: each names a near side that a verb 长 shares, so each has
6
- * to check the far side as well.
7
- */
8
1
  import { type EdgeContext } from "./rules.js";
9
2
  /**
10
3
  * Whether a 长 is the whole of what an adverb is scoping.
@@ -22,6 +15,15 @@ export declare function isPredicated(context: EdgeContext): boolean;
22
15
  * near side has to say the rest. A 量词 or 有 in front of a 长 leaves it nothing
23
16
  * to be the verb of: 一个长头发的女生 and 兔子有长耳朵 have their subject
24
17
  * already spoken for, and 他长毛了 and 树长叶子 do not.
18
+ *
19
+ * A verb in front is **not** enough, though 他留长头发 wears long hair where
20
+ * 他长头发 grows it. jieba tags 树 a verb and 习惯 a noun, so the tag names
21
+ * neither set: taking every verb read 树长叶子 as an adjective and 教育长邓演达
22
+ * with it.
23
+ *
24
+ * Every word ending at the position is asked rather than the longest, because
25
+ * the longest is 一个 where the 量词 is the 个 inside it. See
26
+ * {@link wordsEndingAt}.
25
27
  */
26
28
  export declare function isAttributive(context: EdgeContext): boolean;
27
29
  //# sourceMappingURL=chang-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chang-context.d.ts","sourceRoot":"","sources":["../../src/decode/chang-context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,YAAY,CAAC;AAqBpB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAO1D;AAYD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAO3D"}
1
+ {"version":3,"file":"chang-context.d.ts","sourceRoot":"","sources":["../../src/decode/chang-context.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,YAAY,CAAC;AAqBpB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAO1D;AAmCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAW3D"}
@@ -5,7 +5,8 @@
5
5
  * These two do not: each names a near side that a verb 长 shares, so each has
6
6
  * to check the far side as well.
7
7
  */
8
- import { tagOf, wordEndingAt, wordStartingAt, } from "./rules.js";
8
+ import { QUANTITY_CHARACTERS } from "../numerals/characters.js";
9
+ import { tagOf, wordsEndingAt, wordStartingAt, } from "./rules.js";
9
10
  /**
10
11
  * The adverbs {@link DEGREE} leaves out, because they scope a verb just as well.
11
12
  *
@@ -46,6 +47,27 @@ const MEASURE = "q";
46
47
  * The tag prefix a noun carries, which is what an attributive 长 modifies.
47
48
  */
48
49
  const NOUN_TAG = "n";
50
+ /**
51
+ * The mark that makes the number after it a position rather than a count.
52
+ */
53
+ const ORDINAL = "第";
54
+ /**
55
+ * Whether the 量词 in front of a position is counting an ordinal.
56
+ *
57
+ * 一个长头发的女生 has its subject spoken for by the 一个, and 第一次长胡子 does
58
+ * not: 第一次 is when the growing happened rather than what is being counted.
59
+ * The walk back over the quantity characters is the same one
60
+ * {@link import("./reading-rules.js").COUNTED_MEASURE} makes, and for the same
61
+ * reason.
62
+ */
63
+ function isOrdinalPhrase(context, at) {
64
+ const { characters } = context;
65
+ let from = at - 1;
66
+ while (from > 0 && QUANTITY_CHARACTERS.has(characters[from - 1] ?? "")) {
67
+ from--;
68
+ }
69
+ return characters[from - 1] === ORDINAL;
70
+ }
49
71
  /**
50
72
  * Whether a 长 is an adjective in front of the noun it modifies.
51
73
  *
@@ -54,13 +76,24 @@ const NOUN_TAG = "n";
54
76
  * near side has to say the rest. A 量词 or 有 in front of a 长 leaves it nothing
55
77
  * to be the verb of: 一个长头发的女生 and 兔子有长耳朵 have their subject
56
78
  * already spoken for, and 他长毛了 and 树长叶子 do not.
79
+ *
80
+ * A verb in front is **not** enough, though 他留长头发 wears long hair where
81
+ * 他长头发 grows it. jieba tags 树 a verb and 习惯 a noun, so the tag names
82
+ * neither set: taking every verb read 树长叶子 as an adjective and 教育长邓演达
83
+ * with it.
84
+ *
85
+ * Every word ending at the position is asked rather than the longest, because
86
+ * the longest is 一个 where the 量词 is the 个 inside it. See
87
+ * {@link wordsEndingAt}.
57
88
  */
58
89
  export function isAttributive(context) {
59
90
  const { edge } = context;
60
91
  if (!tagOf(context, wordStartingAt(context, edge.to)).startsWith(NOUN_TAG)) {
61
92
  return false;
62
93
  }
63
- const before = wordEndingAt(context, edge.from);
64
- return before === "有" || tagOf(context, before) === MEASURE;
94
+ if (isOrdinalPhrase(context, edge.from)) {
95
+ return false;
96
+ }
97
+ return wordsEndingAt(context, edge.from).some((word) => word === "有" || tagOf(context, word) === MEASURE);
65
98
  }
66
99
  //# sourceMappingURL=chang-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chang-context.js","sourceRoot":"","sources":["../../src/decode/chang-context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAEL,KAAK,EACL,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAoB;IAC/C,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClC,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;GAEG;AACH,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"chang-context.js","sourceRoot":"","sources":["../../src/decode/chang-context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAEL,KAAK,EACL,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAoB;IAC/C,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClC,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;GAEG;AACH,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;;GAEG;AACH,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;;;;;;;GAQG;AACH,SAAS,eAAe,CAAC,OAAoB,EAAE,EAAU;IACvD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC/B,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,GAAG,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACvE,IAAI,EAAE,CAAC;IACT,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAC3C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,OAAO,CAC3D,CAAC;AACJ,CAAC"}
@@ -11,24 +11,34 @@ import { type EdgeRule } from "./rules.js";
11
11
  * adjective, and nothing in the cost model can prefer an alternate at a
12
12
  * position no word covers: 这篇文章不太长 came out `bú tài zhǎng`.
13
13
  *
14
- * Three contexts settle it, and the first of them needs only one side. A 长
15
- * that is *growing* is a verb, and a degree adverb cannot modify one — there is
16
- * no 很长 meaning it grew a lot — so 很, 太, 最, 多 and their kin in front of a
17
- * bare 长 make it the adjective whatever follows. {@link DEGREE} is that set.
14
+ * Five contexts settle it, and one of them needs a single side. A 长 that is
15
+ * *growing* is a verb, and a degree adverb cannot modify one — there is no 很长
16
+ * meaning it grew a lot — so 很, 太, 最, 多 and their kin in front of a bare 长
17
+ * make it the adjective whatever follows. {@link DEGREE} is that set.
18
18
  *
19
- * The other two need both sides, and they are in `chang-context.ts`:
20
- * {@link isPredicated} for 那座桥不长, {@link isAttributive} for 他有长头发.
21
- * What they have in common is that the near side alone would be wrong. 不长 is
22
- * 不长在耳朵外面 as readily as it is 不长, and a noun after a 长 is 长知识 as
23
- * readily as 长头发.
19
+ * Two more read the far side alone, in `chang-complement.ts`. A quality can be
20
+ * compared, intensified and conjoined where a growing cannot, so 长一点, 长极了
21
+ * and 长而美丽 need nothing in front of them ({@link isCompared}); and a length
22
+ * can be given in metres, so 长三百公里 settles itself ({@link isMeasured}).
23
+ *
24
+ * The last two need both sides, in `chang-context.ts`: {@link isPredicated} for
25
+ * 那座桥不长, {@link isAttributive} for 他有长头发. What those two have in common
26
+ * is that the near side alone would be wrong. 不长 is 不长在耳朵外面 as readily
27
+ * as it is 不长, and a noun after a 长 is 长知识 as readily as 长头发.
24
28
  *
25
29
  * Measured over the same 88,866 lines of Tatoeba and zh.wikipedia the other
26
- * rules were sized against, 260 长 decode as a word of their own. The degree
27
- * adverbs move 75 of them to `cháng`, all 75 correctly; the two contexts added
28
- * since move 8 more, also all correct — 那座桥不长, 生命不长, 射程不长, 还长,
29
- * 生得又瘦又长, 他有长头发, 兔子有长耳朵 and 那位长胡子德国人. On CPP's 40
30
- * hand-labelled 长 the character stands at 90.00%, against 85.00% with no rule
31
- * and 87.50% with the degree adverbs alone.
30
+ * rules were sized against, 379 长 and 長 decode as a word of their own and this
31
+ * moves 125 of them to `cháng`. Nine of the 125 are 长 the run they end could
32
+ * not see past until the decode was given the 汉字 behind the digits after it,
33
+ * as 那条河长300公里 is. Every conversion the last three contexts changed is
34
+ * right: 一个长头发的女生, 一个长毛绒玩具, 没有长胡子的舅舅, 要长一点, 活长点,
35
+ * 已经长极了, 神经棘长而狭窄 and 拉得很长. On CPP's 40 hand-labelled 长 the
36
+ * character stands at 92.50%, against 85.00% with no rule at all.
37
+ *
38
+ * **A verb in front is not one of the contexts**, though 他留长头发 wears long
39
+ * hair where 他长头发 grows it. jieba tags 树 a verb and 习惯 a noun, so no tag
40
+ * names the set, and taking every verb read 树长叶子 and 教育长邓演达 as
41
+ * adjectives.
32
42
  *
33
43
  * The last piece is {@link GROWN_INTO}, which pushes the opposite way on the one
34
44
  * shape the sources get wrong.
@@ -1 +1 @@
1
- {"version":3,"file":"chang-rule.d.ts","sourceRoot":"","sources":["../../src/decode/chang-rule.ts"],"names":[],"mappings":"AASA,OAAO,EAAoB,KAAK,QAAQ,EAAgB,MAAM,YAAY,CAAC;AA2H3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAmB9B,CAAC"}
1
+ {"version":3,"file":"chang-rule.d.ts","sourceRoot":"","sources":["../../src/decode/chang-rule.ts"],"names":[],"mappings":"AAUA,OAAO,EAAoB,KAAK,QAAQ,EAAiB,MAAM,YAAY,CAAC;AA+H5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAyB9B,CAAC"}
@@ -1,5 +1,6 @@
1
+ import { isCompared, isMeasured } from "./chang-complement.js";
1
2
  import { isAttributive, isPredicated } from "./chang-context.js";
2
- import { wordEndingAt } from "./rules.js";
3
+ import { wordsEndingAt } from "./rules.js";
3
4
  /**
4
5
  * Whether a syllable is `cháng`, the stative reading of 长.
5
6
  */
@@ -22,6 +23,10 @@ function isChang(syllable) {
22
23
  * even though 距离还长 and 那座桥不长 are both `cháng`: they modify verbs as
23
24
  * readily as qualities, and 还长有毛 and 胡子不长在前额上 are the same two
24
25
  * characters around the verb.
26
+ *
27
+ * Matched against every word ending in front of the 长 rather than the longest
28
+ * one, since 得很 is a word and hides the 很 inside it. See
29
+ * {@link wordsEndingAt}.
25
30
  */
26
31
  const DEGREE = new Set([
27
32
  "一样",
@@ -124,24 +129,34 @@ function isGrowthCorrelative(context) {
124
129
  * adjective, and nothing in the cost model can prefer an alternate at a
125
130
  * position no word covers: 这篇文章不太长 came out `bú tài zhǎng`.
126
131
  *
127
- * Three contexts settle it, and the first of them needs only one side. A 长
128
- * that is *growing* is a verb, and a degree adverb cannot modify one — there is
129
- * no 很长 meaning it grew a lot — so 很, 太, 最, 多 and their kin in front of a
130
- * bare 长 make it the adjective whatever follows. {@link DEGREE} is that set.
132
+ * Five contexts settle it, and one of them needs a single side. A 长 that is
133
+ * *growing* is a verb, and a degree adverb cannot modify one — there is no 很长
134
+ * meaning it grew a lot — so 很, 太, 最, 多 and their kin in front of a bare 长
135
+ * make it the adjective whatever follows. {@link DEGREE} is that set.
136
+ *
137
+ * Two more read the far side alone, in `chang-complement.ts`. A quality can be
138
+ * compared, intensified and conjoined where a growing cannot, so 长一点, 长极了
139
+ * and 长而美丽 need nothing in front of them ({@link isCompared}); and a length
140
+ * can be given in metres, so 长三百公里 settles itself ({@link isMeasured}).
131
141
  *
132
- * The other two need both sides, and they are in `chang-context.ts`:
133
- * {@link isPredicated} for 那座桥不长, {@link isAttributive} for 他有长头发.
134
- * What they have in common is that the near side alone would be wrong. 不长 is
135
- * 不长在耳朵外面 as readily as it is 不长, and a noun after a 长 is 长知识 as
136
- * readily as 长头发.
142
+ * The last two need both sides, in `chang-context.ts`: {@link isPredicated} for
143
+ * 那座桥不长, {@link isAttributive} for 他有长头发. What those two have in common
144
+ * is that the near side alone would be wrong. 不长 is 不长在耳朵外面 as readily
145
+ * as it is 不长, and a noun after a 长 is 长知识 as readily as 长头发.
137
146
  *
138
147
  * Measured over the same 88,866 lines of Tatoeba and zh.wikipedia the other
139
- * rules were sized against, 260 长 decode as a word of their own. The degree
140
- * adverbs move 75 of them to `cháng`, all 75 correctly; the two contexts added
141
- * since move 8 more, also all correct — 那座桥不长, 生命不长, 射程不长, 还长,
142
- * 生得又瘦又长, 他有长头发, 兔子有长耳朵 and 那位长胡子德国人. On CPP's 40
143
- * hand-labelled 长 the character stands at 90.00%, against 85.00% with no rule
144
- * and 87.50% with the degree adverbs alone.
148
+ * rules were sized against, 379 长 and 長 decode as a word of their own and this
149
+ * moves 125 of them to `cháng`. Nine of the 125 are 长 the run they end could
150
+ * not see past until the decode was given the 汉字 behind the digits after it,
151
+ * as 那条河长300公里 is. Every conversion the last three contexts changed is
152
+ * right: 一个长头发的女生, 一个长毛绒玩具, 没有长胡子的舅舅, 要长一点, 活长点,
153
+ * 已经长极了, 神经棘长而狭窄 and 拉得很长. On CPP's 40 hand-labelled 长 the
154
+ * character stands at 92.50%, against 85.00% with no rule at all.
155
+ *
156
+ * **A verb in front is not one of the contexts**, though 他留长头发 wears long
157
+ * hair where 他长头发 grows it. jieba tags 树 a verb and 习惯 a noun, so no tag
158
+ * names the set, and taking every verb read 树长叶子 and 教育长邓演达 as
159
+ * adjectives.
145
160
  *
146
161
  * The last piece is {@link GROWN_INTO}, which pushes the opposite way on the one
147
162
  * shape the sources get wrong.
@@ -159,11 +174,15 @@ export const ADJECTIVAL_CHANG = {
159
174
  if (GROWING.has(characters[edge.to] ?? "")) {
160
175
  return "keep";
161
176
  }
162
- if (isPredicated(context) || isAttributive(context)) {
177
+ if (isPredicated(context) ||
178
+ isAttributive(context) ||
179
+ isCompared(context) ||
180
+ isMeasured(context)) {
163
181
  return "force";
164
182
  }
165
- const before = wordEndingAt(context, edge.from);
166
- return before !== undefined && DEGREE.has(before) ? "force" : "keep";
183
+ return wordsEndingAt(context, edge.from).some((word) => DEGREE.has(word))
184
+ ? "force"
185
+ : "keep";
167
186
  },
168
187
  };
169
188
  //# sourceMappingURL=chang-rule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chang-rule.js","sourceRoot":"","sources":["../../src/decode/chang-rule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chang-rule.js","sourceRoot":"","sources":["../../src/decode/chang-rule.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"convert-pipeline.d.ts","sourceRoot":"","sources":["../../src/decode/convert-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAU9D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAW,MAAM,aAAa,CAAC;AAE3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI5C;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GACtB,SAAS,cAAc,EAAE,CAiF3B"}
1
+ {"version":3,"file":"convert-pipeline.d.ts","sourceRoot":"","sources":["../../src/decode/convert-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAU9D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAW,MAAM,aAAa,CAAC;AAG3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI5C;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GACtB,SAAS,cAAc,EAAE,CAgF3B"}
@@ -4,7 +4,8 @@ import { readNumbersIn } from "../numerals/text.js";
4
4
  import { toCharacters } from "../script/characters.js";
5
5
  import { hintsWithin, resolveHints } from "./hints.js";
6
6
  import { splitRuns, surroundingCharacters } from "./runs.js";
7
- import { numeralBefore, surrounding, writeNumbers } from "./numbers.js";
7
+ import { surrounding, writeNumbers } from "./numbers.js";
8
+ import { contextAround } from "./run-context.js";
8
9
  import { wordsOf } from "./run-words.js";
9
10
  import { writeRun, rewrite } from "./write-run.js";
10
11
  /**
@@ -42,8 +43,7 @@ export function convertWith(decode, dictionary, text, options) {
42
43
  const within = hints === undefined
43
44
  ? undefined
44
45
  : hintsWithin(hints, starts[at] ?? 0, toCharacters(run.text).length);
45
- const said = numeralBefore(read[at - 1] ?? []);
46
- return wordsOf(decode(dictionary, run.text, said, within), dictionary, grouping);
46
+ return wordsOf(decode(dictionary, run.text, contextAround(runs, read, at), within), dictionary, grouping);
47
47
  });
48
48
  for (const [at, run] of runs.entries()) {
49
49
  const words = decoded[at] ?? [];
@@ -1 +1 @@
1
- {"version":3,"file":"convert-pipeline.js","sourceRoot":"","sources":["../../src/decode/convert-pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"convert-pipeline.js","sourceRoot":"","sources":["../../src/decode/convert-pipeline.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,26 @@ import { type EdgeRule } from "./rules.js";
28
28
  * which nothing short of semantics separates from 必须得承认.
29
29
  */
30
30
  export declare const MODAL_DE: EdgeRule;
31
+ /**
32
+ * A verb and a 得 in front of a complement is not a word reading `dé`.
33
+ *
34
+ * 他算得上一个作家 came out `suàn dé shàng`, because 算得 is a key jieba counted
35
+ * and the phrase corpus reads it `suàn dé`. In a potential complement the 得 is
36
+ * the particle: 算得上, 吃得了, 买得起 and 看得住 are all `de`, and the reading
37
+ * the key carries is the one 算得 has standing alone, which is not what a
38
+ * complement leaves it doing.
39
+ *
40
+ * Both sides are needed and neither is enough. A verb before the 得 rules out
41
+ * 只得上山 and 不得下车, where the 得 belongs to an adverb and the character
42
+ * after it starts a verb phrase of its own; the complement after it rules out
43
+ * 取得上级批准, where 上 is the first character of 上级 rather than a complement.
44
+ * That second test is why the complement has to be the whole of the word
45
+ * starting there.
46
+ *
47
+ * Over the 88,866 lines it changes 5 conversions and all 5 are 算得上, which is
48
+ * the only word of this shape the corpus holds. CPP does not move.
49
+ */
50
+ export declare const POTENTIAL_DE: EdgeRule;
31
51
  /**
32
52
  * A word beginning with 的 does not start where the particle 的 does.
33
53
  *
@@ -1 +1 @@
1
- {"version":3,"file":"de-rule.d.ts","sourceRoot":"","sources":["../../src/decode/de-rule.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,QAAQ,EAId,MAAM,YAAY,CAAC;AAgCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,QAAQ,EAAE,QActB,CAAC;AAWF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,WAAW,EAAE,QAczB,CAAC"}
1
+ {"version":3,"file":"de-rule.d.ts","sourceRoot":"","sources":["../../src/decode/de-rule.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,QAAQ,EAKd,MAAM,YAAY,CAAC;AAgCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,QAAQ,EAAE,QActB,CAAC;AAkDF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,EAAE,QAoB1B,CAAC;AAWF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,WAAW,EAAE,QAczB,CAAC"}
@@ -1,4 +1,13 @@
1
- import { tagOf, wordEndingAt, wordStartingAt, } from "./rules.js";
1
+ /**
2
+ * The two rules about 得 and 的, which are one character each and three jobs.
3
+ *
4
+ * 得 is stored as the structural particle with `dé` and `děi` as alternates,
5
+ * and 的 is stored as the particle full stop. Both are among the commonest
6
+ * characters in the language, so the words they begin and end are numerous and
7
+ * mostly wrong.
8
+ */
9
+ import { toCharacters } from "../script/characters.js";
10
+ import { tagOf, wordEndingAt, wordStartingAt, wordsStartingAt, } from "./rules.js";
2
11
  /**
3
12
  * Whether a syllable is `děi`, the modal reading of 得.
4
13
  *
@@ -67,6 +76,83 @@ export const MODAL_DE = {
67
76
  : "keep";
68
77
  },
69
78
  };
79
+ /**
80
+ * What a potential complement is made of, after the 得 that marks it.
81
+ *
82
+ * 算得上, 买得起, 看得住, 说得过去. The complement is a resultative or a
83
+ * directional, and this is the closed set of the ones that take a 得 in front of
84
+ * them rather than a verb of their own.
85
+ *
86
+ * 了 and 过 are deliberately absent, and for the same reason: both are aspect
87
+ * markers as well as complements, and the aspect is the commoner by a wide
88
+ * margin. Over 88,866 lines of Tatoeba and zh.wikipedia, including 了 broke 70
89
+ * conversions and fixed none — 获得了, 取得了 and 赢得了 all became 获 得 了 —
90
+ * and 过 broke 赢得过 twice. 吃得了 and 说得过去 are the shapes that gives up.
91
+ */
92
+ const COMPLEMENTS = new Set(["上", "起", "下", "住"]);
93
+ /**
94
+ * The tag prefix jieba gives a verb, which is what a complement attaches to.
95
+ */
96
+ const VERB_TAG = "v";
97
+ /**
98
+ * Whether a syllable is `dé`, the reading 得 takes as a verb of its own.
99
+ */
100
+ function isDe(syllable) {
101
+ return (syllable?.initial === "d" && syllable.final === "e" && syllable.tone === 2);
102
+ }
103
+ /**
104
+ * Whether a word starting at the complement takes it away from the 得.
105
+ *
106
+ * The one thing that separates 算得上一个作家 from 取得上级批准, since both put a
107
+ * verb, a 得 and a 上 in the same order. 上级 is a word and nothing follows it
108
+ * that starts another, so the 上 belongs to it; 上道 is also a word, but 道歉
109
+ * follows and is the better claim on the 道, so the 上 is left to the 得.
110
+ *
111
+ * Only multi-character words are asked, because every character is a word of its
112
+ * own and a test that counted those would answer yes everywhere.
113
+ */
114
+ function isSwallowed(context, at) {
115
+ const longer = (from) => wordsStartingAt(context, from).some((word) => toCharacters(word).length > 1);
116
+ return longer(at) && !longer(at + 1);
117
+ }
118
+ /**
119
+ * A verb and a 得 in front of a complement is not a word reading `dé`.
120
+ *
121
+ * 他算得上一个作家 came out `suàn dé shàng`, because 算得 is a key jieba counted
122
+ * and the phrase corpus reads it `suàn dé`. In a potential complement the 得 is
123
+ * the particle: 算得上, 吃得了, 买得起 and 看得住 are all `de`, and the reading
124
+ * the key carries is the one 算得 has standing alone, which is not what a
125
+ * complement leaves it doing.
126
+ *
127
+ * Both sides are needed and neither is enough. A verb before the 得 rules out
128
+ * 只得上山 and 不得下车, where the 得 belongs to an adverb and the character
129
+ * after it starts a verb phrase of its own; the complement after it rules out
130
+ * 取得上级批准, where 上 is the first character of 上级 rather than a complement.
131
+ * That second test is why the complement has to be the whole of the word
132
+ * starting there.
133
+ *
134
+ * Over the 88,866 lines it changes 5 conversions and all 5 are 算得上, which is
135
+ * the only word of this shape the corpus holds. CPP does not move.
136
+ */
137
+ export const POTENTIAL_DE = {
138
+ name: "potential-de",
139
+ verdictFor: (context) => {
140
+ const { characters, edge } = context;
141
+ if (edge.to - edge.from !== 2 ||
142
+ edge.text.at(-1) !== "得" ||
143
+ edge.reading.length !== 2 ||
144
+ !isDe(edge.reading[1])) {
145
+ return "keep";
146
+ }
147
+ if (!tagOf(context, characters[edge.from]).startsWith(VERB_TAG)) {
148
+ return "keep";
149
+ }
150
+ return COMPLEMENTS.has(characters[edge.to] ?? "") &&
151
+ !isSwallowed(context, edge.to)
152
+ ? "forbid"
153
+ : "keep";
154
+ },
155
+ };
70
156
  /**
71
157
  * The tags a word carries when the 的 after it is the structural particle.
72
158
  *
@@ -1 +1 @@
1
- {"version":3,"file":"de-rule.js","sourceRoot":"","sources":["../../src/decode/de-rule.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,EACL,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,SAAS,KAAK,CAAC,QAA8B;IAC3C,OAAO,CACL,QAAQ,EAAE,OAAO,KAAK,GAAG,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,eAAe,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAa;IAChC,IAAI,EAAE,UAAU;IAChB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7C,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACzC,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAa;IACnC,IAAI,EAAE,aAAa;IACnB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,IACE,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;YACvB,IAAI,CAAC,YAAY,KAAK,EAAE;YACxB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAC1B,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IACxE,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"de-rule.js","sourceRoot":"","sources":["../../src/decode/de-rule.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,15 @@
1
+ /**
2
+ * Decoding a Han run into words: the two entry points a caller reaches for.
3
+ *
4
+ * The sweeps over the lattice itself are in `lattice-decode.ts`, and are
5
+ * re-exported here so that the decoder's parts stay one import away.
6
+ */
1
7
  import type { Dictionary } from "../dictionary/dictionary.js";
2
8
  import type { ResolvedHints } from "./hints.js";
3
- import { type Lattice } from "./lattice.js";
4
- import { type ReadingProjection, type ReadingUnit } from "./locking.js";
5
9
  import type { EdgeRule } from "./rules.js";
6
10
  import type { DecodedWord, ScoredWord } from "./word.js";
7
- /**
8
- * Decode the run's readings, scoring only where the readings are still open.
9
- *
10
- * The asymmetry ALGORITHM.md calls for. A stretch between two cut points whose
11
- * positions all locked reads the same way on every path, so its readings are
12
- * read off the locks and no shortest path is run over it at all. Only the
13
- * stretches with a genuine choice in them are decoded.
14
- */
15
- export declare function decodeReadings(lattice: Lattice, projection: ReadingProjection): readonly ReadingUnit[];
16
- /**
17
- * Where a decode would put the word boundaries, as character positions.
18
- *
19
- * Run over the whole lattice rather than the open stretches, because spacing
20
- * stays ambiguous where readings do not: 研究生命起源 reads identically whether
21
- * it splits 研究生/命 or 研究/生命, so every position in it locks, and the
22
- * spacing question is still open.
23
- */
24
- export declare function decodeSpacing(lattice: Lattice): readonly number[];
25
- export declare function decodeRun(dictionary: Dictionary, run: string, rules?: readonly EdgeRule[], before?: string, hints?: ResolvedHints): readonly DecodedWord[];
11
+ export { decodeReadings, decodeSpacing } from "./lattice-decode.js";
12
+ export declare function decodeRun(dictionary: Dictionary, run: string, rules?: readonly EdgeRule[], before?: string, hints?: ResolvedHints, after?: string): readonly DecodedWord[];
26
13
  /**
27
14
  * Decode a Han run, keeping what each reading was chosen over.
28
15
  *
@@ -31,9 +18,9 @@ export declare function decodeRun(dictionary: Dictionary, run: string, rules?: r
31
18
  * only worth running for a caller that will use the answer — rendering
32
19
  * uncertain readings differently, or reporting them.
33
20
  *
34
- * `before` is the context {@link decodeRun} takes, and means the same here: it
35
- * is decoded with the run and reported with neither words nor confidence of its
36
- * own.
21
+ * `before` and `after` are the context {@link decodeRun} takes, and mean the
22
+ * same here: they are decoded with the run and reported with neither words nor
23
+ * confidence of their own.
37
24
  */
38
- export declare function decodeRunScored(dictionary: Dictionary, run: string, rules?: readonly EdgeRule[], before?: string, hints?: ResolvedHints): readonly ScoredWord[];
25
+ export declare function decodeRunScored(dictionary: Dictionary, run: string, rules?: readonly EdgeRule[], before?: string, hints?: ResolvedHints, after?: string): readonly ScoredWord[];
39
26
  //# sourceMappingURL=decode.d.ts.map