From 1bd2bfef30ca28e69350e421d70bf1487a955d57 Mon Sep 17 00:00:00 2001 From: untunt Date: Mon, 30 Oct 2023 09:28:16 +0800 Subject: [PATCH] Add Mongol --- README.md | 1 + mongol.js | 483 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/main.js | 2 + 3 files changed, 486 insertions(+) create mode 100644 mongol.js diff --git a/README.md b/README.md index 5d41d97..7ab62d3 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ https://nk2028-1305783649.file.myqcloud.com/qieyun-examples/ - 推導盛中唐擬音 (Extrapolated Reconstruction of High and Middle Tang Chinese): `mid_tang.js` - 推導《聲音唱和圖》擬音 (Extrapolated Reconstruction of _Shing-im Chiang-xhua Dhu_): `chiangxhua.js` +- 推導《蒙古字韻》 (Extrapolated _Menggu Ziyun_): `mongol.js` - 推導《中原音韻》擬音 (Extrapolated Reconstruction of _Zhongyuan Yinyun_): `zhongyuan.js` - 推導《分韻撮要》擬音 (Extrapolated Reconstruction of _Fan-Wan Tsʽüt-Iú_): `fanwan.js` - 推導普通話 (Extrapolated Putonghua): `putonghua.js` diff --git a/mongol.js b/mongol.js new file mode 100644 index 0000000..a460ac0 --- /dev/null +++ b/mongol.js @@ -0,0 +1,483 @@ +/* 推導《蒙古字韻》 + * + * 由切韻音系音韻地位完美推導《蒙古字韻》八思巴字及各家轉寫、擬音 + * + * 《蒙古字韻》音節表(不含聲調)反映金、南宋時官話發音,但各音節轄字係由《平水韻》系韻書直接填入,不反映實際字音。聲調方面《蒙古字韻》全濁聲母獨立、全濁上獨立、入聲韻拼作對應的陰聲韻,皆爲沿襲等韻學習慣,不反映實際字音。不過正因如此,本推導方案的推導準確率達 100% + * + * 參考文獻: + * + * - 元刊本. 禮部韻略七音三十六母通考. https://www.digital.archives.go.jp/item/3215715 + * (載於《古今韻會舉要》書前,以下簡稱《通考》) + * - 照那斯圖, 楊耐思. 1987. 蒙古字韻校本. + * - 甯忌浮. 1997. 《古今韻會舉要》及相關韻書. + * - Coblin, W. South. 2007. A Handbook of 'Phags-pa Chinese. https://doi.org/10.1515/9780824861261 + * - Shen, Zhongwei. 2008. Studies on the Menggu Ziyun. + * - 沈鐘偉. 2015. 《蒙古字韻》集校. + * - 宋洪民. 2017. 八思巴字資料與蒙古字韻. + * - 濱田武志. 2019. 論《蒙古字韻》所反映的漢語方言音系. https://doi.org/10.1163/2405478x-01101006 + * - unt. 2023. 《蒙古字韻》音系. https://zhuanlan.zhihu.com/p/597563597 + * + * 其他轉寫來源: + * + * - 照那斯圖. 1980. 論八思巴字. + * - 吉池孝一. 2005. パスパ文字の字母表. + * + * @author unt + */ + +const is = (x) => 音韻地位.屬於(x); +const when = (...x) => 音韻地位.判斷(...x); +const 字母韻後綴 = 選項?.後綴 ?? '₂'; + +if (!音韻地位) return [...[ + ['顯示', [1, + '八思巴字', + '照那斯圖 1987 轉寫 ⭐', + '吉池孝一 2005 轉寫', + 'Coblin 2007 轉寫', + 'Coblin 2007 擬音', + '沈鐘偉 2008/2015 轉寫兼擬音', + // TODO: '濱田武志 2019 擬音', + 'unt 2023 轉寫 ⭐', + 'unt 2023 擬音 ⭐', + ]], + ['ꡠ、ꡦ 的轉寫', 選項?.顯示 === '照那斯圖 1987 轉寫 ⭐' ? [1, 'ꡠe ꡦė(八思巴字漢語風格)', 'ꡠė ꡦe(八思巴字蒙古語風格)'] : null], + ['聲母附加數字', 選項?.顯示 === '吉池孝一 2005 轉寫' ? [1, '₁ ₂', '1 2(原文)'] : null], + ['零聲母陽調下加', 選項?.顯示 === '沈鐘偉 2008/2015 轉寫兼擬音' ? [2, + '◌\u0331 長音符(U+0331)', + '◌\u0332 橫線(U+0332)', + '◌\u035F 雙長音符(U+035F)', + ] : null], // 原文爲整個音節加下劃線 +], ...(選項?.顯示 === 'unt 2023 擬音 ⭐' ? [] : [ + '', + ['兩字母韻拼寫相同時加後綴區分', true], + ...(選項?.兩字母韻拼寫相同時加後綴區分 ?? true ? [ + ['後綴', [1, '₂', '²', '2', '′']], + '', ['經韻 ꡦꡞꡃ ≠ 行韻 ꡦꡞꡃ' + 字母韻後綴, true], + '', ['弓韻 ꡦꡟꡃ ≠ 雄韻 ꡦꡟꡃ' + 字母韻後綴, true], + '', ['規韻 ꡦꡟꡠ ≠ 麾韻 ꡦꡟꡠ' + 字母韻後綴, true], + '', ['杴韻 ꡦꡠꡏ ≠ 嫌韻 ꡦꡠꡏ' + 字母韻後綴, true], + '', + ] : []), + ['寶字採用 ꡎꡖꡡ 拼寫(「御寳上用此寳字」)', false], +]), ...[ + '音韻地位的選取', + '', ['推導器 ≠ 傳統等韻學 = 原書 時', [2, '依推導器', '依原書']], + '', ['推導器 = 傳統等韻學 ≠ 原書 時', [2, '依推導器', '依原書']], + '', ['保留《蒙古字韻》小韻歸併錯誤', false], + // 不保留《蒙古字韻》小韻拼寫錯誤 + '', ['不字讀重唇音', true], +]]; + +const use傳統 = 選項['推導器 ≠ 傳統等韻學 = 原書 時'] === '依原書'; +const use創新 = 選項['推導器 = 傳統等韻學 ≠ 原書 時'] === '依原書'; + +function 調整音韻地位() { + function 調整(表達式, 調整屬性, 字頭串 = null) { + if (typeof (字頭串) === 'string' && !字頭串.includes(字頭)) return; + if (is(表達式)) 音韻地位 = 音韻地位.調整(調整屬性); + } + + [[true, [ // 《廣韻》特殊小韻的正常調整 + ['云母 通曾攝 舒聲 非 開口', { 母: '匣' }], // 雄熊 + ['云匣母 眞韻 開口', { 母: '匣', 重紐: 'A' }], // 礥 + ]], + [use傳統, [ + ['從母 眞韻 去聲', { 母: '邪' }], // 賮燼藎贐 + ['影母 青韻 去聲', { 呼: '開' }], // 鎣瑩瀅 + ['清母 歌韻 去聲', { 呼: '合' }, '磋'], // 磋 + ['見母 仙韻 重紐A類 開口 入聲', { 重紐: 'B' }], // 孑 + ['並母 灰韻 上聲', { 韻: '咍' }, '倍菩蓓萯䔒培痱傰'], // 倍 + ['滂母 灰韻 上聲', { 韻: '咍' }], // (仿照倍) + ['廢韻 平上聲 開口', { 韻: '皆', 等: '二' }], // 茝 + ['匣母 先韻 開口 上聲', { 母: '匣', 韻: '眞', 等: '三', 重紐: 'A' }, '礥𧥺㘋'], // 礥 + ]], + [use創新, [ // 《通考》也如此 + ['云母 咸攝 舒聲', { 母: '以' }], // 炎焱 + ['云母 蒸韻 合口 入聲', { 母: '影' }], // 域罭棫緎淢 + ['端母 庚韻 二等', { 韻: '麻' }], // 打 + ['來母 歌韻 去聲', { 呼: '合' }], // 邏 + ['曉母 脂韻 重紐A類 合口 去聲', { 韻: '灰', 等: '一' }, '䁤睢𥍋婎'], // 《通考》睢(《蒙古字韻》無字) + // ['曉母 青韻 合口 入聲', { 韻: '庚', 等: '三' }], // 《通考》殈(《蒙古字韻》無字) + ['曉母 梗攝 三四等 合口 去聲', { 韻: '庚', 等: '三' }], // 夐 + ['曉母 青韻 開口 入聲', { 呼: '合' }], // 赥䦧𥍠 + ['溪母 仙韻 重紐A類 開口 去聲', { 重紐: 'B' }], // 譴遣 + ['曉母 咸攝 三等 入聲', { 韻: '添', 等: '四' }], // 脅愶㢵嗋熁 + ]], + [選項['保留《蒙古字韻》小韻歸併錯誤'], [ // 《通考》不誤 + ['曉母 (止攝 或 臻攝 入聲 非 元韻) 重紐A類', { 母: '匣' }], // 屎欯、隳墮獝 + ['曉母 陽韻 合口 入聲', { 母: '並' }], // 戄(ħwjaw 混入 vaw) + ['澄母 仙韻 開口 入聲', { 母: '知' }], // 轍徹撤澈 + ['溪母 青韻 開口 上聲', { 呼: '合' }, '綮'], // 《廣韻》未收,《集韻》溪開四青上 + ]], + [選項.不字讀重唇音, [ // 《古今韻會舉要》也有此音 + ['幫母 文韻 入聲', { 韻: '魂', 等: '一' }, '不'], + ]]].forEach(e => { + if (e[0]) e[1].forEach(args => 調整(...args)); + }); +} + +調整音韻地位(); + +const 韻圖等 = when([ + ['幫組 東鍾微虞廢文元歌陽尤凡韻 三等 非 重紐A類', '輕'], + + // 切韻一二四等到韻圖不變 + ['非 三等', 音韻地位.等], + + // 按韻圖約定,幽韻一律歸四等 + ['幽韻', '四'], + + // 切韻三等,聲母是銳音的情況 + ['莊組', '二'], + ['知章組 或 來日母', '三'], + ['端精組 或 以母', '四'], // 含“爹、地” + + // 切韻三等,聲母是鈍音的情況 + ['重紐A類 或 麻清韻', '四'], // TODO: qieyun-js 更新後刪去麻清韻 + ['', '三'], +]); + +// 接下來先推導 unt 擬音,再反推八思巴字 +function get聲母() { + const is創新的二四等併入三等 = is`見溪羣曉母 臻攝 舒聲 重紐A類 合口` || + is`曉母 ((曾梗攝 開口 二三四等) 或 (山咸攝 (四等 或 重紐A類)) 或 幽韻) 舒聲` || + is`羣母 山攝 三四等 合口 舒聲`; + let 聲母字典 = {}; + if ((韻圖等 === '四' || 韻圖等 === '二' && !is`合口 或 江韻 舒聲`) && !(use創新 && is創新的二四等併入三等)) 聲母字典 = { + 見: 'c', 溪: 'cʰ', 羣: 'ɟ', 曉: 'ç', 匣: 'ʝ', + 影: 'ʔ', 疑: '', 云: '', 以: '', + }; + else if (韻圖等 === '輕') 聲母字典 = { + 幫: 'f', 滂: 'f', 並: 'v', 明: 'ʋ', + }; + else if (韻圖等 === '三' || use創新 && is創新的二四等併入三等 || is`江韻 舒聲`) 聲母字典 = { + 曉: 'x', 匣: use創新 ? 'ʝ' : 'ɣ', // 匣三(雄小韻)併入四等 + }; + if (聲母字典[音韻地位.母] === undefined) 聲母字典 = { + 幫: 'p', 滂: 'pʰ', 並: 'b', 明: 'm', + 端: 't', 透: 'tʰ', 定: 'd', 泥: 'n', 來: 'l', + + 精: 'ts', 清: 'tsʰ', 從: 'dz', 心: 's', 邪: 'z', + 知: 'tʂ', 徹: 'tʂʰ', 澄: 'dʐ', 孃: 'n', // 泥孃合併 + 莊: 'tʂ', 初: 'tʂʰ', 崇: 'dʐ', 生: 'ʂ', 俟: 'dʐ', // 俟母併入崇母 + 章: 'tʂ', 昌: 'tʂʰ', 船: 'dʐ', 書: 'ʂ', 常: 'ʐ', 日: 'ɻ', // 常船顛倒 + 見: 'k', 溪: 'kʰ', 羣: 'ɡ', 曉: 'χ', 匣: 'ʁ', + 影: 'ʡ', 疑: 'ŋ', 云: 'ŋ', 以: 'ŋ', // ŋ 稍後處理 + }; + return 聲母字典[音韻地位.母]; +} + +function get韻母() { + const is合口 = when([ + ['效深咸攝 舒聲', '開'], // 流攝唇音歸合口 + ['遇通攝 或 痕韻 入聲', '合'], + ['江韻 銳音', '合'], + [use創新 && '明母 曾梗攝 一二等 舒聲', '合'], + ['幫組', [ + [韻圖等 === '三' && '止蟹攝 或 (臻深曾梗攝 入聲)', '合'], + [韻圖等 === '輕' && '臻流果攝 非 元韻', '合'], // TODO: qieyun-js 更新後刪去元韻,下同 + ['二三四等', '開'], + ['曾攝 舒聲 或 宕攝', '開'], + [use創新 && '咍泰韻', '開'], + ['', '合'], + ]], + ['', 音韻地位.呼 ?? '開'], + ]) === '合'; + const is三四等 = '三四'.includes(韻圖等) && !is`止攝 精組 開口` || + is`見影組 江梗攝 二等 舒聲 非 合口` || + 韻圖等 === '輕' && is`止蟹攝`; + + // 推導底層形式,僅 3 個元音:ɨ、ʌ、a + let 韻基 = when([ + ['(臻深攝 非 元韻) 入聲', [ + [韻圖等 === '四' && '見影組 或 以母', 'ɨj'], + [韻圖等 === '三' && '幫組', 'ɨj'], + ['', 'ɨ'], + ]], + + ['止攝 精莊組 開口 或 遇攝 或 通攝 入聲', 'ɨ'], + ['果假攝 或 (山咸攝 或 元韻) 入聲', [ + [韻圖等 === '輕' && '果攝', 'ʌ'], // 《通考》縛(《蒙古字韻》無字) + [is三四等 || 韻圖等 === '一' && (is合口 || '非 (入聲 非 見影組)'), 'ʌ'], + ['', 'a'], + ]], + + ['通曾梗攝 舒聲', 'ɨŋ'], + ['宕江攝 舒聲', 'aŋ'], + + ['止蟹攝 或 曾梗攝 入聲', [ + [use創新 && 韻圖等 === '二' && '曾攝', 'ɨj'], + [use創新 && 韻圖等 === '二' && '蟹攝 三四等', 'ɨj'], // 㯔毳。另有《廣韻》𠻜小韻 + [is三四等 || 韻圖等 === '一' && (is合口 || '入聲'), 'ɨj'], + ['', 'aj'], + ]], + + ['(臻攝 非 元韻) 舒聲', 'ɨn'], + ['(山攝 或 元韻) 舒聲', [ + [is三四等 || 韻圖等 === '一' && is合口, 'ʌn'], + ['', 'an'], + ]], + + ['流攝', 'ɨw'], + ['效攝 或 宕江攝 入聲', [ + [use創新 && '宕攝 莊組 三等', 'ʌw'], // 斮 + [is三四等, 'ʌw'], + ['', 'aw'], + ]], + + ['深攝 舒聲', 'ɨm'], + ['咸攝 舒聲', [ + [is三四等, 'ʌm'], + ['', 'am'], + ]], + ], '無韻母規則', true); + + // 生成表層形式 + const is細音 = is三四等 || + 韻圖等 === '二' && !is合口 && is`見影組 或 以母` || + use創新 && is`莊組 蟹攝 三四等 開口` || // 《通考》殺(《集韻》生開三祭去,對應《廣韻》㡜小韻)(《蒙古字韻》無字) + use創新 && is`宕攝 莊組 三等 入聲`; + 韻基 = { + ɨ: ['i', 'y', 'ɨ', 'u'], + ʌ: ['jɛ', 'ɥɛ', 'ʌ', 'wɔ'], + a: ['ja', 'wa', 'a', 'wa'], // 撮口呼併入合口呼 + }[韻基[0]][!is細音 * 2 + (is合口)] + 韻基.slice(1); + if (韻基 === 'ij') 韻基 = 'i'; + if (韻基 === 'y') 韻基 = 'ɥu'; + if (韻基 === 'yj' && !(韻圖等 === '四' && is`見影組 或 以母`)) 韻基 = 'uj'; // 三等併入合口呼 + if (韻基 === 'ɥɛn' && 韻圖等 === '三' && is`見影組 或 來母`) 韻基 = 'ɥɔn'; // 條件變體 + if (韻基 === 'ɥɛn' && use創新 && is`羣曉母`) return 'ɥɔn'; // 四等併入三等 + return 韻基; +} + +function get擬音() { + let 擬音 = get聲母() + get韻母(); + [ + [/ŋ(?=ɥ|y|w|u)/, 'w'], + ['jj', 'j'], ['ww', 'w'], + ].forEach(e => 擬音 = 擬音.replace(...e)); + return 擬音; +} + +function 擬音to八思巴字(擬音) { + if (選項['寶字採用 ꡎꡖꡡ 拼寫(「御寳上用此寳字」)'] && + 擬音 === 'paw' && '寶寳宝珤'.includes(字頭)) { // 只考慮推導器的廣韻資料,不增加更多字頭 + return 'ꡎꡖꡡ'; + } + const 聲母字典 = { + p: 'ꡎ', pʰ: 'ꡍ', b: 'ꡌ', m: 'ꡏ', f: 'ꡰ', v: 'ꡤ', ʋ: 'ꡓ', + t: 'ꡊ', tʰ: 'ꡉ', d: 'ꡈ', n: 'ꡋ', l: 'ꡙ', // ꡇ 稍後處理 + ts: 'ꡒ', tsʰ: 'ꡑ', dz: 'ꡐ', s: 'ꡛ', z: 'ꡕ', + tʂ: 'ꡆ', tʂʰ: 'ꡅ', dʐ: 'ꡄ', ʂ: 'ꡮ', ʐ: 'ꡚ', ɻ: 'ꡔ', + c: 'ꡂꡦ', cʰ: 'ꡁꡦ', ɟ: 'ꡀꡦ', ç: 'ꡜꡦ', ʝ: 'ꡯꡦ', ɣ: 'ꡯꡦ', ʝjaŋ: 'ꡯjaŋ', ɣjaŋ: 'ꡯjaŋ', + k: 'ꡂ', kʰ: 'ꡁ', ɡ: 'ꡀ', x: 'ꡜ', χ: 'ꡜ', ʁ: 'ꡣ', + xwaŋ: 'ꡜɥaŋ', xuj: 'ꡜuj₂', // 怳、麾 + ʔ: 'ꡗ', ʔja: 'ꡗa', + j: 'ꡭ', ɥ: 'ꡭɥ', i: 'ꡭi', y: 'ꡭy', jɛ: 'ꡭjɛ', + ʡ: 'ꡖ', + ŋ: 'ꡃ', wɥ: 'ꡝɥ', w: 'ꡝw', wy: 'ꡝy', wu: 'ꡝu', + }; + const 後處理替換列表 = [ + // 【韻母到八思巴字】 + // 介音 + 韻核 + ['i', 'ꡞ'], ['ɨ', 'ꡜꡞ'], + [/y|ꡦy(?=j)|ɥu/, 'ꡦꡟ'], ['u', 'ꡟ'], + [/ꡦjɛ|(? e + [/(?<=[ꡤ])ꡟꡓ/, 'ꡡꡓ'], // (v)uw -> ow + [/(?<=[ꡣ])ꡧꡃ/, 'ꡡꡃ'], // (ʁ)waŋ -> oŋ(可能代表 o̯aŋ) + + // 照組(含孃母)後調整洪細 + [/(?<=[ꡆꡅ ꡮꡚꡔꡇ])ꡦꡟꡃ/, 'ꡟꡃ'], // juŋ -> uŋ(崇母除外) + [/(?<=[ꡆꡅꡄꡮꡚꡔꡇ])ꡃ/, 'ꡜꡃ'], // aŋ -> ħaŋ + [/(?<=[ꡆꡅꡄꡮꡚꡔꡇ])ꡦꡃ/, 'ꡃ'], // jaŋ -> aŋ + [/(?<=[ꡔ])ꡟꡃ/, use創新 ? 'ꡦꡟꡃ' : 'ꡟꡃ'], // (ɻ)uŋ -> juŋ + + // ħ、ɣ、ʁ 後調整洪細 + [/(?<=^[ꡜꡯ])ꡞ(?!$)/, 'ꡦꡞ'], // (ħ|ɣ)i(C) -> ji + [/(?<=^[ꡜꡣ])ꡜ/, ''], // (ħ|ʁ)ħ -> 刪除 + [/(?<=^[ꡜ])ꡦ(?=ꡋ)/, use創新 ? 'ꡠ' : 'ꡦ'], // (ħ)je(n) -> e + [/(?<=^[ꡜꡯ])ꡦ(?=ꡋ|ꡏ)/, 'ꡦꡠ'], // (ħ|ɣ)je(n|m) -> jee + [/(?<=^[ꡜꡯ])ꡠ(?=ꡋ|ꡏ)/, 'ꡦ'], // (ħ|ɣ)e(n|m) -> je + [/(?<=^[ꡜ])ꡦ(?=ꡏ)/, use創新 ? 'ꡦꡠ' : 'ꡦ'], // (ħ)je(m) -> jee + + // 三四等的不規則分佈 + [/(? e + [/(? e + [/(?<=[ꡗ])ꡠ(?!ꡟ|ꡃ|ꡡ)/, 'ꡦ'], // (ʔ͡j)e -> je + [/(?<=[ꡖꡭꡃ])ꡦ(?!ꡟ|ꡃ|ꡡ)/, 'ꡠ'], // (ʔ|j|ŋ)je -> e + [/(?<=[ꡖ])ꡠ(?=$|ꡋ)/, use創新 ? 'ꡦ' : 'ꡠ'], // (ʔ)e(0|n) -> je + [/(?<=[ꡍꡐ])ꡠ(?=ꡓ|ꡏ)/, use創新 ? 'ꡦ' : 'ꡠ'], // (pʰ|dz)e(w|m) -> je + [/(?<=[ꡏꡔ])ꡦ(?=ꡋ)/, use創新 ? 'ꡠ' : 'ꡦ'], // (m|ɻ)je(n) -> e + [/(?<=[ꡙ])ꡦ(?=ꡓ)/, use創新 ? 'ꡠ' : 'ꡦ'], // (l)je(w) -> e + + // 韻母特殊拼寫 + [/(?<=[ꡗꡭ])ꡦꡟꡠ/, 'ꡧꡞ'], // (ʔ͡j|j)jue -> wi + [/(?<=[ꡖꡝ])ꡦꡟꡋ/, 'ꡧꡞꡋ'], // (ʔ|ɦ)jun -> win + [/(?<=[ꡖ])ꡧꡦ$/, use創新 ? 'ꡧꡠ' : 'ꡧꡦ'], // (ʔ)jwe -> we。《通考》噦(《蒙古字韻》無字) + [/(?<=[ꡀꡜꡣꡖꡝ])ꡦꡡꡋ/, 'ꡧꡦꡋ'], // (ɡ|ħ|ʁ|ʔ|ɦ)jon -> wjen + [/ꡦꡦꡟꡃ/, 'ꡦꡟꡃ' + (選項['弓韻 ꡦꡟꡃ ≠ 雄韻 ꡦꡟꡃ' + 字母韻後綴] ? 字母韻後綴 : '')], + [/(?<=ꡯ)ꡦꡞꡃ/, 'ꡦꡞꡃ' + (選項['經韻 ꡦꡞꡃ ≠ 行韻 ꡦꡞꡃ' + 字母韻後綴] ? 字母韻後綴 : '')], + [/ꡟꡠ₂/, 'ꡦꡟꡠ' + (選項['規韻 ꡦꡟꡠ ≠ 麾韻 ꡦꡟꡠ' + 字母韻後綴] ? 字母韻後綴 : '')], + [/(?<=ꡯ)ꡦꡠꡏ/, 'ꡦꡠꡏ' + (選項['杴韻 ꡦꡠꡏ ≠ 嫌韻 ꡦꡠꡏ' + 字母韻後綴] ? 字母韻後綴 : '')], + + // 聲母特殊拼寫 + [/ꡗ(?=ꡧꡞ|ꡧꡦ$)/, use創新 ? 'ꡖ' : 'ꡗ'], // 恚、抉 ʔ͡j > ʔ。《通考》也如此 + [/ꡝꡧ?(?=ꡟ(?!ꡠ)|ꡡ)/, ''], // 主要元音是 u、o 時,省略 w 母(ue 中的 u 不被視爲主要元音) + + [/ꡦ+/, 'ꡦ'], // 不use創新時的潛在情況 + ]; + const 古代對立未合併列表 = [ + [/ꡋ(?=ꡞ$|ꡟꡠ|ꡠꡏ)/, 'ꡇ', '孃母'], // 泥捼鮎 n > 尼諉黏 ɲ + [/(?<=[ꡭ])ꡠ$/, 'ꡦ', '疑母'], // 謁 je > 齧 jje + [/(?<=[ꡜ])ꡦꡟꡃ/, 'ꡧꡞꡃ', '梗攝 庚韻 平聲'], // 兄 ħwiŋ > 胷 ħjuŋ // TODO: qieyun-js 更新後改爲梗攝 重紐B類 + [/(?<=[ꡖ])ꡟꡃ/, 'ꡧꡟꡃ', '梗攝'], // 翁 ʔuŋ > 泓 ʔwuŋ + [/(?<=[ꡆꡅ])ꡦꡋ/, 'ꡠꡋ', '知組 平去聲'], // 饘 tʂjen > 邅 tʂen + [/(?<=[ꡅ])ꡠꡓ/, 'ꡦꡓ', '徹母 開口'], // 弨 tʂʰew > 超 tʂʰjew + ]; + + let 聲母 = ''; + Object.keys(聲母字典).forEach(e => { if (擬音.startsWith(e) && e.length > 聲母.length) 聲母 = e; }); + 擬音 = 擬音.replace(聲母, 聲母字典[聲母]); + 後處理替換列表.forEach(e => 擬音 = 擬音.replace(...e)); + if (use創新) 古代對立未合併列表.forEach(e => { if (is(e[2])) 擬音 = 擬音.replace(e[0], e[1]); }); + return 擬音; +} + +function 八思巴字to轉寫(str) { + const 八思巴字轉寫列表 = { + '八思巴字': [ + 'ꡂ', 'ꡁ', 'ꡀ', 'ꡃ', + 'ꡊ', 'ꡉ', 'ꡈ', 'ꡋ', + 'ꡆ', 'ꡅ', 'ꡄ', 'ꡇ', + 'ꡎ', 'ꡍ', 'ꡌ', 'ꡏ', 'ꡰ', 'ꡤ', 'ꡓ', + 'ꡒ', 'ꡑ', 'ꡐ', 'ꡛ', 'ꡕ', 'ꡮ', 'ꡚ', + 'ꡜ', 'ꡣ', 'ꡯ', 'ꡖ', 'ꡗ', 'ꡝ', 'ꡭ', 'ꡙ', 'ꡔ', + 'ꡞ', 'ꡟ', 'ꡠ', 'ꡡ', 'ꡦ', 'ꡧ', 'ꡨ', + ], + '照那斯圖 1987 轉寫 ⭐': [ + 'g', 'kʻ', 'k', 'ŋ', + 'd', 'tʻ', 't', 'n', + 'dž', 'tšʻ', 'tš', 'ň', + 'b', 'pʻ', 'p', 'm', 'hu̯', 'ħu̯', 'w', + 'dz', 'tsʻ', 'ts', 's', 'z', 'š₂', 'š₁', + 'h', 'ɣ', 'ħ', 'ꞏ', 'j̊', 'ʼ', 'j', 'l', 'ž', + 'i', 'u', 'e', 'o', 'ė', 'u̯', 'i̯', + ], + '吉池孝一 2005 轉寫': [ + 'g', 'kʻ', 'k', 'ŋ', + 'd', 'tʻ', 't', 'n', + 'ǰ', 'čʻ', 'č', 'ň', + 'b', 'pʻ', 'p', 'm', 'f1', 'f2', 'v', + 'j', 'cʻ', 'c', 's', 'z', 'š2', 'š1', + 'h2', 'γ', 'h1', 'ꞏ', 'y2', 'ʼ', 'y1', 'l', 'ž', + 'i', 'u', 'ė', 'o', 'e', 'ŭ', 'ĭ', + ], + 'Coblin 2007 轉寫': [ + 'g', 'kh', 'k', 'ng', + 'd', 'th', 't', 'n', + 'j', 'ch', 'c', 'ñ', + 'b', 'ph', 'p', 'm', 'Hw', 'hw', 'w', + 'dz', 'tsh', 'ts', 's', 'z', 'sh', 'zh', + 'ʰ', 'X', 'H', '\'', 'Y', 'x', 'y', 'l', 'Zh', + 'i', 'u', 'e', 'o', 'ÿ', 'w', 'y', + ], + 'Coblin 2007 擬音': [ + 'k', 'kʼ', 'ɡ', 'ŋ', + 't', 'tʼ', 'd', 'n', + 'tʂ', 'tʂʼ', 'dʐ', 'ȵ', + 'p', 'pʼ', 'b', 'm', 'f', 'v', 'ʋ', + 'ts', 'tsʼ', 'dz', 's', 'z', 'ʂ', 'ʐ', + 'ʰ', 'ɣ', 'ɣj', 'ʔ', 'ʔj', 'ɦ', 'j', 'l', 'r', + 'i', 'u', 'ɛ', 'ɔ', 'ÿ', 'w', 'j', + ], + '沈鐘偉 2008/2015 轉寫兼擬音': [ + 'k', 'kʰ', 'ɡ', 'ŋ', + 't', 'tʰ', 'd', 'n', + 'tʃ', 'tʃʰ', 'dʒ', 'ɲ', + 'p', 'pʰ', 'b', 'm', 'f', 'v', 'ʋ', + 'ts', 'tsʰ', 'dz', 's', 'z', 'ʃ', 'ʒ', + 'h', 'ɦ', 'ɦj', '0', 'j', '0̲', 'j̲', 'l', 'r', + 'i', 'u', 'e', 'o', 'ɛ', 'w', 'j', + ], + 'unt 2023 轉寫 ⭐': [ + 'k', 'kʰ', 'ɡ', 'ŋ', + 't', 'tʰ', 'd', 'n', + 'tʂ', 'tʂʰ', 'dʐ', 'ɲ', + 'p', 'pʰ', 'b', 'm', 'f', 'v', 'w', + 'ts', 'tsʰ', 'dz', 's', 'z', 'ʂ', 'ʐ', + 'ħ', 'ʁ', 'ɣ', 'ʔ', 'ʔ͡j', 'ɦ', 'j', 'l', 'ɻ', + 'i', 'u', 'e', 'o', 'jE', 'w', 'j', + ], + }; + + const 後處理替換列表字典 = { + '照那斯圖 1987 轉寫 ⭐': [['ėa', 'ė']].concat( + 選項['ꡠ、ꡦ 的轉寫'] === 'ꡠė ꡦe(八思巴字蒙古語風格)' ? [['ė', 'E'], ['e', 'ė'], ['E', 'e'],] : [] + ), + '吉池孝一 2005 轉寫': [ + [/(?<=[fšhy])1/g, 選項.聲母附加數字?.split(' ')[0][0]], + [/(?<=[fšhy])2/g, 選項.聲母附加數字?.split(' ')[1][0]] + ], + 'Coblin 2007 轉寫': [[/^ʰ/, 'h']], + 'Coblin 2007 擬音': [ + [/ʋ$/, 'w'], + [/^ʰ/, 'x'], ['ʰa', 'A'], ['ʰi', 'ə'], [/(?<=s|z)ə$/, 'ɿ'], [/ə$/, 'ʅ'], + ['ÿaŋ', 'jaŋ'], ['ÿa', 'jɛ'], ['ÿ', 'j'], ['jj', 'j'], + ['juŋ', 'yuŋ'], ['ju', 'y'], ['jɔ', 'yɔ'], [/jwj|jw|wj/, 'y'], + [/^y/, 'jy'], + ['uɛ', 'uɛ̌'], + ['paʔɔ', 'paw'], + ], + '沈鐘偉 2008/2015 轉寫兼擬音': [ + [/ɦj(?=w?ɛ)/, 'ɦ'], + ['ɛi', 'ji'], ['ɛe', 'je'], + ['ɛu', 'y'], ['ɛo', 'ø'], ['ɛa', 'ɛ'], + [/(? (str.includes(元音)))) { + if (str.length > 1 && 'ꡏꡋꡃꡭꡓ'.includes(str.slice(-1))) { + // 有韻尾則 a 補在韻尾前 + str = str.slice(0, -1) + 'a' + str.slice(-1); + } else { + // 否則 a 補在最後 + str += 'a'; + } + } + const 八思巴字轉寫字典 = Object.fromEntries( + 八思巴字轉寫列表.八思巴字.map((e, i) => [e, 八思巴字轉寫列表[選項.顯示][i]]) + ); + str = [...str].map(e => 八思巴字轉寫字典[e] ?? e).join(''); + 後處理替換列表字典[選項.顯示].forEach(pair => str = str.replace(...pair)); + return str; +} + +const 擬音 = get擬音(); +if (選項.顯示 === 'unt 2023 擬音 ⭐') return 擬音; +const 八思巴字 = 擬音to八思巴字(擬音); +return 選項.顯示 === '八思巴字' ? 八思巴字 : 八思巴字to轉寫(八思巴字); diff --git a/test/main.js b/test/main.js index 3fc64dd..1e34e0d 100644 --- a/test/main.js +++ b/test/main.js @@ -14,6 +14,7 @@ import { msoeg_v8, mid_tang, chiangxhua, + mongol, zhongyuan, fanwan, putonghua, @@ -47,6 +48,7 @@ assert_equal(unt(音韻地位), "ɕéw"); assert_equal(msoeg_v8(音韻地位), "çiɛuˀ"); assert_equal(mid_tang(音韻地位), "ɕiɛw˦˥"); assert_equal(chiangxhua(音韻地位), "ʃiɛ́w"); +assert_equal(mongol(音韻地位), "ꡮꡠꡓ"); assert_equal(zhongyuan(音韻地位), "ʂjɛw³"); assert_equal(fanwan(音韻地位), "shiu2"); assert_equal(putonghua(音韻地位), "shǎo");