@kensio/pinyinjs 1.9.3 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/core.entries +3 -3
- package/data/full.entries +10423 -10423
- package/data/manifest.json +6 -6
- package/data/standard.entries +1148 -1148
- package/dist/decode/cai-rule.d.ts +25 -0
- package/dist/decode/cai-rule.d.ts.map +1 -0
- package/dist/decode/cai-rule.js +78 -0
- package/dist/decode/cai-rule.js.map +1 -0
- package/dist/decode/dou-rule.d.ts +23 -0
- package/dist/decode/dou-rule.d.ts.map +1 -0
- package/dist/decode/dou-rule.js +40 -0
- package/dist/decode/dou-rule.js.map +1 -0
- package/dist/decode/erhua-rule.d.ts +26 -0
- package/dist/decode/erhua-rule.d.ts.map +1 -0
- package/dist/decode/erhua-rule.js +34 -0
- package/dist/decode/erhua-rule.js.map +1 -0
- package/dist/decode/ge-rule.d.ts +23 -0
- package/dist/decode/ge-rule.d.ts.map +1 -0
- package/dist/decode/ge-rule.js +77 -0
- package/dist/decode/ge-rule.js.map +1 -0
- package/dist/decode/mei-rule.d.ts +22 -0
- package/dist/decode/mei-rule.d.ts.map +1 -0
- package/dist/decode/mei-rule.js +95 -0
- package/dist/decode/mei-rule.js.map +1 -0
- package/dist/decode/name-count-rule.d.ts +15 -0
- package/dist/decode/name-count-rule.d.ts.map +1 -0
- package/dist/decode/name-count-rule.js +81 -0
- package/dist/decode/name-count-rule.js.map +1 -0
- package/dist/decode/polyphone-rules.d.ts +3 -1
- package/dist/decode/polyphone-rules.d.ts.map +1 -1
- package/dist/decode/polyphone-rules.js +3 -1
- package/dist/decode/polyphone-rules.js.map +1 -1
- package/dist/decode/reading-rules.d.ts +5 -22
- package/dist/decode/reading-rules.d.ts.map +1 -1
- package/dist/decode/reading-rules.js +15 -35
- package/dist/decode/reading-rules.js.map +1 -1
- package/dist/dictionary/entry-invariants.d.ts.map +1 -1
- package/dist/dictionary/entry-invariants.js +16 -13
- package/dist/dictionary/entry-invariants.js.map +1 -1
- package/dist/dictionary/merge-types.d.ts +3 -0
- package/dist/dictionary/merge-types.d.ts.map +1 -1
- package/dist/dictionary/merge-types.js.map +1 -1
- package/dist/dictionary/merge-word.d.ts.map +1 -1
- package/dist/dictionary/merge-word.js +2 -2
- package/dist/dictionary/merge-word.js.map +1 -1
- package/dist/dictionary/merge.d.ts.map +1 -1
- package/dist/dictionary/merge.js +2 -0
- package/dist/dictionary/merge.js.map +1 -1
- package/dist/dictionary/proper-noun.d.ts +14 -1
- package/dist/dictionary/proper-noun.d.ts.map +1 -1
- package/dist/dictionary/proper-noun.js +46 -7
- package/dist/dictionary/proper-noun.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/sources/cedict.d.ts +8 -0
- package/dist/sources/cedict.d.ts.map +1 -1
- package/dist/sources/cedict.js +11 -0
- package/dist/sources/cedict.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 才能 that is 才 *only then* and 能 *can*, and not the noun *talent*.
|
|
3
|
+
*
|
|
4
|
+
* 才能 is a word, *talent* or *ability*, and every source counts it. The same
|
|
5
|
+
* two characters are far more often the adverb 才 and the modal 能 in front of
|
|
6
|
+
* a verb: 怎样才能提高爆发力, 必须先完成这件事才能回家, 到北方才能吃到真正的饺子.
|
|
7
|
+
* The decode read every one of them as the noun.
|
|
8
|
+
*/
|
|
9
|
+
import { type EdgeRule } from "./rules.js";
|
|
10
|
+
/**
|
|
11
|
+
* 才能 is taken apart where a verb is left for 能 to be the modal of.
|
|
12
|
+
*
|
|
13
|
+
* The noun is kept after a 的 or a 有, and before a 的, a 是, a degree word or
|
|
14
|
+
* the end of the run.
|
|
15
|
+
* Everywhere else the 才 is the adverb and the 能 the modal. Taking the edge
|
|
16
|
+
* away leaves the two to read as themselves. The readings are `cái néng`
|
|
17
|
+
* either way, so this changes the segmentation and the spacing.
|
|
18
|
+
*
|
|
19
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
20
|
+
* sentences, the decode read 才能 as the word in 184 runs. The rule splits 164,
|
|
21
|
+
* and one of them is wrong: 他的钢琴才能为他在音乐专家中赢得了美名 is talent before a
|
|
22
|
+
* 为 that reads like a verb.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MODAL_CAI: EdgeRule;
|
|
25
|
+
//# sourceMappingURL=cai-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cai-rule.d.ts","sourceRoot":"","sources":["../../src/decode/cai-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,QAAQ,EAId,MAAM,YAAY,CAAC;AAwDpB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,EAAE,QAUvB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 才能 that is 才 *only then* and 能 *can*, and not the noun *talent*.
|
|
3
|
+
*
|
|
4
|
+
* 才能 is a word, *talent* or *ability*, and every source counts it. The same
|
|
5
|
+
* two characters are far more often the adverb 才 and the modal 能 in front of
|
|
6
|
+
* a verb: 怎样才能提高爆发力, 必须先完成这件事才能回家, 到北方才能吃到真正的饺子.
|
|
7
|
+
* The decode read every one of them as the noun.
|
|
8
|
+
*/
|
|
9
|
+
import { tagOf, wordsEndingAt, wordsStartingAt, } from "./rules.js";
|
|
10
|
+
/**
|
|
11
|
+
* The word, in both scripts.
|
|
12
|
+
*/
|
|
13
|
+
const TALENT = new Set(["才能"]);
|
|
14
|
+
/**
|
|
15
|
+
* The characters that close a word in front of the noun.
|
|
16
|
+
*
|
|
17
|
+
* 的 makes 才能 something owned or described (他的才能, 一定的才能), and 有 is
|
|
18
|
+
* having it (有才能, 富有才能, 具有才能, 很有才能). 才 and 能 can follow neither.
|
|
19
|
+
*/
|
|
20
|
+
const BEFORE_NOUN = new Set(["的", "有"]);
|
|
21
|
+
/**
|
|
22
|
+
* What can follow the noun and not the modal.
|
|
23
|
+
*
|
|
24
|
+
* 能 needs a verb after it, so a 的 (有才能的人) or the end of the run (你很有才能,
|
|
25
|
+
* 她具有卓越才能) leaves it nothing to be the modal of. A 是 or a degree word
|
|
26
|
+
* says something about the talent (音乐才能是可以培养的, 她的唱歌才能非常出众).
|
|
27
|
+
*/
|
|
28
|
+
const AFTER_NOUN = new Set(["的", "是", "很", "非常", "十分"]);
|
|
29
|
+
/**
|
|
30
|
+
* Whether a longer word ends at the 才, and would take it once 才能 is gone.
|
|
31
|
+
*
|
|
32
|
+
* 处方才能买 is 处方 and then 才能, and taking the edge away let 方才 *just
|
|
33
|
+
* now* take the 才, reading 处方 as `chù fāng`. 刚才能 and 人才能 have the same
|
|
34
|
+
* shape. Which word the 才 belongs to there is a question this rule cannot
|
|
35
|
+
* answer, so it leaves the decode as it was. Only a tagged word counts, since
|
|
36
|
+
* the full tier holds untagged keys such as 时才 that no decode would choose.
|
|
37
|
+
*/
|
|
38
|
+
function isClaimed(context, from) {
|
|
39
|
+
return wordsEndingAt(context, from + 1).some((word) => word.length > 1 && tagOf(context, word) !== "");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whether the context at a 才能 says it is the noun.
|
|
43
|
+
*/
|
|
44
|
+
function isNoun(context, from, to) {
|
|
45
|
+
if (wordsEndingAt(context, from).some((word) => BEFORE_NOUN.has(word.at(-1) ?? ""))) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
// Every word starting there is asked, since the longest hides the one the
|
|
49
|
+
// rule is looking for: 音乐才能是否可以培养 has 是否 wrapped around its 是.
|
|
50
|
+
const next = wordsStartingAt(context, to);
|
|
51
|
+
return next.length === 0 || next.some((word) => AFTER_NOUN.has(word));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 才能 is taken apart where a verb is left for 能 to be the modal of.
|
|
55
|
+
*
|
|
56
|
+
* The noun is kept after a 的 or a 有, and before a 的, a 是, a degree word or
|
|
57
|
+
* the end of the run.
|
|
58
|
+
* Everywhere else the 才 is the adverb and the 能 the modal. Taking the edge
|
|
59
|
+
* away leaves the two to read as themselves. The readings are `cái néng`
|
|
60
|
+
* either way, so this changes the segmentation and the spacing.
|
|
61
|
+
*
|
|
62
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
63
|
+
* sentences, the decode read 才能 as the word in 184 runs. The rule splits 164,
|
|
64
|
+
* and one of them is wrong: 他的钢琴才能为他在音乐专家中赢得了美名 is talent before a
|
|
65
|
+
* 为 that reads like a verb.
|
|
66
|
+
*/
|
|
67
|
+
export const MODAL_CAI = {
|
|
68
|
+
name: "modal-cai",
|
|
69
|
+
verdictFor: (context) => {
|
|
70
|
+
const { edge } = context;
|
|
71
|
+
return TALENT.has(edge.text) &&
|
|
72
|
+
!isClaimed(context, edge.from) &&
|
|
73
|
+
!isNoun(context, edge.from, edge.to)
|
|
74
|
+
? "forbid"
|
|
75
|
+
: "keep";
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=cai-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cai-rule.js","sourceRoot":"","sources":["../../src/decode/cai-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAGL,KAAK,EACL,aAAa,EACb,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAExD;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,OAAoB,EAAE,IAAY;IACnD,OAAO,aAAa,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAC1C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CACzD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,OAAoB,EAAE,IAAY,EAAE,EAAU;IAC5D,IACE,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACzC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CACnC,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,0EAA0E;IAC1E,+DAA+D;IAC/D,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAa;IACjC,IAAI,EAAE,WAAW;IACjB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1B,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;YAC9B,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACpC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 都 that is the adverb *all*, read into a place name in front of it.
|
|
3
|
+
*
|
|
4
|
+
* 花都 is a district of Guangzhou, `Huādū`, and the dictionary holds it as a
|
|
5
|
+
* proper noun. In running text it is nearly always 花 *flowers* and 都 *all*:
|
|
6
|
+
* 花都开了, 公园里的花都开了, 所有的花都是纸做的. The decode read the name,
|
|
7
|
+
* capital and `dū` included.
|
|
8
|
+
*/
|
|
9
|
+
import { type EdgeRule } from "./rules.js";
|
|
10
|
+
/**
|
|
11
|
+
* 花都 is taken apart where no noun follows it.
|
|
12
|
+
*
|
|
13
|
+
* The district names what it holds: 花都区, 花都机场. Where a verb, an
|
|
14
|
+
* adverb, a 是 or the end of the run follows, the 都 is the adverb and sums up
|
|
15
|
+
* the flowers. Taking the edge away leaves 花 and 都 to read as themselves,
|
|
16
|
+
* `huā dōu`.
|
|
17
|
+
*
|
|
18
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
19
|
+
* sentences, the decode read 花都 as the name in 11 runs, and none of them was
|
|
20
|
+
* the district.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SUMMING_DOU: EdgeRule;
|
|
23
|
+
//# sourceMappingURL=dou-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dou-rule.d.ts","sourceRoot":"","sources":["../../src/decode/dou-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,QASzB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 都 that is the adverb *all*, read into a place name in front of it.
|
|
3
|
+
*
|
|
4
|
+
* 花都 is a district of Guangzhou, `Huādū`, and the dictionary holds it as a
|
|
5
|
+
* proper noun. In running text it is nearly always 花 *flowers* and 都 *all*:
|
|
6
|
+
* 花都开了, 公园里的花都开了, 所有的花都是纸做的. The decode read the name,
|
|
7
|
+
* capital and `dū` included.
|
|
8
|
+
*/
|
|
9
|
+
import { tagOf, wordStartingAt, } from "./rules.js";
|
|
10
|
+
/**
|
|
11
|
+
* The place names whose first character is a common noun that 都 can sum up.
|
|
12
|
+
*/
|
|
13
|
+
const NAMES = new Set(["花都"]);
|
|
14
|
+
/**
|
|
15
|
+
* The tag prefix jieba gives a noun.
|
|
16
|
+
*/
|
|
17
|
+
const NOUN_TAG = "n";
|
|
18
|
+
/**
|
|
19
|
+
* 花都 is taken apart where no noun follows it.
|
|
20
|
+
*
|
|
21
|
+
* The district names what it holds: 花都区, 花都机场. Where a verb, an
|
|
22
|
+
* adverb, a 是 or the end of the run follows, the 都 is the adverb and sums up
|
|
23
|
+
* the flowers. Taking the edge away leaves 花 and 都 to read as themselves,
|
|
24
|
+
* `huā dōu`.
|
|
25
|
+
*
|
|
26
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
27
|
+
* sentences, the decode read 花都 as the name in 11 runs, and none of them was
|
|
28
|
+
* the district.
|
|
29
|
+
*/
|
|
30
|
+
export const SUMMING_DOU = {
|
|
31
|
+
name: "summing-dou",
|
|
32
|
+
verdictFor: (context) => {
|
|
33
|
+
const { edge } = context;
|
|
34
|
+
return NAMES.has(edge.text) &&
|
|
35
|
+
!tagOf(context, wordStartingAt(context, edge.to)).startsWith(NOUN_TAG)
|
|
36
|
+
? "forbid"
|
|
37
|
+
: "keep";
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=dou-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dou-rule.js","sourceRoot":"","sources":["../../src/decode/dou-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAGL,KAAK,EACL,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAE9B;;GAEG;AACH,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;;;;;;;;;;;GAWG;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,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACzB,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;YACtE,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 儿 that belongs to the word in front of it.
|
|
3
|
+
*/
|
|
4
|
+
import type { EdgeRule } from "./rules.js";
|
|
5
|
+
/**
|
|
6
|
+
* 儿 does not stand on its own where the dictionary attests the 儿化.
|
|
7
|
+
*
|
|
8
|
+
* 儿化 is a per-word dictionary fact taken from CC-CEDICT's explicit `r5`
|
|
9
|
+
* token, and 2,009 of the 2,067 keys ending in 儿 carry it. What that leaves is
|
|
10
|
+
* an edge: 这边儿, 上边儿 and 旁边儿 are all listed and 那边儿 is not, so
|
|
11
|
+
* 我得跑到那边儿去 read the 儿 as a syllable of its own — `nàbian ér` — and the
|
|
12
|
+
* decode was choosing between 那边 plus 儿 and 那 plus 边儿 on frequency alone.
|
|
13
|
+
*
|
|
14
|
+
* This forbids the bare 儿 edge when the character in front of it makes an
|
|
15
|
+
* attested 儿化 word, so the only paths left are the ones that absorb it. That
|
|
16
|
+
* asserts nothing the dictionary does not already say — 边儿 is `biānr` because
|
|
17
|
+
* CC-CEDICT says so — which is what separates it from synthesising 儿化 with a
|
|
18
|
+
* suffix rule, the thing ORTHOGRAPHY.md rejects and the old project got wrong.
|
|
19
|
+
*
|
|
20
|
+
* Measured over the same 88,866 lines it fires 7 times, and all 7 are right:
|
|
21
|
+
* 照片儿, 出门儿, 热点儿, 辣味儿, 晚会儿, 针管儿, 碍事儿. It is deliberately
|
|
22
|
+
* silent on the 20 bare 儿 with no attested 儿化 behind them, which are 马儿,
|
|
23
|
+
* 门铃儿 and a row of Mongol names transliterated with 儿.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ATTESTED_ERHUA: EdgeRule;
|
|
26
|
+
//# sourceMappingURL=erhua-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erhua-rule.d.ts","sourceRoot":"","sources":["../../src/decode/erhua-rule.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,cAAc,EAAE,QAY5B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 儿 does not stand on its own where the dictionary attests the 儿化.
|
|
3
|
+
*
|
|
4
|
+
* 儿化 is a per-word dictionary fact taken from CC-CEDICT's explicit `r5`
|
|
5
|
+
* token, and 2,009 of the 2,067 keys ending in 儿 carry it. What that leaves is
|
|
6
|
+
* an edge: 这边儿, 上边儿 and 旁边儿 are all listed and 那边儿 is not, so
|
|
7
|
+
* 我得跑到那边儿去 read the 儿 as a syllable of its own — `nàbian ér` — and the
|
|
8
|
+
* decode was choosing between 那边 plus 儿 and 那 plus 边儿 on frequency alone.
|
|
9
|
+
*
|
|
10
|
+
* This forbids the bare 儿 edge when the character in front of it makes an
|
|
11
|
+
* attested 儿化 word, so the only paths left are the ones that absorb it. That
|
|
12
|
+
* asserts nothing the dictionary does not already say — 边儿 is `biānr` because
|
|
13
|
+
* CC-CEDICT says so — which is what separates it from synthesising 儿化 with a
|
|
14
|
+
* suffix rule, the thing ORTHOGRAPHY.md rejects and the old project got wrong.
|
|
15
|
+
*
|
|
16
|
+
* Measured over the same 88,866 lines it fires 7 times, and all 7 are right:
|
|
17
|
+
* 照片儿, 出门儿, 热点儿, 辣味儿, 晚会儿, 针管儿, 碍事儿. It is deliberately
|
|
18
|
+
* silent on the 20 bare 儿 with no attested 儿化 behind them, which are 马儿,
|
|
19
|
+
* 门铃儿 and a row of Mongol names transliterated with 儿.
|
|
20
|
+
*/
|
|
21
|
+
export const ATTESTED_ERHUA = {
|
|
22
|
+
name: "attested-erhua",
|
|
23
|
+
verdictFor: (context) => {
|
|
24
|
+
const { characters, edge } = context;
|
|
25
|
+
if (edge.text !== "儿" || edge.from === 0) {
|
|
26
|
+
return "keep";
|
|
27
|
+
}
|
|
28
|
+
/* c8 ignore next -- the edge starts inside the run it was built from */
|
|
29
|
+
const absorbed = `${characters[edge.from - 1] ?? ""}儿`;
|
|
30
|
+
const reading = context.dictionary.lookup(absorbed)?.reading;
|
|
31
|
+
return (reading?.at(-1)?.erhua ?? false) ? "forbid" : "keep";
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=erhua-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erhua-rule.js","sourceRoot":"","sources":["../../src/decode/erhua-rule.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAa;IACtC,IAAI,EAAE,gBAAgB;IACtB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACrC,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,wEAAwE;QACxE,MAAM,QAAQ,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC;QACvD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC7D,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 个人 whose 个 is counting one 人, and not the word *individual*.
|
|
3
|
+
*
|
|
4
|
+
* {@link import("./measure-rule.js").COUNTED_MEASURE} takes 个人 apart after a
|
|
5
|
+
* number, so 三个人 is three people. A bare 个 with no number at all stands for
|
|
6
|
+
* 一个 after a verb that introduces somebody, and the measure rule has nothing
|
|
7
|
+
* to go on there: 门口有个人, 想找个人聊聊天, 我今天雇了个人.
|
|
8
|
+
*/
|
|
9
|
+
import { type EdgeRule } from "./rules.js";
|
|
10
|
+
/**
|
|
11
|
+
* 个人 is taken apart where an introducing verb makes its 个 count one 人.
|
|
12
|
+
*
|
|
13
|
+
* Taking the edge away leaves 个 and 人 to read as themselves. The readings
|
|
14
|
+
* are `gè rén` either way, so this changes the segmentation and the spacing.
|
|
15
|
+
*
|
|
16
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
17
|
+
* sentences, the decode kept 个人 as one word in 61 runs. The rule splits 12,
|
|
18
|
+
* and every one of them is somebody. A rough number in front (十几个人,
|
|
19
|
+
* 一百多个人) is left alone, because taking the edge away there moves the 个
|
|
20
|
+
* onto the 几 and reads 十 几个 人.
|
|
21
|
+
*/
|
|
22
|
+
export declare const COUNTED_GE: EdgeRule;
|
|
23
|
+
//# sourceMappingURL=ge-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ge-rule.d.ts","sourceRoot":"","sources":["../../src/decode/ge-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,YAAY,CAAC;AAoDpB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,EAAE,QASxB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 个人 whose 个 is counting one 人, and not the word *individual*.
|
|
3
|
+
*
|
|
4
|
+
* {@link import("./measure-rule.js").COUNTED_MEASURE} takes 个人 apart after a
|
|
5
|
+
* number, so 三个人 is three people. A bare 个 with no number at all stands for
|
|
6
|
+
* 一个 after a verb that introduces somebody, and the measure rule has nothing
|
|
7
|
+
* to go on there: 门口有个人, 想找个人聊聊天, 我今天雇了个人.
|
|
8
|
+
*/
|
|
9
|
+
import { tagOf, wordStartingAt, } from "./rules.js";
|
|
10
|
+
/**
|
|
11
|
+
* The word, in both scripts.
|
|
12
|
+
*/
|
|
13
|
+
const INDIVIDUAL = new Set(["个人", "個人"]);
|
|
14
|
+
/**
|
|
15
|
+
* The verbs that bring an unnamed somebody into a sentence.
|
|
16
|
+
*
|
|
17
|
+
* 有个人 is *somebody*, 找个人 and 叫个人 are finding and sending one, 雇了个人
|
|
18
|
+
* is hiring one and 换了个人 is becoming somebody else.
|
|
19
|
+
*/
|
|
20
|
+
const INTRODUCING = new Set([
|
|
21
|
+
"有",
|
|
22
|
+
"找",
|
|
23
|
+
"叫",
|
|
24
|
+
"请",
|
|
25
|
+
"請",
|
|
26
|
+
"雇",
|
|
27
|
+
"换",
|
|
28
|
+
"換",
|
|
29
|
+
"派",
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* The aspect particle that can sit between the verb and the 个.
|
|
33
|
+
*/
|
|
34
|
+
const PERFECTIVE = "了";
|
|
35
|
+
/**
|
|
36
|
+
* The tag prefix jieba gives a noun.
|
|
37
|
+
*/
|
|
38
|
+
const NOUN_TAG = "n";
|
|
39
|
+
/**
|
|
40
|
+
* Whether a verb that introduces somebody stands in front of a 个人, with or
|
|
41
|
+
* without a 了 after it.
|
|
42
|
+
*
|
|
43
|
+
* The word after the 个人 is asked about too. 个人 in front of a noun is the
|
|
44
|
+
* modifier *personal* (我有个人问题, 有个人信息), and only a verb, a particle
|
|
45
|
+
* or the end of the run leaves the 人 to be the person.
|
|
46
|
+
*/
|
|
47
|
+
function isIntroduced(context, from, to) {
|
|
48
|
+
const { characters } = context;
|
|
49
|
+
const verb = characters[from - 1] === PERFECTIVE ? from - 2 : from - 1;
|
|
50
|
+
if (!INTRODUCING.has(characters[verb] ?? "")) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return !tagOf(context, wordStartingAt(context, to)).startsWith(NOUN_TAG);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 个人 is taken apart where an introducing verb makes its 个 count one 人.
|
|
57
|
+
*
|
|
58
|
+
* Taking the edge away leaves 个 and 人 to read as themselves. The readings
|
|
59
|
+
* are `gè rén` either way, so this changes the segmentation and the spacing.
|
|
60
|
+
*
|
|
61
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
62
|
+
* sentences, the decode kept 个人 as one word in 61 runs. The rule splits 12,
|
|
63
|
+
* and every one of them is somebody. A rough number in front (十几个人,
|
|
64
|
+
* 一百多个人) is left alone, because taking the edge away there moves the 个
|
|
65
|
+
* onto the 几 and reads 十 几个 人.
|
|
66
|
+
*/
|
|
67
|
+
export const COUNTED_GE = {
|
|
68
|
+
name: "counted-ge",
|
|
69
|
+
verdictFor: (context) => {
|
|
70
|
+
const { edge } = context;
|
|
71
|
+
return INDIVIDUAL.has(edge.text) &&
|
|
72
|
+
isIntroduced(context, edge.from, edge.to)
|
|
73
|
+
? "forbid"
|
|
74
|
+
: "keep";
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=ge-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ge-rule.js","sourceRoot":"","sources":["../../src/decode/ge-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAGL,KAAK,EACL,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;CACJ,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB;;GAEG;AACH,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,OAAoB,EAAE,IAAY,EAAE,EAAU;IAClE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACvE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC7C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,IAAI,EAAE,YAAY;IAClB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9B,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACzC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 美的 that is an adjective and its 的, and not the brand.
|
|
3
|
+
*
|
|
4
|
+
* 美的 is a word, the name of the appliance maker read `Měidí`, and the
|
|
5
|
+
* dictionary holds it as a proper noun. The same two characters are far more
|
|
6
|
+
* often 美 *beautiful* and the particle after it: 最美的姑娘, 很美的动物, 多美的日出.
|
|
7
|
+
* The decode took the name every time, so a learner's sentence about a
|
|
8
|
+
* sunrise came out with a capitalised `Měidí` in it.
|
|
9
|
+
*/
|
|
10
|
+
import { type EdgeRule } from "./rules.js";
|
|
11
|
+
/**
|
|
12
|
+
* 美的 is taken apart where a degree word or a 是 grades it.
|
|
13
|
+
*
|
|
14
|
+
* Taking the edge away leaves 美 and 的 to read as themselves, `měi de`, which
|
|
15
|
+
* is the reading as well as the spacing: the name's 的 is `dí`.
|
|
16
|
+
*
|
|
17
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
18
|
+
* sentences, the decode read 美的 as the name in 28 runs and none of them was
|
|
19
|
+
* the company.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ADJECTIVAL_MEI: EdgeRule;
|
|
22
|
+
//# sourceMappingURL=mei-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mei-rule.d.ts","sourceRoot":"","sources":["../../src/decode/mei-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAEL,KAAK,QAAQ,EAId,MAAM,YAAY,CAAC;AA0EpB;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,QAQ5B,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 美的 that is an adjective and its 的, and not the brand.
|
|
3
|
+
*
|
|
4
|
+
* 美的 is a word, the name of the appliance maker read `Měidí`, and the
|
|
5
|
+
* dictionary holds it as a proper noun. The same two characters are far more
|
|
6
|
+
* often 美 *beautiful* and the particle after it: 最美的姑娘, 很美的动物, 多美的日出.
|
|
7
|
+
* The decode took the name every time, so a learner's sentence about a
|
|
8
|
+
* sunrise came out with a capitalised `Měidí` in it.
|
|
9
|
+
*/
|
|
10
|
+
import { tagOf, wordStartingAt, wordsEndingAt, } from "./rules.js";
|
|
11
|
+
/**
|
|
12
|
+
* The word, in both scripts.
|
|
13
|
+
*/
|
|
14
|
+
const BRAND = new Set(["美的"]);
|
|
15
|
+
/**
|
|
16
|
+
* The words that grade or assert an adjective, in both scripts.
|
|
17
|
+
*
|
|
18
|
+
* Each one says something about how beautiful a thing is, and a company name
|
|
19
|
+
* takes none of them: 最美的, 非常美的, 这么美的. 多 is in for 多美的日出啊, the
|
|
20
|
+
* exclamation.
|
|
21
|
+
*/
|
|
22
|
+
const DEGREE = new Set([
|
|
23
|
+
"最",
|
|
24
|
+
"很",
|
|
25
|
+
"更",
|
|
26
|
+
"太",
|
|
27
|
+
"真",
|
|
28
|
+
"挺",
|
|
29
|
+
"多",
|
|
30
|
+
"多么",
|
|
31
|
+
"多麼",
|
|
32
|
+
"非常",
|
|
33
|
+
"十分",
|
|
34
|
+
"特别",
|
|
35
|
+
"特別",
|
|
36
|
+
"极其",
|
|
37
|
+
"極其",
|
|
38
|
+
"比较",
|
|
39
|
+
"比較",
|
|
40
|
+
"相当",
|
|
41
|
+
"相當",
|
|
42
|
+
"如此",
|
|
43
|
+
"这么",
|
|
44
|
+
"這麼",
|
|
45
|
+
"那么",
|
|
46
|
+
"那麼",
|
|
47
|
+
"这样",
|
|
48
|
+
"這樣",
|
|
49
|
+
"那样",
|
|
50
|
+
"那樣",
|
|
51
|
+
]);
|
|
52
|
+
/**
|
|
53
|
+
* The copula, which asserts 美 of its subject (都是美的) and also names what a
|
|
54
|
+
* thing is (这是美的冰箱, a Midea fridge).
|
|
55
|
+
*/
|
|
56
|
+
const COPULA = "是";
|
|
57
|
+
/**
|
|
58
|
+
* The tag prefix jieba gives a noun.
|
|
59
|
+
*/
|
|
60
|
+
const NOUN_TAG = "n";
|
|
61
|
+
/**
|
|
62
|
+
* Whether the 美的 starting at a position is graded or asserted.
|
|
63
|
+
*
|
|
64
|
+
* A degree word in front always grades it. A 是 asserts it only where nothing
|
|
65
|
+
* follows for 美的 to name: 都是美的 is beautiful, and 这是美的冰箱 and
|
|
66
|
+
* 这是美的牌冰箱 are the brand.
|
|
67
|
+
*/
|
|
68
|
+
function isGraded(context, from, to) {
|
|
69
|
+
const before = wordsEndingAt(context, from, 2);
|
|
70
|
+
if (before.some((word) => DEGREE.has(word))) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return (before.includes(COPULA) &&
|
|
74
|
+
!tagOf(context, wordStartingAt(context, to)).startsWith(NOUN_TAG));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 美的 is taken apart where a degree word or a 是 grades it.
|
|
78
|
+
*
|
|
79
|
+
* Taking the edge away leaves 美 and 的 to read as themselves, `měi de`, which
|
|
80
|
+
* is the reading as well as the spacing: the name's 的 is `dí`.
|
|
81
|
+
*
|
|
82
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
83
|
+
* sentences, the decode read 美的 as the name in 28 runs and none of them was
|
|
84
|
+
* the company.
|
|
85
|
+
*/
|
|
86
|
+
export const ADJECTIVAL_MEI = {
|
|
87
|
+
name: "adjectival-mei",
|
|
88
|
+
verdictFor: (context) => {
|
|
89
|
+
const { edge } = context;
|
|
90
|
+
return BRAND.has(edge.text) && isGraded(context, edge.from, edge.to)
|
|
91
|
+
? "forbid"
|
|
92
|
+
: "keep";
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=mei-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mei-rule.js","sourceRoot":"","sources":["../../src/decode/mei-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAGL,KAAK,EACL,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;IACrB,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;CACL,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,GAAG,GAAG,CAAC;AAEnB;;GAEG;AACH,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,OAAoB,EAAE,IAAY,EAAE,EAAU;IAC9D,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QACvB,CAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAClE,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAa;IACtC,IAAI,EAAE,gBAAgB;IACtB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YAClE,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type EdgeRule } from "./rules.js";
|
|
2
|
+
/**
|
|
3
|
+
* A proper noun is taken apart where its 量词 is counting with a number.
|
|
4
|
+
*
|
|
5
|
+
* Two shapes are caught. The name starts with the number and the 量词 follows
|
|
6
|
+
* (三本书, 五本书) and no title follows, or the name starts with the 量词 and the
|
|
7
|
+
* number is just in front of it (一堵墙). Taking the edge away leaves each
|
|
8
|
+
* character to read as itself, and the spacing follows the count.
|
|
9
|
+
*
|
|
10
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
11
|
+
* sentences, the rule changes 13 runs, 9 of them 三本 and 4 堵墙, and each one
|
|
12
|
+
* is a count.
|
|
13
|
+
*/
|
|
14
|
+
export declare const COUNTED_NAME: EdgeRule;
|
|
15
|
+
//# sourceMappingURL=name-count-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-count-rule.d.ts","sourceRoot":"","sources":["../../src/decode/name-count-rule.ts"],"names":[],"mappings":"AAWA,OAAO,EAAoB,KAAK,QAAQ,EAAkB,MAAM,YAAY,CAAC;AA+C7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,QAkB1B,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The proper noun that is really a number and the 量词 counting with it.
|
|
3
|
+
*
|
|
4
|
+
* 三本 is a Japanese surname and 堵墙 a place, and jieba tags both as names
|
|
5
|
+
* (`ns` and `nr`). In running text they are 三本书 (three books) and 一堵墙 (a
|
|
6
|
+
* wall), and the decode read them as one word: `sānběn shū`, `yì dǔqiáng`.
|
|
7
|
+
* {@link import("./measure-rule.js").COUNTED_MEASURE} keeps a counted 量词
|
|
8
|
+
* out of the next word, and it finds the 量词 by its tag. 本 is tagged `r` and
|
|
9
|
+
* 堵 `v`, so it never sees these two.
|
|
10
|
+
*/
|
|
11
|
+
import { QUANTITY_CHARACTERS } from "../numerals/characters.js";
|
|
12
|
+
import { wordStartingAt } from "./rules.js";
|
|
13
|
+
/**
|
|
14
|
+
* The tags jieba gives a person, a place and another proper name.
|
|
15
|
+
*
|
|
16
|
+
* Asked as well as the proper-noun flag, because a word only jieba tags as a
|
|
17
|
+
* name keeps the tag and loses the flag.
|
|
18
|
+
*/
|
|
19
|
+
const NAME_TAG = /^n[rsz]/u;
|
|
20
|
+
/**
|
|
21
|
+
* The 量词 the dictionary does not tag `q` and a proper noun has taken in.
|
|
22
|
+
*
|
|
23
|
+
* Kept to the two the corpus shows. The untagged 量词 are many (条, 件, 只 and
|
|
24
|
+
* 块 among them), and a wider set would reach names such as 四川, whose 川 is
|
|
25
|
+
* no 量词 at all.
|
|
26
|
+
*/
|
|
27
|
+
const UNTAGGED_MEASURES = new Set(["本", "堵"]);
|
|
28
|
+
/**
|
|
29
|
+
* The titles that follow a surname, in both scripts.
|
|
30
|
+
*
|
|
31
|
+
* 三本先生 is Mr Sanbon, and a title after the name says the name is meant.
|
|
32
|
+
*/
|
|
33
|
+
const TITLES = new Set([
|
|
34
|
+
"先生",
|
|
35
|
+
"小姐",
|
|
36
|
+
"女士",
|
|
37
|
+
"太太",
|
|
38
|
+
"老师",
|
|
39
|
+
"老師",
|
|
40
|
+
"同学",
|
|
41
|
+
"同學",
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Whether a character is a numeral, or 几 asking how many.
|
|
45
|
+
*/
|
|
46
|
+
function isNumeral(character) {
|
|
47
|
+
return (character !== undefined &&
|
|
48
|
+
(QUANTITY_CHARACTERS.has(character) ||
|
|
49
|
+
character === "几" ||
|
|
50
|
+
character === "幾"));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A proper noun is taken apart where its 量词 is counting with a number.
|
|
54
|
+
*
|
|
55
|
+
* Two shapes are caught. The name starts with the number and the 量词 follows
|
|
56
|
+
* (三本书, 五本书) and no title follows, or the name starts with the 量词 and the
|
|
57
|
+
* number is just in front of it (一堵墙). Taking the edge away leaves each
|
|
58
|
+
* character to read as itself, and the spacing follows the count.
|
|
59
|
+
*
|
|
60
|
+
* Over the 139,893 distinct Han runs of Tatoeba and the Chinese Boost example
|
|
61
|
+
* sentences, the rule changes 13 runs, 9 of them 三本 and 4 堵墙, and each one
|
|
62
|
+
* is a count.
|
|
63
|
+
*/
|
|
64
|
+
export const COUNTED_NAME = {
|
|
65
|
+
name: "counted-name",
|
|
66
|
+
verdictFor: (context) => {
|
|
67
|
+
const { characters, edge } = context;
|
|
68
|
+
if (!edge.isProperNoun && !NAME_TAG.test(edge.partOfSpeech)) {
|
|
69
|
+
return "keep";
|
|
70
|
+
}
|
|
71
|
+
const first = characters[edge.from];
|
|
72
|
+
const second = characters[edge.from + 1];
|
|
73
|
+
const startsWithCount = isNumeral(first) &&
|
|
74
|
+
UNTAGGED_MEASURES.has(second ?? "") &&
|
|
75
|
+
!TITLES.has(wordStartingAt(context, edge.to) ?? "");
|
|
76
|
+
const followsCount = UNTAGGED_MEASURES.has(first ?? "") &&
|
|
77
|
+
isNumeral(characters[edge.from - 1]);
|
|
78
|
+
return startsWithCount || followsCount ? "forbid" : "keep";
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=name-count-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-count-rule.js","sourceRoot":"","sources":["../../src/decode/name-count-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAmC,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE9C;;;;GAIG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;IACrB,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;CACL,CAAC,CAAC;AAEH;;GAEG;AACH,SAAS,SAAS,CAAC,SAA6B;IAC9C,OAAO,CACL,SAAS,KAAK,SAAS;QACvB,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC;YACjC,SAAS,KAAK,GAAG;YACjB,SAAS,KAAK,GAAG,CAAC,CACrB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAa;IACpC,IAAI,EAAE,cAAc;IACpB,UAAU,EAAE,CAAC,OAAoB,EAAE,EAAE;QACnC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5D,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACzC,MAAM,eAAe,GACnB,SAAS,CAAC,KAAK,CAAC;YAChB,iBAAiB,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;YACnC,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,YAAY,GAChB,iBAAiB,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YAClC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,OAAO,eAAe,IAAI,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7D,CAAC;CACF,CAAC"}
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 弹 is `tán` or `dàn`, and which one a text means is a question about the
|
|
5
5
|
* neighbours rather than about the character. 长 is the same question and has
|
|
6
|
-
* a file of its own, and
|
|
6
|
+
* a file of its own, and 好学, 美的 and 花都 are the same question asked of a word. The other rules in `reading-rules.ts` are about particles
|
|
7
7
|
* and 儿化, which is a different kind of evidence.
|
|
8
8
|
*/
|
|
9
9
|
export { ADJECTIVAL_CHANG } from "./chang-rule.js";
|
|
10
10
|
export { PLAYING_TAN } from "./tan-rule.js";
|
|
11
11
|
export { EASY_HAO } from "./hao-rule.js";
|
|
12
|
+
export { ADJECTIVAL_MEI } from "./mei-rule.js";
|
|
13
|
+
export { SUMMING_DOU } from "./dou-rule.js";
|
|
12
14
|
//# sourceMappingURL=polyphone-rules.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polyphone-rules.d.ts","sourceRoot":"","sources":["../../src/decode/polyphone-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"polyphone-rules.d.ts","sourceRoot":"","sources":["../../src/decode/polyphone-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 弹 is `tán` or `dàn`, and which one a text means is a question about the
|
|
5
5
|
* neighbours rather than about the character. 长 is the same question and has
|
|
6
|
-
* a file of its own, and
|
|
6
|
+
* a file of its own, and 好学, 美的 and 花都 are the same question asked of a word. The other rules in `reading-rules.ts` are about particles
|
|
7
7
|
* and 儿化, which is a different kind of evidence.
|
|
8
8
|
*/
|
|
9
9
|
export { ADJECTIVAL_CHANG } from "./chang-rule.js";
|
|
10
10
|
export { PLAYING_TAN } from "./tan-rule.js";
|
|
11
11
|
export { EASY_HAO } from "./hao-rule.js";
|
|
12
|
+
export { ADJECTIVAL_MEI } from "./mei-rule.js";
|
|
13
|
+
export { SUMMING_DOU } from "./dou-rule.js";
|
|
12
14
|
//# sourceMappingURL=polyphone-rules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polyphone-rules.js","sourceRoot":"","sources":["../../src/decode/polyphone-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"polyphone-rules.js","sourceRoot":"","sources":["../../src/decode/polyphone-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|