@kensio/pinyinjs 1.5.2 → 1.5.3

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 CHANGED
@@ -9,6 +9,20 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
9
9
 
10
10
  ## Unreleased
11
11
 
12
+ ## 1.5.3
13
+
14
+ ### Fixed
15
+
16
+ - **The changelog inside the package described five releases as unreleased.**
17
+ Every tarball from 1.1.0 to 1.5.2 shipped a `## Unreleased` section holding
18
+ everything since 1.0.0, so a reader who opened the copy they installed —
19
+ which [the API page](docs/api/#stability) points them at — had no way to tell
20
+ which version any of it arrived in. The entries are filed under the versions
21
+ that shipped them now. No code changes; this release exists to put the
22
+ corrected file on the registry.
23
+
24
+ ## 1.5.2
25
+
12
26
  ### Fixed
13
27
 
14
28
  - **Third-tone sandhi ran over the syllables rather than over the feet.** The
@@ -52,28 +66,11 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
52
66
  written, so 相親 keeps the `xiàngqīn` its dominant sense carries. CC-CEDICT
53
67
  now supplies 335 deltas rather than 349.
54
68
 
55
- - **240 dictionary entries could not be looked up at all.** Recognising Hong
56
- Kong glyph forms on the lookup path means a key written in a form the path
57
- normalises _away from_ can never be found, and the merge derived 繁體 forms
58
- per word from Unihan's variant lists with no single standard behind them — so
59
- it wrote 裏 where the corpus overwhelmingly writes 裡, and 上樑, 中峯 and 义藴
60
- became keys nothing could reach. The merge now derives canonical glyph forms,
61
- and keys a headword's canonical spelling alongside it where the phrase corpus
62
- wrote one with a 繁體 variant. **No key is now unreachable**, and Hong Kong
63
- spellings resolve slightly better than before: 5,499 of the 9,978 keys with a
64
- distinct Hong Kong form, against 5,439.
69
+ ## 1.5.1
65
70
 
66
- Two things had to be got right alongside it. The evidence for "简体 writes
67
- this character" comes from CC-CEDICT entries whose two columns differ, not
68
- from the phrase corpus, which is nominally 简体 but carries 峯, 藴 and 枱 of
69
- its own — counting it cut the table from 50 mappings to 32 and stopped Hong
70
- Kong text converting at all. And a 繁體 form differing from its 简体 one only
71
- by glyph normalisation is not evidence about script, or the alias key would
72
- put that entry's 简体 characters into the 繁體-only set, which is how 发
73
- briefly stopped being 简体-only.
71
+ Tooling and test-suite work only; nothing a consumer installs changed.
74
72
 
75
- `toScript` drops the pass that was papering over this. Key counts move:
76
- 723,149 for `full`, 97,997 for `standard`, 16,975 for `core`.
73
+ ## 1.5.0
77
74
 
78
75
  ### Added
79
76
 
@@ -91,6 +88,10 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
91
88
  command line — leaves it off, for a caller who would rather declare the
92
89
  language once on a wrapper of their own than repeat it on every syllable.
93
90
 
91
+ ## 1.4.0
92
+
93
+ ### Added
94
+
94
95
  - **`pinyinjs script`,** script conversion at the command line, with `--to` for
95
96
  the target and `--from-script` where the text is too short for detection to
96
97
  tell. The lines carry the converted text and nothing else so it pipes;
@@ -168,6 +169,35 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
168
169
  before any dictionary has loaded; `pnpm build:data` re-derives them from
169
170
  OpenCC and fails the build if the two have drifted.
170
171
 
172
+ ### Fixed
173
+
174
+ - **240 dictionary entries could not be looked up at all.** Recognising Hong
175
+ Kong glyph forms on the lookup path means a key written in a form the path
176
+ normalises _away from_ can never be found, and the merge derived 繁體 forms
177
+ per word from Unihan's variant lists with no single standard behind them — so
178
+ it wrote 裏 where the corpus overwhelmingly writes 裡, and 上樑, 中峯 and 义藴
179
+ became keys nothing could reach. The merge now derives canonical glyph forms,
180
+ and keys a headword's canonical spelling alongside it where the phrase corpus
181
+ wrote one with a 繁體 variant. **No key is now unreachable**, and Hong Kong
182
+ spellings resolve slightly better than before: 5,499 of the 9,978 keys with a
183
+ distinct Hong Kong form, against 5,439.
184
+
185
+ Two things had to be got right alongside it. The evidence for "简体 writes
186
+ this character" comes from CC-CEDICT entries whose two columns differ, not
187
+ from the phrase corpus, which is nominally 简体 but carries 峯, 藴 and 枱 of
188
+ its own — counting it cut the table from 50 mappings to 32 and stopped Hong
189
+ Kong text converting at all. And a 繁體 form differing from its 简体 one only
190
+ by glyph normalisation is not evidence about script, or the alias key would
191
+ put that entry's 简体 characters into the 繁體-only set, which is how 发
192
+ briefly stopped being 简体-only.
193
+
194
+ `toScript` drops the pass that was papering over this. Key counts move:
195
+ 723,149 for `full`, 97,997 for `standard`, 16,975 for `core`.
196
+
197
+ ## 1.3.0
198
+
199
+ ### Added
200
+
171
201
  - **`slug`,** hanzi to a URL-safe slug: 我想学中文。 is
172
202
  `wo3-xiang3-xue2-zhong1wen2`. Built on the decode rather than on a finished
173
203
  string, which is the whole point of it — 银行 is `yin2hang2` and not
@@ -179,30 +209,20 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
179
209
  The options generalise it past URLs to search keys and identifiers, which the
180
210
  [slug page](docs/slug/) tabulates. `pinyinjs slug` at the command line.
181
211
 
212
+ ## 1.2.2
213
+
214
+ ### Added
215
+
182
216
  - **`TEACHING_JIAO` and `COUNTED_MEASURE`,** two more lattice rules, and
183
217
  `QUANTITY_CHARACTERS`, the 汉字 a quantity is written with that the second of
184
218
  them asks about. See the fixes below for what they do and what they measure.
219
+
185
220
  - **`counts` on the numeral options.** Whether the number stands immediately in
186
221
  front of something it counts, which is what makes a lone 2 两:
187
222
  `numeralHanzi(2, { counts: true })` is `两` and `numeralHanzi(2)` is `二`.
188
223
  Unlike `liang` it is not a variable choice — 二个 is simply wrong — but
189
224
  nothing about the number says whether it is counting, so the caller says.
190
225
  `convert` sets it from the character after the digits.
191
- - **`SYLLABLE_TONES` and `isAttestedTone`.** Which tones each of the 424
192
- syllables is actually written in, extracted from the merged dictionary and
193
- held to it by a build assertion. 424 syllables in five tones would be 2,120
194
- combinations and only 1,708 of them occur, so a fifth of that grid is empty.
195
- - **`Syllable.originalTone`,** the tone a neutral syllable had before it was
196
- reduced. Gwoyeu Romatzyh writes the neutral tone as a dot in front of the
197
- syllable _in its original tonal spelling_, so 没有 méiyou is `mei.yeou`, and
198
- nothing else in a pinyin syllable records what that tone was. Optional, never
199
- inferred, and used by GR alone.
200
- - **Two more outside sources for the transcription tables.** 148 words from
201
- en.wiktionary's Mandarin pronunciation blocks, in bopomofo, Wade-Giles, Yale
202
- and GR with their tones, and all 50 rows of Wikipedia's _Help:IPA/Mandarin_
203
- key. The 417-row syllabary already checked was toneless, so it could say
204
- nothing about tone marks, the neutral tone, 儿化 or how a word is joined,
205
- which is where the four fixes below were found.
206
226
 
207
227
  ### Fixed
208
228
 
@@ -222,6 +242,7 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
222
242
  `jiāo`, three of them wrongly — 统一教创始人, 方法教深思 and 做到了教政分离,
223
243
  where a nominal compound takes an object's shape. CPP's polyphone score is
224
244
  89.05%, up from 89.04%.
245
+
225
246
  - **A 量词 was swallowed by the word behind it.** 三个人 was `sān gèrén`, three
226
247
  _personals_, because 个人 is a common noun and nothing weighed it against the
227
248
  个 belonging to the 三 in front of it. It is now `sān gè rén`, and so are
@@ -237,6 +258,7 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
237
258
  and moves 53 decodes, three of them wrongly — 一批评, 这一名词 and 六七股灾,
238
259
  where the 一 and the 六七 count nothing. Exactly one reading changes in the
239
260
  whole corpus and it is a fix: 已经下了两天雨了 read 天雨 as `tiān yù`.
261
+
240
262
  - **The Han after a number was decoded without it.** 2个人 was `liǎng gèrén`
241
263
  while 两个人 written out was already `liǎng gè rén`, because a Han run was
242
264
  decoded on its own and had no idea a number preceded it. A run is now decoded
@@ -245,6 +267,7 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
245
267
  take that context as a fourth argument; where a reading would straddle the
246
268
  join — 1点儿事, whose 一点儿 is one `yìdiǎnr` over both sides of it — the run
247
269
  is decoded alone, as before.
270
+
248
271
  - **A lone 2 in front of a 量词 was read 二.** 我们买了2个西瓜 came out as
249
272
  `wǒmen mǎile èr gè xīguā`, and a 2 standing immediately in front of what it
250
273
  counts is 两: it is now `liǎng gè`, and 2岁 is `liǎng suì`, 2点 `liǎng diǎn`
@@ -255,43 +278,22 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
255
278
  the 第 in front of it marks (第2次 is `dì èr cì`), and 十 and 百, which follow
256
279
  二 as 20 and 200 already do. A 2 inside a larger number is untouched: 12个 is
257
280
  still `shí'èr gè`.
281
+
282
+ ## 1.2.1
283
+
284
+ ### Fixed
285
+
258
286
  - **A decimal lost the grouping of its counted part.** 一共75.5元 was
259
287
  `yígòng qī shí wǔ diǎn wǔ yuán`, with the 75 in loose syllables, and is now
260
288
  `yígòng qīshíwǔ diǎn wǔ yuán`, the same word 一共75元 already got. Only what
261
289
  follows the 点 is read a digit at a time, and that part is unchanged: 3.14 is
262
290
  still `sān diǎn yī sì`, and sandhi still stops at the point.
291
+
263
292
  - **A decimal point was read as a full stop.** 一共75.5元 came back as
264
293
  `Yígòng …`, capitalised as though the text were a sentence, and a conversion
265
294
  keeping its digits capitalised again after the point: 我有75.5个。was
266
295
  `Wǒ yǒu75.5Gè.` A stop between two digits now ends no sentence.
267
- - **Bopomofo wrote the tone mark after the 儿化 ㄦ.** 哪儿 nǎr was `ㄋㄚㄦˇ` and
268
- is now `ㄋㄚˇㄦ`: the mark belongs to the nucleus and the suffix is not part of
269
- what it marks. A mark written after the ㄦ is still read.
270
- - **Wade-Giles put the tone digit on the 儿化 suffix,** so 花儿 huār was
271
- `hua-êrh¹`, a first-tone 兒. It is now `hua¹-'rh`, with the digit on the
272
- syllable the tone belongs to and the suffix written as the reduced `'rh` that
273
- keeps it apart from 女儿 nǚ'ér's `nü³-êrh²`.
274
- - **Gwoyeu Romatzyh wrote 儿化 as a plain `-l` suffix.** GR fuses it into the
275
- rime instead, and the rules are now implemented as _Spelling in Gwoyeu
276
- Romatzyh_ gives them: 玩儿 wánr is `wal` rather than `wanl`, 事儿 shìr is
277
- `shell`, 今儿 jīnr is `jiel`. The fusion is many-to-one, so `jiel` is 今儿 and
278
- 鸡儿 both and 128 forms no longer round-trip, every one of them a form the
279
- language does not write.
280
- - **Gwoyeu Romatzyh wrote `.mhe` for a neutral 么.** The `-h-` is the first tone
281
- of a sonorant initial, and a neutral syllable is in no tone at all; the basic
282
- form goes behind the dot, so 什么 shénme is `shern.me`.
283
- - **The IPA module said it followed _Help:IPA/Mandarin_ and did not.** It
284
- follows the broader IPA column of _Comparison of Standard Chinese
285
- transcription systems_, which is where its ground truth comes from; the two
286
- pages differ at the medials, -ang, the empty rhyme and the diphthongs. No
287
- output changed, only the claim.
288
- - **`--system ipa` capitalised the IPA.** 我去银行。他姓王。 came out as
289
- `Uo˨˩˦ ... Tʰa˥ ɕiŋ˥˩ Uaŋ˧˥`, with the sentence capital and the proper noun
290
- carried over from the pinyin as though a transcription spelled words. IPA
291
- letters are symbols rather than an alphabet, since `[T]` is not `[t]` in a
292
- larger size but a symbol the IPA does not have, so the capitals are now dropped for
293
- IPA and bopomofo and kept for the three romanisations. `toTranscription`
294
- takes `{ capitals: false }` for callers writing their own.
296
+
295
297
  - **A compound lost the zh-TW reading its own parts carry.** 垃圾分類 read
296
298
  `lājīfēnlèi` under `zh-TW`, because CC-CEDICT marks `Taiwan pr.` on 垃圾 and
297
299
  垃圾桶 and on no other compound, and the decoder prefers the longer word, so
@@ -303,6 +305,7 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
303
305
  it, and it has to be a whole word rather than a bare character, since 會's `huǐ`
304
306
  would rewrite 三合會 as `sānhéhuǐ` and 3,743 entries would compose that way
305
307
  against the 101 that whole words compose.
308
+
306
309
  - **A character's zh-TW delta was often a choice between its 普通话 senses.**
307
310
  从容地 read `cōngróng dì` and 他都知道 read `tā dū zhīdào` under `zh-TW`,
308
311
  because 地 was stored with a Taiwan reading of `dì` and 都 with `dū`. Neither
@@ -315,12 +318,75 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
315
318
  only read off a sense matching the reading the entry settled on, which drops
316
319
  16 more: the note on 著's chess-move sense, which reads `zhāo`, had been
317
320
  giving the aspect particle 着 a 國語 reading of `zhuó`.
321
+
318
322
  - **A locale delta overwrote a reading it was not measured against.** The delta
319
323
  describes the entry's own 普通话 reading, so a polyphone the decode read some
320
324
  other way, such as 得 forced to the modal `děi` rather than the particle `de`
321
325
  its entry stores, now keeps what the decode worked out instead of being
322
326
  rewritten from the entry.
323
327
 
328
+ ## 1.2.0
329
+
330
+ ### Fixed
331
+
332
+ - **`--system ipa` capitalised the IPA.** 我去银行。他姓王。 came out as
333
+ `Uo˨˩˦ ... Tʰa˥ ɕiŋ˥˩ Uaŋ˧˥`, with the sentence capital and the proper noun
334
+ carried over from the pinyin as though a transcription spelled words. IPA
335
+ letters are symbols rather than an alphabet, since `[T]` is not `[t]` in a
336
+ larger size but a symbol the IPA does not have, so the capitals are now dropped for
337
+ IPA and bopomofo and kept for the three romanisations. `toTranscription`
338
+ takes `{ capitals: false }` for callers writing their own.
339
+
340
+ ## 1.1.0
341
+
342
+ ### Added
343
+
344
+ - **`SYLLABLE_TONES` and `isAttestedTone`.** Which tones each of the 424
345
+ syllables is actually written in, extracted from the merged dictionary and
346
+ held to it by a build assertion. 424 syllables in five tones would be 2,120
347
+ combinations and only 1,708 of them occur, so a fifth of that grid is empty.
348
+
349
+ - **`Syllable.originalTone`,** the tone a neutral syllable had before it was
350
+ reduced. Gwoyeu Romatzyh writes the neutral tone as a dot in front of the
351
+ syllable _in its original tonal spelling_, so 没有 méiyou is `mei.yeou`, and
352
+ nothing else in a pinyin syllable records what that tone was. Optional, never
353
+ inferred, and used by GR alone.
354
+
355
+ - **Two more outside sources for the transcription tables.** 148 words from
356
+ en.wiktionary's Mandarin pronunciation blocks, in bopomofo, Wade-Giles, Yale
357
+ and GR with their tones, and all 50 rows of Wikipedia's _Help:IPA/Mandarin_
358
+ key. The 417-row syllabary already checked was toneless, so it could say
359
+ nothing about tone marks, the neutral tone, 儿化 or how a word is joined,
360
+ which is where the four fixes below were found.
361
+
362
+ ### Fixed
363
+
364
+ - **Bopomofo wrote the tone mark after the 儿化 ㄦ.** 哪儿 nǎr was `ㄋㄚㄦˇ` and
365
+ is now `ㄋㄚˇㄦ`: the mark belongs to the nucleus and the suffix is not part of
366
+ what it marks. A mark written after the ㄦ is still read.
367
+
368
+ - **Wade-Giles put the tone digit on the 儿化 suffix,** so 花儿 huār was
369
+ `hua-êrh¹`, a first-tone 兒. It is now `hua¹-'rh`, with the digit on the
370
+ syllable the tone belongs to and the suffix written as the reduced `'rh` that
371
+ keeps it apart from 女儿 nǚ'ér's `nü³-êrh²`.
372
+
373
+ - **Gwoyeu Romatzyh wrote 儿化 as a plain `-l` suffix.** GR fuses it into the
374
+ rime instead, and the rules are now implemented as _Spelling in Gwoyeu
375
+ Romatzyh_ gives them: 玩儿 wánr is `wal` rather than `wanl`, 事儿 shìr is
376
+ `shell`, 今儿 jīnr is `jiel`. The fusion is many-to-one, so `jiel` is 今儿 and
377
+ 鸡儿 both and 128 forms no longer round-trip, every one of them a form the
378
+ language does not write.
379
+
380
+ - **Gwoyeu Romatzyh wrote `.mhe` for a neutral 么.** The `-h-` is the first tone
381
+ of a sonorant initial, and a neutral syllable is in no tone at all; the basic
382
+ form goes behind the dot, so 什么 shénme is `shern.me`.
383
+
384
+ - **The IPA module said it followed _Help:IPA/Mandarin_ and did not.** It
385
+ follows the broader IPA column of _Comparison of Standard Chinese
386
+ transcription systems_, which is where its ground truth comes from; the two
387
+ pages differ at the medials, -ang, the empty rhyme and the diphthongs. No
388
+ output changed, only the claim.
389
+
324
390
  ### Changed
325
391
 
326
392
  - **Reading a romanisation narrows on the tone that was written.**
@@ -333,6 +399,7 @@ which a dictionary rebuild can change, and the artifact format under `data/`.
333
399
  candidates alone, since that says the tone is wrong rather than the spelling.
334
400
  Over the phrase corpus, taking the first candidate recovers 82.66% of
335
401
  syllables when the tone digit is written, against 79.05% without it.
402
+
336
403
  - Eight Wade-Giles forms no longer round-trip, and one to three in each of the
337
404
  other systems, because they are forms the language does not write: `lo` in the
338
405
  four contour tones, a first-tone 兒, and a neutral 誒. Every attested
package/dist/cli/main.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "@kensio/pinyinjs",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "Chinese hanzi to pinyin conversion",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://github.com/KensioSoftware/pinyinjs"
8
- },
5
+ "repository": "https://github.com/KensioSoftware/pinyinjs",
9
6
  "homepage": "https://pinyinjs.dev",
10
7
  "bugs": "https://github.com/KensioSoftware/pinyinjs/issues",
11
8
  "main": "./dist/index.js",
@@ -39,20 +36,44 @@
39
36
  "imports": {
40
37
  "#test/*": "./test/*"
41
38
  },
39
+ "packageManager": "pnpm@11.17.0+sha512.cca3cea332ad254bb84145f966d19f4879615210346fc92c79a047f23a0d7b3cca3c3792f0076ba1f1831d277efbcf0a9119b31a9a60eca7fb3d6231f331ef72",
42
40
  "engines": {
43
41
  "node": ">=22.0.0"
44
42
  },
43
+ "scripts": {
44
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
45
+ "prepack": "pnpm build",
46
+ "cli": "node --import jiti/register src/cli/main.ts",
47
+ "build:check": "tsc -p tsconfig.json --noEmit",
48
+ "fmt": "oxlint --fix . && oxfmt .",
49
+ "lint": "oxlint . && oxfmt --check .",
50
+ "lint:ci": "oxlint --format=github . && oxfmt --check .",
51
+ "fta": "./scripts/sh/fta.sh",
52
+ "pack:check": "./scripts/sh/pack-check.sh",
53
+ "build:data": "node --import jiti/register scripts/build-data/build.ts",
54
+ "fetch:data": "node --import jiti/register scripts/build-data/fetch.ts",
55
+ "test": "vitest run",
56
+ "test:coverage": "vitest run --coverage",
57
+ "check": "pnpm fmt && pnpm fta && pnpm build && pnpm build:check && pnpm test:coverage",
58
+ "accuracy": "node --import jiti/register scripts/build-data/accuracy.ts",
59
+ "polyphones": "node --import jiti/register scripts/build-data/polyphones.ts",
60
+ "numerals": "node --import jiti/register scripts/build-data/numerals.ts",
61
+ "transcription": "node --import jiti/register scripts/build-data/transcription.ts"
62
+ },
45
63
  "devDependencies": {
46
64
  "@kensio/smartass": "^1.33.0",
65
+ "@semantic-release/exec": "7.1.0",
47
66
  "@types/lodash": "^4.17.24",
48
67
  "@types/node": "^26.0.0",
49
68
  "@typescript/native": "npm:typescript@^7.0.2",
50
69
  "@vitest/coverage-v8": "^4.1.10",
70
+ "conventional-changelog-conventionalcommits": "10.2.1",
51
71
  "fta-cli": "^3.0.0",
52
72
  "jiti": "^2.7.0",
53
73
  "oxfmt": "^0.62.0",
54
74
  "oxlint": "^1.77.0",
55
75
  "oxlint-tsgolint": "^7.0.2001",
76
+ "semantic-release": "25.0.9",
56
77
  "typescript": "npm:@typescript/typescript6@^6.0.2",
57
78
  "vitest": "^4.1.10"
58
79
  },
@@ -67,24 +88,5 @@
67
88
  },
68
89
  "author": "Kensio Software",
69
90
  "license": "Apache-2.0 AND CC-BY-SA-4.0",
70
- "type": "module",
71
- "scripts": {
72
- "build": "rm -rf dist && tsc -p tsconfig.build.json",
73
- "cli": "node --import jiti/register src/cli/main.ts",
74
- "build:check": "tsc -p tsconfig.json --noEmit",
75
- "fmt": "oxlint --fix . && oxfmt .",
76
- "lint": "oxlint . && oxfmt --check .",
77
- "lint:ci": "oxlint --format=github . && oxfmt --check .",
78
- "fta": "./scripts/sh/fta.sh",
79
- "pack:check": "./scripts/sh/pack-check.sh",
80
- "build:data": "node --import jiti/register scripts/build-data/build.ts",
81
- "fetch:data": "node --import jiti/register scripts/build-data/fetch.ts",
82
- "test": "vitest run",
83
- "test:coverage": "vitest run --coverage",
84
- "check": "pnpm fmt && pnpm fta && pnpm build && pnpm build:check && pnpm test:coverage",
85
- "accuracy": "node --import jiti/register scripts/build-data/accuracy.ts",
86
- "polyphones": "node --import jiti/register scripts/build-data/polyphones.ts",
87
- "numerals": "node --import jiti/register scripts/build-data/numerals.ts",
88
- "transcription": "node --import jiti/register scripts/build-data/transcription.ts"
89
- }
90
- }
91
+ "type": "module"
92
+ }