@kensio/pinyinjs 1.5.3 → 1.7.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/README.md +252 -5
- package/data/core.entries +462 -460
- package/data/core.freq +0 -0
- package/data/core.keys +2 -0
- package/data/full.entries +13732 -13734
- package/data/full.freq +0 -0
- package/data/full.keys +0 -2
- package/data/manifest.json +15 -15
- package/data/script.map +34 -55
- package/data/standard.entries +1354 -1352
- package/data/standard.freq +0 -0
- package/data/standard.keys +2 -0
- package/dist/cli/arguments.d.ts +38 -0
- package/dist/cli/arguments.d.ts.map +1 -1
- package/dist/cli/arguments.js +46 -0
- package/dist/cli/arguments.js.map +1 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +229 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +5 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/decode/convert.d.ts +58 -0
- package/dist/decode/convert.d.ts.map +1 -1
- package/dist/decode/convert.js +135 -37
- 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/decode/runs.d.ts +11 -0
- package/dist/decode/runs.d.ts.map +1 -1
- package/dist/decode/runs.js +19 -0
- package/dist/decode/runs.js.map +1 -1
- package/dist/decode/segment.d.ts +66 -0
- package/dist/decode/segment.d.ts.map +1 -0
- package/dist/decode/segment.js +79 -0
- package/dist/decode/segment.js.map +1 -0
- package/dist/dictionary/artifact.d.ts +10 -0
- package/dist/dictionary/artifact.d.ts.map +1 -1
- package/dist/dictionary/artifact.js +17 -0
- package/dist/dictionary/artifact.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/corpus-mass.d.ts +68 -0
- package/dist/dictionary/corpus-mass.d.ts.map +1 -0
- package/dist/dictionary/corpus-mass.js +123 -0
- package/dist/dictionary/corpus-mass.js.map +1 -0
- package/dist/dictionary/dictionary.d.ts +56 -0
- package/dist/dictionary/dictionary.d.ts.map +1 -1
- package/dist/dictionary/dictionary.js +116 -1
- package/dist/dictionary/dictionary.js.map +1 -1
- package/dist/dictionary/erhua.d.ts +4 -0
- package/dist/dictionary/erhua.d.ts.map +1 -1
- package/dist/dictionary/erhua.js +6 -0
- package/dist/dictionary/erhua.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 +46 -9
- package/dist/dictionary/merge.js.map +1 -1
- package/dist/dictionary/tiers.d.ts +2 -1
- package/dist/dictionary/tiers.d.ts.map +1 -1
- package/dist/dictionary/tiers.js +77 -11
- package/dist/dictionary/tiers.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/grade/check.d.ts +156 -0
- package/dist/grade/check.d.ts.map +1 -0
- package/dist/grade/check.js +356 -0
- package/dist/grade/check.js.map +1 -0
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/search/candidates.d.ts +84 -0
- package/dist/search/candidates.d.ts.map +1 -0
- package/dist/search/candidates.js +290 -0
- package/dist/search/candidates.js.map +1 -0
- package/dist/search/match.d.ts +72 -0
- package/dist/search/match.d.ts.map +1 -0
- package/dist/search/match.js +419 -0
- package/dist/search/match.js.map +1 -0
- package/dist/search/query.d.ts +49 -0
- package/dist/search/query.d.ts.map +1 -0
- package/dist/search/query.js +115 -0
- package/dist/search/query.js.map +1 -0
- package/dist/search/reverse-index.d.ts +141 -0
- package/dist/search/reverse-index.d.ts.map +1 -0
- package/dist/search/reverse-index.js +356 -0
- package/dist/search/reverse-index.js.map +1 -0
- package/dist/sources/unihan.d.ts +22 -4
- package/dist/sources/unihan.d.ts.map +1 -1
- package/dist/sources/unihan.js +74 -13
- package/dist/sources/unihan.js.map +1 -1
- package/package.json +2 -3
- package/CHANGELOG.md +0 -485
package/README.md
CHANGED
|
@@ -35,6 +35,11 @@ wo3-xiang3-xue2-zhong1wen2
|
|
|
35
35
|
$ pinyinjs script 我们后来发现了头发问题 --to zh-Hant
|
|
36
36
|
我們後來發現了頭髮問題
|
|
37
37
|
|
|
38
|
+
$ pinyinjs check 银行 yínxíng
|
|
39
|
+
银行 yínháng 50%
|
|
40
|
+
银 yín yín correct
|
|
41
|
+
行 háng xíng wrong
|
|
42
|
+
|
|
38
43
|
$ pinyinjs explain 银行
|
|
39
44
|
银行 yínháng
|
|
40
45
|
yín locked
|
|
@@ -43,6 +48,11 @@ $ pinyinjs explain 银行
|
|
|
43
48
|
$ pinyinjs lookup 头发
|
|
44
49
|
头发 tóu fa n
|
|
45
50
|
|
|
51
|
+
$ pinyinjs match --query bjdx 北京大学 我在北京大学学中文 上海大学
|
|
52
|
+
[北京大学] 7.00
|
|
53
|
+
我在[北京大学]学中文 6.33
|
|
54
|
+
上海大学 no match
|
|
55
|
+
|
|
46
56
|
$ pinyinjs syllable nǐhǎo
|
|
47
57
|
nǐhǎo nǐ hǎo
|
|
48
58
|
nǐ n + i, tone 3 nǐ ni3 ni³
|
|
@@ -59,6 +69,10 @@ běijīng běijīng ㄅㄟˇ ㄐㄧㄥ pei³-ching¹ běijīng beeij
|
|
|
59
69
|
| ------------ | --------------------------------------------------- |
|
|
60
70
|
| `convert` | hanzi to pinyin |
|
|
61
71
|
| `html` | the same, as HTML |
|
|
72
|
+
| `annotate` | hanzi with its pinyin above, as ruby HTML |
|
|
73
|
+
| `segment` | split text into words |
|
|
74
|
+
| `match` | filter text by a pinyin query, best first |
|
|
75
|
+
| `check` | mark typed pinyin against the text |
|
|
62
76
|
| `slug` | hanzi to a URL-safe slug |
|
|
63
77
|
| `script` | 简体 ↔ 繁體 conversion |
|
|
64
78
|
| `explain` | each syllable, how settled it was, and what it beat |
|
|
@@ -143,9 +157,9 @@ Load the dictionary once and keep it; it is immutable and safe to share.
|
|
|
143
157
|
|
|
144
158
|
| Tier | Entries | Download (brotli) | Contains |
|
|
145
159
|
| ---------- | ------: | ----------------: | ---------------------- |
|
|
146
|
-
| `core` | 16,
|
|
147
|
-
| `standard` | 66,
|
|
148
|
-
| `full` | 461,
|
|
160
|
+
| `core` | 16,970 | 70 KB | single characters only |
|
|
161
|
+
| `standard` | 66,970 | 377 KB | the most common words |
|
|
162
|
+
| `full` | 461,555 | 2,378 KB | every word |
|
|
149
163
|
|
|
150
164
|
`full` is the default. The tiers are nested, so a page can load `standard`
|
|
151
165
|
first, convert with it, and reload as `full` arrives.
|
|
@@ -349,6 +363,231 @@ included, so write your own:
|
|
|
349
363
|
Takes any `convert` option, plus `toneClasses: false`, `markUncertain: false`
|
|
350
364
|
and `lang: false`. `toHtml(pieces, options)` renders pieces you already have.
|
|
351
365
|
|
|
366
|
+
## Annotated output: hanzi and pinyin together
|
|
367
|
+
|
|
368
|
+
`convertToHtml` writes the pinyin _instead of_ the hanzi. To keep both — a
|
|
369
|
+
learner's text, a subtitle, a dictionary entry — annotate it instead:
|
|
370
|
+
|
|
371
|
+
```ts
|
|
372
|
+
import { convertToAnnotatedHtml } from "@kensio/pinyinjs";
|
|
373
|
+
|
|
374
|
+
convertToAnnotatedHtml(dictionary, "银行");
|
|
375
|
+
// <ruby lang="zh">银<rp>(</rp><rt><span class="py-syllable py-tone-2"
|
|
376
|
+
// lang="zh-Latn-CN-pinyin">yín</span></rt><rp>)</rp></ruby>…
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
The markup is `<ruby>`, which browsers lay out natively — the reading sits
|
|
380
|
+
above the characters, and `<rp>` puts it in parentheses where it does not. Each
|
|
381
|
+
`<rt>` holds exactly what `convertToHtml` would have written, so tone colours
|
|
382
|
+
and uncertainty marking work inside an annotation as they do outside one.
|
|
383
|
+
|
|
384
|
+
**A base is not always one character**, and this is where per-character
|
|
385
|
+
annotation goes wrong. 玩儿 is two characters and the one syllable `wánr`, and a
|
|
386
|
+
read number reverses on the way, so both are annotated whole:
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
convertToAnnotatedHtml(dictionary, "玩儿"); // one <ruby>, 玩儿 over wánr
|
|
390
|
+
convertToAnnotatedHtml(dictionary, "95%"); // one <ruby>, 95% over bǎifēnzhījiǔshíwǔ
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Ruby needs no styling to work, but the reading is small by default:
|
|
394
|
+
|
|
395
|
+
```css
|
|
396
|
+
ruby rt {
|
|
397
|
+
font-size: 0.5em;
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
`toAnnotatedHtml(pieces, options)` renders pieces you already have, and
|
|
402
|
+
`ConvertedPiece.source` is what makes that possible: the characters each piece
|
|
403
|
+
reads, or undefined where it reads on into the ones before it.
|
|
404
|
+
|
|
405
|
+
## Segment
|
|
406
|
+
|
|
407
|
+
Converting has to find the words before it can read them, because the unit a
|
|
408
|
+
reading belongs to is the word — 行 is `xíng` or `háng` and only 银行 and 行长
|
|
409
|
+
say which. `segment` returns that answer instead of throwing it away.
|
|
410
|
+
|
|
411
|
+
```ts
|
|
412
|
+
import { segment } from "@kensio/pinyinjs";
|
|
413
|
+
|
|
414
|
+
segment(dictionary, "南京市长江大桥").map((found) => found.text);
|
|
415
|
+
// ["南京市", "长江", "大桥"], not ["南京", "市长", "江大桥"]
|
|
416
|
+
|
|
417
|
+
const found = segment(dictionary, "我要去北京。");
|
|
418
|
+
found.map((one) => one.text); // ["我", "要", "去", "北京", "。"]
|
|
419
|
+
found[3]?.partOfSpeech; // "ns", jieba's tag
|
|
420
|
+
found[3]?.isProperNoun; // true
|
|
421
|
+
found[3]?.at; // 3, in code points from the start of the text
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Every stretch comes back in order, including the ones that were never Han, so
|
|
425
|
+
the segments rejoin into exactly the text they came from — which is what makes
|
|
426
|
+
it safe to rebuild a document, highlight in place, or index a corpus. Filter on
|
|
427
|
+
`isKnown` for the stretches the dictionary recognised.
|
|
428
|
+
|
|
429
|
+
What it does not apply is 分词连写, the word spacing written pinyin wants: 他看了
|
|
430
|
+
segments as 他 / 看 / 了 and converts as `tā kànle`, because attaching an aspect
|
|
431
|
+
particle to its verb is a fact about writing pinyin rather than about where the
|
|
432
|
+
words are.
|
|
433
|
+
|
|
434
|
+
## Match a pinyin query
|
|
435
|
+
|
|
436
|
+
A search box on a Latin keyboard, filtering Chinese text. `match` returns where
|
|
437
|
+
a query landed, or undefined where it did not land at all.
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
import { match } from "@kensio/pinyinjs";
|
|
441
|
+
|
|
442
|
+
match(dictionary, "北京大学", "bjdx")?.ranges; // [{ at: 0, length: 4 }]
|
|
443
|
+
match(dictionary, "北京大学", "beijing")?.ranges; // [{ at: 0, length: 2 }]
|
|
444
|
+
match(dictionary, "北京大学", "nanjing"); // undefined
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Every way anybody types it: full syllables joined or spaced, `beijing` and
|
|
448
|
+
`bei jing`; initials, `bj`; the two mixed, `beij` and `bjing`; tones as digits
|
|
449
|
+
where they are worth writing, `bei3jing1`; `v` or `u:` for ü; and the r of 儿化
|
|
450
|
+
on the syllable it belongs to, so 玩儿 answers to `wanr`.
|
|
451
|
+
|
|
452
|
+
**No index is built and none is needed.** The haystack is Chinese, so the query
|
|
453
|
+
is tested as a path over each character's readings rather than the text being
|
|
454
|
+
spelled out in advance — which is why every reading of a polyphone is
|
|
455
|
+
matchable, where a default reading table only ever offers one of them:
|
|
456
|
+
|
|
457
|
+
```ts
|
|
458
|
+
match(dictionary, "银行", "yh")?.score; // 7, and 银行 is yínháng
|
|
459
|
+
match(dictionary, "银行", "yx")?.score; // 5 — a reading 行 has, but not here
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Both match, and the decoder's own reading is what ranks them, along with
|
|
463
|
+
whether the match starts a word. Sort a filtered list by `score`, highest
|
|
464
|
+
first. Ranges rather than a boolean, in code points, so a caller can highlight
|
|
465
|
+
what matched — and there is more than one where the query stepped over
|
|
466
|
+
something with no reading of its own, as 北京·大学 does.
|
|
467
|
+
|
|
468
|
+
The `core` tier is enough, so a page that never loads a word list can still
|
|
469
|
+
filter. See [matching](docs/matching/).
|
|
470
|
+
|
|
471
|
+
## Go the other way: pinyin to hanzi
|
|
472
|
+
|
|
473
|
+
`candidates` answers a pinyin query with the words it could be spelling, and
|
|
474
|
+
`homophonesOf` lists the words read exactly like one you already have. Both run
|
|
475
|
+
off a reverse index derived from the dictionary in memory.
|
|
476
|
+
|
|
477
|
+
```ts
|
|
478
|
+
import { candidates, homophonesOf, ReverseIndex } from "@kensio/pinyinjs";
|
|
479
|
+
|
|
480
|
+
const index = ReverseIndex.of(dictionary);
|
|
481
|
+
|
|
482
|
+
candidates(index, "shi", { limit: 5 }); // ["是", "时", "事", "使", "市"]
|
|
483
|
+
candidates(index, "yinhang"); // ["銀行", "银行", "引吭", "引航", "印航"]
|
|
484
|
+
candidates(index, "yínháng"); // ["銀行", "银行"], narrowed by tone
|
|
485
|
+
homophonesOf(index, "长城"); // ["長城", "長程", "长程", "常程"]
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
This is the half of search with no haystack: `match` filters Chinese text you
|
|
489
|
+
already hold, and this answers a query with nothing behind it but the
|
|
490
|
+
dictionary. Pinyin-only lookup, a homophones section on a word page, or a
|
|
491
|
+
browser input method for somebody with no Chinese keyboard.
|
|
492
|
+
|
|
493
|
+
**Nothing is downloaded for it.** Shipping a reverse index of the `full` tier
|
|
494
|
+
would add 1,995 KB to a 2,378 KB download and could not be compressed below
|
|
495
|
+
about 1,474 KB, so the client derives it instead — 510 ms and 2.03 MB of heap on
|
|
496
|
+
`full`, and 4 ms on `core`. `ReverseIndex.building` drives that build a slice at
|
|
497
|
+
a time, and `serialise` hands it out of a worker, so nothing has to hold the
|
|
498
|
+
main thread for it.
|
|
499
|
+
|
|
500
|
+
Candidates come back likeliest first, because a posting is a dictionary position
|
|
501
|
+
and a position indexes the frequency table. Tones may be written or left off,
|
|
502
|
+
`v` and `u:` reach ü, and the r of 儿化 is optional, so 玩儿 answers to `wanr`
|
|
503
|
+
and to `wan`. Both scripts are dictionary keys, so pass a script preference and
|
|
504
|
+
the conversion tables to keep one writing of a word rather than both. See
|
|
505
|
+
[candidates](docs/candidates/).
|
|
506
|
+
|
|
507
|
+
## Check what somebody typed
|
|
508
|
+
|
|
509
|
+
`check` marks a typed pinyin transcription against the Chinese it was written
|
|
510
|
+
for, syllable by syllable.
|
|
511
|
+
|
|
512
|
+
```ts
|
|
513
|
+
import { check } from "@kensio/pinyinjs";
|
|
514
|
+
|
|
515
|
+
const marked = check(dictionary, "银行", "yínxíng");
|
|
516
|
+
marked.syllables.map((one) => one.verdict); // ["correct", "wrong"]
|
|
517
|
+
marked.syllables[1]?.source; // "行", the character that was misread
|
|
518
|
+
marked.score; // 0.5
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
Each syllable comes back as one of six verdicts, with `source` and `at` naming
|
|
522
|
+
the characters it reads so a mistake can be shown against the text rather than
|
|
523
|
+
against the answer:
|
|
524
|
+
|
|
525
|
+
| Verdict | Means |
|
|
526
|
+
| ---------- | ---------------------------------------------- |
|
|
527
|
+
| `correct` | right syllable, right tone |
|
|
528
|
+
| `toneless` | right syllable, no tone written |
|
|
529
|
+
| `tone` | right syllable, wrong tone |
|
|
530
|
+
| `wrong` | wrong syllable |
|
|
531
|
+
| `missing` | a syllable of the reading that was not typed |
|
|
532
|
+
| `extra` | a syllable typed that the reading does not use |
|
|
533
|
+
|
|
534
|
+
**The point is being fair in the ways a string comparison cannot be.** All of
|
|
535
|
+
these are a learner being marked wrong for being right, and all of them pass:
|
|
536
|
+
|
|
537
|
+
```ts
|
|
538
|
+
check(dictionary, "北京", "bei3jīng").isCorrect; // true, either notation, mixed
|
|
539
|
+
check(dictionary, "行", "háng").isCorrect; // true, the decoder was guessing too
|
|
540
|
+
check(dictionary, "你好", "ní hǎo").isCorrect; // true, said with sandhi
|
|
541
|
+
check(dictionary, "不是", "bù shì").isCorrect; // true, written without it
|
|
542
|
+
check(dictionary, "海鸥", "hǎiōu").isCorrect; // true, an apostrophe is not a sound
|
|
543
|
+
check(dictionary, "我的书", "wǒ de shū").isCorrect; // true, pinyin marks no neutral tone
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
A guess is only forgiven where the library was guessing: 行 alone is chosen by a
|
|
547
|
+
prior and nothing more, whereas 银行 settles both its syllables, so `yínxíng` is
|
|
548
|
+
a real mistake. See [confidence](docs/confidence/).
|
|
549
|
+
|
|
550
|
+
### Tones and word spacing
|
|
551
|
+
|
|
552
|
+
Two axes an exercise may or may not be teaching yet, each reported always and
|
|
553
|
+
each counted only when asked for.
|
|
554
|
+
|
|
555
|
+
Tones left off are `toneless` rather than `tone`, because `Syllable.tone` knows
|
|
556
|
+
the difference:
|
|
557
|
+
|
|
558
|
+
```ts
|
|
559
|
+
check(dictionary, "北京", "bei jing").isCorrect; // true
|
|
560
|
+
check(dictionary, "北京", "bei jing", { tones: "required" }).isCorrect; // false
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Word spacing is graded on `spacing`, separately from the syllable's own verdict,
|
|
564
|
+
because it is a separate mistake: `yín háng` reads 银行 perfectly and writes it
|
|
565
|
+
as two words.
|
|
566
|
+
|
|
567
|
+
```ts
|
|
568
|
+
const split = check(dictionary, "银行", "yín háng");
|
|
569
|
+
split.syllables.map((one) => one.spacing); // ["correct", "split"]
|
|
570
|
+
split.isCorrect; // true, spacing is not counted by default
|
|
571
|
+
check(dictionary, "银行", "yín háng", { spacing: "required" }).isCorrect; // false
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
It is `split` for a word written as two and `joined` for two written as one, and
|
|
575
|
+
it is tolerant in the same spirit as everything else — 分词连写 and the words the
|
|
576
|
+
dictionary knows are two conventions this package writes, and a learner may have
|
|
577
|
+
been taught either:
|
|
578
|
+
|
|
579
|
+
```ts
|
|
580
|
+
const graded = { spacing: "required" } as const;
|
|
581
|
+
check(dictionary, "他看了", "tā kànle", graded).isCorrect; // true, 分词连写
|
|
582
|
+
check(dictionary, "他看了", "tā kàn le", graded).isCorrect; // true, the words
|
|
583
|
+
check(dictionary, "干干净净", "gāngān jìngjìng", graded).isCorrect; // true, a hyphen is a boundary
|
|
584
|
+
check(dictionary, "我要去北京。", "wǒyàoqùběijīng", graded).isCorrect; // false
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
Takes every `convert` option besides, so an exercise that knows which sense of 长
|
|
588
|
+
its own sentence uses can say so with `readings`. More in
|
|
589
|
+
[checking](docs/checking/).
|
|
590
|
+
|
|
352
591
|
## Look words up
|
|
353
592
|
|
|
354
593
|
```ts
|
|
@@ -598,6 +837,13 @@ This is orthography and not translation — 软件 becomes 軟件, never 軟體.
|
|
|
598
837
|
| `convert(dictionary, text, options?)` | hanzi → pinyin |
|
|
599
838
|
| `convertPieces(dictionary, text, ...)` | the same, per syllable, with confidence |
|
|
600
839
|
| `convertToHtml(dictionary, text, ...)` | the same, as HTML |
|
|
840
|
+
| `convertToAnnotatedHtml(dictionary, text, ...)` | hanzi and pinyin together, as ruby HTML |
|
|
841
|
+
| `segment(dictionary, text)` | split text into words |
|
|
842
|
+
| `match(dictionary, haystack, query)` | where a pinyin query matches a text |
|
|
843
|
+
| `candidates(index, query, options?)` | pinyin → the hanzi it could be |
|
|
844
|
+
| `homophonesOf(index, word, options?)` | the words read exactly like this one |
|
|
845
|
+
| `ReverseIndex.of(dictionary)` | derive the reading → words index |
|
|
846
|
+
| `check(dictionary, text, typed, options?)` | mark typed pinyin against the text |
|
|
601
847
|
| `slug(dictionary, text, options?)` | hanzi → a URL-safe slug |
|
|
602
848
|
| `joinPieces(pieces)` / `toHtml(pieces)` | render pieces |
|
|
603
849
|
| `isUncertain(confidence)` | was this syllable a guess? |
|
|
@@ -613,8 +859,9 @@ This is orthography and not translation — 软件 becomes 軟件, never 軟體.
|
|
|
613
859
|
| `convertGreedily(...)` | the old longest-match decoder, kept as a baseline |
|
|
614
860
|
|
|
615
861
|
Types (`Syllable`, `Tone`, `ConvertOptions`, `ConvertedPiece`,
|
|
616
|
-
`ReadingConfidence`, `HtmlOptions`, `
|
|
617
|
-
|
|
862
|
+
`ReadingConfidence`, `HtmlOptions`, `Segment`, `PinyinMatch`, `MatchRange`,
|
|
863
|
+
`ReadingConfidence`, `HtmlOptions`, `Segment`, `PinyinCheck`, `CheckedSyllable`,
|
|
864
|
+
`WordEntry`, `Tier`, `Locale`, `Script`) are exported alongside them.
|
|
618
865
|
|
|
619
866
|
## Development
|
|
620
867
|
|