mirror of
				https://github.com/skishore/makemeahanzi.git
				synced 2025-11-01 03:45:51 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			75 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| if (this.pinyin_util !== undefined) {
 | |
|   throw new Error('Redefining pinyin_util global!');
 | |
| }
 | |
| this.pinyin_util = {};
 | |
| 
 | |
| const vowel_to_tone =
 | |
|     {0: "aeiouü", 1: "āēīōūǖ", 2: "áéíóúǘ", 3: "ǎěǐǒǔǚ", 4: "àèìòùǜ"};
 | |
| 
 | |
| const tokenSet = (tokens) => {
 | |
|   const result = {};
 | |
|   tokens.split(' ').map((x) => result[x] = true);
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| const consonants = tokenSet('b p m f d t n l g k h j q x zh ch sh r z c s y w');
 | |
| const vowels = tokenSet('a ai an ang ao e ei en eng er i ia ian iang iao ie ' +
 | |
|                         'in ing io iong iu o ong ou u ua uai uan uang ue ui ' +
 | |
|                         'un uo v van vn');
 | |
| const two_syllables = tokenSet('ia ian iang iao ie io iong iu ua uai uan ' +
 | |
|                                'uang ue ui uo van');
 | |
| 
 | |
| pinyin_util.dropTones = (pinyin) => {
 | |
|   for (let i = 0; i < pinyin.length; i++) {
 | |
|     for (let option = 1; option <= 4; option++) {
 | |
|       const index = vowel_to_tone[option].indexOf(pinyin[i]);
 | |
|       if (index >= 0) {
 | |
|         const toneless = 'aeiouv'[index];
 | |
|         pinyin = pinyin.substr(0, i) + toneless + pinyin.substr(i + 1);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return pinyin;
 | |
| }
 | |
| 
 | |
| pinyin_util.numberedPinyinToTonePinyin = (numbered) => {
 | |
|   assert(numbered && numbered === numbered.toLowerCase());
 | |
|   let tone = 0;
 | |
|   if ('01234'.indexOf(numbered[numbered.length - 1]) >= 0) {
 | |
|     tone = parseInt(numbered[numbered.length - 1], 10);
 | |
|     numbered = numbered.substr(0, numbered.length - 1);
 | |
|   }
 | |
|   for (let i = 0; i < numbered.length; i++) {
 | |
|     for (let option = 1; option <= 4; option++) {
 | |
|       const index = vowel_to_tone[option].indexOf(numbered[i]);
 | |
|       if (index >= 0) {
 | |
|         tone = option;
 | |
|         const toneless = 'aeiouv'[index];
 | |
|         numbered = numbered.substr(0, i) + toneless + numbered.substr(i + 1);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   let consonant = '';
 | |
|   for (let i = 1; i < numbered.length; i++) {
 | |
|     const candidate = numbered.substr(0, i);
 | |
|     if (consonants[candidate]) {
 | |
|       consonant = candidate;
 | |
|     } else {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   let vowel = numbered.substr(consonant.length);
 | |
|   assert((!consonant || consonants[consonant]) && vowels[vowel]);
 | |
|   if (two_syllables[vowel]) {
 | |
|     const index = 'aeiouv'.indexOf(vowel[1]);
 | |
|     vowel = vowel[0] + vowel_to_tone[tone][index] + vowel.substr(2);
 | |
|   } else {
 | |
|     const index = 'aeiouv'.indexOf(vowel[0]);
 | |
|     assert(index >= 0);
 | |
|     vowel = vowel_to_tone[tone][index] + vowel.substr(1);
 | |
|   }
 | |
|   return consonant + vowel.replace('v', 'ü');
 | |
| }
 | 
