@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.
- package/README.md +128 -123
- package/data/full.entries +2637 -2637
- package/data/manifest.json +9 -9
- package/data/script.map +168 -3
- package/data/standard.entries +8 -8
- package/dist/decode/chang-complement.d.ts +19 -0
- package/dist/decode/chang-complement.d.ts.map +1 -0
- package/dist/decode/chang-complement.js +113 -0
- package/dist/decode/chang-complement.js.map +1 -0
- package/dist/decode/chang-context.d.ts +29 -0
- package/dist/decode/chang-context.d.ts.map +1 -0
- package/dist/decode/chang-context.js +99 -0
- package/dist/decode/chang-context.js.map +1 -0
- package/dist/decode/chang-rule.d.ts +47 -0
- package/dist/decode/chang-rule.d.ts.map +1 -0
- package/dist/decode/chang-rule.js +188 -0
- package/dist/decode/chang-rule.js.map +1 -0
- package/dist/decode/confidence.d.ts +11 -3
- package/dist/decode/confidence.d.ts.map +1 -1
- package/dist/decode/confidence.js +11 -3
- package/dist/decode/confidence.js.map +1 -1
- package/dist/decode/convert-pipeline.d.ts.map +1 -1
- package/dist/decode/convert-pipeline.js +5 -4
- package/dist/decode/convert-pipeline.js.map +1 -1
- package/dist/decode/de-rule.d.ts +74 -0
- package/dist/decode/de-rule.d.ts.map +1 -0
- package/dist/decode/de-rule.js +199 -0
- package/dist/decode/de-rule.js.map +1 -0
- package/dist/decode/decode.d.ts +12 -25
- package/dist/decode/decode.d.ts.map +1 -1
- package/dist/decode/decode.js +10 -47
- package/dist/decode/decode.js.map +1 -1
- package/dist/decode/decoders.d.ts +9 -4
- package/dist/decode/decoders.d.ts.map +1 -1
- package/dist/decode/decoders.js +7 -7
- package/dist/decode/decoders.js.map +1 -1
- package/dist/decode/edge-context.d.ts +19 -0
- package/dist/decode/edge-context.d.ts.map +1 -1
- package/dist/decode/edge-context.js +41 -0
- package/dist/decode/edge-context.js.map +1 -1
- package/dist/decode/hint-lattice.d.ts.map +1 -1
- package/dist/decode/hint-lattice.js +17 -3
- package/dist/decode/hint-lattice.js.map +1 -1
- package/dist/decode/jiao-rule.d.ts +9 -3
- package/dist/decode/jiao-rule.d.ts.map +1 -1
- package/dist/decode/jiao-rule.js +44 -5
- package/dist/decode/jiao-rule.js.map +1 -1
- package/dist/decode/lattice-decode.d.ts +28 -0
- package/dist/decode/lattice-decode.d.ts.map +1 -0
- package/dist/decode/lattice-decode.js +48 -0
- package/dist/decode/lattice-decode.js.map +1 -0
- package/dist/decode/lattice-slice.d.ts +22 -6
- package/dist/decode/lattice-slice.d.ts.map +1 -1
- package/dist/decode/lattice-slice.js +24 -18
- package/dist/decode/lattice-slice.js.map +1 -1
- package/dist/decode/lattice-types.d.ts +27 -8
- package/dist/decode/lattice-types.d.ts.map +1 -1
- package/dist/decode/lattice-types.js +27 -8
- package/dist/decode/lattice-types.js.map +1 -1
- package/dist/decode/numbers.d.ts +0 -8
- package/dist/decode/numbers.d.ts.map +1 -1
- package/dist/decode/numbers.js +0 -10
- package/dist/decode/numbers.js.map +1 -1
- package/dist/decode/polyphone-rules.d.ts +7 -27
- package/dist/decode/polyphone-rules.d.ts.map +1 -1
- package/dist/decode/polyphone-rules.js +7 -155
- package/dist/decode/polyphone-rules.js.map +1 -1
- package/dist/decode/reading-rules.d.ts +1 -29
- package/dist/decode/reading-rules.d.ts.map +1 -1
- package/dist/decode/reading-rules.js +5 -69
- package/dist/decode/reading-rules.js.map +1 -1
- package/dist/decode/rules.d.ts +1 -1
- package/dist/decode/rules.d.ts.map +1 -1
- package/dist/decode/rules.js +1 -1
- package/dist/decode/rules.js.map +1 -1
- package/dist/decode/run-context.d.ts +33 -0
- package/dist/decode/run-context.d.ts.map +1 -0
- package/dist/decode/run-context.js +47 -0
- package/dist/decode/run-context.js.map +1 -0
- package/dist/decode/run-lattice.d.ts +13 -10
- package/dist/decode/run-lattice.d.ts.map +1 -1
- package/dist/decode/run-lattice.js +15 -12
- package/dist/decode/run-lattice.js.map +1 -1
- package/dist/decode/run-words.d.ts +17 -0
- package/dist/decode/run-words.d.ts.map +1 -0
- package/dist/decode/run-words.js +29 -0
- package/dist/decode/run-words.js.map +1 -0
- package/dist/decode/sandhi-input.d.ts +30 -0
- package/dist/decode/sandhi-input.d.ts.map +1 -0
- package/dist/decode/sandhi-input.js +35 -0
- package/dist/decode/sandhi-input.js.map +1 -0
- package/dist/decode/sandhi-tones.d.ts +33 -5
- package/dist/decode/sandhi-tones.d.ts.map +1 -1
- package/dist/decode/sandhi-tones.js +59 -8
- package/dist/decode/sandhi-tones.js.map +1 -1
- package/dist/decode/sandhi.d.ts +9 -6
- package/dist/decode/sandhi.d.ts.map +1 -1
- package/dist/decode/sandhi.js +10 -7
- package/dist/decode/sandhi.js.map +1 -1
- package/dist/decode/script-region.d.ts +15 -0
- package/dist/decode/script-region.d.ts.map +1 -0
- package/dist/decode/script-region.js +61 -0
- package/dist/decode/script-region.js.map +1 -0
- package/dist/decode/script-types.d.ts +11 -2
- package/dist/decode/script-types.d.ts.map +1 -1
- package/dist/decode/script-types.js +2 -1
- package/dist/decode/script-types.js.map +1 -1
- package/dist/decode/script-words.d.ts +7 -5
- package/dist/decode/script-words.d.ts.map +1 -1
- package/dist/decode/script-words.js +18 -25
- package/dist/decode/script-words.js.map +1 -1
- package/dist/decode/script.d.ts.map +1 -1
- package/dist/decode/script.js +2 -1
- package/dist/decode/script.js.map +1 -1
- package/dist/decode/write-run.d.ts +0 -7
- package/dist/decode/write-run.d.ts.map +1 -1
- package/dist/decode/write-run.js +4 -39
- package/dist/decode/write-run.js.map +1 -1
- package/dist/dictionary/cedict-senses.d.ts +7 -0
- package/dist/dictionary/cedict-senses.d.ts.map +1 -1
- package/dist/dictionary/cedict-senses.js +12 -0
- package/dist/dictionary/cedict-senses.js.map +1 -1
- package/dist/dictionary/constituent-repair.d.ts +36 -0
- package/dist/dictionary/constituent-repair.d.ts.map +1 -0
- package/dist/dictionary/constituent-repair.js +117 -0
- package/dist/dictionary/constituent-repair.js.map +1 -0
- package/dist/dictionary/measure-tone.d.ts +36 -0
- package/dist/dictionary/measure-tone.d.ts.map +1 -0
- package/dist/dictionary/measure-tone.js +139 -0
- package/dist/dictionary/measure-tone.js.map +1 -0
- package/dist/dictionary/merge-types.d.ts +13 -2
- package/dist/dictionary/merge-types.d.ts.map +1 -1
- package/dist/dictionary/merge-types.js.map +1 -1
- package/dist/dictionary/merge-walk.d.ts +27 -0
- package/dist/dictionary/merge-walk.d.ts.map +1 -0
- package/dist/dictionary/merge-walk.js +49 -0
- package/dist/dictionary/merge-walk.js.map +1 -0
- package/dist/dictionary/merge.d.ts +3 -3
- package/dist/dictionary/merge.d.ts.map +1 -1
- package/dist/dictionary/merge.js +24 -28
- package/dist/dictionary/merge.js.map +1 -1
- package/dist/dictionary/overrides.d.ts +5 -0
- package/dist/dictionary/overrides.d.ts.map +1 -1
- package/dist/dictionary/overrides.js +5 -5
- package/dist/dictionary/overrides.js.map +1 -1
- package/dist/dictionary/script-tables.js +91 -13
- package/dist/dictionary/script-tables.js.map +1 -1
- package/dist/dictionary/word-readings.d.ts.map +1 -1
- package/dist/dictionary/word-readings.js +6 -0
- package/dist/dictionary/word-readings.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/script/glyphs.d.ts +9 -8
- package/dist/script/glyphs.d.ts.map +1 -1
- package/dist/script/glyphs.js +21 -48
- package/dist/script/glyphs.js.map +1 -1
- package/dist/script/reading-splits.d.ts +41 -0
- package/dist/script/reading-splits.d.ts.map +1 -0
- package/dist/script/reading-splits.js +98 -0
- package/dist/script/reading-splits.js.map +1 -0
- package/package.json +2 -2
|
@@ -4,8 +4,10 @@ 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 {
|
|
8
|
-
import {
|
|
7
|
+
import { surrounding, writeNumbers } from "./numbers.js";
|
|
8
|
+
import { contextAround } from "./run-context.js";
|
|
9
|
+
import { wordsOf } from "./run-words.js";
|
|
10
|
+
import { writeRun, rewrite } from "./write-run.js";
|
|
9
11
|
/**
|
|
10
12
|
* Run the pipeline over a text with a given decoder.
|
|
11
13
|
*/
|
|
@@ -41,8 +43,7 @@ export function convertWith(decode, dictionary, text, options) {
|
|
|
41
43
|
const within = hints === undefined
|
|
42
44
|
? undefined
|
|
43
45
|
: hintsWithin(hints, starts[at] ?? 0, toCharacters(run.text).length);
|
|
44
|
-
|
|
45
|
-
return wordsOf(decode(dictionary, run.text, said, within), dictionary, grouping);
|
|
46
|
+
return wordsOf(decode(dictionary, run.text, contextAround(runs, read, at), within), dictionary, grouping);
|
|
46
47
|
});
|
|
47
48
|
for (const [at, run] of runs.entries()) {
|
|
48
49
|
const words = decoded[at] ?? [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert-pipeline.js","sourceRoot":"","sources":["../../src/decode/convert-pipeline.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EACvB,UAAU,GACX,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"convert-pipeline.js","sourceRoot":"","sources":["../../src/decode/convert-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type EdgeRule } from "./rules.js";
|
|
2
|
+
/**
|
|
3
|
+
* 得 read as `děi` where it is a modal rather than a particle.
|
|
4
|
+
*
|
|
5
|
+
* One character, three readings, and the dictionary can only carry a default:
|
|
6
|
+
* 得 is stored `de` — the structural particle, which is far the commonest — with
|
|
7
|
+
* `dé` and `děi` as alternates. Nothing in the cost model can prefer an
|
|
8
|
+
* alternate at a position no word covers, so 我得走了 came out `wǒ de zǒule`
|
|
9
|
+
* and every other modal 得 with it. This is the case ROADMAP.md was waiting for
|
|
10
|
+
* before building stage 4: neither harness could see it, since the gold corpus
|
|
11
|
+
* had only 觉得 and CPP's 40 得 cases are labelled `dé` or `de` and never `děi`.
|
|
12
|
+
*
|
|
13
|
+
* The context is what separates the three, and only one side of it carries
|
|
14
|
+
* information. The particle 得 always follows the verb or adjective it attaches
|
|
15
|
+
* to (说得好, 跑得快, 累得要命), so a 得 with a *pronoun, adverb or time word*
|
|
16
|
+
* in front of it is not that particle. Requiring a verb phrase after it as well
|
|
17
|
+
* keeps 得了感冒 and 得了奖 — `dé`, and a real reading of the same character —
|
|
18
|
+
* out of it.
|
|
19
|
+
*
|
|
20
|
+
* Conditioning on what precedes rather than on what follows was measured, not
|
|
21
|
+
* assumed: "the word before is not a verb" fires 309 times over 88,866 lines of
|
|
22
|
+
* Tatoeba and zh.wikipedia and is wrong about four times in five, because
|
|
23
|
+
* jieba tags 下 as `f`, 学 as `n` and 飞 as nothing at all, and 雨下得很大 is a
|
|
24
|
+
* particle whatever the tag says. Naming the small closed set of things that
|
|
25
|
+
* can precede a modal is the same rule from the other side, and over the same
|
|
26
|
+
* text it fires 126 times and is right 122: the four misses are literary 得
|
|
27
|
+
* read `dé` after an adverb — 未必得喜悦, 暂得于己, 仅得约, 未得迁还家乡 —
|
|
28
|
+
* which nothing short of semantics separates from 必须得承认.
|
|
29
|
+
*/
|
|
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;
|
|
51
|
+
/**
|
|
52
|
+
* A word beginning with 的 does not start where the particle 的 does.
|
|
53
|
+
*
|
|
54
|
+
* The structural particle attaches to the modifier in front of it and the head
|
|
55
|
+
* follows, so a dictionary key spanning that 的 and the head's first character
|
|
56
|
+
* is describing some other sentence: 没有人知道他的真名字 came out
|
|
57
|
+
* `tā dí zhēn míngzi` on the strength of 的真, 图书馆的卡 on 的卡, and 你說的對
|
|
58
|
+
* came out as one word, `deduì`.
|
|
59
|
+
*
|
|
60
|
+
* Only a key **no source has tagged** is forbidden, which is the same line
|
|
61
|
+
* {@link TEACHING_JIAO} draws for a word ending in 教. 的确, 的士 and 的哥 are
|
|
62
|
+
* words jieba counted and tagged, and every one of them can genuinely begin
|
|
63
|
+
* where this fires: 我的确知道, 我要一辆的士, 那个的哥. That leaves 我的哥哥们
|
|
64
|
+
* reading `wǒ dī gēgē men`, since 的哥 is a taxi driver and jieba has counted
|
|
65
|
+
* them. What this does reach is the untagged tail — a reading somebody asserted
|
|
66
|
+
* rather than a word anybody counted — where the 的 is the particle every time.
|
|
67
|
+
*
|
|
68
|
+
* Measured over the 88,866 lines of Tatoeba and zh.wikipedia it forbids edges
|
|
69
|
+
* in 40 runs: 的筆 13, 的這 11, 的真 6, 的對 4, 的卡 4 and 的歷 once. Every one
|
|
70
|
+
* is a correction, and half of them are corrections to the spacing as much as
|
|
71
|
+
* to the reading — 你說的對 was one word `deduì` and is now two.
|
|
72
|
+
*/
|
|
73
|
+
export declare const PARTICLE_DE: EdgeRule;
|
|
74
|
+
//# sourceMappingURL=de-rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
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";
|
|
11
|
+
/**
|
|
12
|
+
* Whether a syllable is `děi`, the modal reading of 得.
|
|
13
|
+
*
|
|
14
|
+
* Compared structurally rather than by spelling it out, since a syllable is
|
|
15
|
+
* stored as its parts and writing one back is the formatting stage's job.
|
|
16
|
+
*/
|
|
17
|
+
function isDei(syllable) {
|
|
18
|
+
return (syllable?.initial === "d" && syllable.final === "ei" && syllable.tone === 3);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* What stands in front of a modal 得: a subject, an adverb, or a time word.
|
|
22
|
+
*
|
|
23
|
+
* 我得走, 你就得去, 我今天得走. The particle 得 cannot follow any of these,
|
|
24
|
+
* because it attaches to the predicate it modifies — which is exactly what
|
|
25
|
+
* makes this the discriminating side of the context.
|
|
26
|
+
*/
|
|
27
|
+
const SUBJECT_TAGS = new Set(["r", "d", "t"]);
|
|
28
|
+
/**
|
|
29
|
+
* What follows a modal 得: the verb phrase it governs.
|
|
30
|
+
*
|
|
31
|
+
* Prepositions and adverbs are in because 我得在八月, 我得先走 and 我得快点 are
|
|
32
|
+
* all modal, and what follows the 得 in each is the front of a verb phrase
|
|
33
|
+
* rather than a verb.
|
|
34
|
+
*/
|
|
35
|
+
const GOVERNED_TAGS = /^(?:v|p|d|a)/u;
|
|
36
|
+
/**
|
|
37
|
+
* 得 read as `děi` where it is a modal rather than a particle.
|
|
38
|
+
*
|
|
39
|
+
* One character, three readings, and the dictionary can only carry a default:
|
|
40
|
+
* 得 is stored `de` — the structural particle, which is far the commonest — with
|
|
41
|
+
* `dé` and `děi` as alternates. Nothing in the cost model can prefer an
|
|
42
|
+
* alternate at a position no word covers, so 我得走了 came out `wǒ de zǒule`
|
|
43
|
+
* and every other modal 得 with it. This is the case ROADMAP.md was waiting for
|
|
44
|
+
* before building stage 4: neither harness could see it, since the gold corpus
|
|
45
|
+
* had only 觉得 and CPP's 40 得 cases are labelled `dé` or `de` and never `děi`.
|
|
46
|
+
*
|
|
47
|
+
* The context is what separates the three, and only one side of it carries
|
|
48
|
+
* information. The particle 得 always follows the verb or adjective it attaches
|
|
49
|
+
* to (说得好, 跑得快, 累得要命), so a 得 with a *pronoun, adverb or time word*
|
|
50
|
+
* in front of it is not that particle. Requiring a verb phrase after it as well
|
|
51
|
+
* keeps 得了感冒 and 得了奖 — `dé`, and a real reading of the same character —
|
|
52
|
+
* out of it.
|
|
53
|
+
*
|
|
54
|
+
* Conditioning on what precedes rather than on what follows was measured, not
|
|
55
|
+
* assumed: "the word before is not a verb" fires 309 times over 88,866 lines of
|
|
56
|
+
* Tatoeba and zh.wikipedia and is wrong about four times in five, because
|
|
57
|
+
* jieba tags 下 as `f`, 学 as `n` and 飞 as nothing at all, and 雨下得很大 is a
|
|
58
|
+
* particle whatever the tag says. Naming the small closed set of things that
|
|
59
|
+
* can precede a modal is the same rule from the other side, and over the same
|
|
60
|
+
* text it fires 126 times and is right 122: the four misses are literary 得
|
|
61
|
+
* read `dé` after an adverb — 未必得喜悦, 暂得于己, 仅得约, 未得迁还家乡 —
|
|
62
|
+
* which nothing short of semantics separates from 必须得承认.
|
|
63
|
+
*/
|
|
64
|
+
export const MODAL_DE = {
|
|
65
|
+
name: "modal-de",
|
|
66
|
+
verdictFor: (context) => {
|
|
67
|
+
const { edge } = context;
|
|
68
|
+
if (edge.text !== "得" || !isDei(edge.reading[0])) {
|
|
69
|
+
return "keep";
|
|
70
|
+
}
|
|
71
|
+
const before = wordEndingAt(context, edge.from);
|
|
72
|
+
const after = wordStartingAt(context, edge.to);
|
|
73
|
+
return SUBJECT_TAGS.has(tagOf(context, before)) &&
|
|
74
|
+
GOVERNED_TAGS.test(tagOf(context, after))
|
|
75
|
+
? "force"
|
|
76
|
+
: "keep";
|
|
77
|
+
},
|
|
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
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* The tags a word carries when the 的 after it is the structural particle.
|
|
158
|
+
*
|
|
159
|
+
* A pronoun, a noun, an adjective, a verb or a distinguishing word: 他的,
|
|
160
|
+
* 图书馆的, 伟大的, 见过面的, 男的. What the particle marks is a modifier, and
|
|
161
|
+
* these are what a modifier is.
|
|
162
|
+
*/
|
|
163
|
+
const MODIFIED_TAGS = /^(?:r|n|a|v|b|z)/u;
|
|
164
|
+
/**
|
|
165
|
+
* A word beginning with 的 does not start where the particle 的 does.
|
|
166
|
+
*
|
|
167
|
+
* The structural particle attaches to the modifier in front of it and the head
|
|
168
|
+
* follows, so a dictionary key spanning that 的 and the head's first character
|
|
169
|
+
* is describing some other sentence: 没有人知道他的真名字 came out
|
|
170
|
+
* `tā dí zhēn míngzi` on the strength of 的真, 图书馆的卡 on 的卡, and 你說的對
|
|
171
|
+
* came out as one word, `deduì`.
|
|
172
|
+
*
|
|
173
|
+
* Only a key **no source has tagged** is forbidden, which is the same line
|
|
174
|
+
* {@link TEACHING_JIAO} draws for a word ending in 教. 的确, 的士 and 的哥 are
|
|
175
|
+
* words jieba counted and tagged, and every one of them can genuinely begin
|
|
176
|
+
* where this fires: 我的确知道, 我要一辆的士, 那个的哥. That leaves 我的哥哥们
|
|
177
|
+
* reading `wǒ dī gēgē men`, since 的哥 is a taxi driver and jieba has counted
|
|
178
|
+
* them. What this does reach is the untagged tail — a reading somebody asserted
|
|
179
|
+
* rather than a word anybody counted — where the 的 is the particle every time.
|
|
180
|
+
*
|
|
181
|
+
* Measured over the 88,866 lines of Tatoeba and zh.wikipedia it forbids edges
|
|
182
|
+
* in 40 runs: 的筆 13, 的這 11, 的真 6, 的對 4, 的卡 4 and 的歷 once. Every one
|
|
183
|
+
* is a correction, and half of them are corrections to the spacing as much as
|
|
184
|
+
* to the reading — 你說的對 was one word `deduì` and is now two.
|
|
185
|
+
*/
|
|
186
|
+
export const PARTICLE_DE = {
|
|
187
|
+
name: "particle-de",
|
|
188
|
+
verdictFor: (context) => {
|
|
189
|
+
const { edge } = context;
|
|
190
|
+
if (edge.to - edge.from < 2 ||
|
|
191
|
+
edge.partOfSpeech !== "" ||
|
|
192
|
+
!edge.text.startsWith("的")) {
|
|
193
|
+
return "keep";
|
|
194
|
+
}
|
|
195
|
+
const before = wordEndingAt(context, edge.from);
|
|
196
|
+
return MODIFIED_TAGS.test(tagOf(context, before)) ? "forbid" : "keep";
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=de-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-rule.js","sourceRoot":"","sources":["../../src/decode/de-rule.ts"],"names":[],"mappings":"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"}
|
package/dist/decode/decode.d.ts
CHANGED
|
@@ -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
|
-
|
|
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`
|
|
35
|
-
*
|
|
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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/decode/decode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/decode/decode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,wBAAgB,SAAS,CACvB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,SAAS,QAAQ,EAAkB,EAC1C,MAAM,SAAK,EACX,KAAK,CAAC,EAAE,aAAa,EACrB,KAAK,SAAK,GACT,SAAS,WAAW,EAAE,CAOxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,SAAS,QAAQ,EAAkB,EAC1C,MAAM,SAAK,EACX,KAAK,CAAC,EAAE,aAAa,EACrB,KAAK,SAAK,GACT,SAAS,UAAU,EAAE,CAcvB"}
|
package/dist/decode/decode.js
CHANGED
|
@@ -1,48 +1,11 @@
|
|
|
1
1
|
import { scoreReadings } from "./confidence.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { decodeReadings } from "./lattice-decode.js";
|
|
3
|
+
import { projectReadings } from "./locking.js";
|
|
4
4
|
import { READING_RULES } from "./reading-rules.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Decode the run's readings, scoring only where the readings are still open.
|
|
8
|
-
*
|
|
9
|
-
* The asymmetry ALGORITHM.md calls for. A stretch between two cut points whose
|
|
10
|
-
* positions all locked reads the same way on every path, so its readings are
|
|
11
|
-
* read off the locks and no shortest path is run over it at all. Only the
|
|
12
|
-
* stretches with a genuine choice in them are decoded.
|
|
13
|
-
*/
|
|
14
|
-
export function decodeReadings(lattice, projection) {
|
|
15
|
-
const cuts = cutPoints(lattice);
|
|
16
|
-
const units = [];
|
|
17
|
-
for (const [index, from] of cuts.entries()) {
|
|
18
|
-
const to = cuts[index + 1];
|
|
19
|
-
if (to === undefined) {
|
|
20
|
-
break;
|
|
21
|
-
}
|
|
22
|
-
if (isSettled(projection, from, to)) {
|
|
23
|
-
units.push(...settledUnits(projection, from, to));
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
for (const edge of shortestPath(lattice, from, to, readingCost)) {
|
|
27
|
-
units.push(...unitsOf(edge));
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return units;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Where a decode would put the word boundaries, as character positions.
|
|
34
|
-
*
|
|
35
|
-
* Run over the whole lattice rather than the open stretches, because spacing
|
|
36
|
-
* stays ambiguous where readings do not: 研究生命起源 reads identically whether
|
|
37
|
-
* it splits 研究生/命 or 研究/生命, so every position in it locks, and the
|
|
38
|
-
* spacing question is still open.
|
|
39
|
-
*/
|
|
40
|
-
export function decodeSpacing(lattice) {
|
|
41
|
-
return shortestPath(lattice, 0, lattice.characters.length, spacingCost).map((edge) => edge.from);
|
|
42
|
-
}
|
|
5
|
+
export { decodeReadings, decodeSpacing } from "./lattice-decode.js";
|
|
43
6
|
import { runGroups, runLattice, wordFrom } from "./run-lattice.js";
|
|
44
|
-
export function decodeRun(dictionary, run, rules = READING_RULES, before = "", hints) {
|
|
45
|
-
const held = runLattice(dictionary, run, rules, before, hints);
|
|
7
|
+
export function decodeRun(dictionary, run, rules = READING_RULES, before = "", hints, after = "") {
|
|
8
|
+
const held = runLattice(dictionary, run, rules, { before, after }, hints);
|
|
46
9
|
const { lattice } = held;
|
|
47
10
|
const units = decodeReadings(lattice, projectReadings(lattice));
|
|
48
11
|
return runGroups(held, units).map((group) => wordFrom(dictionary, lattice, group));
|
|
@@ -55,12 +18,12 @@ export function decodeRun(dictionary, run, rules = READING_RULES, before = "", h
|
|
|
55
18
|
* only worth running for a caller that will use the answer — rendering
|
|
56
19
|
* uncertain readings differently, or reporting them.
|
|
57
20
|
*
|
|
58
|
-
* `before`
|
|
59
|
-
*
|
|
60
|
-
* 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.
|
|
61
24
|
*/
|
|
62
|
-
export function decodeRunScored(dictionary, run, rules = READING_RULES, before = "", hints) {
|
|
63
|
-
const held = runLattice(dictionary, run, rules, before, hints);
|
|
25
|
+
export function decodeRunScored(dictionary, run, rules = READING_RULES, before = "", hints, after = "") {
|
|
26
|
+
const held = runLattice(dictionary, run, rules, { before, after }, hints);
|
|
64
27
|
const { lattice } = held;
|
|
65
28
|
const units = scoreReadings(lattice, projectReadings(lattice));
|
|
66
29
|
return runGroups(held, units).map((group) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/decode/decode.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/decode/decode.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnE,MAAM,UAAU,SAAS,CACvB,UAAsB,EACtB,GAAW,EACX,KAAK,GAAwB,aAAa,EAC1C,MAAM,GAAG,EAAE,EACX,KAAqB,EACrB,KAAK,GAAG,EAAE;IAEV,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1E,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1C,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,CACrC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAC7B,UAAsB,EACtB,GAAW,EACX,KAAK,GAAwB,aAAa,EAC1C,MAAM,GAAG,EAAE,EACX,KAAqB,EACrB,KAAK,GAAG,EAAE;IAEV,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1E,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAE/D,OAAO,SAAS,CAAa,IAAI,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC;QAC1C,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC,CAAC,CACJ;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -7,12 +7,17 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Dictionary } from "../dictionary/dictionary.js";
|
|
9
9
|
import type { ResolvedHints } from "./hints.js";
|
|
10
|
+
import type { DecodeContext } from "./lattice-slice.js";
|
|
10
11
|
import type { ScoredWord } from "./word.js";
|
|
11
12
|
/**
|
|
12
13
|
* How a Han run is turned into words, with whatever the decoder can say about
|
|
13
14
|
* how settled they were.
|
|
15
|
+
*
|
|
16
|
+
* The context is one argument here where the exported decoders keep `before`
|
|
17
|
+
* and `after` apart, since nothing outside this package calls it and the two
|
|
18
|
+
* are one claim about the text around the run.
|
|
14
19
|
*/
|
|
15
|
-
export type Decode = (dictionary: Dictionary, run: string,
|
|
20
|
+
export type Decode = (dictionary: Dictionary, run: string, context: DecodeContext, hints: ResolvedHints | undefined) => readonly ScoredWord[];
|
|
16
21
|
/**
|
|
17
22
|
* The lattice decoder, reporting nothing about its own confidence.
|
|
18
23
|
*/
|
|
@@ -24,9 +29,9 @@ export declare const SCORED: Decode;
|
|
|
24
29
|
/**
|
|
25
30
|
* The greedy baseline, which has nothing to report either way.
|
|
26
31
|
*
|
|
27
|
-
* The context
|
|
28
|
-
*
|
|
29
|
-
*
|
|
32
|
+
* The context around a run goes unused: longest-match has no way to weigh one
|
|
33
|
+
* segmentation against another, which is the whole reason it is the baseline,
|
|
34
|
+
* and 汉字 it cannot report would only be another thing to trim.
|
|
30
35
|
*/
|
|
31
36
|
export declare const GREEDY: Decode;
|
|
32
37
|
//# sourceMappingURL=decoders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoders.d.ts","sourceRoot":"","sources":["../../src/decode/decoders.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"decoders.d.ts","sourceRoot":"","sources":["../../src/decode/decoders.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,WAAW,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,MAAM,MAAM,GAAG,CACnB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,aAAa,GAAG,SAAS,KAC7B,SAAS,UAAU,EAAE,CAAC;AAoB3B;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MASrB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAQlB,CAAC;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,EAAE,MAEpB,CAAC"}
|
package/dist/decode/decoders.js
CHANGED
|
@@ -5,7 +5,7 @@ import { READING_RULES } from "./reading-rules.js";
|
|
|
5
5
|
* A decoder that reports no confidence at all, which is every decoder but one.
|
|
6
6
|
*/
|
|
7
7
|
function unscored(decode) {
|
|
8
|
-
return (dictionary, run,
|
|
8
|
+
return (dictionary, run, context, hints) => decode(dictionary, run, context, hints).map((word) => ({
|
|
9
9
|
word,
|
|
10
10
|
confidence: [],
|
|
11
11
|
}));
|
|
@@ -13,17 +13,17 @@ function unscored(decode) {
|
|
|
13
13
|
/**
|
|
14
14
|
* The lattice decoder, reporting nothing about its own confidence.
|
|
15
15
|
*/
|
|
16
|
-
export const LATTICE = unscored((dictionary, run,
|
|
16
|
+
export const LATTICE = unscored((dictionary, run, context, hints) => decodeRun(dictionary, run, READING_RULES, context.before, hints, context.after));
|
|
17
17
|
/**
|
|
18
18
|
* The lattice decoder, with what each reading was chosen over.
|
|
19
19
|
*/
|
|
20
|
-
export const SCORED = (dictionary, run,
|
|
20
|
+
export const SCORED = (dictionary, run, context, hints) => decodeRunScored(dictionary, run, READING_RULES, context.before, hints, context.after);
|
|
21
21
|
/**
|
|
22
22
|
* The greedy baseline, which has nothing to report either way.
|
|
23
23
|
*
|
|
24
|
-
* The context
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* The context around a run goes unused: longest-match has no way to weigh one
|
|
25
|
+
* segmentation against another, which is the whole reason it is the baseline,
|
|
26
|
+
* and 汉字 it cannot report would only be another thing to trim.
|
|
27
27
|
*/
|
|
28
|
-
export const GREEDY = unscored(decodeGreedily);
|
|
28
|
+
export const GREEDY = unscored((dictionary, run) => decodeGreedily(dictionary, run));
|
|
29
29
|
//# sourceMappingURL=decoders.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoders.js","sourceRoot":"","sources":["../../src/decode/decoders.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"decoders.js","sourceRoot":"","sources":["../../src/decode/decoders.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAkBnD;;GAEG;AACH,SAAS,QAAQ,CACf,MAK2B;IAE3B,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CACzC,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI;QACJ,UAAU,EAAE,EAAE;KACf,CAAC,CAAC,CAAC;AACR,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAW,QAAQ,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAC1E,SAAS,CACP,UAAU,EACV,GAAG,EACH,aAAa,EACb,OAAO,CAAC,MAAM,EACd,KAAK,EACL,OAAO,CAAC,KAAK,CACd,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAW,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAChE,eAAe,CACb,UAAU,EACV,GAAG,EACH,aAAa,EACb,OAAO,CAAC,MAAM,EACd,KAAK,EACL,OAAO,CAAC,KAAK,CACd,CAAC;AAEJ;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAW,QAAQ,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE,CACzD,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,CAChC,CAAC"}
|
|
@@ -14,10 +14,29 @@ import type { EdgeContext } from "./rules.js";
|
|
|
14
14
|
* usually choose, since the reading charge prefers fewer words.
|
|
15
15
|
*/
|
|
16
16
|
export declare function wordEndingAt(context: EdgeContext, at: number, longest?: number): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Every word the dictionary has ending at a position, longest first.
|
|
19
|
+
*
|
|
20
|
+
* {@link wordEndingAt} answers with the longest, which is what a rule asking
|
|
21
|
+
* "what word is this" wants. A rule asking whether a *particular* word stands
|
|
22
|
+
* here wants all of them, because the longest match is often a word the rule
|
|
23
|
+
* has no opinion about wrapped around the one it does: 很 is a degree adverb
|
|
24
|
+
* and 得很 is the longest word ending at the same position, so 留得很长 hid its
|
|
25
|
+
* 很 and read `zhǎng`. 一个 hides 个 the same way.
|
|
26
|
+
*/
|
|
27
|
+
export declare function wordsEndingAt(context: EdgeContext, at: number, longest?: number): readonly string[];
|
|
17
28
|
/**
|
|
18
29
|
* The word starting at a position, longest first, or undefined.
|
|
19
30
|
*/
|
|
20
31
|
export declare function wordStartingAt(context: EdgeContext, at: number, longest?: number): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Every word the dictionary has starting at a position, longest first.
|
|
34
|
+
*
|
|
35
|
+
* The mirror of {@link wordsEndingAt}, and needed for the same reason: 五公 is a
|
|
36
|
+
* word and hides the 五 inside it, so a rule asking whether a numeral starts
|
|
37
|
+
* here has to be shown all of them.
|
|
38
|
+
*/
|
|
39
|
+
export declare function wordsStartingAt(context: EdgeContext, at: number, longest?: number): readonly string[];
|
|
21
40
|
/**
|
|
22
41
|
* The part of speech the dictionary gives a word, or the empty string.
|
|
23
42
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge-context.d.ts","sourceRoot":"","sources":["../../src/decode/edge-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,MAAM,GAAG,SAAS,CAYpB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,MAAM,GAAG,SAAS,CAUpB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI5E;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,aAA0C,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,YAAY,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"edge-context.d.ts","sourceRoot":"","sources":["../../src/decode/edge-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,MAAM,GAAG,SAAS,CAYpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,SAAS,MAAM,EAAE,CAanB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,MAAM,GAAG,SAAS,CAUpB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,SAAI,GACV,SAAS,MAAM,EAAE,CASnB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI5E;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,aAA0C,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,YAAY,MAAM,CAAC"}
|