# Script conversion Source: https://pinyinjs.dev/script-conversion/ Index of every page: https://pinyinjs.dev/llms.txt `toScript` converts between simplified (简体) and traditional (繁體) Chinese. ```ts import { loadScriptTables, toScript } from "@kensio/pinyinjs"; const tables = await loadScriptTables(source); toScript(dictionary, tables, "我们后来发现了头发问题", { to: "zh-Hant" }); // "我們後來發現了頭髮問題" ``` Load the script tables as well as a dictionary. The tables are separate from the data used for pinyin conversion. See [dictionaries](https://pinyinjs.dev/dictionaries/) for setting up a data source. ## Resolving ambiguous characters A simplified character can correspond to several traditional characters. PinyinJS first reads the text, then uses the selected pronunciation to choose among those forms. ```ts toScript(dictionary, tables, "头发", { to: "zh-Hant" }); // "頭髮" toScript(dictionary, tables, "出发", { to: "zh-Hant" }); // "出發" ``` For example, 发 can become 發 or 髮. The readings of 头发 (`tóufà`) and 出发 (`chūfā`) select the appropriate form. Readings also distinguish forms of 干 and 只: | Text | Reading | 繁體 | | ------ | ---------- | ------ | | 干燥 | `gānzào` | 乾燥 | | 干部 | `gànbù` | 幹部 | | 干扰 | `gānrǎo` | 干擾 | | 一只猫 | `yìzhīmāo` | 一隻貓 | | 只有 | `zhǐyǒu` | 只有 | This can resolve a character even when the script-conversion tables do not contain the complete phrase. ## Traditional to simplified conversion Some traditional characters also have more than one simplified mapping. The reading selects among them: ```ts toScript(dictionary, tables, "乾燥", { to: "zh-Hans" }); // "干燥" toScript(dictionary, tables, "乾隆", { to: "zh-Hans" }); // "乾隆" ``` 乾 is 干 when it is `gān` and stays 乾 when it is `qián`. ## Taiwan and Hong Kong Taiwan and Hong Kong use different standard forms for 58 characters. These regional forms represent the same characters and readings. ```ts toScript(dictionary, tables, "面包", { to: "zh-Hant-TW" }); // "麵包" toScript(dictionary, tables, "面包", { to: "zh-Hant-HK" }); // "麪包" ``` | 简体 | `zh-Hant-TW` | `zh-Hant-HK` | | ---- | ------------ | ------------ | | 群众 | 群眾 | 羣眾 | | 里面 | 裡面 | 裏面 | | 卫生 | 衛生 | 衞生 | `zh-Hant` uses Taiwan forms by default. Specify the Hong Kong target when you need forms such as 爲, 衆, 峯, 羣, 裏 and 麪. Two regional mappings also depend on pronunciation: Taiwan uses 著 across its senses. Hong Kong distinguishes 著 and 着: ```ts toScript(dictionary, tables, "看着", { to: "zh-Hant-HK" }); // "看着" toScript(dictionary, tables, "著作", { to: "zh-Hant-HK" }); // "著作" ``` 看著 is `kànzhe` and takes 着. 著作 is `zhùzuò` and keeps 著. The variant 蔘 applies only to the `shēn` reading of 參 (ginseng): ```ts toScript(dictionary, tables, "人参", { to: "zh-Hant-HK" }); // "人蔘" toScript(dictionary, tables, "参加", { to: "zh-Hant-HK" }); // "參加" toScript(dictionary, tables, "参差", { to: "zh-Hant-HK" }); // "參差" ``` Without a reading, 著 defaults to 着 and 參 defaults to 參. These choices are reported as uncertain. `isReadingSensitive` identifies these characters. Of the 58 regional mappings, 39 come from Hong Kong's standard table and 19 reverse Taiwan mergers. 著 and 參 are the reading-sensitive cases among those mergers. ## Inspecting conversion choices Some choices remain ambiguous after reading the text. For example, 下面 can refer to a surface or noodles, both pronounced `xiàmiàn`. `toScriptPieces` returns the selected form and supporting evidence for each character. ```ts import { isUncertainChoice, toScriptPieces } from "@kensio/pinyinjs"; const { text, choices } = toScriptPieces(dictionary, tables, "下面", { to: "zh-Hant", }); text; // "下面" choices.filter(isUncertainChoice).map((choice) => choice.from); // ["面"] choices[1]?.alternatives; // ["麵"] ``` Evidence has four levels, from strongest to weakest: | `evidence` | Means | | ---------- | ------------------------------------------------------------ | | `locked` | the character has one form; there was nothing to decide | | `word` | a word some source wrote in both scripts settled it | | `reading` | rival forms existed and the syllable picked between them | | `default` | rival forms existed and nothing separated them — **a guess** | `alternatives` is empty when the evidence is `locked`. The original character can itself be an alternative. For example, 万 usually becomes 萬 but remains 万 in the surname 万俟. ```ts const { choices } = toScriptPieces(dictionary, tables, "一万人", { to: "zh-Hant", }); choices[1]?.evidence; // "default" choices[1]?.alternatives; // ["万"] ``` Alternatives use the target region's forms. A Hong Kong conversion offers 麪 where Taiwan offers 麵. Regional rules can also remove ambiguity. Hong Kong uses 台 for both Taiwan forms 台 and 臺, so 台北 remains 台北 without an uncertain choice. `isUncertainChoice` is true only for `default` evidence. Choices resolved by a reading are treated as settled. ```ts const { choices } = toScriptPieces(dictionary, tables, "头发", { to: "zh-Hant", }); choices.map((choice) => choice.evidence); // ["locked", "reading"] ``` In the reference corpus, 97.6% of character choices were `locked` and 1.7% used the default. Run `pnpm accuracy` to reproduce the measurement. ## Detecting the input The converter detects the input script unless you supply `from`. Detection prevents a valid traditional form from being treated as simplified input. For example, traditional 准將 should retain 准. ```ts toScript(dictionary, tables, "准將", { to: "zh-Hant" }); // "准將", unchanged toScript(dictionary, tables, "群众", { to: "zh-Hant", from: "Hans" }); // "群眾" ``` Set `from` when short input consists only of characters shared by both scripts. Without evidence for the source script, the converter assumes the input needs conversion. ## Vocabulary is preserved ```ts toScript(dictionary, tables, "软件", { to: "zh-Hant" }); // "軟件" ``` Script conversion changes character forms while preserving word choice. It does not replace 软件 with the Taiwan term 軟體. Vocabulary substitution requires a separate application step. ## Accuracy The accuracy check converts simplified dictionary keys to traditional and back. Most should reproduce the original simplified word. Run it with `pnpm accuracy`: | Trip | words in use | every key | | -------------- | -----------: | --------: | | 简→繁→简 | 99.6% | 99.3% | | 繁→简→繁 | 98.9% | 99.8% | | 繁TW→繁HK→繁TW | 99.7% | 99.6% | A traditional-to-simplified-to-traditional conversion can lose distinctions. For example, 卻 and 却 both simplify to 却, so only one form can be reconstructed. The check reports this loss. ## At the command line ```console $ pinyinjs script 我们后来发现了头发问题 --to zh-Hant 我們後來發現了頭髮問題 ``` See [the command line](https://pinyinjs.dev/cli/).