i18n: generate zh-Hant from zh-CN

zh-Hant is the zh-CN text in Traditional characters, but contributors
still translated it by hand from `--missing zh-Hant`, and a model asked
for Traditional Chinese writes Taiwan vocabulary (影片, 伺服器, 載入).

`npm run i18n -- --zh-hant` now rewrites zh-Hant.json from zh-CN.json
with OpenCC s2tw (opencc-js 1.4.2, cn -> tw, characters only), then the
fixed list of characters it picks wrongly. The check that `npm test`
runs fails when zh-Hant differs from that conversion, naming the key,
and `--missing zh-Hant` points to the command instead of printing a
template.

The conversion reproduces every one of the 3346 entries on main. 25
keys were out of zh-CN order and move; no value changes.

The converter loads on first use, so a copy of the script without
node_modules (stale-index.test.mjs) still extracts messages.
This commit is contained in:
German Khokhlov committed 2026-11-13 18:46:27 +04:00
1 parent 42540ad85e
commit 5d28d614e0
9 files changed
+230 -38

No files matched your search

+3 -1
View File
@@ -5096,7 +5096,9 @@ Shipped locales: **en** (source and fallback), **ar**, **de**, **es**, **fr**, *
- **Gate.** `npm run i18n` (and `src/i18n/catalog.test.mjs` under `npm test`)
extracts every message and fails on missing, empty, unused,
placeholder-mismatched, still-English (plural forms included) or
wrongly-shaped plural entries.
wrongly-shaped plural entries. `zh-Hant` is generated from `zh-CN`
(`npm run i18n -- --zh-hant`: OpenCC `s2tw` through `opencc-js`, then a
fixed list of character corrections), and the gate fails when it differs.
- **Not translated by design:** layer ids, share-link and hash parameters, API
fields, voice tool schemas, provider names, feed data (callsigns, vessel and
station names) and attribution.