/* jshint -W100 */ /** * @name translit.js * @author XGuest * @link https://github.com/xguest/iso_9_js * @version 1.0.4 * @copyright GPL applies. * No warranties XGuest[28.03.2016/07:59:18] translit [ver.1.0.4] * #guid {E7088033-479F-47EF-A573-BBF3520F493C} * * @description Прямая и обратная транслитерация * Соответствует ISO 9:1995 и ГОСТ 7.79-2000 системы А и Б * * @param {String} str транслитерируемая строка * @param {Number} typ ± направление (тип) транслитерации * + прямая с латиницы в кириллицу * - обратная * system A = 1-диакритика; * system B = 2-Беларусь;3-Болгария;4-Македония;5-Россия;6-Украина; * @example * function example() { * var a, b = [ * [], * ["Диакритика", "Съешь ещё этих мягких французских булок, да выпей же чаю!"], * ["Беларускую", "З'ясі яшчэ гэтых мяккіх французскіх булак, ды выпі ж чаю!"], * ["Български", "Яжте повече от тези меки кифлички, но също така се пие чай!"], * ["Македонски", "Јадат повеќе од овие меки францускиот ролни, па пијат чај!"], * ["Русский", "Съешь ещё этих мягких французских булок, да выпей же чаю!"], * ["Українська", "З'їж ще цих м'яких французьких булок, та випий же чаю!"] * ], c, d; * for(a = 1; a < b.length - 1; a++) { * c = b[a][0]; // Language * d = b[a][1]; // Source * e = translit(d, a); // Forward * console.log( * "%s - %s\nSource : %s\nTranslit: %s\nReverse : %s\n", * c, // Language * translit(c, a), // Transliterated language * d, // Source * e, // Forward * translit(e, -1 * a) // Reverse * ); * } * }; **/ angular.module('KMS').factory('TransliterationService', function() { return { translit: function(str, typ) { var func = (function(typ) { /** Function Expression * Вспомогательная функция. * * FINISHED TESTED! * В ней и хотелось навести порядок. * * Проверяет направление транслитерации. * Возвращает массив из 2 функций: * построения таблиц транслитерации. * и пост-обработки строки (правила из ГОСТ). * * @param {Number} typ * @return {Array} Массив функций пред и пост обработки. **/ function prep (a) { var write = !a ? function(chr, row) {trantab[row] = chr;regarr.push(row);} : function(row, chr) {trantab[row] = chr;regarr.push(row);}; return function(col, row) { // создаем таблицу и RegExp var chr = col[abs] || col[0]; // Символ if (chr) write(chr, row); // Если символ есть } } var abs = Math.abs(typ); // Абсолютное значение транслитерации if (typ === abs) { // Прямая транслитерация в латиницу str = str.replace(/(i(?=.[^аеиоуъ\s]+))/ig, '$1`'); // "i`" ГОСТ ст. рус. и болг. return [prep(), // Возвращаем массив функций function(str) { // str - транслируемая строка. return str.replace(/i``/ig, 'i`'). // "i`" в ГОСТ ст. рус. и болг. replace(/((c)z)(?=[ieyj])/ig, '$1'); // "cz" в символ "c" }]; } else { // Обратная транслитерация в кириллицу str = str.replace(/(c)(?=[ieyj])/ig, '$1z'); // Правило сочетания "cz" return [prep(1),function(str) {return str;}];// nop - пустая функция. } }(typ)); var iso9 = { // Объект описания стандарта // Имя - кириллица // 0 - общие для всех // 1 - диакритика 4 - MK|MKD - Македония // 2 - BY|BLR - Беларусь 5 - RU|RUS - Россия // 3 - BG|BGR - Болгария 6 - UA|UKR - Украина /*-Имя---------0-,-------1-,---2-,---3-,---4-,----5-,---6-*/ '\u0449': [ '', '\u015D', '','sth', '', 'shh','shh'], // 'щ' '\u044F': [ '', '\u00E2', 'ya', 'ya', '', 'ya', 'ya'], // 'я' '\u0454': [ '', '\u00EA', '', '', '', '', 'ye'], // 'є' '\u0463': [ '', '\u011B', '', 'ye', '', 'ye', ''], // ять '\u0456': [ '', '\u00EC', 'i', 'i`', '', 'i`', 'i'], // 'і' йота '\u0457': [ '', '\u00EF', '', '', '', '', 'yi'], // 'ї' '\u0451': [ '', '\u00EB', 'yo', '', '', 'yo', ''], // 'ё' '\u044E': [ '', '\u00FB', 'yu', 'yu', '', 'yu', 'yu'], // 'ю' '\u0436': [ 'zh','\u017E'], // 'ж' '\u0447': [ 'ch','\u010D'], // 'ч' '\u0448': [ 'sh', '\u0161', '', '', '', '', ''], // 'ш' '\u0473': [ '','f\u0300', '', 'fh', '', 'fh', ''], // фита '\u045F': [ '','d\u0302', '', '', 'dh', '', ''], // 'џ' '\u0491': [ '','g\u0300', '', '', '', '', 'g`'], // 'ґ' '\u0453': [ '', '\u01F5', '', '', 'g`', '', ''], // 'ѓ' '\u0455': [ '', '\u1E91', '', '', 'z`', '', ''], // 'ѕ' '\u045C': [ '', '\u1E31', '', '', 'k`', '', ''], // 'ќ' '\u0459': [ '','l\u0302', '', '', 'l`', '', ''], // 'љ' '\u045A': [ '','n\u0302', '', '', 'n`', '', ''], // 'њ' '\u044D': [ '', '\u00E8', 'e`', '', '', 'e`', ''], // 'э' '\u044A': [ '', '\u02BA', '', 'a`', '', '``', ''], // 'ъ' '\u044B': [ '', 'y', 'y`', '', '', 'y`', ''], // 'ы' '\u045E': [ '', '\u01D4', 'u`', '', '', '', ''], // 'ў' '\u046B': [ '', '\u01CE', '', 'o`', '', '', ''], // юс '\u0475': [ '', '\u1EF3', '', 'yh', '', 'yh', ''], // ижица '\u0446': [ 'cz', 'c'], // 'ц' '\u0430': [ 'a'], // 'а' '\u0431': [ 'b'], // 'б' '\u0432': [ 'v'], // 'в' '\u0433': [ 'g'], // 'г' '\u0434': [ 'd'], // 'д' '\u0435': [ 'e'], // 'е' '\u0437': [ 'z'], // 'з' '\u0438': [ '', 'i', '', 'i', 'i', 'i', 'y`'], // 'и' '\u0439': [ '', 'j', 'j', 'j', '', 'j', 'j'], // 'й' '\u043A': [ 'k'], // 'к' '\u043B': [ 'l'], // 'л' '\u043C': [ 'm'], // 'м' '\u043D': [ 'n'], // 'н' '\u043E': [ 'o'], // 'о' '\u043F': [ 'p'], // 'п' '\u0440': [ 'r'], // 'р' '\u0441': [ 's'], // 'с' '\u0442': [ 't'], // 'т' '\u0443': [ 'u'], // 'у' '\u0444': [ 'f'], // 'ф' '\u0445': [ 'x', 'h'], // 'х' '\u044C': [ '', '\u02B9', '`', '`', '', '`', '`'], // 'ь' '\u0458': [ '','j\u030C', '', '', 'j', '', ''], // 'ј' '\u2019': [ '\'','\u02BC'], // '’' '\u2116': [ '#'] // '№' /*-Имя---------0-,-------1-,---2-,---3-,---4-,----5-,---6-*/ }, regarr = [], trantab = {}; /* jshint -W030 */ // Создание таблицы и массива RegExp for (var row in iso9) {if (Object.hasOwnProperty.call(iso9, row)) {func[0](iso9[row], row);}} /* jshint +W030 */ return func[1]( // функция пост-обработки строки (правила и т.д.) str.replace( // Транслитерация new RegExp(regarr.join('|'), 'gi'),// Создаем RegExp из массива function(R) { // CallBack Функция RegExp if (R.toLowerCase() === R) { // Обработка строки с учетом регистра return trantab[R]; } else { return trantab[R.toLowerCase()].toUpperCase(); } })); } }; });