Naraguna:Bennylin/trans-batak.js

Saka Wikipédia Jawa, bauwarna mardika basa Jawa

Cathetan: Nalika rampung nyimpen, panjenengan kudu mbusek telihing pangluruné panjenengan supaya owahané katon.

  • Firefox / Safari: Pencèt Shift nalika ngeklik Reload, utawa pencèt Ctrl-F5 utawa Ctrl-R (⌘-R ing Mac)
  • Google Chrome: Pencèt Ctrl-Shift-R (⌘-Shift-R ing Mac)
  • Internet Explorer / Edge: Pencèt Ctrl nalika ngeklik Refresh, utawa pencèt Ctrl-F5
  • Opera: Menyang Menu → Settings (Opera → Preferences ing Mac) nuli menyang Privacy & security → Clear browsing data → Cached images and files.
/*!
* trans.js
* https://bennylin.github.com/transliterasi/batak.html
*
* Copyright 2013-2021, Bennylin @bennylin
* Dual licensed under the MIT or GPL Version 2 licenses.
* Released under the MIT, BSD, and GPL Licenses.
*
* Versions:
* 1 April 2021 - v 1.0
* July 2023 - v 1.1, thank you User:Surung_Simanullang
* TODO: -h, bindu, u_1bef, -ou simalungun u_1bed
*
* Derived from my Javanese transliteration: https://jv.wikipedia.org/wiki/Naraguna:Bennylin/trans.js
*/
var vowelPrev = false;
/***************************
Function SuperTrim, findstr
trim string, menemukan karakter di dalam string
****************************/
function SuperTrim(str) {
	str = str || '';
	return str.replace(/^\s*|\s*$/g,'').replace(/\s+/g,' ');
}
function findstr(str,tofind) {
	for (var i = 0; i < str.length; i++)
	if (str[i] == tofind)
	return true;
	return false;
}
/***************************
Function isDigit, isPunct, isVowel
cek apakah digit, tanda baca, atau huruf vokal (a, e/è/é, i, o, u, ě/ê, ô, ā/ī/ū/ō)
****************************/
function isDigit(a) {
	var str = "0123456789";
	return findstr(str,a);
}
function isPunct(a) {
	var str = ",.><?/+=-_}{[]*&^%$#@!~`\"\\|:;()";
	return findstr(str,a);
}
function isVowel(a) {
	var str = "AaEeÈèÉéIiOoUuÊêĚěXxôāīūō";
	return findstr(str,a);
}
function isConsonant(a) {
	var str = "BCDfGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";
	//QXqx are special chars, add engma & enye
	return findstr(str,a);
}

function getLanguage() {
    var bahasa;
    var modeTranslit = document.getElementsByName("bahasa");
    for(var rad in modeTranslit) {
      if(modeTranslit[rad].checked)
        bahasa = modeTranslit[rad].value;
    }
    return bahasa;
}
/***************************
Function GetMatra
apabila huruf vokal, return matra (sandhangan swara)
****************************/
function GetMatra(str) {
	var i = 0;
	if (str.length < 1) {
		return "";
	}
	if (i < str.length) {
		str = str.substring(i);
	}
    //Aksara i (ᯤ) dan u (ᯥ) hanya digunakan untuk suku kata terbuka, misal
    // pada kata dan ina ᯤᯉ dan ulu ᯥᯞᯮ. Untuk suku kata tertutup yang diawali 
    // dengan bunyi i atau u, digunakanlah aksara a (ᯀ atau ᯁ) bersama 
    // diaktirik untuk masing-masing vokal, misal pada kata indung ᯀᯪᯉ᯲ᯑᯮᯰ dan
    // umpama ᯀᯮᯔ᯲ᯇᯔ
    //Huruf Latin kapital I dan U menghasilkan aksara-aksara "ina ni surat" 
    // ᯤ dan ᯥ, sementara huruf Latin kecil i dan u menghasilkan aksara-aksara 
    // "anak ni surat" ᯀᯪ dan ᯀᯮ.
	var matramapT= { //toba, pakpak, mandailing
		"e":'ᯩ', "é":'ᯩ', "i":'ᯪ', "o":'ᯬ', "u":'ᯮ', "x":'ᯧ',
		"A":'ᯀ', "E":'ᯀᯩ', "I":'ᯤ', "O":'ᯀᯬ', "U":'ᯥ', "X":'ᯀᯧ'
	} 
	var matramapS= { //simalungun
		"e":'ᯩ', "é":'ᯩ', "i":'ᯫ', "o":'ᯬ', "u":'ᯮ', "x":'ᯧ',
		"A":'ᯁ', "E":'ᯁᯩ', "I":'ᯤ', "O":'ᯁᯬ', "U":'ᯥ', "X":'ᯁᯧ'
	} 
	var matramapK= { //karo
		"e":'ᯩ', "é":'ᯩ', "i":'ᯫ', "o":'ᯭ', "u":'ᯬ', "x":'ᯧ',
		"A":'ᯀ', "E":'ᯀᯩ', "I":'ᯤ', "O":'ᯀᯭ', "U":'ᯥ', "X":'ᯀᯧ'
	}
    var matramap;
    var bahasa = getLanguage();
    if (bahasa == "karo") matramap = matramapK;
    else if (bahasa == "simalungun") matramap = matramapS;
    else //if (bahasa == "toba" || bahasa == "pakpak-dairi" || bahasa == "angkola-mandailing")
      matramap = matramapT;

	if(matramap[str]!==undefined) {
		return matramap[str];
	}
	return "";
}
/***************************
Function GetShift
apabila huruf bikonsonan, return karakter khusus
****************************/
function GetShift(str) {
    var bahasa = getLanguage();
	str = str.toLowerCase();
	if (str.indexOf("ng") == 0) {
		//suku kata diawali 'ng'
      if (str.indexOf("nga") == 0) { return { "CoreSound": "" + "ᯝ", "len": 3 };
      } else if (str.indexOf("nge") == 0) { return { "CoreSound": "" + "ᯝᯩ", "len": 3 };
      } else if (str.indexOf("ngi") == 0 && bahasa == "karo") { return { "CoreSound": "" + "ᯝᯫ", "len": 3 };
      } else if (str.indexOf("ngi") == 0) { return { "CoreSound": "" + "ᯝᯪ", "len": 3 };
      } else if (str.indexOf("ngo") == 0 && bahasa == "karo") { return { "CoreSound": "" + "ᯝᯭ", "len": 3 };
      } else if (str.indexOf("ngo") == 0) { return { "CoreSound": "" + "ᯝᯬ", "len": 3 };
      } else if (str.indexOf("ngu") == 0 && bahasa == "simalungun") { return { "CoreSound": "" + "ᯝᯯ", "len": 3 };
      } else if (str.indexOf("ngu") == 0) { return { "CoreSound": "" + "ᯝᯮ", "len": 3 };
      } else if (str.indexOf("ngg") == 0) { return { "CoreSound": "" + "ᯰᯎ", "len": 3 }; //contoh "hutonggohon"
      } else {
		return { "CoreSound": "ᯰ", "len": 2 }; //amisara (sandhangan / cecak)
      }
	} 
	if (str.indexOf("ny") == 0) {//suku kata diawali 'ny'
		return { "CoreSound": "ᯠ", "len": 2 };
	}
	if (str.indexOf("nd") == 0 && bahasa == "karo") {//nd-
		return { "CoreSound": "ᯢ", "len": 2 };
	} else if (str.indexOf("nd") == 0) {//nd-
		return { "CoreSound": "ᯉ᯲ᯑ", "len": 2 };
	}
	if (str.indexOf("mb") == 0 && bahasa == "karo") {//mb-
		return { "CoreSound": "ᯣ", "len": 2 };
	} else if (str.indexOf("mb") == 0 && bahasa == "simalungun") {//mb-
		return { "CoreSound": "ᯕ᯳ᯅ", "len": 2 };
	} else if (str.indexOf("mb") == 0) {//mb-
		return { "CoreSound": "ᯔ᯲ᯅ", "len": 2 };
	}
	return {
		"CoreSound": null, "len": 1
	}
	;
}
/***************************
Function GetCoreSound
return aksara nglegana
****************************/
function GetCoreSound(str) {
	var soundMapT = { //toba
		"A":"ᯀ", "E":"ᯀᯩ", "I":"ᯤ", "O":"ᯀᯬ", "U":"ᯥ", "X":"ᯀᯧ",
		"a":"ᯀ", "e":"ᯀᯩ", "i":"ᯤ", "o":"ᯀᯬ", "u":"ᯥ", "x":"ᯀᯧ", 
		"B":"ᯅ", "C":"ᯡ", "D":"ᯑ", "G":"ᯎ", "H":"ᯂ", "J":"ᯐ", "Z":"ᯐ", "K":"ᯄ᯦", "Q":"ᯂ", "L":"ᯞ",
		"M":"ᯔ", "N":"ᯉ", "P":"ᯇ", "F":"ᯇ", "R":"ᯒ", "S":"ᯘ", "T":"ᯗ", "V":"ᯋ", "W":"ᯍ", "Y":"ᯛ",
		"b":"ᯅ", "c":"ᯚ᯦", "d":"ᯑ", "g":"ᯎ", "h":"ᯂ", "j":"ᯐ", "z":"ᯐ", "k":"ᯄ᯦", "q":"ᯂ", "l":"ᯞ",
		"m":"ᯔ", "n":"ᯉ", "p":"ᯇ", "f":"ᯇ", "r":"ᯒ", "s":"ᯘ", "t":"ᯖ", "v":"ᯋ", "w":"ᯋ", "y":"ᯛ"
	}
	var soundMapS = { //simalungun
		"A":"ᯁ", "E":"ᯁᯩ", "I":"ᯤ", "O":"ᯁᯬ", "U":"ᯥ", "X":"ᯁᯧ", 
		"a":"ᯁ", "e":"ᯁᯩ", "i":"ᯁᯪ", "o":"ᯁᯬ", "u":"ᯁᯮ", "x":"ᯁᯧ", 
		"B":"ᯅ", "C":"ᯡ", "D":"ᯑ", "G":"ᯏ", "H":"ᯃ", "J":"ᯐ", "Z":"ᯐ", "K":"ᯃ", "Q":"ᯃ", "L":"ᯟ", 
		"M":"ᯕ", "N":"ᯉ", "P":"ᯈ", "F":"ᯈ", "R":"ᯓ", "S":"ᯙ", "T":"ᯖ", "V":"ᯌ", "W":"ᯌ", "Y":"ᯜ", 
		"b":"ᯅ", "c":"ᯡ", "d":"ᯑ", "g":"ᯏ", "h":"ᯃ", "j":"ᯐ", "z":"ᯐ", "k":"ᯃ", "q":"ᯃ", "l":"ᯟ",
		"m":"ᯕ", "n":"ᯉ", "p":"ᯈ", "f":"ᯈ", "r":"ᯓ", "s":"ᯙ", "t":"ᯖ", "v":"ᯌ", "w":"ᯌ", "y":"ᯜ"
	}
	var soundMapK = { //karo
		"A":"ᯀ", "E":"ᯀᯩ", "I":"ᯤ", "O":"ᯀᯬ", "U":"ᯥ", "X":"ᯀᯧ",
		"a":"ᯀ", "e":"ᯀᯩ", "i":"ᯀᯪ", "o":"ᯀᯬ", "u":"ᯀᯮ", "x":"ᯀᯧ",
		"B":"ᯆ", "C":"ᯠ", "D":"ᯑ", "G":"ᯎ", "H":"ᯀ", "J":"ᯐ", "Z":"ᯐ", "K":"ᯂ", "Q":"ᯂ", "L":"ᯞ",
		"M":"ᯔ", "N":"ᯉ", "P":"ᯇ", "F":"ᯇ", "R":"ᯒ", "S":"ᯘ", "T":"ᯖ", "V":"ᯋ", "W":"ᯋ", "Y":"ᯛ",
		"b":"ᯆ", "c":"ᯠ", "d":"ᯑ", "g":"ᯎ", "h":"ᯀ", "j":"ᯐ", "z":"ᯐ", "k":"ᯂ", "q":"ᯂ", "l":"ᯞ",
		"m":"ᯔ", "n":"ᯉ", "p":"ᯇ", "f":"ᯇ", "r":"ᯒ", "s":"ᯘ", "t":"ᯖ", "v":"ᯋ", "w":"ᯋ", "y":"ᯛ"
	}
	var soundMapAM = { //angkola-mandailing
		"A":"ᯀ", "E":"ᯀᯩ", "I":"ᯤ", "O":"ᯀᯬ", "U":"ᯥ", "X":"ᯀᯧ",
		"a":"ᯀ", "e":"ᯀᯩ", "i":"ᯀᯪ", "o":"ᯀᯬ", "u":"ᯀᯮ", "x":"ᯀᯧ",
		"B":"ᯅ", "C":"ᯚ᯦", "D":"ᯑ", "G":"ᯎ", "H":"ᯄ", "J":"ᯐ", "Z":"ᯐ", "K":"ᯄ᯦", "Q":"ᯂ", "L":"ᯞ",
		"M":"ᯔ", "N":"ᯊ", "P":"ᯇ", "F":"ᯇ", "R":"ᯒ", "S":"ᯚ", "T":"ᯖ", "V":"ᯋ", "W":"ᯋ", "Y":"ᯛ",
		"b":"ᯅ", "c":"ᯚ᯦", "d":"ᯑ", "g":"ᯎ", "h":"ᯄ", "j":"ᯐ", "z":"ᯐ", "k":"ᯄ᯦", "q":"ᯂ", "l":"ᯞ",
		"m":"ᯔ", "n":"ᯊ", "p":"ᯇ", "f":"ᯇ", "r":"ᯒ", "s":"ᯚ", "t":"ᯖ", "v":"ᯋ", "w":"ᯋ", "y":"ᯛ"
	}
	var soundMapPD = { //pakpak-dairi
		"A":"ᯀ", "E":"ᯀᯩ", "I":"ᯤ", "O":"ᯀᯬ", "U":"ᯥ", "X":"ᯀᯧ",
		"a":"ᯀ", "e":"ᯀᯩ", "i":"ᯀᯪ", "o":"ᯀᯬ", "u":"ᯀᯮ", "x":"ᯀᯧ",
		"B":"ᯅ", "C":"ᯘ", "D":"ᯑ", "G":"ᯎ", "H":"ᯀ", "J":"ᯐ", "Z":"ᯐ", "K":"ᯂ", "Q":"ᯂ", "L":"ᯞ",
		"M":"ᯔ", "N":"ᯉ", "P":"ᯇ", "F":"ᯇ", "R":"ᯒ", "S":"ᯘ", "T":"ᯖ", "V":"ᯋ", "W":"ᯍ", "Y":"ᯛ",
		"b":"ᯅ", "c":"ᯘ", "d":"ᯑ", "g":"ᯎ", "h":"ᯀ", "j":"ᯐ", "z":"ᯐ", "k":"ᯂ", "q":"ᯂ", "l":"ᯞ",
		"m":"ᯔ", "n":"ᯉ", "p":"ᯇ", "f":"ᯇ", "r":"ᯒ", "s":"ᯘ", "t":"ᯖ", "v":"ᯋ", "w":"ᯍ", "y":"ᯛ"
	}
    var soundMap;
    var bahasa = getLanguage();
    if (bahasa == "karo") soundMap = soundMapK;
    else if (bahasa == "simalungun") soundMap = soundMapS;
    else if (bahasa == "toba") soundMap = soundMapT;
    else if (bahasa == "pakpak-dairi") soundMap = soundMapPD;
    else if (bahasa == "angkola-mandailing") soundMap = soundMapAM;

	var h_shift = GetShift(str);
	var core = str;
	if (h_shift["CoreSound"] == null) {
		if (soundMap[str.charAt(0)]) core = soundMap[str.charAt(0)];
		return {
			"CoreSound": core,
			"len": 1
		}
		;
	} else {
		return h_shift;
	}
}
/***************************
Function ResolveCharacterSound
return tanda baca, digit, vokal, maupun nglegana+pangkon
****************************/
function ResolveCharacterSound(c) {
    var bahasa = getLanguage();
	var str = "" + c;
	var len = 0;
	if (isConsonant(str[0]) && (bahasa == "karo" || bahasa == "simalungun")) {
		return "" + GetCoreSound(str).CoreSound + "᯳"; //virama panongonan
	} else if (isConsonant(str[0])) {
		return "" + GetCoreSound(str).CoreSound + "᯲"; //virama pangolat
	} else {
		//if (isVowel(str[0])) {
		return "" + GetCoreSound(str).CoreSound;
	}
	/**/
}
/***************************
Function GetSound
fungsi yang mentransliterasi masing-masing suku kata
****************************/
function GetSound(str) {

    var len = 0;
    str = SuperTrim(str);
    str2 = str.toLowerCase();
    if (str == null || str == "") {
        return "";
    }
    if (str.length == 1) {
        return ResolveCharacterSound(str[0]);
    } else {
        var core_sound = GetCoreSound(str);
        //return "1"+core_sound.CoreSound+"2";
        var matra = "";
        var konsonan = "";
            if (core_sound.len >= 1) {
                matra = GetMatra(str.substring(core_sound.len)); //xeiou (pepet, taling, suku, taling tarung, wulu, dll.)
                /*if () {

                } else {

                }*/
            } else {
                matra = ""; } //a/å/ɔ

/* rules for some cluster like ngg- that have different behaviour depending if it's the start of a word or not.
TODO: find more elegant solution */
        if (core_sound.CoreSound == 'ᯱ' && matra == "᯲") { // wignyan
            konsonan = "ᯱ"; matra = ""; //wignyan
        } else if (core_sound.CoreSound == 'ᯱ' && matra != "᯲") { // wignyan
            konsonan = "ᯂ"; //ha
        } else if (core_sound.CoreSound == 'ᯰ​' && matra == "᯲") { // cecak
            konsonan = "ᯰ​"; matra = ""; //cecak
        } else if (core_sound.CoreSound == 'ᯰ​' && matra != "᯲") { // cecak
            konsonan = "ᯝ"; //nga
        } else {
            konsonan = core_sound.CoreSound;
        }
        return "" + konsonan + matra;
    }
}
/***************************
Function DoTransliterate
fungsi utama yang dipanggil (main function)
****************************/
function DoTransliterate(str) {
	var i = 0;
	var ret = "";
	var pi = 0;
	var vowelFlag = false;
	startVowel = false;
	str = str.toLowerCase();
	str = SuperTrim(str);
	while (i < str.length) {

        if (i > 0 && isVowel(str[i]) && isVowel(str[i-1])) { //deal with words with two vocals in a row
           if ((str[i-1] == 'e' || str[i-1] == 'è' || str[i-1] == 'é' || str[i-1] == 'i' || str[i-1] == 'o' || str[i-1] == 'u') && (str[i] == 'a')) { // -oa- / -ua-
               str = str.substring(0, i)+'ᯀ'+str.substring(i+1, str.length);
           } else if ((str[i-1] == 'a' || str[i-1] == 'e' || str[i-1] == 'è' || str[i-1] == 'é' || str[i-1] == 'o' || str[i-1] == 'u') && (str[i] == 'i')) { // -oi- / -ui-
               str = str.substring(0, i)+'ᯤ'+str.substring(i+1, str.length); //contoh: Ai godang na masa angka naung salpu
           } else if ((str[i-1] == 'a' || str[i-1] == 'e' || str[i-1] == 'è' || str[i-1] == 'é' || str[i-1] == 'i' || str[i-1] == 'o') && (str[i] == 'u')) { // -ou-
               str = str.substring(0, i)+'ᯥ'+str.substring(i+1, str.length);
           } else if ((str[i-1] == 'a' || str[i-1] == 'e' || str[i-1] == 'è' || str[i-1] == 'é' || str[i-1] == 'i' || str[i-1] == 'u') && (str[i] == 'o')) { // -uo-
               str = str.substring(0, i)+'ᯀᯬ'+str.substring(i+1, str.length);
           } else if ((str[i-1] == 'a' || str[i-1] == 'i' || str[i-1] == 'u') && (str[i] == 'e' || str[i] == 'è' || str[i] == 'é')) { // -oe- / -ue-
               str = str.substring(0, i)+'ᯀᯩ'+str.substring(i+1, str.length);
           } else {
               str = str.substring(0, i)+'h'+str.substring(i, str.length);
           }
        }
		if (i > 0 && ((str[i-1] == 'n' && (str[i] == 'g' || str[i] == 'y' || str[i] == 'd')) || (str[i-1] == 'm' && str[i] == 'b')) && !vowelFlag) {
			//i++;
		} else if ((str[i] == 'h' && vowelFlag) || (!isVowel(str[i]) && i > 0) || (str[i] == ' ') || isPunct(str[i]) || isDigit(str[i]) || ((i - pi) > 5)) {
			ret += GetSound(str.substring(pi, i));
            if (str[i] == ' ') { ret += ' '; }
			if (isPunct(str[i])) {
					ret += str[i];
					pi = i + 1;
			} else {
				pi = i;
			}
			vowelFlag = false;
		} else if (isVowel(str[i]) && str[i] != 'h') {
			//ret += GetSound(str.substring(pi, i));
			vowelFlag = true;
		}
		if (pi > 0 && isVowel(str[pi-1])) {
			//<vowel>ngg
			vowelPrev = true;
		} else vowelPrev = false;
		i++;
	}
	//endwhile
	if (pi < i) {
		ret += GetSound(str.substring(pi, i));
	}
	return SuperTrim(ret);
}