Skip to content

Commit

Permalink
Refactor tupa and msoeg: simplify get韻母()
Browse files Browse the repository at this point in the history
  • Loading branch information
untunt committed Dec 10, 2024
1 parent 6e1d5dc commit d0c0fd9
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 143 deletions.
169 changes: 73 additions & 96 deletions msoeg_v8.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ if (!音韻地位) return [
['顯示高級選項', false],

選項.顯示高級選項 ? '高級選項' : '',
['保留非三等ʶ記號|保留非三等 ʶ 記號\nʶ 不是標準國際音標',
['保留非三等ʶ記號|保留非三等 ʶ 記號\nʶ 不是標準國際音標,代表舌根偏後',
false, { hidden: !選項.顯示高級選項 }],
['章組|\n知乎文章和韻鑒用腭噝音',
[2, '齦後噝音 tʃ', isIPA ? '腭噝音 tɕ' : '腭噝音 tç'], { hidden: !選項.顯示高級選項 }],
Expand All @@ -75,7 +75,7 @@ function get聲母_默認拼寫() {
: 'tʂ', : 'tʂʰ', : 'dʐ', : 'ʂ', : 'ʐ',
: 'tɕ', : 'tɕʰ', : 'dʑ', : 'ɕ', : 'ʑ', : 'ɲ', : 'j',
};
const 小舌化聲母字典 = {
const 非三等聲母字典 = {
: 'pʶ', : 'pʶʰ', : 'bʶ', : 'mʶ',
: 'tʶ', : 'tʶʰ', : 'dʶ', : 'nʶ', : 'lʶ',
: 'q', : 'qʰ', : 'ɴ',
Expand All @@ -84,8 +84,8 @@ function get聲母_默認拼寫() {
};
if (is`云母 開口 非 侵鹽韻`) return 'ɰ';
if (is`以母 合口 或 以母 東鍾虞韻`) return 'ɥ';
if (is`三等 或 來母 二等 非 庚韻`) return 普通聲母字典[音韻地位.] || 小舌化聲母字典[音韻地位.];
return 小舌化聲母字典[音韻地位.] || 普通聲母字典[音韻地位.];
if (is`三等 或 來母 二等 非 庚韻`) return 普通聲母字典[音韻地位.] || 非三等聲母字典[音韻地位.];
return 非三等聲母字典[音韻地位.] || 普通聲母字典[音韻地位.];
}

function get聲母() {
Expand All @@ -102,106 +102,83 @@ function get聲母() {
}

function get韻母() {
// 爲了方便推導,對韻類稍作調整
const = when([
['臻韻 或 莊組 殷韻', '真'],
['文韻', '殷'],
['灰韻', '咍'],
['魂韻', '痕'],
['凡韻', '嚴'],
['東韻 三等', '終'],
['麻韻 三四等', '遮'],
['歌韻 三等', '迦'],
['庚清韻 三等', 選項.庚三清 === '中元音' ? '淸' : '清'],
['庚韻 二等 (端組 或 來母)', '打'],
['江韻 入聲', 選項.覺韻 === '中元音' ? '江' : '覺'],
['', 音韻地位.],
let 韻母 = when([
['之韻', 'ɯ'], ['支韻', 'e'], ['魚韻', 'ɤ'], ['虞模韻', 'o'],
['佳韻', 'ɜ̣'],
['麻韻 三四等', 'a'], ['麻韻', 'ạ'], ['歌韻', 'ɑ'],

[選項.庚三清 === '中元音' && '庚清韻 三等', 'ɛŋ'],
[選項.覺韻 === '低元音' && '江韻 入聲', 'ɑ̣ɴ'],
['蒸韻', 'ɯŋ'], ['東韻', 'uɴ'], ['鍾韻', 'oɴ'],
['青韻', 'ɛŋ'], ['耕韻', 'ɜ̣ŋ'], ['登韻', 'ʌŋ'], ['冬韻', 'ɔɴ'], ['江韻', 'ɞ̣ɴ'],
['庚清韻 (三四等 或 端組 或 來母)', 'aŋ'], ['庚清韻', 'ạŋ'], ['陽唐韻', 'ɑɴ'],

['脂韻', 'ii'], ['微韻', 'ɯi'],
['齊祭韻', 'ɛi'], ['皆韻', 'ɜ̣i'], ['灰咍廢韻', 'ʌi'],
['夬韻', 'ại'], ['泰韻', 'ɑi'],

['真臻韻', 'in'], ['殷韻', 'ɯn'], ['文韻', 'un'],
['先仙韻', 'ɛn'], ['山韻', 'ɜ̣n'], ['元魂痕韻', 'ʌn'],
['刪韻', 'ạn'], ['寒韻', 'ɑn'],

['幽韻', 'iu'], ['尤侯韻', 'uu'],
['蕭宵韻', 'ɛu'],
['肴韻', 'ạu'], ['豪韻', 'ɑu'],

['侵韻', 'im'],
['鹽添韻', 'ɛm'], ['咸韻', 'ɜ̣m'], ['嚴凡韻', 'ʌm'], ['覃韻', 'ɔm'],
['銜韻', 'ạm'], ['談韻', 'ɑm'],
]);
const 推導韻到元音 = [
// ŋ u ŋʷi n m
['  幽 脂真侵', 'i'],
['之蒸  微殷 ', 'ɯ'],
['  尤終   ', 'u'],
['  侯東   ', 'ᵒu'],

['支      ', 'ie'], // 知乎原文支韻在 -i 列
['魚      ', 'ɯɤ'],
['虞  鍾   ', 'uo'], // 知乎原文虞韻在 -u 列
['模      ', 'o'], // 知乎原文模韻在 -u 列

[' 淸宵 祭仙鹽', 'iɛ'], // 用“淸”表示庚三清的中元音變體
[' 青蕭 齊先添', 'ɛ'],
['佳耕  皆山咸', 'ɜ̣'],
['   江   ', 'ɞ̣'],
['  宵 廢元嚴', 'ɯʌ'],
[' 登  咍痕 ', 'ʌ'],
['   冬  覃', 'ɔ'],

['遮清     ', 'ia'],
[' 打     ', 'a'],
['麻庚肴 夬刪銜', 'ạ'],
['   覺   ', 'ɑ̣'],
['迦  陽   ', 'ɯɑ'],
['歌 豪唐泰寒談', 'ɑ'],
];
const 韻尾列表 = ['', 'ŋ/k', 'u', 選項.通江宕攝韻尾, 'i', 'n/t', 'm/p'];

let 匹配行 = 推導韻到元音.find(e => e[0].includes());
let 元音 = 匹配行[1];
let 韻尾 = 韻尾列表[匹配行[0].indexOf()].split('/')[+is`入聲`];
if ( === '覺' && !韻尾.includes('ʷ')) {
韻尾 += 'ʷ';
}
if (is`宕攝 入聲` && !韻尾.includes('ʷ')) {
韻尾 += 選項.宕攝入聲附加.replace('無', '');
}

// 處理三等介音
if (元音 === 'ɯ' && is`銳音 或 蒸韻 B類`) {
// 銳音之蒸韻歸 A 類,唇音性蒸韻下面歸 B 類
元音 = 'i' + 元音;
}
if (元音.includes('i') && is`B類 非 幽韻`) {
// 幽韻知乎原文和韻鑒僅 A 類
// 其中,支宵侵的重紐三等開口歸 C 類
元音 = 元音.replace('i', is`支宵韻 或 侵韻 見影組 非 云母` ? 'ɯ' : 'ị');
}
if (選項.莊三韻母起始 === '普通' && is`莊組 三等`) {
// AB 類歸 B 類
元音 = 元音[0].replace('i', 'ị') + 元音.slice(1);
} else if (is`莊組 三等`) {
元音 = 元音[0] + '̣' + 元音.slice(1);
if (!is`支魚韻`) {
// 介音變爲等同於二等的 ɨ̣(支魚的第一部分不是介音)
元音 = 元音[0].replace('ɯ', 'ɨ').replace('i', 'ɨ') + 元音.slice(1);
// 等類記號
if (is`三等` || is`四等` && 韻母.startsWith('a')) {
if (韻母.startsWith('ɯ') && is`銳音 或 蒸韻 AB類`) 韻母 = 'i' + 韻母;
else if (韻母.match(/^[eɛa]/)) 韻母 = 'i' + 韻母;
else if (韻母.match(/^[ɤʌɑ]/)) 韻母 = 'ɯ' + 韻母;
else if (韻母.startsWith('o')) 韻母 = 'u' + 韻母;

if (韻母.startsWith('i') && is`B類 非 幽韻`) {
// 幽韻知乎原文和韻鑒僅 A 類
// 其中,支宵侵的重紐三等開口歸 C 類
韻母 = 韻母.replace('i', is`支宵韻 或 侵韻 見影組 非 云母` ? 'ɯ' : 'ị');
}
if (選項.莊三韻母起始 !== 'r 化元音') {
// 介音是 ɨ̣ 則改寫爲 ɻ,否則前加 ɻ。支韻的 ị 也改寫爲 ɻ
元音 = 選項.莊三韻母起始 + 元音.replace('ị', '').replace('ɨ̣', '').replace('̣', '');
}
}

// 處理開合介音
if (元音[0] === 'ɯ') {
if (is`合口 或 幫組 非 支宵侵韻`) {
元音 = 元音.replace('ɯ', 'u');
if (is`莊組`) {
韻母 = 韻母.replace(/^i/, 'ị'); // 莊組 AB 類歸 B 類
if (選項.莊三韻母起始 === 'r 化元音') {
韻母 = 韻母.replace(/^(.)̣?(.*)/, '$1̣$2');
韻母 = 韻母.replace(/ị(?!e)|ɯ̣(?!ɤ)/, 'ɨ̣'); // ABC 類的起始都等同於二等的 ɨ̣,支魚韻除外
} else if (選項.莊三韻母起始 === 'ɻ') {
韻母 = 韻母.replace(/(ị|^ɯ(?!ɤ))?/, 'ɻ'); // 以其他元音起始的則直接前加 ɻ,魚韻除外
}
}
} else if (is`合口 非 云以母 非 虞韻`) {
元音 = 'ʷ' + 元音;
元音 = 元音.replace('ʷɻ', 'ɻʷ');
} else {
if (韻母.startsWith('u')) 韻母 = 'ᵒ' + 韻母;
}

if (isIPA) {
[
['ɨ', 'ɯ'],
['ɜ', 'ɛ'],
['ɞ', 'ɔ'],
].forEach(([a, b]) => { 元音 = 元音.replace(a + '̣', b + '̣'); });
元音 = 元音.replace('ᵒ', 'o̯');
// 開合記號
if (韻母.startsWith('ɯ')) {
if (is`合口 或 幫組 非 支宵侵韻`) 韻母 = 韻母.replace('ɯ', 'u');
} else {
if (is`合口 非 云以母`) 韻母 = 韻母.replace(/(ɻ?)(.*)/, '$1ʷ$2').replace('ʷu', 'u');
}
元音 = 元音.replace('̣', 選項.r化元音記號);
韻尾 = 韻尾.replace(元音.slice(-1), ''); // 刪去重複字母 ii、uu
return 元音 + 韻尾;

if (isIPA) 韻母 = 韻母
.replace('ɨ̣', 'ɯ̣')
.replace('ɜ̣', 'ɛ̣').replace('ɞ̣', 'ɔ̣')
.replace('ᵒ', 'o̯');
韻母 = 韻母
.replace('ii', 'i').replace('uu', 'u')
.replace('̣', 選項.r化元音記號)
.replace('ɴ', 選項.通江宕攝韻尾.split('/')[0]);
if (is`入聲`) 韻母 = 韻母
.replace('m', 'p')
.replace('n', 't')
.replace('ŋ', 'k')
.replace('ɴ', 'q');
if (is`江攝 入聲` && !韻母.endsWith('ʷ') && 選項.覺韻 === '低元音') 韻母 += 'ʷ';
if (is`宕攝 入聲` && !韻母.endsWith('ʷ')) 韻母 += 選項.宕攝入聲附加.replace('無', '');
return 韻母;
}

function get聲調() {
Expand Down
96 changes: 49 additions & 47 deletions tupa.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* 切韻拼音
*
* https://phesoca.com/tupa/ 或
* https://www.bilibili.com/read/cv19972367 或
* https://zhuanlan.zhihu.com/p/478751152
*
* @author unt
Expand All @@ -26,57 +28,57 @@ function get聲母() {
}

function get韻母() {
// 爲了方便推導,對韻類稍作調整
const = when([
['蒸韻 B類', '冰'],
['東韻 三等', '終'],
['清韻', '庚'],
['陽韻', '唐'],
['臻韻', '真'],
['凡韻', '嚴'],
['', 音韻地位.],
]);
const 韻到韻尾 = [
['脂之尤侯  佳 模  支魚虞 麻歌', ''],
['冰蒸終東 青耕登冬江   鍾 庚唐', 'ng', 'k'],
[' 微微  齊皆咍灰  祭廢廢 夬泰', 'j'],
['真殷文  先山痕魂  仙元元 刪寒', 'n', 't'],
['幽    蕭     宵   肴豪', 'w'],
['侵    添咸 覃  鹽嚴嚴 銜談', 'm', 'p'],
];
const 元音列表 = [
'i', 'y', 'u', 'ou',
'e', 'ee', 'eo', 'o', 'oeu',
'e', 'yo', 'uo',
'ae', 'a',
];
let 韻母 = when([
['脂韻', 'i'], ['之韻', 'y'], ['尤侯韻', 'u'],
['支韻', 'e'], ['佳韻', 'ee'], ['魚韻', 'eo'], ['虞模韻', 'o'],
['麻韻', 'ae'], ['歌韻', 'a'],

let 匹配行 = 韻到韻尾.find( => [0].includes());
let 元音 = 元音列表[匹配行[0].replace(/ /g, '')[is`開口` ? 'indexOf' : 'lastIndexOf']()];
let 韻尾 = 匹配行[1 + is`入聲`];
['蒸韻 AB類', 'ing'], ['蒸韻', 'yng'], ['東韻', 'ung'],
['青韻', 'eng'], ['耕韻', 'eeng'], ['登韻', 'eong'], ['冬鍾韻', 'ong'], ['江韻', 'oeung'],
['庚清韻', 'aeng'], ['陽唐韻', 'ang'],

// 元音 a 添加三等介音(一般是 C 類)
if (is`三等` && 元音 === 'a') {
// A類見於「𩦠」小韻
元音 = (is`A類` ? 'i' : is`開口` ? 'y' : 'u') + 元音;
}
// 前元音添加三等 A、B 介音
if (
(is`三等` && ['i', 'e', 'ae'].includes(元音)) ||
(元音 === 'ae' && is`端組 四等`)
) {
if (is`B類 或 莊組`) {
元音 = (is`合口` ? 'u' : 'y') + 元音;
} else if (元音 !== 'i') {
// 拼莊組以外的銳音一律視爲 A 類(同《切韻》清韻、《廣韻》諄韻的獨立條件)
元音 = 'i' + 元音;
['微韻', 'uj'],
['齊祭韻', 'ej'], ['皆韻', 'eej'], ['灰咍廢韻', 'oj'],
['夬韻', 'aej'], ['泰韻', 'aj'],

['真臻韻', 'in'], ['殷文韻', 'un'],
['先仙韻', 'en'], ['山韻', 'een'], ['元魂痕韻', 'on'],
['刪韻', 'aen'], ['寒韻', 'an'],

['幽韻', 'iw'],
['蕭宵韻', 'ew'],
['肴韻', 'aew'], ['豪韻', 'aw'],

['侵韻', 'im'],
['鹽添韻', 'em'], ['咸韻', 'eem'], ['覃嚴凡韻', 'om'],
['銜韻', 'aem'], ['談韻', 'am'],
]);
// 不圓脣元音
if (is`開口` && !韻母.endsWith('m')) 韻母 = 韻母.replace(/^u/, 'y').replace(/^o/, 'eo');
// 等類標記
if (is`三等` || is`四等` && 韻母.startsWith('ae')) {
if (is`A類` || is`銳音 非 莊組` && 韻母.match(/^i|^e(?!o)|^ae/)) {
// A 類以 i- 標記
if (!韻母.startsWith('i')) 韻母 = 'i' + 韻母;
} else {
// B、C 類以 y-/u- 標記
if (韻母.match(/^[uo]|^a(?!e)/) ? is`開口` : is`非 合口`) {
if (!韻母.startsWith('y')) 韻母 = 'y' + 韻母;
韻母 = 韻母.replace('yeo', 'yo');
} else {
if (!韻母.startsWith('u')) 韻母 = 'u' + 韻母;
}
}
} else {
// 高元音非三等以 o- 標記
if (韻母.match(/^[yu]/)) 韻母 = 'o' + 韻母;
}
// 添加合口介音
if (is`合口` && !['u', 'o'].includes(元音[0])) {
元音 = 'w' + 元音;
}
return 元音 + 韻尾;
if (is`合口` && !韻母.match(/^[uo]/)) 韻母 = 'w' + 韻母;
if (is`入聲`) 韻母 = 韻母
.replace('ng', 'k')
.replace('n', 't')
.replace('m', 'p');
return 韻母;
}

function get聲調() {
Expand Down

0 comments on commit d0c0fd9

Please sign in to comment.