// ==UserScript==
// @name Cyrillic Transliterator (Ukrainian)
// @description Transliterates Ukranian cyrillic characters to latin characters on any webpage (Czech version)
// @version 2.3
// @match *://*/*
// @include *
// @grant none
// @author w4t3r1ily
// @icon https://opu.peklo.biz/p/23/05/13/1684010167-8264b.jpg
// @namespace https://greasyfork.org/users/905173
// ==/UserScript==
(function() {
//Custom rules
var customMap = {
'’Є': 'Je',
'’є': 'je',
"’Ї": "Ji",
"’ї": "ji",
'’Ю': 'Ju',
'’ю': 'ju',
'’Я': 'Ja',
'’я': 'ja',
"'Є": 'Je',
"'є": "je",
"'Ї": "Ji",
"'ї": "ji",
"'Ю": "Ju",
"'ю": "ju",
"'Я": "Ja",
"'я": "ja",
};
// Custom rules for begining of words
var additionalCustomMap = {
'Є': 'Je',
'є': 'je',
'Ю': 'Ju',
'ю': 'ju',
'Я': 'Ja',
'я': 'ja',
};
//Normal transliteration
var map = {
'A': 'A',
'a': 'a',
'Б': 'B',
'б': 'b',
'В': 'V',
'в': 'v',
'Г': 'H',
'г': 'h',
'Ґ': 'G',
'ґ': 'g',
'Д': 'D',
'д': 'd',
'Е': 'E',
'е': 'e',
'Є': 'Ê',
'є': 'ê',
'Ж': 'Ž',
'ж': 'ž',
'З': 'Z',
'з': 'z',
'И': 'Y',
'и': 'y',
'І': 'I',
'і': 'i',
"Ї": "Ji",
"ї": "ji",
'Й': 'J',
'й': 'j',
'К': 'K',
'к': 'k',
'Л': 'L',
'л': 'l',
'М': 'M',
'м': 'm',
'Н': 'N',
'н': 'n',
'О': 'O',
'о': 'o',
'П': 'P',
'п': 'p',
'Р': 'R',
'р': 'r',
'С': 'S',
'с': 's',
'Т': 'T',
'т': 't',
'У': 'U',
'у': 'u',
'Ф': 'F',
'ф': 'f',
'Х': 'Ch',
'х': 'ch',
'Ц': 'C',
'ц': 'c',
'Ч': 'Č',
'ч': 'č',
'Ш': 'Š',
'ш': 'š',
'Щ': 'Šč',
'щ': 'šč',
'Ю': 'Û',
'ю': 'û',
'Я': 'Â',
'я': 'â',
'Ь': 'ʹ',
'ь': 'ʹ',
'’': 'ʺ',
"'": "ʺ",
//Archaic symbols
'Ё': 'Jo',
'ё': 'jo',
'Ъ': '″',
'ъ': '″',
'Ы': 'Y',
'ы': 'y',
'Ѣ': 'Ě',
'ѣ': 'ě',
'Э': 'È',
'э': 'è',
'Ѳ': 'F̀',
'ѳ': 'f̀',
'Ѵ': 'Ỳ',
'ѵ': 'ỳ',
'Ѧ': 'Ę',
'ѧ': 'ę',
};
// Merge the customMap, additionalCustomMap, and map objects
map = Object.assign({}, customMap, additionalCustomMap, map);
function replaceText(node) {
var value = node.nodeValue;
var newValue = '';
var i = 0;
while (i < value.length) {
var char = value.charAt(i);
var nextChar = value.charAt(i + 1);
var combined = char + nextChar;
// Check if the current character is a space or a punctuation mark
var isBeginning = i === 0 || value.charAt(i - 1).match(/\s|[^\p{L}\p{N}]/u);
if (isBeginning && (combined in additionalCustomMap)) {
newValue += additionalCustomMap[combined];
i += 2;
} else if (isBeginning && (char in additionalCustomMap)) {
newValue += additionalCustomMap[char];
i++;
} else if (combined in map) {
newValue += map[combined];
i += 2;
} else if (char in map) {
newValue += map[char];
i++;
} else {
newValue += char;
i++;
}
}
node.nodeValue = newValue;
}
function replaceCyrillic() {
var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
var node;
while (node = walker.nextNode()) {
replaceText(node);
}
}
function createToggleButton() {
var button = document.createElement('button');
button.innerHTML = 'Transliterate (ukr)';
button.className = 'cyr-tr-button'; // Set the class name to "tr-cyr-button"
button.style.position = 'fixed';
button.style.bottom = '40px';
button.style.right = '20px';
button.onclick = toggleTransliteration;
document.body.appendChild(button);
}
function toggleTransliteration() {
isTransliterationEnabled = !isTransliterationEnabled;
if (isTransliterationEnabled) {
replaceCyrillic();
} else {
location.reload();
}
}
var isTransliterationEnabled = false;
var cyrillicRegex = /[\u0400-\u04FF]/;
if (cyrillicRegex.test(document.body.innerHTML)) {
createToggleButton();
}
})();