示例#1
0
 def _addValue(self, begin : 'Token', end : 'Token') -> None:
     tmp = io.StringIO()
     t = begin
     first_pass2889 = True
     while True:
         if first_pass2889: first_pass2889 = False
         else: t = t.next0_
         if (not (t is not None and t.previous != end)): break
         if (isinstance(t, NumberToken)): 
             print(t.getSourceText(), end="", file=tmp)
             continue
         if (isinstance(t, TextToken)): 
             s = (t).term
             if (t.isCharOf("-\\/")): 
                 s = "-"
             print(s, end="", file=tmp)
     i = 0
     while i < tmp.tell(): 
         if (Utils.getCharAtStringIO(tmp, i) == '-' and i > 0 and ((i + 1) < tmp.tell())): 
             ch0 = Utils.getCharAtStringIO(tmp, i - 1)
             ch1 = Utils.getCharAtStringIO(tmp, i + 1)
             if (str.isalnum(ch0) and str.isalnum(ch1)): 
                 if (str.isdigit(ch0) and not str.isdigit(ch1)): 
                     Utils.removeStringIO(tmp, i, 1)
                 elif (not str.isdigit(ch0) and str.isdigit(ch1)): 
                     Utils.removeStringIO(tmp, i, 1)
         i += 1
     self.addSlot(DenominationReferent.ATTR_VALUE, Utils.toStringStringIO(tmp), False, 0)
     self.__m_names = (None)
示例#2
0
 def to_string(self,
               short_variant: bool,
               lang: 'MorphLang' = None,
               lev: int = 0) -> str:
     res = Utils.newStringIO(self.template)
     vals = list()
     for s in self.slots:
         if (s.type_name == MeasureReferent.ATTR_VALUE):
             if (isinstance(s.value, str)):
                 val = Utils.asObjectOrNull(s.value, str)
                 if (val == "NaN"):
                     val = "?"
                 vals.append(val)
             elif (isinstance(s.value, Referent)):
                 vals.append(s.value.to_string(True, lang, 0))
     for i in range(res.tell() - 1, -1, -1):
         ch = Utils.getCharAtStringIO(res, i)
         if (not str.isdigit(ch)):
             continue
         j = ((ord(ch)) - (ord('1')))
         if ((j < 0) or j >= len(vals)):
             continue
         Utils.removeStringIO(res, i, 1)
         Utils.insertStringIO(res, i, vals[j])
     print(self.out_units(lang), end="", file=res)
     if (not short_variant):
         nam = self.get_string_value(MeasureReferent.ATTR_NAME)
         if (nam is not None):
             print(" - {0}".format(nam), end="", file=res, flush=True)
         for s in self.slots:
             if (s.type_name == MeasureReferent.ATTR_REF
                     and (isinstance(s.value, MeasureReferent))):
                 print(" / {0}".format(s.value.to_string(True, lang, 0)),
                       end="",
                       file=res,
                       flush=True)
         ki = self.kind
         if (ki != MeasureKind.UNDEFINED):
             print(" ({0})".format(Utils.enumToString(ki).upper()),
                   end="",
                   file=res,
                   flush=True)
     return Utils.toStringStringIO(res)
示例#3
0
 def toString(self, short_variant : bool, lang : 'MorphLang'=None, lev : int=0) -> str:
     res = Utils.newStringIO(self.template)
     vals = list()
     for s in self.slots: 
         if (s.type_name == MeasureReferent.ATTR_VALUE): 
             if (isinstance(s.value, str)): 
                 vals.append(Utils.asObjectOrNull(s.value, str))
             elif (isinstance(s.value, Referent)): 
                 vals.append((s.value).toString(True, lang, 0))
     for i in range(res.tell() - 1, -1, -1):
         ch = Utils.getCharAtStringIO(res, i)
         if (not str.isdigit(ch)): 
             continue
         j = ((ord(ch)) - (ord('1')))
         if ((j < 0) or j >= len(vals)): 
             continue
         Utils.removeStringIO(res, i, 1)
         Utils.insertStringIO(res, i, vals[j])
     uu = self.units
     if (len(uu) > 0): 
         print(uu[0].toString(True, lang, 0), end="", file=res)
         i = 1
         while i < len(uu): 
             pow0_ = uu[i].getStringValue(UnitReferent.ATTR_POW)
             if (not Utils.isNullOrEmpty(pow0_) and pow0_[0] == '-'): 
                 print("/{0}".format(uu[i].toString(True, lang, 1)), end="", file=res, flush=True)
                 if (pow0_ != "-1"): 
                     print("<{0}>".format(pow0_[1:]), end="", file=res, flush=True)
             else: 
                 print("*{0}".format(uu[i].toString(True, lang, 0)), end="", file=res, flush=True)
             i += 1
     if (not short_variant): 
         nam = self.getStringValue(MeasureReferent.ATTR_NAME)
         if (nam is not None): 
             print(" - {0}".format(nam), end="", file=res, flush=True)
         for s in self.slots: 
             if (s.type_name == MeasureReferent.ATTR_REF and (isinstance(s.value, MeasureReferent))): 
                 print(" / {0}".format((s.value).toString(True, lang, 0)), end="", file=res, flush=True)
         ki = self.kind
         if (ki != MeasureKind.UNDEFINED): 
             print(" ({0})".format(Utils.enumToString(ki).upper()), end="", file=res, flush=True)
     return Utils.toStringStringIO(res)
示例#4
0
 def correct_word_by_morph(self, word: str) -> str:
     vars0_ = list()
     tmp = Utils.newStringIO(len(word))
     ch = 1
     while ch < len(word):
         Utils.setLengthStringIO(tmp, 0)
         print(word, end="", file=tmp)
         Utils.setCharAtStringIO(tmp, ch, '*')
         var = self.__check_corr_var(Utils.toStringStringIO(tmp),
                                     self.m_root, 0)
         if (var is not None):
             if (not var in vars0_):
                 vars0_.append(var)
         ch += 1
     if (len(vars0_) == 0):
         ch = 1
         while ch < len(word):
             Utils.setLengthStringIO(tmp, 0)
             print(word, end="", file=tmp)
             Utils.insertStringIO(tmp, ch, '*')
             var = self.__check_corr_var(Utils.toStringStringIO(tmp),
                                         self.m_root, 0)
             if (var is not None):
                 if (not var in vars0_):
                     vars0_.append(var)
             ch += 1
     if (len(vars0_) == 0):
         ch = 1
         while ch < (len(word) - 1):
             Utils.setLengthStringIO(tmp, 0)
             print(word, end="", file=tmp)
             Utils.removeStringIO(tmp, ch, 1)
             var = self.__check_corr_var(Utils.toStringStringIO(tmp),
                                         self.m_root, 0)
             if (var is not None):
                 if (not var in vars0_):
                     vars0_.append(var)
             ch += 1
     if (len(vars0_) != 1):
         return None
     return vars0_[0]
示例#5
0
 def __try_attach_(self, pli : typing.List['PhoneItemToken'], ind : int, is_phone_before : bool, prev_phone : 'PhoneReferent', lev : int=0) -> 'ReferentToken':
     if (ind >= len(pli) or lev > 4): 
         return None
     country_code = None
     city_code = None
     j = ind
     if (prev_phone is not None and prev_phone._m_template is not None and pli[j].item_type == PhoneItemToken.PhoneItemType.NUMBER): 
         tmp = io.StringIO()
         jj = j
         first_pass3391 = True
         while True:
             if first_pass3391: first_pass3391 = False
             else: jj += 1
             if (not (jj < len(pli))): break
             if (pli[jj].item_type == PhoneItemToken.PhoneItemType.NUMBER): 
                 print(len(pli[jj].value), end="", file=tmp)
             elif (pli[jj].item_type == PhoneItemToken.PhoneItemType.DELIM): 
                 if (pli[jj].value == " "): 
                     break
                 print(pli[jj].value, end="", file=tmp)
                 continue
             else: 
                 break
             templ0 = Utils.toStringStringIO(tmp)
             if (templ0 == prev_phone._m_template): 
                 if ((jj + 1) < len(pli)): 
                     if (pli[jj + 1].item_type == PhoneItemToken.PhoneItemType.PREFIX and (jj + 2) == len(pli)): 
                         pass
                     else: 
                         del pli[jj + 1:jj + 1+len(pli) - jj - 1]
                 break
     if ((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.COUNTRYCODE): 
         country_code = pli[j].value
         if (country_code != "8"): 
             cc = PhoneHelper.get_country_prefix(country_code)
             if (cc is not None and (len(cc) < len(country_code))): 
                 city_code = country_code[len(cc):]
                 country_code = cc
         j += 1
     elif ((j < len(pli)) and pli[j].can_be_country_prefix): 
         k = j + 1
         if ((k < len(pli)) and pli[k].item_type == PhoneItemToken.PhoneItemType.DELIM): 
             k += 1
         rrt = self.__try_attach_(pli, k, is_phone_before, None, lev + 1)
         if (rrt is not None): 
             if ((((is_phone_before and pli[j + 1].item_type == PhoneItemToken.PhoneItemType.DELIM and pli[j + 1].begin_token.is_hiphen) and pli[j].item_type == PhoneItemToken.PhoneItemType.NUMBER and len(pli[j].value) == 3) and ((j + 2) < len(pli)) and pli[j + 2].item_type == PhoneItemToken.PhoneItemType.NUMBER) and len(pli[j + 2].value) == 3): 
                 pass
             else: 
                 country_code = pli[j].value
                 j += 1
     if (((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.NUMBER and ((pli[j].value[0] == '8' or pli[j].value[0] == '7'))) and country_code is None): 
         if (len(pli[j].value) == 1): 
             country_code = pli[j].value
             j += 1
         elif (len(pli[j].value) == 4): 
             country_code = pli[j].value[0:0+1]
             if (city_code is None): 
                 city_code = pli[j].value[1:]
             else: 
                 city_code += pli[j].value[1:]
             j += 1
         elif (len(pli[j].value) == 11 and j == (len(pli) - 1) and is_phone_before): 
             ph0 = PhoneReferent()
             if (pli[j].value[0] != '8'): 
                 ph0.country_code = pli[j].value[0:0+1]
             ph0.number = pli[j].value[1:1+3] + pli[j].value[4:]
             return ReferentToken(ph0, pli[0].begin_token, pli[j].end_token)
         elif (city_code is None and len(pli[j].value) > 3 and ((j + 1) < len(pli))): 
             sum0_ = 0
             for it in pli: 
                 if (it.item_type == PhoneItemToken.PhoneItemType.NUMBER): 
                     sum0_ += len(it.value)
             if (sum0_ == 11): 
                 city_code = pli[j].value[1:]
                 j += 1
     if ((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.CITYCODE): 
         if (city_code is None): 
             city_code = pli[j].value
         else: 
             city_code += pli[j].value
         j += 1
     if ((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.DELIM): 
         j += 1
     if ((country_code == "8" and city_code is None and ((j + 3) < len(pli))) and pli[j].item_type == PhoneItemToken.PhoneItemType.NUMBER): 
         if (len(pli[j].value) == 3 or len(pli[j].value) == 4): 
             city_code = pli[j].value
             j += 1
             if ((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.DELIM): 
                 j += 1
     normal_num_len = 0
     if (country_code == "421"): 
         normal_num_len = 9
     num = io.StringIO()
     templ = io.StringIO()
     part_length = list()
     delim = None
     ok = False
     additional = None
     std = False
     if (country_code is not None and ((j + 4) < len(pli)) and j > 0): 
         if (((((pli[j - 1].value == "-" or pli[j - 1].item_type == PhoneItemToken.PhoneItemType.COUNTRYCODE)) and pli[j].item_type == PhoneItemToken.PhoneItemType.NUMBER and pli[j + 1].item_type == PhoneItemToken.PhoneItemType.DELIM) and pli[j + 2].item_type == PhoneItemToken.PhoneItemType.NUMBER and pli[j + 3].item_type == PhoneItemToken.PhoneItemType.DELIM) and pli[j + 4].item_type == PhoneItemToken.PhoneItemType.NUMBER): 
             if ((((len(pli[j].value) + len(pli[j + 2].value)) == 6 or ((len(pli[j].value) == 4 and len(pli[j + 2].value) == 5)))) and ((len(pli[j + 4].value) == 4 or len(pli[j + 4].value) == 1))): 
                 print(pli[j].value, end="", file=num)
                 print(pli[j + 2].value, end="", file=num)
                 print(pli[j + 4].value, end="", file=num)
                 print("{0}{1}{2}{3}{4}".format(len(pli[j].value), pli[j + 1].value, len(pli[j + 2].value), pli[j + 3].value, len(pli[j + 4].value)), end="", file=templ, flush=True)
                 std = True
                 ok = True
                 j += 5
     first_pass3392 = True
     while True:
         if first_pass3392: first_pass3392 = False
         else: j += 1
         if (not (j < len(pli))): break
         if (std): 
             break
         if (pli[j].item_type == PhoneItemToken.PhoneItemType.DELIM): 
             if (pli[j].is_in_brackets): 
                 continue
             if (j > 0 and pli[j - 1].is_in_brackets): 
                 continue
             if (templ.tell() > 0): 
                 print(pli[j].value, end="", file=templ)
             if (delim is None): 
                 delim = pli[j].value
             elif (pli[j].value != delim): 
                 if ((len(part_length) == 2 and ((part_length[0] == 3 or part_length[0] == 4)) and city_code is None) and part_length[1] == 3): 
                     city_code = Utils.toStringStringIO(num)[0:0+part_length[0]]
                     Utils.removeStringIO(num, 0, part_length[0])
                     del part_length[0]
                     delim = pli[j].value
                     continue
                 if (is_phone_before and ((j + 1) < len(pli)) and pli[j + 1].item_type == PhoneItemToken.PhoneItemType.NUMBER): 
                     if (num.tell() < 6): 
                         continue
                     if (normal_num_len > 0 and (num.tell() + len(pli[j + 1].value)) == normal_num_len): 
                         continue
                 break
             else: 
                 continue
             ok = False
         elif (pli[j].item_type == PhoneItemToken.PhoneItemType.NUMBER): 
             if (num.tell() == 0 and pli[j].begin_token.previous is not None and pli[j].begin_token.previous.is_table_control_char): 
                 tt = pli[len(pli) - 1].end_token.next0_
                 if (tt is not None and tt.is_char_of(",.")): 
                     tt = tt.next0_
                 if (isinstance(tt, NumberToken)): 
                     return None
             if ((num.tell() + len(pli[j].value)) > 13): 
                 if (j > 0 and pli[j - 1].item_type == PhoneItemToken.PhoneItemType.DELIM): 
                     j -= 1
                 ok = True
                 break
             print(pli[j].value, end="", file=num)
             part_length.append(len(pli[j].value))
             print(len(pli[j].value), end="", file=templ)
             ok = True
             if (num.tell() > 10): 
                 j += 1
                 if ((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.ADDNUMBER): 
                     additional = pli[j].value
                     j += 1
                 break
         elif (pli[j].item_type == PhoneItemToken.PhoneItemType.ADDNUMBER): 
             additional = pli[j].value
             j += 1
             break
         else: 
             break
     if ((j == (len(pli) - 1) and pli[j].is_in_brackets and ((len(pli[j].value) == 3 or len(pli[j].value) == 4))) and additional is None): 
         additional = pli[j].value
         j += 1
     if ((j < len(pli)) and pli[j].item_type == PhoneItemToken.PhoneItemType.PREFIX and pli[j].is_in_brackets): 
         is_phone_before = True
         j += 1
     if ((country_code is None and city_code is not None and len(city_code) > 3) and (num.tell() < 8) and city_code[0] != '8'): 
         if ((len(city_code) + num.tell()) == 10): 
             pass
         else: 
             cc = PhoneHelper.get_country_prefix(city_code)
             if (cc is not None): 
                 if (len(cc) > 1 and (len(city_code) - len(cc)) > 1): 
                     country_code = cc
                     city_code = city_code[len(cc):]
     if (country_code is None and city_code is not None and city_code.startswith("00")): 
         cc = PhoneHelper.get_country_prefix(city_code[2:])
         if (cc is not None): 
             if (len(city_code) > (len(cc) + 3)): 
                 country_code = cc
                 city_code = city_code[len(cc) + 2:]
     if (num.tell() == 0 and city_code is not None): 
         if (len(city_code) == 10): 
             print(city_code[3:], end="", file=num)
             part_length.append(num.tell())
             city_code = city_code[0:0+3]
             ok = True
         elif (((len(city_code) == 9 or len(city_code) == 11 or len(city_code) == 8)) and ((is_phone_before or country_code is not None))): 
             print(city_code, end="", file=num)
             part_length.append(num.tell())
             city_code = (None)
             ok = True
     if (num.tell() < 4): 
         ok = False
     if (num.tell() < 7): 
         if (city_code is not None and (len(city_code) + num.tell()) > 7): 
             if (not is_phone_before and len(city_code) == 3): 
                 ii = 0
                 ii = 0
                 while ii < len(part_length): 
                     if (part_length[ii] == 3): 
                         pass
                     elif (part_length[ii] > 3): 
                         break
                     elif ((ii < (len(part_length) - 1)) or (part_length[ii] < 2)): 
                         break
                     ii += 1
                 if (ii >= len(part_length)): 
                     if (country_code == "61"): 
                         pass
                     else: 
                         ok = False
         elif (((num.tell() == 6 or num.tell() == 5)) and ((len(part_length) >= 1 and len(part_length) <= 3)) and is_phone_before): 
             if (pli[0].item_type == PhoneItemToken.PhoneItemType.PREFIX and pli[0].kind == PhoneKind.HOME): 
                 ok = False
         elif (prev_phone is not None and prev_phone.number is not None and ((len(prev_phone.number) == num.tell() or len(prev_phone.number) == (num.tell() + 3) or len(prev_phone.number) == (num.tell() + 4)))): 
             pass
         elif (num.tell() > 4 and prev_phone is not None and Utils.toStringStringIO(templ) == prev_phone._m_template): 
             ok = True
         else: 
             ok = False
     if (delim == "." and country_code is None and city_code is None): 
         ok = False
     if ((is_phone_before and country_code is None and city_code is None) and num.tell() > 10): 
         cc = PhoneHelper.get_country_prefix(Utils.toStringStringIO(num))
         if (cc is not None): 
             if ((num.tell() - len(cc)) == 9): 
                 country_code = cc
                 Utils.removeStringIO(num, 0, len(cc))
                 ok = True
     if (ok): 
         if (std): 
             pass
         elif (prev_phone is not None and prev_phone.number is not None and (((len(prev_phone.number) == num.tell() or len(prev_phone.number) == (num.tell() + 3) or len(prev_phone.number) == (num.tell() + 4)) or prev_phone._m_template == Utils.toStringStringIO(templ)))): 
             pass
         elif ((len(part_length) == 3 and part_length[0] == 3 and part_length[1] == 2) and part_length[2] == 2): 
             pass
         elif (len(part_length) == 3 and is_phone_before): 
             pass
         elif ((len(part_length) == 4 and (((part_length[0] + part_length[1]) == 3)) and part_length[2] == 2) and part_length[3] == 2): 
             pass
         elif ((len(part_length) == 4 and part_length[0] == 3 and part_length[1] == 3) and part_length[2] == 2 and part_length[3] == 2): 
             pass
         elif (len(part_length) == 5 and (part_length[1] + part_length[2]) == 4 and (part_length[3] + part_length[4]) == 4): 
             pass
         elif (len(part_length) > 4): 
             ok = False
         elif (len(part_length) > 3 and city_code is not None): 
             ok = False
         elif ((is_phone_before or city_code is not None or country_code is not None) or additional is not None): 
             ok = True
         else: 
             ok = False
             if (((num.tell() == 6 or num.tell() == 7)) and (len(part_length) < 4) and j > 0): 
                 next_ph = self.__get_next_phone(pli[j - 1].end_token.next0_, lev + 1)
                 if (next_ph is not None): 
                     d = len(next_ph.number) - num.tell()
                     if (d == 0 or d == 3 or d == 4): 
                         ok = True
     end = (pli[j - 1].end_token if j > 0 else None)
     if (end is None): 
         ok = False
     if ((ok and city_code is None and country_code is None) and prev_phone is None and not is_phone_before): 
         if (not end.is_whitespace_after and end.next0_ is not None): 
             tt = end.next0_
             if (tt.is_char_of(".,)") and tt.next0_ is not None): 
                 tt = tt.next0_
             if (not tt.is_whitespace_before): 
                 ok = False
     if (not ok): 
         return None
     if (templ.tell() > 0 and not str.isdigit(Utils.getCharAtStringIO(templ, templ.tell() - 1))): 
         Utils.setLengthStringIO(templ, templ.tell() - 1)
     if ((country_code is None and city_code is not None and len(city_code) > 3) and num.tell() > 6): 
         cc = PhoneHelper.get_country_prefix(city_code)
         if (cc is not None and ((len(cc) + 1) < len(city_code))): 
             country_code = cc
             city_code = city_code[len(cc):]
     if (pli[0].begin_token.previous is not None): 
         if (pli[0].begin_token.previous.is_value("ГОСТ", None) or pli[0].begin_token.previous.is_value("ТУ", None)): 
             return None
     ph = PhoneReferent()
     if (country_code is not None): 
         ph.country_code = country_code
     number = Utils.toStringStringIO(num)
     if ((city_code is None and num.tell() > 7 and len(part_length) > 0) and (part_length[0] < 5)): 
         city_code = number[0:0+part_length[0]]
         number = number[part_length[0]:]
     if (city_code is None and num.tell() == 11 and Utils.getCharAtStringIO(num, 0) == '8'): 
         city_code = number[1:1+3]
         number = number[4:]
     if (city_code is None and num.tell() == 10): 
         city_code = number[0:0+3]
         number = number[3:]
     if (city_code is not None): 
         number = (city_code + number)
     elif (country_code is None and prev_phone is not None): 
         ok1 = False
         if (len(prev_phone.number) >= (len(number) + 2)): 
             ok1 = True
         elif (templ.tell() > 0 and prev_phone._m_template is not None and LanguageHelper.ends_with(prev_phone._m_template, Utils.toStringStringIO(templ))): 
             ok1 = True
         if (ok1 and len(prev_phone.number) > len(number)): 
             number = (prev_phone.number[0:0+len(prev_phone.number) - len(number)] + number)
     if (ph.country_code is None and prev_phone is not None and prev_phone.country_code is not None): 
         if (len(prev_phone.number) == len(number)): 
             ph.country_code = prev_phone.country_code
     ok = False
     for d in number: 
         if (d != '0'): 
             ok = True
             break
     if (not ok): 
         return None
     if (country_code is not None): 
         if (len(number) < 7): 
             return None
     else: 
         s = PhoneHelper.get_country_prefix(number)
         if (s is not None): 
             num2 = number[len(s):]
             if (len(num2) >= 10 and len(num2) <= 11): 
                 number = num2
                 if (s != "7"): 
                     ph.country_code = s
         if (len(number) == 8 and prev_phone is None): 
             return None
     if (len(number) > 11): 
         if ((len(number) < 14) and ((country_code == "1" or country_code == "43"))): 
             pass
         else: 
             return None
     ph.number = number
     if (additional is not None): 
         ph.add_slot(PhoneReferent.ATTR_ADDNUMBER, additional, True, 0)
     if (not is_phone_before and end.next0_ is not None and not end.is_newline_after): 
         if (end.next0_.is_char_of("+=") or end.next0_.is_hiphen): 
             return None
     if (country_code is not None and country_code == "7"): 
         if (len(number) != 10): 
             return None
     ph._m_template = Utils.toStringStringIO(templ)
     if (j == (len(pli) - 1) and pli[j].item_type == PhoneItemToken.PhoneItemType.PREFIX and not pli[j].is_newline_before): 
         end = pli[j].end_token
         if (pli[j].kind != PhoneKind.UNDEFINED): 
             ph.kind = pli[j].kind
     res = ReferentToken(ph, pli[0].begin_token, end)
     if (pli[0].item_type == PhoneItemToken.PhoneItemType.PREFIX and pli[0].end_token.next0_.is_table_control_char): 
         res.begin_token = pli[1].begin_token
     return res
示例#6
0
 def transliteral_correction(value: str,
                             prev_value: str,
                             always: bool = False) -> str:
     """ Транслитеральная корректировка
     
     Args:
         value(str): 
         prev_value(str): 
         always(bool): 
     
     """
     pure_cyr = 0
     pure_lat = 0
     ques_cyr = 0
     ques_lat = 0
     udar_cyr = 0
     y = False
     udaren = False
     i = 0
     first_pass2897 = True
     while True:
         if first_pass2897: first_pass2897 = False
         else: i += 1
         if (not (i < len(value))): break
         ch = value[i]
         ui = UnicodeInfo.ALL_CHARS[ord(ch)]
         if (not ui.is_letter):
             if (ui.is_udaren):
                 udaren = True
                 continue
             if (ui.is_apos and len(value) > 2):
                 return LanguageHelper.transliteral_correction(
                     value.replace("{0}".format(ch), ""), prev_value, False)
             return value
         if (ui.is_cyrillic):
             if (LanguageHelper._m_cyr_chars.find(ch) >= 0):
                 ques_cyr += 1
             else:
                 pure_cyr += 1
         elif (ui.is_latin):
             if (LanguageHelper._m_lat_chars.find(ch) >= 0):
                 ques_lat += 1
             else:
                 pure_lat += 1
         elif (LanguageHelper.__m_udar_chars.find(ch) >= 0):
             udar_cyr += 1
         else:
             return value
         if (ch == 'Ь' and ((i + 1) < len(value)) and value[i + 1] == 'I'):
             y = True
     to_rus = False
     to_lat = False
     if (pure_lat > 0 and pure_cyr > 0):
         return value
     if (((pure_lat > 0 or always)) and ques_cyr > 0):
         to_lat = True
     elif (((pure_cyr > 0 or always)) and ques_lat > 0):
         to_rus = True
     elif (pure_cyr == 0 and pure_lat == 0):
         if (ques_cyr > 0 and ques_lat > 0):
             if (not Utils.isNullOrEmpty(prev_value)):
                 if (LanguageHelper.is_cyrillic_char(prev_value[0])):
                     to_rus = True
                 elif (LanguageHelper.is_latin_char(prev_value[0])):
                     to_lat = True
             if (not to_lat and not to_rus):
                 if (ques_cyr > ques_lat):
                     to_rus = True
                 elif (ques_cyr < ques_lat):
                     to_lat = True
     if (not to_rus and not to_lat):
         if (not y and not udaren and udar_cyr == 0):
             return value
     tmp = Utils.newStringIO(value)
     i = 0
     first_pass2898 = True
     while True:
         if first_pass2898: first_pass2898 = False
         else: i += 1
         if (not (i < tmp.tell())): break
         if (Utils.getCharAtStringIO(tmp, i) == 'Ь'
                 and ((i + 1) < tmp.tell())
                 and Utils.getCharAtStringIO(tmp, i + 1) == 'I'):
             Utils.setCharAtStringIO(tmp, i, 'Ы')
             Utils.removeStringIO(tmp, i + 1, 1)
             continue
         cod = ord(Utils.getCharAtStringIO(tmp, i))
         if (cod >= 0x300 and (cod < 0x370)):
             Utils.removeStringIO(tmp, i, 1)
             continue
         if (to_rus):
             ii = LanguageHelper._m_lat_chars.find(
                 Utils.getCharAtStringIO(tmp, i))
             if (ii >= 0):
                 Utils.setCharAtStringIO(tmp, i,
                                         LanguageHelper._m_cyr_chars[ii])
             else:
                 ii = LanguageHelper.__m_udar_chars.find(
                     Utils.getCharAtStringIO(tmp, i))
                 if (((ii)) >= 0):
                     Utils.setCharAtStringIO(
                         tmp, i, LanguageHelper.__m_udar_cyr_chars[ii])
         elif (to_lat):
             ii = LanguageHelper._m_cyr_chars.find(
                 Utils.getCharAtStringIO(tmp, i))
             if (ii >= 0):
                 Utils.setCharAtStringIO(tmp, i,
                                         LanguageHelper._m_lat_chars[ii])
         else:
             ii = LanguageHelper.__m_udar_chars.find(
                 Utils.getCharAtStringIO(tmp, i))
             if (ii >= 0):
                 Utils.setCharAtStringIO(
                     tmp, i, LanguageHelper.__m_udar_cyr_chars[ii])
     return Utils.toStringStringIO(tmp)