@kensio/pinyinjs 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +153 -4
- package/README.md +44 -3
- package/data/core.entries +82 -81
- package/data/core.freq +0 -0
- package/data/core.keys +1 -0
- package/data/full.entries +4897 -4899
- package/data/full.freq +0 -0
- package/data/full.keys +0 -2
- package/data/manifest.json +12 -12
- package/data/script.map +27 -48
- package/data/standard.entries +438 -437
- package/data/standard.freq +0 -0
- package/data/standard.keys +1 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +22 -1
- package/dist/cli/commands.js.map +1 -1
- package/dist/decode/convert.d.ts +42 -0
- package/dist/decode/convert.d.ts.map +1 -1
- package/dist/decode/convert.js +140 -17
- package/dist/decode/convert.js.map +1 -1
- package/dist/decode/decode.d.ts +3 -2
- package/dist/decode/decode.d.ts.map +1 -1
- package/dist/decode/decode.js +15 -10
- package/dist/decode/decode.js.map +1 -1
- package/dist/decode/hints.d.ts +138 -0
- package/dist/decode/hints.d.ts.map +1 -0
- package/dist/decode/hints.js +214 -0
- package/dist/decode/hints.js.map +1 -0
- package/dist/decode/lattice.d.ts +9 -1
- package/dist/decode/lattice.d.ts.map +1 -1
- package/dist/decode/lattice.js +5 -3
- package/dist/decode/lattice.js.map +1 -1
- package/dist/decode/reading-rules.d.ts +28 -0
- package/dist/decode/reading-rules.d.ts.map +1 -1
- package/dist/decode/reading-rules.js +157 -0
- package/dist/decode/reading-rules.js.map +1 -1
- package/dist/dictionary/assertions.d.ts.map +1 -1
- package/dist/dictionary/assertions.js +8 -0
- package/dist/dictionary/assertions.js.map +1 -1
- package/dist/dictionary/frequency-table.js +1 -1
- package/dist/dictionary/locale.js +2 -2
- package/dist/dictionary/merge.d.ts.map +1 -1
- package/dist/dictionary/merge.js +30 -1
- package/dist/dictionary/merge.js.map +1 -1
- package/dist/format/html.d.ts +32 -0
- package/dist/format/html.d.ts.map +1 -1
- package/dist/format/html.js +144 -0
- package/dist/format/html.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/sources/unihan.d.ts +13 -4
- package/dist/sources/unihan.d.ts.map +1 -1
- package/dist/sources/unihan.js +63 -13
- package/dist/sources/unihan.js.map +1 -1
- package/package.json +1 -1
package/dist/decode/decode.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { toCharacters } from "../script/characters.js";
|
|
2
2
|
import { scoreReadings } from "./confidence.js";
|
|
3
|
+
import { shiftHints } from "./hints.js";
|
|
3
4
|
import { allEdges, buildLattice, cutPoints } from "./lattice.js";
|
|
4
5
|
import { isSettled, projectReadings, settledUnits, unitsOf, } from "./locking.js";
|
|
5
6
|
import { READING_RULES } from "./reading-rules.js";
|
|
@@ -95,8 +96,8 @@ function wordFrom(dictionary, lattice, group) {
|
|
|
95
96
|
* between, so everything downstream sees one lattice rather than a decode and
|
|
96
97
|
* a list of corrections to it.
|
|
97
98
|
*/
|
|
98
|
-
function ruledLattice(dictionary, run, rules) {
|
|
99
|
-
return applyEdgeRules(buildLattice(dictionary, run), dictionary, rules);
|
|
99
|
+
function ruledLattice(dictionary, run, rules, hints) {
|
|
100
|
+
return applyEdgeRules(buildLattice(dictionary, run, hints), dictionary, rules);
|
|
100
101
|
}
|
|
101
102
|
/**
|
|
102
103
|
* Whether any reading in the lattice would hold the two sides of a join
|
|
@@ -120,16 +121,20 @@ function isJoinedAt(lattice, at) {
|
|
|
120
121
|
* run decoded on its own, which is what it would have been before there was any
|
|
121
122
|
* context to give.
|
|
122
123
|
*/
|
|
123
|
-
function runLattice(dictionary, run, rules, before) {
|
|
124
|
+
function runLattice(dictionary, run, rules, before, hints) {
|
|
124
125
|
const alone = () => ({
|
|
125
|
-
lattice: ruledLattice(dictionary, run, rules),
|
|
126
|
+
lattice: ruledLattice(dictionary, run, rules, hints),
|
|
126
127
|
at: 0,
|
|
127
128
|
});
|
|
128
129
|
if (before === "") {
|
|
129
130
|
return alone();
|
|
130
131
|
}
|
|
131
|
-
const
|
|
132
|
-
|
|
132
|
+
const held = toCharacters(before).length;
|
|
133
|
+
// The context is decoded with the run, so every hint position moves along
|
|
134
|
+
// with it. Shifting a copy keeps the caller's positions relative to the run
|
|
135
|
+
// they were given for.
|
|
136
|
+
const lattice = ruledLattice(dictionary, before + run, rules, hints === undefined ? undefined : shiftHints(hints, held));
|
|
137
|
+
const at = held;
|
|
133
138
|
return isJoinedAt(lattice, at) ? alone() : { lattice, at };
|
|
134
139
|
}
|
|
135
140
|
/**
|
|
@@ -155,8 +160,8 @@ function runGroups({ lattice, at }, units) {
|
|
|
155
160
|
* what preceded it — 个人 alone is the word `gèrén`, while the 两 of 2个人 makes
|
|
156
161
|
* 两个 the word and leaves 人 to itself.
|
|
157
162
|
*/
|
|
158
|
-
export function decodeRun(dictionary, run, rules = READING_RULES, before = "") {
|
|
159
|
-
const held = runLattice(dictionary, run, rules, before);
|
|
163
|
+
export function decodeRun(dictionary, run, rules = READING_RULES, before = "", hints) {
|
|
164
|
+
const held = runLattice(dictionary, run, rules, before, hints);
|
|
160
165
|
const { lattice } = held;
|
|
161
166
|
const units = decodeReadings(lattice, projectReadings(lattice));
|
|
162
167
|
return runGroups(held, units).map((group) => wordFrom(dictionary, lattice, group));
|
|
@@ -173,8 +178,8 @@ export function decodeRun(dictionary, run, rules = READING_RULES, before = "") {
|
|
|
173
178
|
* is decoded with the run and reported with neither words nor confidence of its
|
|
174
179
|
* own.
|
|
175
180
|
*/
|
|
176
|
-
export function decodeRunScored(dictionary, run, rules = READING_RULES, before = "") {
|
|
177
|
-
const held = runLattice(dictionary, run, rules, before);
|
|
181
|
+
export function decodeRunScored(dictionary, run, rules = READING_RULES, before = "", hints) {
|
|
182
|
+
const held = runLattice(dictionary, run, rules, before, hints);
|
|
178
183
|
const { lattice } = held;
|
|
179
184
|
const units = scoreReadings(lattice, projectReadings(lattice));
|
|
180
185
|
return runGroups(held, units).map((group) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/decode/decode.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/decode/decode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { type Syllable } from "../syllable/syllable.js";
|
|
2
|
+
import { type Lattice } from "./lattice.js";
|
|
3
|
+
/**
|
|
4
|
+
* A reading a caller asserts for a word, wherever that word occurs.
|
|
5
|
+
*
|
|
6
|
+
* The same shape as the build-time override table
|
|
7
|
+
* {@link import("../dictionary/overrides.js").READING_OVERRIDES}, because it is
|
|
8
|
+
* the same idea moved from build time to call time: text on the left, the
|
|
9
|
+
* reading it takes on the right.
|
|
10
|
+
*/
|
|
11
|
+
export interface WordReading {
|
|
12
|
+
/** The characters this reading is asserted for. */
|
|
13
|
+
readonly word: string;
|
|
14
|
+
/** The reading, space-separated: `"tài cháng"`. */
|
|
15
|
+
readonly reading: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A reading a caller asserts for one character of one text.
|
|
19
|
+
*
|
|
20
|
+
* The escape hatch for a text no word-keyed hint can settle, which is a real
|
|
21
|
+
* category rather than a hypothetical one: 孩子越长越漂亮 grows and
|
|
22
|
+
* 头发越长越漂亮 lengthens, so the same four characters take different readings
|
|
23
|
+
* and only the caller knows which was meant.
|
|
24
|
+
*/
|
|
25
|
+
export interface PositionalReading {
|
|
26
|
+
/**
|
|
27
|
+
* Which character, counted in code points from the start of the text.
|
|
28
|
+
*
|
|
29
|
+
* Code points rather than UTF-16 units, matching {@link toCharacters}, so
|
|
30
|
+
* that a character outside the BMP counts as the one character it is.
|
|
31
|
+
*/
|
|
32
|
+
readonly at: number;
|
|
33
|
+
/** The reading that character takes, which is one syllable. */
|
|
34
|
+
readonly reading: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* One reading a caller asserts, keyed either by the word or by the position.
|
|
38
|
+
*/
|
|
39
|
+
export type ReadingHint = WordReading | PositionalReading;
|
|
40
|
+
/**
|
|
41
|
+
* Readings a caller asserts over whatever the sources say.
|
|
42
|
+
*
|
|
43
|
+
* Either a plain object of word to reading, which is the terse form for the
|
|
44
|
+
* corrections table an application accumulates, or a list, which is what to
|
|
45
|
+
* reach for when positions are needed or when both kinds are mixed.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* convert(dictionary, text, { readings: { 太长: "tài cháng" } });
|
|
49
|
+
* convert(dictionary, text, { readings: [{ at: 3, reading: "cháng" }] });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export type ReadingHints = Readonly<Record<string, string>> | readonly ReadingHint[];
|
|
53
|
+
/**
|
|
54
|
+
* A caller's hints, parsed and split by which kind they are.
|
|
55
|
+
*/
|
|
56
|
+
export interface ResolvedHints {
|
|
57
|
+
/** Word hints, longest first, so a longer assertion wins a shared start. */
|
|
58
|
+
readonly words: readonly WordHint[];
|
|
59
|
+
/**
|
|
60
|
+
* Positional hints, by code-point index into the text.
|
|
61
|
+
*
|
|
62
|
+
* One syllable rather than a reading, because a position names one character
|
|
63
|
+
* and there is nowhere to put a second. {@link resolveHints} is what makes
|
|
64
|
+
* that true, so nothing downstream has to check it.
|
|
65
|
+
*/
|
|
66
|
+
readonly at: ReadonlyMap<number, Syllable>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* One word hint, with its characters and reading already taken apart.
|
|
70
|
+
*/
|
|
71
|
+
interface WordHint {
|
|
72
|
+
readonly characters: readonly string[];
|
|
73
|
+
readonly reading: readonly Syllable[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Take a space-separated reading apart into syllables.
|
|
77
|
+
*
|
|
78
|
+
* An unmarked syllable is 轻声, as it is everywhere else in this package: a
|
|
79
|
+
* caller writing `"dài fu"` means the neutral 夫 rather than an unknown tone.
|
|
80
|
+
*
|
|
81
|
+
* Throws rather than ignoring what it cannot read. A hint is a caller asserting
|
|
82
|
+
* something against every source, so a hint that does not parse is a mistake in
|
|
83
|
+
* the calling code, and silently converting as though it had not been given
|
|
84
|
+
* would hide it behind a reading that merely looks plausible.
|
|
85
|
+
*/
|
|
86
|
+
export declare function readHintReading(reading: string, subject: string): readonly Syllable[];
|
|
87
|
+
/**
|
|
88
|
+
* Parse a caller's hints once, before any run is decoded.
|
|
89
|
+
*
|
|
90
|
+
* Word hints are sorted longest first so that a caller asserting both 长 and
|
|
91
|
+
* 太长 gets the longer assertion where both match, which is the same
|
|
92
|
+
* longest-wins rule the dictionary itself is read by.
|
|
93
|
+
*/
|
|
94
|
+
export declare function resolveHints(hints: ReadingHints): ResolvedHints;
|
|
95
|
+
/**
|
|
96
|
+
* The same hints with every position moved along by an offset.
|
|
97
|
+
*
|
|
98
|
+
* Word hints match on what is written and so are carried over untouched; only
|
|
99
|
+
* the positional ones are counted from somewhere. Used where a run is decoded
|
|
100
|
+
* with context in front of it, which moves the run's own characters up the
|
|
101
|
+
* lattice by the length of that context.
|
|
102
|
+
*/
|
|
103
|
+
export declare function shiftHints(hints: ResolvedHints, by: number): ResolvedHints;
|
|
104
|
+
/**
|
|
105
|
+
* The hints that fall inside a run, with their positions made relative to it.
|
|
106
|
+
*
|
|
107
|
+
* A caller counts positions from the start of the whole text, while a run is
|
|
108
|
+
* decoded on its own, so the positions have to be moved to where the run put
|
|
109
|
+
* them — and the ones naming a character in some other run dropped, rather than
|
|
110
|
+
* landing on whatever happens to sit at that index here.
|
|
111
|
+
*/
|
|
112
|
+
export declare function hintsWithin(hints: ResolvedHints, from: number, length: number): ResolvedHints;
|
|
113
|
+
/**
|
|
114
|
+
* A caller's readings, put into a lattice that was built without them.
|
|
115
|
+
*
|
|
116
|
+
* Two kinds of hint with deliberately different reach, which is the whole of
|
|
117
|
+
* the semantics:
|
|
118
|
+
*
|
|
119
|
+
* A **word** hint is an assertion about the text it names, so it rewrites the
|
|
120
|
+
* edge spanning exactly those characters and supplies the single-character
|
|
121
|
+
* edges underneath it. It says nothing about a *longer* word that happens to
|
|
122
|
+
* contain it — a bare 长 hint leaves 校长 as `xiàozhǎng`, because the dictionary
|
|
123
|
+
* knowing 校长 is better evidence about that stretch than a caller's remark
|
|
124
|
+
* about one of its characters. That is what makes a corrections table safe to
|
|
125
|
+
* accumulate: entries do not reach into words nobody was thinking about.
|
|
126
|
+
*
|
|
127
|
+
* A **positional** hint is an assertion about one character of one text, and it
|
|
128
|
+
* is the escape hatch precisely because nothing outranks it: it rewrites every
|
|
129
|
+
* edge covering that position, the enclosing word included. Only a reading of
|
|
130
|
+
* one syllable per character can be rewritten this way; a 儿化 edge is a single
|
|
131
|
+
* claim about its whole span and there is no one syllable in it to replace.
|
|
132
|
+
*
|
|
133
|
+
* Nothing is invented that a caller did not write, and nothing is dropped: an
|
|
134
|
+
* edge whose reading no hint touches comes through as it was.
|
|
135
|
+
*/
|
|
136
|
+
export declare function applyHints(lattice: Lattice, hints: ResolvedHints): Lattice;
|
|
137
|
+
export {};
|
|
138
|
+
//# sourceMappingURL=hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hints.d.ts","sourceRoot":"","sources":["../../src/decode/hints.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EACL,KAAK,OAAO,EAIb,MAAM,cAAc,CAAC;AAEtB;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GACpB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAChC,SAAS,WAAW,EAAE,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,UAAU,QAAQ;IAChB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;CACvC;AASD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,SAAS,QAAQ,EAAE,CAYrB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAwC/D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,aAAa,CAQf;AAeD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAyF1E"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { toCharacters } from "../script/characters.js";
|
|
2
|
+
import { readSyllable } from "../syllable/syllable.js";
|
|
3
|
+
import { NEUTRAL_TONE } from "../tone/tone.js";
|
|
4
|
+
import { READING_CHARGE, UNKNOWN_COST, } from "./lattice.js";
|
|
5
|
+
/**
|
|
6
|
+
* Whether a hint names a position rather than a word.
|
|
7
|
+
*/
|
|
8
|
+
function isPositional(hint) {
|
|
9
|
+
return "at" in hint;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Take a space-separated reading apart into syllables.
|
|
13
|
+
*
|
|
14
|
+
* An unmarked syllable is 轻声, as it is everywhere else in this package: a
|
|
15
|
+
* caller writing `"dài fu"` means the neutral 夫 rather than an unknown tone.
|
|
16
|
+
*
|
|
17
|
+
* Throws rather than ignoring what it cannot read. A hint is a caller asserting
|
|
18
|
+
* something against every source, so a hint that does not parse is a mistake in
|
|
19
|
+
* the calling code, and silently converting as though it had not been given
|
|
20
|
+
* would hide it behind a reading that merely looks plausible.
|
|
21
|
+
*/
|
|
22
|
+
export function readHintReading(reading, subject) {
|
|
23
|
+
const syllables = reading.split(/\s+/u).filter((token) => token !== "");
|
|
24
|
+
if (syllables.length === 0) {
|
|
25
|
+
throw new Error(`reading hint for ${subject} is empty`);
|
|
26
|
+
}
|
|
27
|
+
return syllables.map((token) => {
|
|
28
|
+
const syllable = readSyllable(token);
|
|
29
|
+
if (syllable === undefined) {
|
|
30
|
+
throw new Error(`reading hint for ${subject} is not pinyin: ${token}`);
|
|
31
|
+
}
|
|
32
|
+
return { ...syllable, tone: syllable.tone ?? NEUTRAL_TONE };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parse a caller's hints once, before any run is decoded.
|
|
37
|
+
*
|
|
38
|
+
* Word hints are sorted longest first so that a caller asserting both 长 and
|
|
39
|
+
* 太长 gets the longer assertion where both match, which is the same
|
|
40
|
+
* longest-wins rule the dictionary itself is read by.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveHints(hints) {
|
|
43
|
+
const list = Array.isArray(hints)
|
|
44
|
+
? hints
|
|
45
|
+
: Object.entries(hints).map(([word, reading]) => ({ word, reading }));
|
|
46
|
+
const words = [];
|
|
47
|
+
const at = new Map();
|
|
48
|
+
for (const hint of list) {
|
|
49
|
+
if (isPositional(hint)) {
|
|
50
|
+
if (!Number.isInteger(hint.at) || hint.at < 0) {
|
|
51
|
+
throw new Error(`reading hint position is not an index: ${hint.at}`);
|
|
52
|
+
}
|
|
53
|
+
const subject = `position ${String(hint.at)}`;
|
|
54
|
+
const syllables = readHintReading(hint.reading, subject);
|
|
55
|
+
// A position names one character. A reading of several syllables is a
|
|
56
|
+
// caller meaning something else — most likely a word hint — and saying so
|
|
57
|
+
// beats applying the first syllable or quietly applying none.
|
|
58
|
+
if (syllables.length !== 1 || syllables[0] === undefined) {
|
|
59
|
+
throw new Error(`reading hint for ${subject} is not one syllable: ${hint.reading}`);
|
|
60
|
+
}
|
|
61
|
+
at.set(hint.at, syllables[0]);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const characters = toCharacters(hint.word);
|
|
65
|
+
if (characters.length === 0) {
|
|
66
|
+
throw new Error("reading hint has no word");
|
|
67
|
+
}
|
|
68
|
+
words.push({
|
|
69
|
+
characters,
|
|
70
|
+
reading: readHintReading(hint.reading, hint.word),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
words.sort((left, right) => right.characters.length - left.characters.length);
|
|
74
|
+
return { words, at };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The same hints with every position moved along by an offset.
|
|
78
|
+
*
|
|
79
|
+
* Word hints match on what is written and so are carried over untouched; only
|
|
80
|
+
* the positional ones are counted from somewhere. Used where a run is decoded
|
|
81
|
+
* with context in front of it, which moves the run's own characters up the
|
|
82
|
+
* lattice by the length of that context.
|
|
83
|
+
*/
|
|
84
|
+
export function shiftHints(hints, by) {
|
|
85
|
+
return {
|
|
86
|
+
words: hints.words,
|
|
87
|
+
at: new Map([...hints.at].map(([at, syllable]) => [at + by, syllable])),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The hints that fall inside a run, with their positions made relative to it.
|
|
92
|
+
*
|
|
93
|
+
* A caller counts positions from the start of the whole text, while a run is
|
|
94
|
+
* decoded on its own, so the positions have to be moved to where the run put
|
|
95
|
+
* them — and the ones naming a character in some other run dropped, rather than
|
|
96
|
+
* landing on whatever happens to sit at that index here.
|
|
97
|
+
*/
|
|
98
|
+
export function hintsWithin(hints, from, length) {
|
|
99
|
+
const at = new Map();
|
|
100
|
+
for (const [position, syllable] of hints.at) {
|
|
101
|
+
if (position >= from && position < from + length) {
|
|
102
|
+
at.set(position - from, syllable);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { words: hints.words, at };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Whether a hint's characters are what stands at a position.
|
|
109
|
+
*/
|
|
110
|
+
function matchesAt(hint, characters, at) {
|
|
111
|
+
return hint.characters.every((character, index) => characters[at + index] === character);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A caller's readings, put into a lattice that was built without them.
|
|
115
|
+
*
|
|
116
|
+
* Two kinds of hint with deliberately different reach, which is the whole of
|
|
117
|
+
* the semantics:
|
|
118
|
+
*
|
|
119
|
+
* A **word** hint is an assertion about the text it names, so it rewrites the
|
|
120
|
+
* edge spanning exactly those characters and supplies the single-character
|
|
121
|
+
* edges underneath it. It says nothing about a *longer* word that happens to
|
|
122
|
+
* contain it — a bare 长 hint leaves 校长 as `xiàozhǎng`, because the dictionary
|
|
123
|
+
* knowing 校长 is better evidence about that stretch than a caller's remark
|
|
124
|
+
* about one of its characters. That is what makes a corrections table safe to
|
|
125
|
+
* accumulate: entries do not reach into words nobody was thinking about.
|
|
126
|
+
*
|
|
127
|
+
* A **positional** hint is an assertion about one character of one text, and it
|
|
128
|
+
* is the escape hatch precisely because nothing outranks it: it rewrites every
|
|
129
|
+
* edge covering that position, the enclosing word included. Only a reading of
|
|
130
|
+
* one syllable per character can be rewritten this way; a 儿化 edge is a single
|
|
131
|
+
* claim about its whole span and there is no one syllable in it to replace.
|
|
132
|
+
*
|
|
133
|
+
* Nothing is invented that a caller did not write, and nothing is dropped: an
|
|
134
|
+
* edge whose reading no hint touches comes through as it was.
|
|
135
|
+
*/
|
|
136
|
+
export function applyHints(lattice, hints) {
|
|
137
|
+
const { characters } = lattice;
|
|
138
|
+
/** The word hint covering a position, and how far into it that position is. */
|
|
139
|
+
const wordAt = (at) => {
|
|
140
|
+
for (const hint of hints.words) {
|
|
141
|
+
if (hint.reading.length !== hint.characters.length) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
for (let held = 0; held < hint.characters.length; held++) {
|
|
145
|
+
if (at - held >= 0 && matchesAt(hint, characters, at - held)) {
|
|
146
|
+
return { hint, held };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
};
|
|
152
|
+
const rewrite = (edge) => {
|
|
153
|
+
const span = edge.to - edge.from;
|
|
154
|
+
// A word hint naming exactly this stretch replaces its reading outright,
|
|
155
|
+
// which is the only way a hint can reach a word the dictionary already has
|
|
156
|
+
// an opinion about: 银行 asserted as `yín xíng` has to beat `yínháng`.
|
|
157
|
+
const exact = hints.words.find((hint) => hint.characters.length === span &&
|
|
158
|
+
matchesAt(hint, characters, edge.from));
|
|
159
|
+
let reading = exact === undefined ? edge.reading : exact.reading;
|
|
160
|
+
// Everything below needs one syllable per character to have a syllable to
|
|
161
|
+
// put anywhere.
|
|
162
|
+
if (reading.length === span) {
|
|
163
|
+
reading = reading.map((syllable, index) => {
|
|
164
|
+
const at = edge.from + index;
|
|
165
|
+
const positional = hints.at.get(at);
|
|
166
|
+
if (positional !== undefined) {
|
|
167
|
+
return positional;
|
|
168
|
+
}
|
|
169
|
+
if (span > 1) {
|
|
170
|
+
return syllable;
|
|
171
|
+
}
|
|
172
|
+
// Single-character edges also take what a longer word hint says about
|
|
173
|
+
// this position, so that the split path reads the same as the whole.
|
|
174
|
+
const found = wordAt(at);
|
|
175
|
+
return found?.hint.reading[found.held] ?? syllable;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return reading === edge.reading ? edge : { ...edge, reading };
|
|
179
|
+
};
|
|
180
|
+
return {
|
|
181
|
+
characters,
|
|
182
|
+
edges: lattice.edges.map((edges, at) => {
|
|
183
|
+
const rewritten = edges.map((edge) => rewrite(edge));
|
|
184
|
+
// A hint spanning characters no edge covers has nowhere to be written, so
|
|
185
|
+
// it brings its own edge: 玩儿 as `wánr` where the dictionary lacks it.
|
|
186
|
+
const spanning = hints.words.find((hint) => hint.reading.length !== hint.characters.length &&
|
|
187
|
+
matchesAt(hint, characters, at) &&
|
|
188
|
+
!rewritten.some((edge) => edge.to === at + hint.characters.length));
|
|
189
|
+
if (spanning === undefined) {
|
|
190
|
+
return rewritten;
|
|
191
|
+
}
|
|
192
|
+
const to = at + spanning.characters.length;
|
|
193
|
+
return [
|
|
194
|
+
...rewritten,
|
|
195
|
+
{
|
|
196
|
+
from: at,
|
|
197
|
+
to,
|
|
198
|
+
text: spanning.characters.join(""),
|
|
199
|
+
reading: spanning.reading,
|
|
200
|
+
cost: UNKNOWN_COST,
|
|
201
|
+
readingCost: UNKNOWN_COST + READING_CHARGE,
|
|
202
|
+
isProperNoun: false,
|
|
203
|
+
partOfSpeech: "",
|
|
204
|
+
// No dictionary entry backs this one — that is the whole reason it
|
|
205
|
+
// had to be brought along — so it reports itself as the fallback it
|
|
206
|
+
// is. A hint written over an edge that *was* backed keeps that edge's
|
|
207
|
+
// own answer, since the entry still covers those characters.
|
|
208
|
+
isKnown: false,
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
}),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=hints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hints.js","sourceRoot":"","sources":["../../src/decode/hints.ts"],"names":[],"mappings":"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"}
|
package/dist/decode/lattice.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Dictionary } from "../dictionary/dictionary.js";
|
|
2
2
|
import type { Syllable } from "../syllable/syllable.js";
|
|
3
|
+
import { type ResolvedHints } from "./hints.js";
|
|
3
4
|
/**
|
|
4
5
|
* One candidate reading of one stretch of characters.
|
|
5
6
|
*
|
|
@@ -51,6 +52,13 @@ export interface Lattice {
|
|
|
51
52
|
* second — is the one ALGORITHM.md already gives its data-free fallback tier.
|
|
52
53
|
*/
|
|
53
54
|
export declare const READING_CHARGE = 16;
|
|
55
|
+
/**
|
|
56
|
+
* What an edge covering a character no dictionary entry knows costs.
|
|
57
|
+
*
|
|
58
|
+
* Above the worst cost a real entry can carry, so that any known reading is
|
|
59
|
+
* preferred to none.
|
|
60
|
+
*/
|
|
61
|
+
export declare const UNKNOWN_COST = 32;
|
|
54
62
|
/**
|
|
55
63
|
* Build the lattice of every way a Han run could be read.
|
|
56
64
|
*
|
|
@@ -59,7 +67,7 @@ export declare const READING_CHARGE = 16;
|
|
|
59
67
|
* candidate so that later stages can compare them — which is the whole point,
|
|
60
68
|
* since a greedy choice that is locally right can be globally wrong.
|
|
61
69
|
*/
|
|
62
|
-
export declare function buildLattice(dictionary: Dictionary, run: string): Lattice;
|
|
70
|
+
export declare function buildLattice(dictionary: Dictionary, run: string, hints?: ResolvedHints): Lattice;
|
|
63
71
|
/**
|
|
64
72
|
* Every edge in the lattice, in no particular order.
|
|
65
73
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lattice.d.ts","sourceRoot":"","sources":["../../src/decode/lattice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"lattice.d.ts","sourceRoot":"","sources":["../../src/decode/lattice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,WAAW,EAAE,CAAC,EAAE,CAAC;CACrD;AAoBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,KAAK,CAAC;AA+F/B;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAaT;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,WAAW,EAAE,CAEjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAuB7D"}
|
package/dist/decode/lattice.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { toCharacters } from "../script/characters.js";
|
|
2
|
+
import { applyHints } from "./hints.js";
|
|
2
3
|
/**
|
|
3
4
|
* How far ahead a match is looked for.
|
|
4
5
|
*
|
|
@@ -41,7 +42,7 @@ export const READING_CHARGE = 16;
|
|
|
41
42
|
* Above the worst cost a real entry can carry, so that any known reading is
|
|
42
43
|
* preferred to none.
|
|
43
44
|
*/
|
|
44
|
-
const UNKNOWN_COST = 32;
|
|
45
|
+
export const UNKNOWN_COST = 32;
|
|
45
46
|
/**
|
|
46
47
|
* The edges leaving a position that come from multi-character dictionary words.
|
|
47
48
|
*
|
|
@@ -125,7 +126,7 @@ function characterEdgesAt(dictionary, characters, at) {
|
|
|
125
126
|
* candidate so that later stages can compare them — which is the whole point,
|
|
126
127
|
* since a greedy choice that is locally right can be globally wrong.
|
|
127
128
|
*/
|
|
128
|
-
export function buildLattice(dictionary, run) {
|
|
129
|
+
export function buildLattice(dictionary, run, hints) {
|
|
129
130
|
const characters = toCharacters(run);
|
|
130
131
|
const edges = [];
|
|
131
132
|
for (let at = 0; at < characters.length; at++) {
|
|
@@ -134,7 +135,8 @@ export function buildLattice(dictionary, run) {
|
|
|
134
135
|
...characterEdgesAt(dictionary, characters, at),
|
|
135
136
|
]);
|
|
136
137
|
}
|
|
137
|
-
|
|
138
|
+
const lattice = { characters, edges };
|
|
139
|
+
return hints === undefined ? lattice : applyHints(lattice, hints);
|
|
138
140
|
}
|
|
139
141
|
/**
|
|
140
142
|
* Every edge in the lattice, in no particular order.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lattice.js","sourceRoot":"","sources":["../../src/decode/lattice.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"lattice.js","sourceRoot":"","sources":["../../src/decode/lattice.ts"],"names":[],"mappings":"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"}
|
|
@@ -106,6 +106,34 @@ export declare const TEACHING_JIAO: EdgeRule;
|
|
|
106
106
|
* corpus and it is a fix, 下了两天雨 having read 天雨 as `tiān yù`.
|
|
107
107
|
*/
|
|
108
108
|
export declare const COUNTED_MEASURE: EdgeRule;
|
|
109
|
+
/**
|
|
110
|
+
* 长 read as `cháng` where an adverb of degree measures it.
|
|
111
|
+
*
|
|
112
|
+
* The character is stored `zhǎng` with `cháng` as an alternate, and the data
|
|
113
|
+
* says so about the character in isolation: Unihan ranks the readings
|
|
114
|
+
* `zhǎng(1879) cháng(1179)` by corpus count and names `zhǎng` in `kMandarin`.
|
|
115
|
+
* That ranking is doing real work — 署长, 团长, 公安局长, 总会长, 审理长 and
|
|
116
|
+
* the rest reach a bare 长 at the end of a title and read it correctly — so the
|
|
117
|
+
* default is not the thing to change. What is left over is the 长 that is an
|
|
118
|
+
* adjective, and nothing in the cost model can prefer an alternate at a
|
|
119
|
+
* position no word covers: 这篇文章不太长 came out `bú tài zhǎng`.
|
|
120
|
+
*
|
|
121
|
+
* The context that separates them is one-sided, as it was for the modal 得. A
|
|
122
|
+
* 长 that is *growing* is a verb, and a degree adverb cannot modify one — there
|
|
123
|
+
* is no 很长 meaning it grew a lot — so 很, 太, 最, 多 and their kin in front of
|
|
124
|
+
* a bare 长 make it the adjective. The other side carries almost nothing: what
|
|
125
|
+
* follows an adjectival 长 is a noun (很长时间), a particle (最长的大桥), or the
|
|
126
|
+
* end of the sentence (他的腿很长), which is also what follows half the verbs.
|
|
127
|
+
*
|
|
128
|
+
* Measured over the same 88,866 lines of Tatoeba and zh.wikipedia the other
|
|
129
|
+
* rules were sized against, 260 长 decode as a word of their own and this moves
|
|
130
|
+
* 75 of them to `cháng`, all 75 correctly. On CPP's 40 hand-labelled 长 it takes
|
|
131
|
+
* the character from 85.00% to 87.50%, fixing 时间最长 and breaking nothing.
|
|
132
|
+
*
|
|
133
|
+
* The other half of the rule is {@link GROWN_INTO}, which pushes the opposite
|
|
134
|
+
* way on the one shape the sources get wrong.
|
|
135
|
+
*/
|
|
136
|
+
export declare const ADJECTIVAL_CHANG: EdgeRule;
|
|
109
137
|
/**
|
|
110
138
|
* The rules the lattice decode applies, in order.
|
|
111
139
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reading-rules.d.ts","sourceRoot":"","sources":["../../src/decode/reading-rules.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,QAAQ,EAId,MAAM,YAAY,CAAC;AAgCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,QAAQ,EAAE,QActB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,cAAc,EAAE,QAY5B,CAAC;AAqDF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,aAAa,EAAE,QAiB3B,CAAC;AAsCF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,eAAe,EAAE,QAuB7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,QAAQ,
|
|
1
|
+
{"version":3,"file":"reading-rules.d.ts","sourceRoot":"","sources":["../../src/decode/reading-rules.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,QAAQ,EAId,MAAM,YAAY,CAAC;AAgCpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,QAAQ,EAAE,QActB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,cAAc,EAAE,QAY5B,CAAC;AAqDF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,aAAa,EAAE,QAiB3B,CAAC;AAsCF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,eAAe,EAAE,QAuB7B,CAAC;AA2HF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAgB9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,QAAQ,EAM5C,CAAC"}
|