@kensio/pinyinjs 0.1.0-beta.0 → 1.0.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 +87 -0
- package/NOTICE +7 -0
- package/README.md +144 -19
- package/data/full.entries +13400 -13400
- package/data/manifest.json +4 -4
- package/data/standard.entries +2492 -2492
- package/dist/cli/arguments.d.ts +67 -0
- package/dist/cli/arguments.d.ts.map +1 -1
- package/dist/cli/arguments.js +79 -0
- package/dist/cli/arguments.js.map +1 -1
- package/dist/cli/colour.d.ts +77 -0
- package/dist/cli/colour.d.ts.map +1 -0
- package/dist/cli/colour.js +117 -0
- package/dist/cli/colour.js.map +1 -0
- package/dist/cli/commands.d.ts +49 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +404 -42
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/environment.d.ts.map +1 -1
- package/dist/cli/environment.js +20 -0
- package/dist/cli/environment.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +43 -16
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/run.d.ts +11 -0
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +4 -2
- package/dist/cli/run.js.map +1 -1
- package/dist/decode/convert.d.ts +20 -0
- package/dist/decode/convert.d.ts.map +1 -1
- package/dist/decode/convert.js +170 -12
- 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 +17 -4
- package/dist/decode/decode.js.map +1 -1
- package/dist/decode/reading-rules.d.ts +56 -0
- package/dist/decode/reading-rules.d.ts.map +1 -0
- package/dist/decode/reading-rules.js +107 -0
- package/dist/decode/reading-rules.js.map +1 -0
- package/dist/decode/rules.d.ts +66 -0
- package/dist/decode/rules.d.ts.map +1 -0
- package/dist/decode/rules.js +138 -0
- package/dist/decode/rules.js.map +1 -0
- package/dist/decode/sandhi.d.ts +1 -1
- package/dist/decode/sandhi.d.ts.map +1 -1
- package/dist/decode/sandhi.js +60 -1
- package/dist/decode/sandhi.js.map +1 -1
- package/dist/decode/word.d.ts +18 -0
- package/dist/decode/word.d.ts.map +1 -1
- package/dist/dictionary/artifact.d.ts.map +1 -1
- package/dist/dictionary/artifact.js +28 -1
- package/dist/dictionary/artifact.js.map +1 -1
- package/dist/dictionary/dictionary.d.ts +9 -0
- package/dist/dictionary/dictionary.d.ts.map +1 -1
- package/dist/dictionary/dictionary.js +7 -0
- package/dist/dictionary/dictionary.js.map +1 -1
- package/dist/dictionary/entry.d.ts +12 -0
- package/dist/dictionary/entry.d.ts.map +1 -1
- package/dist/dictionary/entry.js.map +1 -1
- package/dist/dictionary/merge.d.ts +3 -1
- package/dist/dictionary/merge.d.ts.map +1 -1
- package/dist/dictionary/merge.js +19 -1
- package/dist/dictionary/merge.js.map +1 -1
- package/dist/format/transcription.d.ts +52 -0
- package/dist/format/transcription.d.ts.map +1 -0
- package/dist/format/transcription.js +88 -0
- package/dist/format/transcription.js.map +1 -0
- package/dist/index.d.ts +24 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/numerals/cardinal.d.ts +39 -0
- package/dist/numerals/cardinal.d.ts.map +1 -0
- package/dist/numerals/cardinal.js +111 -0
- package/dist/numerals/cardinal.js.map +1 -0
- package/dist/numerals/characters.d.ts +31 -0
- package/dist/numerals/characters.d.ts.map +1 -0
- package/dist/numerals/characters.js +80 -0
- package/dist/numerals/characters.js.map +1 -0
- package/dist/numerals/numerals.d.ts +76 -0
- package/dist/numerals/numerals.d.ts.map +1 -0
- package/dist/numerals/numerals.js +119 -0
- package/dist/numerals/numerals.js.map +1 -0
- package/dist/numerals/text.d.ts +52 -0
- package/dist/numerals/text.d.ts.map +1 -0
- package/dist/numerals/text.js +248 -0
- package/dist/numerals/text.js.map +1 -0
- package/dist/orthography/grouping.d.ts +56 -11
- package/dist/orthography/grouping.d.ts.map +1 -1
- package/dist/orthography/grouping.js +109 -35
- package/dist/orthography/grouping.js.map +1 -1
- package/dist/orthography/idiom-list.d.ts +56 -0
- package/dist/orthography/idiom-list.d.ts.map +1 -0
- package/dist/orthography/idiom-list.js +296 -0
- package/dist/orthography/idiom-list.js.map +1 -0
- package/dist/orthography/idioms.d.ts +18 -0
- package/dist/orthography/idioms.d.ts.map +1 -0
- package/dist/orthography/idioms.js +22 -0
- package/dist/orthography/idioms.js.map +1 -0
- package/dist/orthography/reduplication.d.ts +52 -0
- package/dist/orthography/reduplication.d.ts.map +1 -0
- package/dist/orthography/reduplication.js +99 -0
- package/dist/orthography/reduplication.js.map +1 -0
- package/dist/orthography/rule.d.ts +50 -0
- package/dist/orthography/rule.d.ts.map +1 -0
- package/dist/orthography/rule.js +101 -0
- package/dist/orthography/rule.js.map +1 -0
- package/dist/sources/cedict.d.ts +23 -0
- package/dist/sources/cedict.d.ts.map +1 -1
- package/dist/sources/cedict.js +28 -0
- package/dist/sources/cedict.js.map +1 -1
- package/dist/syllable/syllable.d.ts +1 -1
- package/dist/syllable/syllable.d.ts.map +1 -1
- package/dist/syllable/syllable.js +2 -37
- package/dist/syllable/syllable.js.map +1 -1
- package/dist/tone/tone-mark.d.ts +23 -0
- package/dist/tone/tone-mark.d.ts.map +1 -1
- package/dist/tone/tone-mark.js +49 -0
- package/dist/tone/tone-mark.js.map +1 -1
- package/dist/transcription/bopomofo.d.ts +46 -0
- package/dist/transcription/bopomofo.d.ts.map +1 -0
- package/dist/transcription/bopomofo.js +371 -0
- package/dist/transcription/bopomofo.js.map +1 -0
- package/dist/transcription/gwoyeu.d.ts +32 -0
- package/dist/transcription/gwoyeu.d.ts.map +1 -0
- package/dist/transcription/gwoyeu.js +491 -0
- package/dist/transcription/gwoyeu.js.map +1 -0
- package/dist/transcription/ipa.d.ts +40 -0
- package/dist/transcription/ipa.d.ts.map +1 -0
- package/dist/transcription/ipa.js +221 -0
- package/dist/transcription/ipa.js.map +1 -0
- package/dist/transcription/spelling-index.d.ts +23 -0
- package/dist/transcription/spelling-index.d.ts.map +1 -0
- package/dist/transcription/spelling-index.js +61 -0
- package/dist/transcription/spelling-index.js.map +1 -0
- package/dist/transcription/wade-giles.d.ts +108 -0
- package/dist/transcription/wade-giles.d.ts.map +1 -0
- package/dist/transcription/wade-giles.js +656 -0
- package/dist/transcription/wade-giles.js.map +1 -0
- package/dist/transcription/yale.d.ts +43 -0
- package/dist/transcription/yale.d.ts.map +1 -0
- package/dist/transcription/yale.js +242 -0
- package/dist/transcription/yale.js.map +1 -0
- package/package.json +9 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to `@kensio/pinyinjs`. Versions follow
|
|
4
|
+
[semantic versioning](https://semver.org) from 1.0.0 onward.
|
|
5
|
+
|
|
6
|
+
Two things are outside the version contract, for the reasons
|
|
7
|
+
[the API page](docs/api/#stability) gives: the readings a conversion produces,
|
|
8
|
+
which a dictionary rebuild can change, and the artifact format under `data/`.
|
|
9
|
+
|
|
10
|
+
## 1.0.0
|
|
11
|
+
|
|
12
|
+
The first stable release. Everything the
|
|
13
|
+
[API page](docs/api/) lists is now covered by semantic versioning, including the
|
|
14
|
+
decoder internals and the build pipeline.
|
|
15
|
+
|
|
16
|
+
### Added since 0.1.0-beta.0
|
|
17
|
+
|
|
18
|
+
- **Transcription systems, all five, in both directions.** Bopomofo, Wade-Giles,
|
|
19
|
+
Yale, Gwoyeu Romatzyh and IPA at the syllable level, plus hanzi → any of them
|
|
20
|
+
end to end via `convert --system` and `convertToWadeGiles`. Checked against
|
|
21
|
+
417 rows of an outside syllabary in every system — 3,336 cells.
|
|
22
|
+
- **Reading ambiguous Wade-Giles.** `readWadeGilesLoosely` allows for the
|
|
23
|
+
apostrophes and diacritics real texts drop, and `splitWadeGiles` puts back the
|
|
24
|
+
hyphens they lose. Measured: 52.07% of written syllables lose their identity
|
|
25
|
+
without their marks, and taking the first candidate recovers 79.05%.
|
|
26
|
+
- **Numbers read aloud** (`src/numerals/`, the `number` command): counting and
|
|
27
|
+
spelling out, 两 against 二, decimals, percentages, fractions, `yāo`, and
|
|
28
|
+
times. `convert` reads the digits it meets and takes the style from what
|
|
29
|
+
follows them.
|
|
30
|
+
- **Orthography rules.** The 重叠 hyphen for AABB and repeated words, the 成语
|
|
31
|
+
hyphen from a curated list of 117, 老王 → `Lǎo Wáng`, and GB/T 16159 5.1 in
|
|
32
|
+
full — 毛泽东 is `Máo Zédōng`, 北京大学 is `Běijīng Dàxué`, on boundaries
|
|
33
|
+
CC-CEDICT's own capitalisation states.
|
|
34
|
+
- **Typed rule overrides on the lattice** (`READING_RULES`), with the modal 得
|
|
35
|
+
and attested 儿化 as the first two.
|
|
36
|
+
- **Tone colour in the terminal**, in MDBG's palette, on every command that
|
|
37
|
+
writes a syllable.
|
|
38
|
+
|
|
39
|
+
### Fixed since 0.1.0-beta.0
|
|
40
|
+
|
|
41
|
+
- **一 sandhi is about the 一 that counts.** 十一月 is `shíyīyuè` and 第一次 is
|
|
42
|
+
`dìyīcì`; the citation tone survives a final digit and an ordinal. 561
|
|
43
|
+
conversions change over 88,866 lines, 520 of them right.
|
|
44
|
+
- **A colon between digits is a time**, not an identifier: 6:30 is
|
|
45
|
+
`liù diǎn sānshí fēn`.
|
|
46
|
+
- **The documented proper-noun mechanism was wrong.** The capitals page
|
|
47
|
+
described a 500-entry surname list that has never existed; what produces
|
|
48
|
+
`Lǐ Huá` is two single-character dictionary entries each flagged a proper
|
|
49
|
+
noun.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- **`engines` is now `>=22.0.0`**, down from `>=24.0.0`. The suite and the
|
|
54
|
+
packaged tarball are both exercised on Node 22 and 24 in CI.
|
|
55
|
+
- **No more `beta` dist-tag.** `pnpm add @kensio/pinyinjs` finds it.
|
|
56
|
+
- `src/romanization/` is `src/transcription/`, since bopomofo has a script of
|
|
57
|
+
its own and IPA is a transcription rather than a spelling. The published docs
|
|
58
|
+
path keeps the older name.
|
|
59
|
+
- The build cleans `dist/` before compiling, and `pnpm pack:check` asserts the
|
|
60
|
+
tarball's contents. The beta tarball shipped 24 stale files from a directory
|
|
61
|
+
that had been renamed away.
|
|
62
|
+
|
|
63
|
+
### Accuracy at 1.0.0
|
|
64
|
+
|
|
65
|
+
Over the 105-case gold corpus, which is committed to the repository — not to
|
|
66
|
+
the published package — and scored by `pnpm accuracy`:
|
|
67
|
+
|
|
68
|
+
| | lattice | greedy baseline |
|
|
69
|
+
| ---------------- | --------: | --------------: |
|
|
70
|
+
| exact match | **97.1%** | 92.4% |
|
|
71
|
+
| reading accuracy | 99.7% | 98.6% |
|
|
72
|
+
| spacing (F1) | **99.7%** | 97.0% |
|
|
73
|
+
|
|
74
|
+
Every figure in that table is asserted against the scorer by
|
|
75
|
+
`src/changelog.test.ts`, because a number nothing executes goes stale — which is
|
|
76
|
+
what happened to this project's README table across three releases.
|
|
77
|
+
|
|
78
|
+
`pnpm polyphones` reports 89.04% for the lattice against greedy's 88.82% over
|
|
79
|
+
CPP's 20,139 hand-labelled polyphones. That corpus is fetched rather than
|
|
80
|
+
committed, so unlike the table above it cannot be asserted here, and it is
|
|
81
|
+
reported rather than guarded.
|
|
82
|
+
|
|
83
|
+
## 0.1.0-beta.0
|
|
84
|
+
|
|
85
|
+
First published release: the lattice decoder, the tiered dictionaries, the
|
|
86
|
+
syllable layer, sandhi, GB/T 16159 spacing and capitals, HTML output and the
|
|
87
|
+
`pinyinjs` command.
|
package/NOTICE
CHANGED
|
@@ -31,3 +31,10 @@ Provides: the bulk of the multi-character word readings
|
|
|
31
31
|
Source: https://raw.githubusercontent.com/fxsjy/jieba/master/jieba/dict.txt
|
|
32
32
|
Licence: MIT, though the dictionary's own provenance is not documented upstream; recorded here as an accepted unknown
|
|
33
33
|
Provides: word frequencies and the part-of-speech tags that mark proper nouns
|
|
34
|
+
|
|
35
|
+
## Comparison of Standard Chinese transcription systems (Wikipedia)
|
|
36
|
+
|
|
37
|
+
Source: https://en.wikipedia.org/wiki/Comparison_of_Standard_Chinese_transcription_systems
|
|
38
|
+
Licence: CC BY-SA 4.0
|
|
39
|
+
Provides: the 417-row syllabary in test/fixtures/syllabary.ts, which the bopomofo, Wade-Giles, Yale, IPA and Gwoyeu Romatzyh tables are checked against, GR having four columns of its own
|
|
40
|
+
Note: used by the tests only; nothing in data/ is derived from it
|
package/README.md
CHANGED
|
@@ -5,18 +5,13 @@ validates and writes pinyin syllables on their own, with no dictionary.
|
|
|
5
5
|
|
|
6
6
|
[https://pinyinjs.dev](https://pinyinjs.dev "PinyinJS docs website")
|
|
7
7
|
|
|
8
|
-
> **Beta.** Published under the `beta` tag, so a plain `pnpm add
|
|
9
|
-
@kensio/pinyinjs` will not find it until 1.0. Wade-Giles, Bopomofo, Yale and
|
|
10
|
-
> IPA, and reading numbers aloud, are not built. Everything below works and is
|
|
11
|
-
> tested, but the API will change before 1.0.
|
|
12
|
-
|
|
13
8
|
## Install
|
|
14
9
|
|
|
15
10
|
```bash
|
|
16
|
-
pnpm add @kensio/pinyinjs
|
|
11
|
+
pnpm add @kensio/pinyinjs
|
|
17
12
|
```
|
|
18
13
|
|
|
19
|
-
Node
|
|
14
|
+
Node 22+, or any browser. The core imports no Node built-ins, and the package is
|
|
20
15
|
ESM only.
|
|
21
16
|
|
|
22
17
|
The dictionaries ship inside the package, which is what makes it a 4 MB
|
|
@@ -46,17 +41,25 @@ $ pinyinjs syllable nǐhǎo
|
|
|
46
41
|
nǐhǎo nǐ hǎo
|
|
47
42
|
nǐ n + i, tone 3 nǐ ni3 ni³
|
|
48
43
|
hǎo h + ao, tone 3 hǎo hao3 hao³
|
|
44
|
+
|
|
45
|
+
$ pinyinjs convert --system wade-giles --notation none 我要去北京。
|
|
46
|
+
Wo yao ch'ü Pei-ching.
|
|
47
|
+
|
|
48
|
+
$ pinyinjs transcribe běijīng
|
|
49
|
+
běijīng běijīng ㄅㄟˇ ㄐㄧㄥ pei³-ching¹ běijīng beeijing pei˨˩˦tɕiŋ˥
|
|
49
50
|
```
|
|
50
51
|
|
|
51
|
-
| Command
|
|
52
|
-
|
|
|
53
|
-
| `convert`
|
|
54
|
-
| `html`
|
|
55
|
-
| `explain`
|
|
56
|
-
| `lookup`
|
|
57
|
-
| `syllable`
|
|
58
|
-
| `sandhi`
|
|
59
|
-
| `
|
|
52
|
+
| Command | Does |
|
|
53
|
+
| ------------ | --------------------------------------------------- |
|
|
54
|
+
| `convert` | hanzi to pinyin |
|
|
55
|
+
| `html` | the same, as HTML |
|
|
56
|
+
| `explain` | each syllable, how settled it was, and what it beat |
|
|
57
|
+
| `lookup` | what the dictionary holds for a word |
|
|
58
|
+
| `syllable` | take written pinyin apart |
|
|
59
|
+
| `sandhi` | apply tone sandhi to written pinyin |
|
|
60
|
+
| `number` | read a number as Chinese numerals |
|
|
61
|
+
| `transcribe` | pinyin to bopomofo, Wade-Giles, Yale, GR and IPA |
|
|
62
|
+
| `info` | which dictionary is loaded, and how big it is |
|
|
60
63
|
|
|
61
64
|
Every conversion option below is a flag: `--notation`, `--locale`,
|
|
62
65
|
`--apostrophe`, `--capitals`, `--punctuation`, `--no-grouping`, `--third-tone`,
|
|
@@ -66,6 +69,12 @@ A command given no arguments reads standard input, one text per line, so
|
|
|
66
69
|
`cat article.txt | pinyinjs convert` works. `syllable` and `sandhi` need no
|
|
67
70
|
dictionary at all and start without loading one.
|
|
68
71
|
|
|
72
|
+
At a terminal each syllable is written in its tone's colour, in
|
|
73
|
+
[MDBG](https://www.mdbg.net)'s palette — red, yellow, green, blue, and the
|
|
74
|
+
terminal's own colour for the neutral tone. It is off for a pipe, `NO_COLOR` is
|
|
75
|
+
honoured, `--colour` and `--no-colour` force it either way, and `--json` is
|
|
76
|
+
never coloured. See [the command line](docs/cli/#colour).
|
|
77
|
+
|
|
69
78
|
### Calling it from something else
|
|
70
79
|
|
|
71
80
|
`convert` writes the pinyin and nothing else, so it drops straight into a
|
|
@@ -140,9 +149,20 @@ first, convert with it, and reload as `full` arrives.
|
|
|
140
149
|
convert(dictionary, "银行"); // "yínháng"
|
|
141
150
|
convert(dictionary, "行长"); // "hángzhǎng"
|
|
142
151
|
convert(dictionary, "我要去北京。"); // "Wǒ yào qù Běijīng."
|
|
143
|
-
convert(dictionary, "3D银行"); // "
|
|
152
|
+
convert(dictionary, "3D银行"); // "sān D yínháng" — the digit is read, the letter is not
|
|
144
153
|
```
|
|
145
154
|
|
|
155
|
+
A reading the dictionary cannot settle on its own is settled by context, with
|
|
156
|
+
typed rules over the lattice rather than tweaks to the output:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
convert(dictionary, "我得走了"); // "wǒ děi zǒule" — modal 得
|
|
160
|
+
convert(dictionary, "他跑得很快"); // "tā pǎo de hěn kuài" — the particle
|
|
161
|
+
convert(dictionary, "那边儿"); // "nà biānr" — 儿 does not stand on its own
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
See [converting](docs/converting/#rules-where-the-cost-model-cannot-reach).
|
|
165
|
+
|
|
146
166
|
### Options
|
|
147
167
|
|
|
148
168
|
```ts
|
|
@@ -157,6 +177,8 @@ convert(dictionary, text, { notation: "numbers", capitals: "none" });
|
|
|
157
177
|
| `capitals` | `"auto"` | `"auto"`, `"proper"`, `"none"` |
|
|
158
178
|
| `punctuation` | `"latin"` | `"latin"`, `"keep"` |
|
|
159
179
|
| `grouping` | `true` | `false` turns off GB/T 16159 word spacing |
|
|
180
|
+
| `numbers` | `"read"` | `"keep"` leaves every digit as it was written |
|
|
181
|
+
| `numbers` | `"read"` | `"keep"` leaves every digit as it was written |
|
|
160
182
|
| `sandhi` | `{ yiBu: true, thirdTone: false }` | `{ yiBu?: boolean; thirdTone?: boolean }` |
|
|
161
183
|
|
|
162
184
|
```ts
|
|
@@ -218,8 +240,36 @@ The list is not a complete 正词法 implementation, so some words it does not
|
|
|
218
240
|
cover are written differently: 不但 is `búdàn`, 大米 is `dàmǐ`, 青海 is
|
|
219
241
|
`Qīnghǎi`.
|
|
220
242
|
|
|
221
|
-
**
|
|
222
|
-
|
|
243
|
+
**Reduplication** takes a hyphen rather than a space, since it is one word with
|
|
244
|
+
a boundary inside it.
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
convert(dictionary, "干干净净"); // "gāngān-jìngjìng"
|
|
248
|
+
convert(dictionary, "研究研究"); // "yánjiū-yánjiū"
|
|
249
|
+
convert(dictionary, "爸爸妈妈"); // "bàba māma" — that shape, but two words
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**A 成语 that can be read as two disyllables** takes the same hyphen, from a
|
|
253
|
+
curated list of 117; the rest are written solid, as the standard writes them.
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
convert(dictionary, "风平浪静"); // "fēngpíng-làngjìng"
|
|
257
|
+
convert(dictionary, "不亦乐乎"); // "búyìlèhū" — cannot be halved
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Digits are read**, and the rest of a non-Han run passes through exactly as
|
|
261
|
+
written:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
convert(dictionary, "我有3个苹果。"); // "Wǒ yǒu sān gè píngguǒ."
|
|
265
|
+
convert(dictionary, "1988年之后"); // "yī jiǔ bā bā nián zhīhòu"
|
|
266
|
+
convert(dictionary, "95%的人"); // "bǎifēnzhījiǔshíwǔ de rén"
|
|
267
|
+
convert(dictionary, "3D打印"); // "sān D dǎyìn"
|
|
268
|
+
convert(dictionary, "6:30起床"); // "liù diǎn sānshí fēn qǐchuáng"
|
|
269
|
+
convert(dictionary, "16:9的"); // "16:9de" — a ratio is not a quantity
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`numbers: "keep"` leaves every digit alone. See [numbers](docs/numerals/).
|
|
223
273
|
|
|
224
274
|
## Syllable by syllable
|
|
225
275
|
|
|
@@ -384,6 +434,77 @@ toneFromMarks("hǎo"); // 3
|
|
|
384
434
|
`de` in 我的 is neutral (5), whereas the `bei` in a typed `beijing` has no tone
|
|
385
435
|
written at all.
|
|
386
436
|
|
|
437
|
+
## Numbers
|
|
438
|
+
|
|
439
|
+
Reading a number needs no dictionary — arithmetic and about twenty readings —
|
|
440
|
+
so this works with nothing loaded.
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
import { numeralHanzi, percentHanzi, readNumeral } from "@kensio/pinyinjs";
|
|
444
|
+
|
|
445
|
+
numeralHanzi(12345); // "一万两千三百四十五"
|
|
446
|
+
numeralHanzi(1005); // "一千零五" — a skipped place is spoken
|
|
447
|
+
numeralHanzi(2000); // "两千" — a leading lone 2 before a big unit
|
|
448
|
+
percentHanzi(95); // "百分之九十五" — the order reverses
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
The same digits are read two ways and nothing in the number says which — 2026年
|
|
452
|
+
is spelled out and 2026个 is counted — so the style is the caller's:
|
|
453
|
+
|
|
454
|
+
```ts
|
|
455
|
+
numeralHanzi(2026); // "两千零二十六"
|
|
456
|
+
numeralHanzi(2026, { style: "digits" }); // "二〇二六"
|
|
457
|
+
readNumeral(110, { style: "digits", yao: true }); // yāo yāo líng
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
More in [numbers](docs/numerals/).
|
|
461
|
+
|
|
462
|
+
## Bopomofo, Wade-Giles, Yale, Gwoyeu Romatzyh and IPA
|
|
463
|
+
|
|
464
|
+
Also dictionary-free: a romanisation is a mapping over about 420 syllables, so
|
|
465
|
+
hanzi → Wade-Giles is hanzi → pinyin → Wade-Giles.
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
import {
|
|
469
|
+
readSyllable,
|
|
470
|
+
readWadeGilesLoosely,
|
|
471
|
+
writeBopomofo,
|
|
472
|
+
writeGwoyeu,
|
|
473
|
+
writeIpa,
|
|
474
|
+
writeWadeGiles,
|
|
475
|
+
writeYale,
|
|
476
|
+
} from "@kensio/pinyinjs";
|
|
477
|
+
|
|
478
|
+
const jiu = readSyllable("jiù");
|
|
479
|
+
writeBopomofo(jiu); // "ㄐㄧㄡˋ"
|
|
480
|
+
writeWadeGiles(jiu); // "chiu⁴"
|
|
481
|
+
writeYale(jiu); // "jyòu"
|
|
482
|
+
writeGwoyeu(jiu); // "jiow"
|
|
483
|
+
writeIpa(jiu); // "tɕiou˥˩"
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Gwoyeu Romatzyh is the odd one, and it needs no tone mark because the tone is
|
|
487
|
+
spelled into the syllable — which is why 陝西 is Shaanxi in English and 山西 is
|
|
488
|
+
Shanxi:
|
|
489
|
+
|
|
490
|
+
```ts
|
|
491
|
+
const gr = (pinyin: string) => writeGwoyeu(readSyllable(pinyin));
|
|
492
|
+
[gr("shān"), gr("shán"), gr("shǎn"), gr("shàn")]; // shan, sharn, shaan, shann
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Reading Wade-Giles back gives an **array**, because real text drops the
|
|
496
|
+
apostrophes and diacritics that carry the distinctions:
|
|
497
|
+
|
|
498
|
+
```ts
|
|
499
|
+
readWadeGilesLoosely("chi¹"); // [jī, qī] — chi is jī, ch'i is qī
|
|
500
|
+
readWadeGilesLoosely("chu¹"); // [zhū, chū, jū, qū]
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
Measured over the phrase corpus, 52.07% of written syllables have a Wade-Giles
|
|
504
|
+
spelling that merges with another once its marks are dropped, and taking the
|
|
505
|
+
first candidate recovers 79.05% of them. More in
|
|
506
|
+
[romanisation](docs/romanization/).
|
|
507
|
+
|
|
387
508
|
## Sandhi
|
|
388
509
|
|
|
389
510
|
The dictionary stores underlying tones, and sandhi is applied to the syllable
|
|
@@ -431,6 +552,10 @@ Both scripts are dictionary keys, so only the locale is an option to pass.
|
|
|
431
552
|
| `readSyllable` / `writeSyllable` / `isSyllable` | one syllable, no dictionary |
|
|
432
553
|
| `splitSyllables` / `readWord` | split written pinyin |
|
|
433
554
|
| `applySandhi` | 一, 不 and optional third-tone sandhi |
|
|
555
|
+
| `writeBopomofo` / `writeWadeGiles` | one syllable, romanised |
|
|
556
|
+
| `writeYale` / `writeGwoyeu` / `writeIpa` | the same, in Yale, GR and IPA |
|
|
557
|
+
| `readBopomofo` / `readWadeGilesLoosely` | and back again |
|
|
558
|
+
| `readYale` / `readGwoyeu` / `readIpa` | and back from those three |
|
|
434
559
|
| `applyToneMark` / `stripToneMarks` / `toneFromMarks` | tone marks |
|
|
435
560
|
| `convertGreedily(...)` | the old longest-match decoder, kept as a baseline |
|
|
436
561
|
|