SickGear/lib/trans/trans.py
2023-02-09 13:41:15 +00:00

273 lines
11 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# coding: utf8
u""" This module translates national characters into similar
sounding latin characters (transliteration).
At the moment, Czech, Greek, Latvian, Polish, Turkish, Russian, Ukrainian
and Kazakh alphabets are supported (it covers 99% of needs).
Python 3:
>>> from trans import trans
>>> trans('Привет, Мир!')
Python 2:
>>> import trans
>>> u'Привет, Мир!'.encode('trans')
u'Privet, Mir!'
>>> trans.trans(u'Привет, Мир!')
u'Privet, Mir!'
Source and full documentations can be found here:
https://github.com/zzzsochi/trans
"""
import sys
import codecs
__version__ = '2.1.0'
__author__ = 'Zelenyak Aleksander aka ZZZ <zzz.sochi@gmail.com>'
PY2 = sys.version_info[0] == 2
class Trans(object):
""" Main class for transliteration with tables.
"""
def __init__(self, tables=None, default_table=None):
self.tables = tables or {}
self.default_table = default_table
def __call__(self, input, table=None):
""" Translate unicode string, using 'table'.
Table may be tuple (diphthongs, other), dict (other) or string name of table.
"""
if table is None:
if self.default_table is not None:
table = self.default_table
else:
raise ValueError('Table not set.')
if not isinstance(input, unicode if PY2 else str): # noqa
raise TypeError(
'trans codec support only unicode string, {0!r} given.'.format(type(input))
)
if isinstance(table, basestring if PY2 else str): # noqa
try:
table = self.tables[table]
except KeyError:
raise ValueError(u'Table "{0}" not found in tables!'.format(table))
if isinstance(table, dict):
table = ({}, table)
first = input
for diphthong, value in table[0].items():
first = first.replace(diphthong, value)
default = table[1].get(None, u'_')
second = u''
for char in first:
second += table[1].get(char, default)
return second
latin = {
u'à': u'a', u'á': u'a', u'â': u'a', u'ã': u'a', u'ä': u'a', u'å': u'a',
u'æ': u'ae', u'ç': u'c', u'è': u'e', u'é': u'e', u'ê': u'e', u'ë': u'e',
u'ì': u'i', u'í': u'i', u'î': u'i', u'ï': u'i', u'ð': u'd', u'ñ': u'n',
u'ò': u'o', u'ó': u'o', u'ô': u'o', u'õ': u'o', u'ö': u'o', u'ő': u'o',
u'ø': u'o', u'ù': u'u', u'ú': u'u', u'û': u'u', u'ü': u'u', u'ű': u'u',
u'ý': u'y', u'þ': u'th', u'ÿ': u'y',
u'À': u'A', u'Á': u'A', u'Â': u'A', u'Ã': u'A', u'Ä': u'A', u'Å': u'A',
u'Æ': u'AE', u'Ç': u'C', u'È': u'E', u'É': u'E', u'Ê': u'E', u'Ë': u'E',
u'Ì': u'I', u'Í': u'I', u'Î': u'I', u'Ï': u'I', u'Ð': u'D', u'Ñ': u'N',
u'Ò': u'O', u'Ó': u'O', u'Ô': u'O', u'Õ': u'O', u'Ö': u'O', u'Ő': u'O',
u'Ø': u'O', u'Ù': u'U', u'Ú': u'U', u'Û': u'U', u'Ü': u'U', u'Ű': u'U',
u'Ý': u'Y', u'Þ': u'TH', u'ß': u'ss',
}
greek = {
u'α': u'a', u'β': u'b', u'γ': u'g', u'δ': u'd', u'ε': u'e', u'ζ': u'z',
u'η': u'h', u'θ': u'8', u'ι': u'i', u'κ': u'k', u'λ': u'l', u'μ': u'm',
u'ν': u'n', u'ξ': u'3', u'ο': u'o', u'π': u'p', u'ρ': u'r', u'σ': u's',
u'τ': u't', u'υ': u'y', u'φ': u'f', u'χ': u'x', u'ψ': u'ps', u'ω': u'w',
u'ά': u'a', u'έ': u'e', u'ί': u'i', u'ό': u'o', u'ύ': u'y', u'ή': u'h',
u'ώ': u'w', u'ς': u's', u'ϊ': u'i', u'ΰ': u'y', u'ϋ': u'y', u'ΐ': u'i',
u'Α': u'A', u'Β': u'B', u'Γ': u'G', u'Δ': u'D', u'Ε': u'E', u'Ζ': u'Z',
u'Η': u'H', u'Θ': u'8', u'Ι': u'I', u'Κ': u'K', u'Λ': u'L', u'Μ': u'M',
u'Ν': u'N', u'Ξ': u'3', u'Ο': u'O', u'Π': u'P', u'Ρ': u'R', u'Σ': u'S',
u'Τ': u'T', u'Υ': u'Y', u'Φ': u'F', u'Χ': u'X', u'Ψ': u'PS', u'Ω': u'W',
u'Ά': u'A', u'Έ': u'E', u'Ί': u'I', u'Ό': u'O', u'Ύ': u'Y', u'Ή': u'H',
u'Ώ': u'W', u'Ϊ': u'I', u'Ϋ': u'Y',
}
turkish = {
u'ş': u's', u'Ş': u'S', u'ı': u'i', u'İ': u'I', u'ç': u'c', u'Ç': u'C',
u'ü': u'u', u'Ü': u'U', u'ö': u'o', u'Ö': u'O', u'ğ': u'g', u'Ğ': u'G'
}
russian = (
{
u'юй': u'yuy', u'ей': u'yay',
u'Юй': u'Yuy', u'Ей': u'Yay'
},
{
u'а': u'a', u'б': u'b', u'в': u'v', u'г': u'g', u'д': u'd', u'е': u'e',
u'ё': u'yo', u'ж': u'zh', u'з': u'z', u'и': u'i', u'й': u'y', u'к': u'k',
u'л': u'l', u'м': u'm', u'н': u'n', u'о': u'o', u'п': u'p', u'р': u'r',
u'с': u's', u'т': u't', u'у': u'u', u'ф': u'f', u'х': u'h', u'ц': u'c',
u'ч': u'ch', u'ш': u'sh', u'щ': u'sh', u'ъ': u'', u'ы': u'y', u'ь': u'',
u'э': u'e', u'ю': u'yu', u'я': u'ya',
u'А': u'A', u'Б': u'B', u'В': u'V', u'Г': u'G', u'Д': u'D', u'Е': u'E',
u'Ё': u'Yo', u'Ж': u'Zh', u'З': u'Z', u'И': u'I', u'Й': u'Y', u'К': u'K',
u'Л': u'L', u'М': u'M', u'Н': u'N', u'О': u'O', u'П': u'P', u'Р': u'R',
u'С': u'S', u'Т': u'T', u'У': u'U', u'Ф': u'F', u'Х': u'H', u'Ц': u'C',
u'Ч': u'Ch', u'Ш': u'Sh', u'Щ': u'Sh', u'Ъ': u'', u'Ы': u'Y', u'Ь': u'',
u'Э': u'E', u'Ю': u'Yu', u'Я': u'Ya',
})
ukrainian = (russian[0].copy(), {
u'Є': u'Ye', u'І': u'I', u'Ї': u'Yi', u'Ґ': u'G',
u'є': u'ye', u'і': u'i', u'ї': u'yi', u'ґ': u'g',
})
ukrainian[1].update(russian[1])
czech = {
u'č': u'c', u'ď': u'd', u'ě': u'e', u'ň': u'n', u'ř': u'r', u'š': u's',
u'ť': u't', u'ů': u'u', u'ž': u'z',
u'Č': u'C', u'Ď': u'D', u'Ě': u'E', u'Ň': u'N', u'Ř': u'R', u'Š': u'S',
u'Ť': u'T', u'Ů': u'U', u'Ž': u'Z',
}
polish = {
u'ą': u'a', u'ć': u'c', u'ę': u'e', u'ł': u'l', u'ń': u'n', u'ó': u'o',
u'ś': u's', u'ź': u'z', u'ż': u'z',
u'Ą': u'A', u'Ć': u'C', u'Ę': u'E', u'Ł': u'L', u'Ń': u'N', u'Ó': u'O',
u'Ś': u'S', u'Ź': u'Z', u'Ż': u'Z',
}
latvian = {
u'ā': u'a', u'č': u'c', u'ē': u'e', u'ģ': u'g', u'ī': u'i', u'ķ': u'k',
u'ļ': u'l', u'ņ': u'n', u'š': u's', u'ū': u'u', u'ž': u'z',
u'Ā': u'A', u'Č': u'C', u'Ē': u'E', u'Ģ': u'G', u'Ī': u'i', u'Ķ': u'k',
u'Ļ': u'L', u'Ņ': u'N', u'Š': u'S', u'Ū': u'u', u'Ž': u'Z',
}
kazakh = (russian[0].copy(), {
u'ә': u'a', u'ғ': u'g', u'қ': u'k', u'ң': 'n', u'ө': u'o', u'ұ': u'u',
u'ү': u'u', u'һ': u'h', u'і': u'i',
u'Ә': u'A', u'Ғ': u'G', u'Қ': u'K', u'Ң': 'N', u'Ө': u'O', u'Ұ': u'U',
u'Ү': u'U', u'Һ': u'H', u'І': u'I',
})
kazakh[1].update(russian[1])
farsi = {
u'ا': u'a',
u'أ': u'a', u'\uFE81': u'a', u'\uFE82': u'a',
u'آ': u'a', u'\uFE83': u'a', u'\uFE84': u'a',
u'ب': u'b', u'\uFE8F': u'b', u'\uFE90': u'b', u'\uFE92': u'b', u'\uFE91': u'b',
u'ت': u't', u'\uFE95': u't', u'\uFE96': u't', u'\uFE98': u't', u'\uFE97': u't',
u'ث': u'th', u'\uFE99': u'th', u'\uFE9A': u'th', u'\uFE9C': u'th', u'\uFE9B': u'th',
u'ج': u'j', u'\uFE9D': u'j', u'\uFE9E': u'j', u'\uFEA0': u'j', u'\uFE9F': u'j',
u'ح': u'h', u'\uFEA1': u'h', u'\uFEA2': u'h', u'\uFEA4': u'h', u'\uFEA3': u'h',
u'خ': u'x', u'\uFEA5': u'x', u'\uFEA6': u'x', u'\uFEA8': u'x', u'\uFEA7': u'x',
u'د': u'd', u'\uFEA9': u'd', u'\uFEAA': u'd',
u'ذ': u'd', u'\uFEAB': u'd', u'\uFEAC': u'd',
u'ر': u'r', u'\uFEAD': u'r', u'\uFEAE': u'r',
u'ز': u'z', u'\uFEAF': u'z', u'\uFEB0': u'z',
u'س': u's', u'\uFEB1': u's', u'\uFEB2': u's', u'\uFEB4': u's', u'\uFEB3 ': u's',
u'ش': u'sh', u'\uFEB5': u'sh', u'\uFEB6': u'sh', u'\uFEB8': u'sh', u'\uFEB7': u'sh',
u'ص': u's', u'\uFEB9': u's', u'\uFEBA': u's', u'\uFEBC': u's', u'\uFEBB': u's',
u'ض': u'd', u'\uFEBD': u'd', u'\uFEBE': u'd', u'\uFEC0': u'd', u'\uFEBF': u'd',
u'ط': u't', u'\uFEC1': u't', u'\uFEC2': u't', u'\uFEC4': u't', u'\uFEC3': u't',
u'ظ': u'z', u'\uFEC5': u'z', u'\uFEC6': u'z', u'\uFEC8': u'z', u'\uFEC7': u'z',
u'ع': u'ao', u'\uFEC9': u'ao', u'\uFECA': u'ao', u'\uFECC': u'ao', u'\uFECB': u'ao',
u'غ': u'za', u'\uFECD': u'za', u'\uFECE': u'za', u'\uFED0': u'za', u'\uFECF': u'za',
u'ف': u'f', u'\uFED1': u'f', u'\uFED2': u'f', u'\uFED4': u'f', u'\uFED3': u'f',
u'ق': u'q', u'\uFED5': u'q', u'\uFED6': u'q', u'\uFED8': u'q', u'\uFED7': u'q',
u'ك': u'k', u'\uFED9': u'k', u'\uFEDA': u'k', u'\uFEDC': u'k', u'\uFEDB': u'k',
u'ل': u'l', u'\uFEDD': u'l', u'\uFEDE': u'l', u'\uFEE0': u'l', u'\uFEDF': u'l',
u'م': u'm', u'\uFEE1': u'm', u'\uFEE2': u'm', u'\uFEE4': u'm', u'\uFEE3': u'm',
u'ن': u'n', u'\uFEE5': u'n', u'\uFEE6': u'n', u'\uFEE8': u'n', u'\uFEE7': u'n',
u'ه': u'h', u'\uFEE9': u'h', u'\uFEEA': u'h', u'\uFEEC': u'h', u'\uFEEB': u'h',
u'و': u'wa', u'\uFEED': u'wa', u'\uFEEE': u'wa',
u'ي': u'ya', u'\uFEF1': u'ya', u'\uFEF2': u'ya', u'\uFEF4': u'ya', u'\uFEF3': u'ya',
u'ة': u'at', u'\uFE93': u'at', u'\uFE94': u'at',
u'ى': u'a', u'\uFEEF': u'a', u'\uFEF0': u'a',
u'ی': u'ye', u'\uFBFC': u'ye', u'\uFBFD': u'ye', u'\uFBFE': u'ye', u'\uFBFF': u'ye',
# Arabic Sukun
u'\u064B': u'', u'\u064C': u'', u'\u064D': u'', u'\u064E': u'', u'\u064F': u'',
u'\u0650': u'', u'\u0651': u'', u'\u0652': u'', u'\u0653': u'', u'\u0670': u'',
# Arabic punctuation
u'،': u',', u'؍': u'.', u'؟': u'?', u'٭': u'', u'؞': u'...', u'٬': u'\'', u'\u200C': u'',
}
ascii_str = (u'_0123456789'
u'abcdefghijklmnopqrstuvwxyz'
u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
u'!"#$%&\'()*+,_-./:;<=>?@[\\]^`{|}~ \t\n\r\x0b\x0c')
ascii = ({}, dict(zip(ascii_str, ascii_str)))
for t in [latin, greek, turkish, russian, ukrainian, czech, polish, latvian, kazakh, farsi]:
if isinstance(t, dict):
t = ({}, t)
ascii[0].update(t[0])
ascii[1].update(t[1])
del t
ascii[1][None] = u'_'
slug = (ascii[0].copy(), ascii[1].copy())
for c in u'''!"#$%&'()*+,_-./:;<=>?@[\\]^`{|}~ \t\n\r\x0b\x0c''':
del slug[1][c]
tables = {u'ascii': ascii, u'text': ascii, u'slug': slug, u'id': slug}
# Main Trans with default tales
# It uses for str.encode('trans')
trans = Trans(tables=tables, default_table='ascii')
# trans codec work only with python 2
if PY2:
def encode(input, errors='strict', table_name='ascii'):
try:
table = trans.tables[table_name]
except KeyError:
raise ValueError("Table {0!r} not found in tables!".format(table_name))
else:
data = trans(input, table)
return data, len(data)
def no_decode(input, errors='strict'):
raise TypeError("trans codec does not support decode.")
def trans_codec(enc):
if enc == 'trans':
return codecs.CodecInfo(encode, no_decode)
try:
enc_name, table_name = enc.split(u'/', 1)
except ValueError:
return None
if enc_name != 'trans':
return None
if table_name not in trans.tables:
raise ValueError(u"Table {0!r} not found in tables!").format(table_name)
return codecs.CodecInfo(lambda i, e='strict': encode(i, e, table_name), no_decode)
codecs.register(trans_codec)